Full Code of misakuo/Dream-Catcher for AI

master 7782266d8b77 cached
289 files
1.0 MB
348.9k tokens
2091 symbols
1 requests
Download .txt
Showing preview only (1,165K chars total). Download the full file or copy to clipboard to get everything.
Repository: misakuo/Dream-Catcher
Branch: master
Commit: 7782266d8b77
Files: 289
Total size: 1.0 MB

Directory structure:
gitextract_4zj9hsfj/

├── .gitignore
├── .idea/
│   ├── compiler.xml
│   ├── copyright/
│   │   └── profiles_settings.xml
│   ├── encodings.xml
│   ├── gradle.xml
│   ├── misc.xml
│   ├── modules.xml
│   └── runConfigurations.xml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── dream_catcher-1.0.1.apk
│   ├── dream_catcher-1.1.0.apk
│   ├── dream_catcher-1.2.0.apk
│   ├── libs/
│   │   └── netty-android.jar
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── me/
│       │           └── moxun/
│       │               └── dreamcatcher/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   ├── me/
│       │   │   │   └── moxun/
│       │   │   │       └── dreamcatcher/
│       │   │   │           ├── CaptureActivity.java
│       │   │   │           ├── DCApplication.java
│       │   │   │           ├── State.java
│       │   │   │           ├── connector/
│       │   │   │           │   ├── Connector.java
│       │   │   │           │   ├── InspectorModulesProvider.java
│       │   │   │           │   ├── console/
│       │   │   │           │   │   ├── CLog.java
│       │   │   │           │   │   ├── ConsolePeerManager.java
│       │   │   │           │   │   ├── RuntimeRepl.java
│       │   │   │           │   │   ├── RuntimeReplFactory.java
│       │   │   │           │   │   └── command/
│       │   │   │           │   │       └── CommandHandler.java
│       │   │   │           │   ├── inspector/
│       │   │   │           │   │   ├── ChromeDevtoolsServer.java
│       │   │   │           │   │   ├── ChromeDiscoveryHandler.java
│       │   │   │           │   │   ├── DevtoolsSocketHandler.java
│       │   │   │           │   │   ├── MessageHandlingException.java
│       │   │   │           │   │   ├── MethodDispatcher.java
│       │   │   │           │   │   ├── MismatchedResponseException.java
│       │   │   │           │   │   ├── helper/
│       │   │   │           │   │   │   ├── ChromePeerManager.java
│       │   │   │           │   │   │   ├── ObjectIdMapper.java
│       │   │   │           │   │   │   ├── PeerRegistrationListener.java
│       │   │   │           │   │   │   ├── PeersRegisteredListener.java
│       │   │   │           │   │   │   ├── ThreadBoundProxy.java
│       │   │   │           │   │   │   └── TracingPeerManager.java
│       │   │   │           │   │   ├── protocol/
│       │   │   │           │   │   │   ├── ChromeDevtoolsDomain.java
│       │   │   │           │   │   │   ├── ChromeDevtoolsMethod.java
│       │   │   │           │   │   │   ├── SimpleBooleanResult.java
│       │   │   │           │   │   │   ├── SimpleIntegerResult.java
│       │   │   │           │   │   │   ├── SimpleStringResult.java
│       │   │   │           │   │   │   └── module/
│       │   │   │           │   │   │       ├── Console.java
│       │   │   │           │   │   │       ├── FileSystem.java
│       │   │   │           │   │   │       ├── Inspector.java
│       │   │   │           │   │   │       ├── Network.java
│       │   │   │           │   │   │       ├── Page.java
│       │   │   │           │   │   │       ├── Profiler.java
│       │   │   │           │   │   │       └── Runtime.java
│       │   │   │           │   │   └── runtime/
│       │   │   │           │   │       └── DefaultRuntimeReplFactory.java
│       │   │   │           │   ├── json/
│       │   │   │           │   │   ├── ObjectMapper.java
│       │   │   │           │   │   └── annotation/
│       │   │   │           │   │       ├── JsonProperty.java
│       │   │   │           │   │       └── JsonValue.java
│       │   │   │           │   ├── jsonrpc/
│       │   │   │           │   │   ├── DisconnectReceiver.java
│       │   │   │           │   │   ├── JsonRpcException.java
│       │   │   │           │   │   ├── JsonRpcPeer.java
│       │   │   │           │   │   ├── JsonRpcResult.java
│       │   │   │           │   │   ├── PendingRequest.java
│       │   │   │           │   │   ├── PendingRequestCallback.java
│       │   │   │           │   │   └── protocol/
│       │   │   │           │   │       ├── EmptyResult.java
│       │   │   │           │   │       ├── JsonRpcError.java
│       │   │   │           │   │       ├── JsonRpcEvent.java
│       │   │   │           │   │       ├── JsonRpcRequest.java
│       │   │   │           │   │       └── JsonRpcResponse.java
│       │   │   │           │   ├── log/
│       │   │   │           │   │   ├── AELog.java
│       │   │   │           │   │   ├── AELogImpl.java
│       │   │   │           │   │   └── IAELog.java
│       │   │   │           │   ├── manager/
│       │   │   │           │   │   ├── Lifecycle.java
│       │   │   │           │   │   └── SimpleConnectorLifecycleManager.java
│       │   │   │           │   ├── reporter/
│       │   │   │           │   │   ├── AsyncPrettyPrinter.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterExecutorHolder.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterFactory.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterInitializer.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterRegistry.java
│       │   │   │           │   │   ├── CountingOutputStream.java
│       │   │   │           │   │   ├── DecompressionHelper.java
│       │   │   │           │   │   ├── DefaultResponseHandler.java
│       │   │   │           │   │   ├── DownloadingAsyncPrettyPrinterFactory.java
│       │   │   │           │   │   ├── GunzippingOutputStream.java
│       │   │   │           │   │   ├── MimeMatcher.java
│       │   │   │           │   │   ├── NetworkEventReporter.java
│       │   │   │           │   │   ├── NetworkEventReporterImpl.java
│       │   │   │           │   │   ├── NetworkPeerManager.java
│       │   │   │           │   │   ├── PrettyPrinterDisplayType.java
│       │   │   │           │   │   ├── RequestBodyHelper.java
│       │   │   │           │   │   ├── ResourceTypeHelper.java
│       │   │   │           │   │   ├── ResponseBodyData.java
│       │   │   │           │   │   ├── ResponseBodyFileManager.java
│       │   │   │           │   │   ├── ResponseHandler.java
│       │   │   │           │   │   └── ResponseHandlingInputStream.java
│       │   │   │           │   ├── server/
│       │   │   │           │   │   ├── AddressNameHelper.java
│       │   │   │           │   │   ├── CompositeInputStream.java
│       │   │   │           │   │   ├── LazySocketHandler.java
│       │   │   │           │   │   ├── LeakyBufferedInputStream.java
│       │   │   │           │   │   ├── LocalSocketServer.java
│       │   │   │           │   │   ├── PeerAuthorizationException.java
│       │   │   │           │   │   ├── ProtocolDetectingSocketHandler.java
│       │   │   │           │   │   ├── SecureSocketHandler.java
│       │   │   │           │   │   ├── ServerManager.java
│       │   │   │           │   │   ├── SocketHandler.java
│       │   │   │           │   │   ├── SocketHandlerFactory.java
│       │   │   │           │   │   ├── SocketLike.java
│       │   │   │           │   │   ├── SocketLikeHandler.java
│       │   │   │           │   │   └── http/
│       │   │   │           │   │       ├── ExactPathMatcher.java
│       │   │   │           │   │       ├── HandlerRegistry.java
│       │   │   │           │   │       ├── HttpHandler.java
│       │   │   │           │   │       ├── HttpHeaders.java
│       │   │   │           │   │       ├── HttpStatus.java
│       │   │   │           │   │       ├── LightHttpBody.java
│       │   │   │           │   │       ├── LightHttpMessage.java
│       │   │   │           │   │       ├── LightHttpRequest.java
│       │   │   │           │   │       ├── LightHttpResponse.java
│       │   │   │           │   │       ├── LightHttpServer.java
│       │   │   │           │   │       ├── PathMatcher.java
│       │   │   │           │   │       └── RegexpPathMatcher.java
│       │   │   │           │   ├── util/
│       │   │   │           │   │   ├── Accumulator.java
│       │   │   │           │   │   ├── ArrayListAccumulator.java
│       │   │   │           │   │   ├── ColorStringUtil.java
│       │   │   │           │   │   ├── DreamCatcherCrashHandler.java
│       │   │   │           │   │   ├── ExceptionUtil.java
│       │   │   │           │   │   ├── IServerManager.java
│       │   │   │           │   │   ├── KLog.java
│       │   │   │           │   │   ├── KLogImpl.java
│       │   │   │           │   │   ├── Keys.java
│       │   │   │           │   │   ├── ListUtil.java
│       │   │   │           │   │   ├── LogFilter.java
│       │   │   │           │   │   ├── LogInterface.java
│       │   │   │           │   │   ├── LogUtil.java
│       │   │   │           │   │   ├── Predicate.java
│       │   │   │           │   │   ├── ProcessUtil.java
│       │   │   │           │   │   ├── ReflectionUtil.java
│       │   │   │           │   │   ├── SocketServerManager.java
│       │   │   │           │   │   ├── StringUtil.java
│       │   │   │           │   │   ├── ThreadBound.java
│       │   │   │           │   │   ├── UncheckedCallable.java
│       │   │   │           │   │   ├── Utf8Charset.java
│       │   │   │           │   │   └── Util.java
│       │   │   │           │   └── websocket/
│       │   │   │           │       ├── CloseCodes.java
│       │   │   │           │       ├── Frame.java
│       │   │   │           │       ├── FrameHelper.java
│       │   │   │           │       ├── MaskingHelper.java
│       │   │   │           │       ├── ReadCallback.java
│       │   │   │           │       ├── ReadHandler.java
│       │   │   │           │       ├── SimpleEndpoint.java
│       │   │   │           │       ├── SimpleSession.java
│       │   │   │           │       ├── WebSocketHandler.java
│       │   │   │           │       ├── WebSocketSession.java
│       │   │   │           │       ├── WriteCallback.java
│       │   │   │           │       └── WriteHandler.java
│       │   │   │           ├── event/
│       │   │   │           │   ├── CaptureEvent.java
│       │   │   │           │   └── OperateEvent.java
│       │   │   │           ├── misc/
│       │   │   │           │   └── X509ExtendedTrustManager.java
│       │   │   │           ├── service/
│       │   │   │           │   ├── ConnectorService.java
│       │   │   │           │   └── ProxyService.java
│       │   │   │           └── wrapper/
│       │   │   │               ├── DCHeader.java
│       │   │   │               ├── DCRequest.java
│       │   │   │               ├── DCResponse.java
│       │   │   │               └── ProxyManager.java
│       │   │   └── net/
│       │   │       └── lightbody/
│       │   │           └── bmp/
│       │   │               ├── BrowserMobProxy.java
│       │   │               ├── BrowserMobProxyServer.java
│       │   │               ├── client/
│       │   │               │   └── ClientUtil.java
│       │   │               ├── core/
│       │   │               │   ├── har/
│       │   │               │   │   ├── Har.java
│       │   │               │   │   ├── HarCache.java
│       │   │               │   │   ├── HarCacheStatus.java
│       │   │               │   │   ├── HarContent.java
│       │   │               │   │   ├── HarCookie.java
│       │   │               │   │   ├── HarEntry.java
│       │   │               │   │   ├── HarLog.java
│       │   │               │   │   ├── HarNameValuePair.java
│       │   │               │   │   ├── HarNameVersion.java
│       │   │               │   │   ├── HarPage.java
│       │   │               │   │   ├── HarPageTimings.java
│       │   │               │   │   ├── HarPostData.java
│       │   │               │   │   ├── HarPostDataParam.java
│       │   │               │   │   ├── HarRequest.java
│       │   │               │   │   ├── HarResponse.java
│       │   │               │   │   └── HarTimings.java
│       │   │               │   └── json/
│       │   │               │       ├── ISO8601DateFormatter.java
│       │   │               │       └── ISO8601WithTDZDateFormatter.java
│       │   │               ├── exception/
│       │   │               │   ├── DecompressionException.java
│       │   │               │   └── UnsupportedCharsetException.java
│       │   │               ├── filters/
│       │   │               │   ├── AddHeadersFilter.java
│       │   │               │   ├── AutoBasicAuthFilter.java
│       │   │               │   ├── BlacklistFilter.java
│       │   │               │   ├── BrowserMobHttpFilterChain.java
│       │   │               │   ├── ClientRequestCaptureFilter.java
│       │   │               │   ├── HarCaptureFilter.java
│       │   │               │   ├── HttpConnectHarCaptureFilter.java
│       │   │               │   ├── HttpsAwareFiltersAdapter.java
│       │   │               │   ├── HttpsHostCaptureFilter.java
│       │   │               │   ├── HttpsOriginalHostCaptureFilter.java
│       │   │               │   ├── LatencyFilter.java
│       │   │               │   ├── ModifiedRequestAwareFilter.java
│       │   │               │   ├── RegisterRequestFilter.java
│       │   │               │   ├── RequestFilter.java
│       │   │               │   ├── RequestFilterAdapter.java
│       │   │               │   ├── ResolvedHostnameCacheFilter.java
│       │   │               │   ├── ResponseFilter.java
│       │   │               │   ├── ResponseFilterAdapter.java
│       │   │               │   ├── RewriteUrlFilter.java
│       │   │               │   ├── ServerResponseCaptureFilter.java
│       │   │               │   ├── UnregisterRequestFilter.java
│       │   │               │   ├── WhitelistFilter.java
│       │   │               │   ├── support/
│       │   │               │   │   └── HttpConnectTiming.java
│       │   │               │   └── util/
│       │   │               │       └── HarCaptureUtil.java
│       │   │               ├── mitm/
│       │   │               │   ├── CertificateAndKey.java
│       │   │               │   ├── CertificateAndKeySource.java
│       │   │               │   ├── CertificateInfo.java
│       │   │               │   ├── CertificateInfoGenerator.java
│       │   │               │   ├── ExistingCertificateSource.java
│       │   │               │   ├── HostnameCertificateInfoGenerator.java
│       │   │               │   ├── KeyStoreCertificateSource.java
│       │   │               │   ├── KeyStoreFileCertificateSource.java
│       │   │               │   ├── PemFileCertificateSource.java
│       │   │               │   ├── RootCertificateGenerator.java
│       │   │               │   ├── TrustSource.java
│       │   │               │   ├── exception/
│       │   │               │   │   ├── CertificateCreationException.java
│       │   │               │   │   ├── CertificateSourceException.java
│       │   │               │   │   ├── ExportException.java
│       │   │               │   │   ├── ImportException.java
│       │   │               │   │   ├── KeyGeneratorException.java
│       │   │               │   │   ├── KeyStoreAccessException.java
│       │   │               │   │   ├── MitmException.java
│       │   │               │   │   ├── SslContextInitializationException.java
│       │   │               │   │   ├── TrustSourceException.java
│       │   │               │   │   └── UncheckedIOException.java
│       │   │               │   ├── keys/
│       │   │               │   │   ├── ECKeyGenerator.java
│       │   │               │   │   ├── KeyGenerator.java
│       │   │               │   │   └── RSAKeyGenerator.java
│       │   │               │   ├── manager/
│       │   │               │   │   └── ImpersonatingMitmManager.java
│       │   │               │   ├── stats/
│       │   │               │   │   └── CertificateGenerationStatistics.java
│       │   │               │   ├── tools/
│       │   │               │   │   ├── BouncyCastleSecurityProviderTool.java
│       │   │               │   │   ├── DefaultSecurityProviderTool.java
│       │   │               │   │   └── SecurityProviderTool.java
│       │   │               │   ├── trustmanager/
│       │   │               │   │   ├── InsecureExtendedTrustManager.java
│       │   │               │   │   └── InsecureTrustManagerFactory.java
│       │   │               │   └── util/
│       │   │               │       ├── EncryptionUtil.java
│       │   │               │       ├── KeyStoreUtil.java
│       │   │               │       ├── MitmConstants.java
│       │   │               │       ├── SslUtil.java
│       │   │               │       └── TrustUtil.java
│       │   │               ├── proxy/
│       │   │               │   ├── ActivityMonitor.java
│       │   │               │   ├── BlacklistEntry.java
│       │   │               │   ├── CaptureType.java
│       │   │               │   ├── RewriteRule.java
│       │   │               │   ├── Whitelist.java
│       │   │               │   ├── auth/
│       │   │               │   │   └── AuthType.java
│       │   │               │   └── dns/
│       │   │               │       ├── AbstractHostNameRemapper.java
│       │   │               │       ├── AdvancedHostResolver.java
│       │   │               │       ├── BasicHostResolver.java
│       │   │               │       ├── ChainedHostResolver.java
│       │   │               │       ├── DelegatingHostResolver.java
│       │   │               │       ├── DnsJavaResolver.java
│       │   │               │       ├── HostResolver.java
│       │   │               │       ├── NativeCacheManipulatingResolver.java
│       │   │               │       └── NativeResolver.java
│       │   │               └── util/
│       │   │                   ├── BrowserMobHttpUtil.java
│       │   │                   ├── BrowserMobProxyUtil.java
│       │   │                   ├── ClasspathResourceUtil.java
│       │   │                   ├── HttpMessageContents.java
│       │   │                   ├── HttpMessageInfo.java
│       │   │                   ├── HttpObjectUtil.java
│       │   │                   └── HttpUtil.java
│       │   ├── res/
│       │   │   ├── layout/
│       │   │   │   └── activity_capture.xml
│       │   │   ├── menu/
│       │   │   │   └── menu_main.xml
│       │   │   ├── values/
│       │   │   │   ├── colors.xml
│       │   │   │   ├── dimens.xml
│       │   │   │   ├── strings.xml
│       │   │   │   └── styles.xml
│       │   │   └── values-w820dp/
│       │   │       └── dimens.xml
│       │   └── resources/
│       │       ├── cacerts.pem
│       │       ├── default-ciphers.txt
│       │       ├── net/
│       │       │   └── lightbody/
│       │       │       └── bmp/
│       │       │           └── version
│       │       └── sslSupport/
│       │           ├── ca-certificate-ec.cer
│       │           ├── ca-certificate-rsa.cer
│       │           ├── ca-keystore-ec.p12
│       │           └── ca-keystore-rsa.p12
│       └── test/
│           └── java/
│               └── me/
│                   └── moxun/
│                       └── dreamcatcher/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild


================================================
FILE: .idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <resourceExtensions />
    <wildcardResourcePatterns>
      <entry name="!?*.java" />
      <entry name="!?*.form" />
      <entry name="!?*.class" />
      <entry name="!?*.groovy" />
      <entry name="!?*.scala" />
      <entry name="!?*.flex" />
      <entry name="!?*.kt" />
      <entry name="!?*.clj" />
      <entry name="!?*.aj" />
    </wildcardResourcePatterns>
    <annotationProcessing>
      <profile default="true" name="Default" enabled="false">
        <processorPath useClasspath="true" />
      </profile>
    </annotationProcessing>
  </component>
</project>

================================================
FILE: .idea/copyright/profiles_settings.xml
================================================
<component name="CopyrightManager">
  <settings default="" />
</component>

================================================
FILE: .idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="PROJECT" charset="UTF-8" />
  </component>
</project>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="EntryPointsManager">
    <entry_points version="2.0" />
  </component>
  <component name="MavenImportPreferences">
    <option name="generalSettings">
      <MavenGeneralSettings>
        <option name="mavenHome" value="Bundled (Maven 3)" />
      </MavenGeneralSettings>
    </option>
  </component>
  <component name="NullableNotNullManager">
    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
    <option name="myNullables">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
        </list>
      </value>
    </option>
    <option name="myNotNulls">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
        </list>
      </value>
    </option>
  </component>
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
  <component name="masterDetails">
    <states>
      <state key="ProjectJDKs.UI">
        <settings>
          <last-edited>1.8</last-edited>
          <splitter-proportions>
            <option name="proportions">
              <list>
                <option value="0.2" />
              </list>
            </option>
          </splitter-proportions>
        </settings>
      </state>
      <state key="ScopeChooserConfigurable.UI">
        <settings>
          <splitter-proportions>
            <option name="proportions">
              <list>
                <option value="0.2" />
              </list>
            </option>
          </splitter-proportions>
        </settings>
      </state>
    </states>
  </component>
</project>

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/Dreamcatcher.iml" filepath="$PROJECT_DIR$/Dreamcatcher.iml" />
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2016 moxun

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Dream-Catcher
[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Dream%20Catcher-green.svg?style=flat)](http://android-arsenal.com/details/1/4834)    
Inspection the Android HTTP(S) traffic in Chrome Developer Tools

## Introduction
Dream Catcher is a HTTP proxy based traffic analysis tools, provides the ability to view http(s) traffic in chrome by adapting the [Chrome Remote Debug Protocol](https://chromedevtools.github.io/debugger-protocol-viewer/).

## Usage
- Install and launch the [Dream Catcher APP](https://github.com/misakuo/Dream-Catcher/releases)
- Connect your device to PC, make sure the USB debugging is active and the `adb` is usable
- Click to enable the HTTP proxy (It's maybe need waiting a bit time)
- Click **Install Certificate** to install CA for enable [MITM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) (Dream Catcher will not do evil, it just be using to decryption the HTTPS traffic. If do not need HTTPS inspection, you can skip this step)
- Click **Trusted Credentials** to examine the MITM CA or remove it
- Click **Setting Proxy** to setup proxy on active connection (General steps: 1. long click the active connection; 2. select *Modify Network* on dialog; 3. select *Manual* on the *Proxy* options; 4. input `127.0.0.1` to the *Proxy hostname* textbox; 5. input proxy port (default is `9999`) to the *Proxy port* textbox; 6. click the *SAVE* button; 7. In some cases you may need to turn off and then turn on WiFi)
- Open Chrome and navigate to **`chrome://inspect`**
- Click **inspect** when Dream Catcher is ready
- Select the **Network** tab to start inspection

## Example
### The homepage
<image src="https://ooo.0o0.ooo/2016/12/13/584f7a044e1fa.png" width="40%"/>

### Enable proxy  
<image src="https://ooo.0o0.ooo/2016/12/13/584f7a04404aa.png" width="40%"/>

### Let's trying to visit Google Play

**Got it!**   
![QQ20161213-0.png](https://ooo.0o0.ooo/2016/12/13/584f7a42daf42.png)

**The headers**    
![QQ20161213-1.png](https://ooo.0o0.ooo/2016/12/13/584f7a42ac344.png)

### Preview response

**Image**    
![QQ20161213-2.png](https://ooo.0o0.ooo/2016/12/13/584f7a422daf8.png)

**JSON**
![QQ20161213-3.png](https://ooo.0o0.ooo/2016/12/13/584f7a4230aba.png)

## Download

| Version        | Github source           | CDN source|    
| :-----: |:------------:|:-----:|    
| 1.2.0![new2_e0.gif](https://ooo.0o0.ooo/2016/12/16/58535628362c0.gif) | [Github](https://github.com/misakuo/Dream-Catcher/releases/download/release-1.2.0/dream_catcher-1.2.0.apk) | |    
| 1.1.0 | [Github](https://github.com/misakuo/Dream-Catcher/releases/download/release-1.0.1/dream_catcher-1.1.0.apk) | [Qiniu CDN](http://sodaless.qiniudn.com/dream_catcher-1.1.0.apk)|    
| ~~1.0.1~~ (Deprecated) | [Github](https://github.com/misakuo/Dream-Catcher/releases/download/release-1.0.1/dream_catcher-1.0.1.apk) | [Qiniu CDN](http://sodaless.qiniudn.com/dream_catcher-1.0.1.apk)|    

## Acknowledgments
[Stetho](https://github.com/facebook/stetho)    
[browsermob-proxy](https://github.com/lightbody/browsermob-proxy)    
[android-morphing-button](https://github.com/dmytrodanylyk/android-morphing-button)


================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.3"
    defaultConfig {
        applicationId "me.moxun.dreamcatcher"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 4
        versionName "1.2.0"
        multiDexEnabled true
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:2.0.1'
    }
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/BCKEY.DSA'
        exclude 'META-INF/BCKEY.SF'
        exclude 'META-INF/LICENSE.uas.txt'
    }
    useLibrary 'org.apache.http.legacy'
    repositories {
        mavenLocal()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.android.support:design:24.2.1'
    compile 'com.android.support:support-annotations:24.2.1'
    compile 'com.android.support:multidex:1.0.1'
    compile 'org.greenrobot:eventbus:3.0.0'

    compile 'com.github.dmytrodanylyk:android-morphing-button:98a4986e56'

    //WELCOME TO HELL
    compile('net.lightbody.bmp:littleproxy:1.1.0-beta-bmp-13') {
        exclude group: 'io.netty'
    }
    compile 'net.sf.qualitycheck:quality-check:1.3'
    compile 'javax.annotation:jsr250-api:1.0'
    compile 'com.fasterxml.jackson.core:jackson-core:2.7.6'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.7.6'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.6'
    compile 'org.bouncycastle:bcprov-jdk15on:1.54'
    compile 'org.bouncycastle:bcpkix-jdk15on:1.54'
    compile 'dnsjava:dnsjava:2.1.7'
    compile 'com.google.guava:guava:19.0'
    compile 'com.google.code.findbugs:jsr305:3.0.1'
    compile 'com.google.jimfs:jimfs:1.1'
    compile 'com.jcraft:jzlib:1.1.3'
    compile 'org.slf4j:slf4j-api:1.7.21'
    compile 'com.noveogroup.android:android-logger:1.3.5'
    testCompile 'junit:junit:4.12'
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/moxun/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: app/src/androidTest/java/me/moxun/dreamcatcher/ExampleInstrumentedTest.java
================================================
package me.moxun.dreamcatcher;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("me.moxun.dreamcatcher", appContext.getPackageName());
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="me.moxun.dreamcatcher">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name=".DCApplication"
        android:allowBackup="true"
        android:icon="@mipmap/icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <service android:name=".service.ProxyService"/>
        <service android:name=".service.ConnectorService"/>

        <activity
            android:name=".CaptureActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/CaptureActivity.java
================================================
package me.moxun.dreamcatcher;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.Settings;
import android.security.KeyChain;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import com.dd.morphingbutton.MorphingButton;
import com.dd.morphingbutton.impl.IndeterminateProgressButton;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.InputStream;

import me.moxun.dreamcatcher.event.OperateEvent;
import me.moxun.dreamcatcher.service.ProxyService;

public class CaptureActivity extends AppCompatActivity {

    final String CA_RESOURCE = "/sslSupport/ca-certificate-rsa.cer";
    final int INSTALL_CA_REQUEST_CODE = 0x99;

    private int size = 112;
    private int defaultDuration = 500;
    private int defaultDelay = 3000;
    private IndeterminateProgressButton controlButton;
    private TextView status;
    private int state = State.IDLE;
    private long timestamp = 0L;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_capture);

        EventBus.getDefault().register(this);

        controlButton = (IndeterminateProgressButton) findViewById(R.id.controller);
        status = (TextView) findViewById(R.id.status);

        morphToIdle(controlButton, 0);

        controlButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (state) {
                    case State.IDLE:
                    case State.FAILURE:
                        timestamp = System.currentTimeMillis();
                        performProgress(controlButton);
                        Intent intent = new Intent(CaptureActivity.this, ProxyService.class);
                        startService(intent);
                        break;
                    case State.RUNNING:
                        timestamp = System.currentTimeMillis();
                        performProgress(controlButton);
                        stopService(new Intent(CaptureActivity.this, ProxyService.class));
                        break;
                    default:
                        break;
                }
            }
        });

        findViewById(R.id.install_ca).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    byte[] keychainBytes;
                    InputStream bis = CaptureActivity.class.getResourceAsStream(CA_RESOURCE);
                    keychainBytes = new byte[bis.available()];
                    bis.read(keychainBytes);
                    Intent intent = KeyChain.createInstallIntent();
                    intent.putExtra(KeyChain.EXTRA_CERTIFICATE, keychainBytes);
                    intent.putExtra(KeyChain.EXTRA_NAME, "DreamCatcher CA Certificate");
                    startActivityForResult(intent, INSTALL_CA_REQUEST_CODE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        findViewById(R.id.trusted_ca).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.android.settings.TRUSTED_CREDENTIALS_USER");
                intent.setFlags(0x14000000);
                startActivity(intent);
            }
        });

        findViewById(R.id.setting_proxy).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
            }
        });
    }

    private void performProgress(@NonNull final IndeterminateProgressButton button) {
        status.setText("This maybe a bit slow, please keep patience ……");
        int progressColor1 = Color.parseColor("#ff00ddff");
        int progressColor2 = Color.parseColor("#ff99cc00");
        int progressColor3 = Color.parseColor("#ffffbb33");
        int progressColor4 = Color.parseColor("#ffff4444");
        int color = Color.parseColor("#ffdedede");
        int progressCornerRadius = $px(4);
        int width = $px(200);
        int height = $px(8);

        button.blockTouch();
        button.morphToProgress(color, progressCornerRadius, width, height, defaultDuration, progressColor1, progressColor2,
                progressColor3, progressColor4);
    }

    private int $px(float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    private void morphToSuccess(final IndeterminateProgressButton btnMorph, int duration) {
        status.setText("Proxy on 127.0.0.1:" + ((DCApplication) getApplication()).getPort());
        btnMorph.unblockTouch();
        MorphingButton.Params circle = MorphingButton.Params.create()
                .duration(duration)
                .cornerRadius($px(size))
                .width($px(size))
                .height($px(size))
                .color(Color.parseColor("#ff99cc00"))
                .colorPressed(Color.parseColor("#ff6d9b00"))
                .icon(R.mipmap.ic_check);
        btnMorph.morph(circle);
    }

    private void morphToFailure(final IndeterminateProgressButton btnMorph, int duration) {
        btnMorph.unblockTouch();
        MorphingButton.Params circle = MorphingButton.Params.create()
                .duration(duration)
                .cornerRadius($px(size))
                .width($px(size))
                .height($px(size))
                .color(Color.parseColor("#ffff4444"))
                .colorPressed(Color.parseColor("#ffcd3a3a"))
                .icon(R.mipmap.ic_closed);
        btnMorph.morph(circle);
    }

    private void morphToIdle(final IndeterminateProgressButton btnMorph, int duration) {
        btnMorph.unblockTouch();
        MorphingButton.Params circle = MorphingButton.Params.create()
                .duration(duration)
                .cornerRadius($px(size))
                .width($px(size))
                .height($px(size))
                .color(Color.parseColor("#ff0099cc"))
                .colorPressed(Color.parseColor("#ff00719b"))
                .icon(R.mipmap.ic_start);
        btnMorph.morph(circle);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(final OperateEvent event) {
        Log.e("Event", event.toString());
        if (event.error) {
            if ((System.currentTimeMillis() - timestamp) < defaultDelay) {
                getWindow().getDecorView().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        morphToFailure(controlButton, defaultDuration);
                        state = State.FAILURE;
                        status.setText(event.msg);
                    }
                }, defaultDelay - (System.currentTimeMillis() - timestamp));
            } else {
                morphToFailure(controlButton, defaultDuration);
                state = State.FAILURE;
                status.setText(event.msg);
            }
            return;
        }

        if (event.target == OperateEvent.TARGET_CONNECTOR) {

        } else if (event.target == OperateEvent.TARGET_PROXY) {
            if (event.active) {
                if ((System.currentTimeMillis() - timestamp) < defaultDelay) {
                    getWindow().getDecorView().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            morphToSuccess(controlButton, defaultDuration);
                            state = State.RUNNING;
                        }
                    }, defaultDelay - (System.currentTimeMillis() - timestamp));
                } else {
                    morphToSuccess(controlButton, defaultDuration);
                    state = State.RUNNING;
                }
            } else {
                if ((System.currentTimeMillis() - timestamp) < defaultDelay) {
                    getWindow().getDecorView().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            morphToIdle(controlButton, defaultDuration);
                            state = State.IDLE;
                            status.setText("Click to start capture");
                        }
                    }, defaultDelay - (System.currentTimeMillis() - timestamp));
                } else {
                    morphToIdle(controlButton, defaultDuration);
                    state = State.IDLE;
                    status.setText("Click to start capture");
                }
            }
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/DCApplication.java
================================================
package me.moxun.dreamcatcher;

import android.content.Intent;
import android.support.multidex.MultiDexApplication;

import me.moxun.dreamcatcher.service.ConnectorService;

/**
 * Created by moxun on 6/12/7.
 */

public class DCApplication extends MultiDexApplication {

    //forgive me...
    private int port = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        startService(new Intent(this, ConnectorService.class));
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        stopService(new Intent(this, ConnectorService.class));
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/State.java
================================================
package me.moxun.dreamcatcher;

/**
 * Created by moxun on 16/12/12.
 */

public interface State {
    int IDLE = 0;
    int RUNNING = 1;
    int FAILURE = 2;
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/Connector.java
================================================
package me.moxun.dreamcatcher.connector;

import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.support.annotation.Nullable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import me.moxun.dreamcatcher.connector.inspector.DevtoolsSocketHandler;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.FileSystem;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Network;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Profiler;
import me.moxun.dreamcatcher.connector.log.AELog;
import me.moxun.dreamcatcher.connector.manager.Lifecycle;
import me.moxun.dreamcatcher.connector.manager.SimpleConnectorLifecycleManager;
import me.moxun.dreamcatcher.connector.server.AddressNameHelper;
import me.moxun.dreamcatcher.connector.server.LazySocketHandler;
import me.moxun.dreamcatcher.connector.server.LocalSocketServer;
import me.moxun.dreamcatcher.connector.server.ProtocolDetectingSocketHandler;
import me.moxun.dreamcatcher.connector.server.ServerManager;
import me.moxun.dreamcatcher.connector.server.SocketHandler;
import me.moxun.dreamcatcher.connector.server.SocketHandlerFactory;
import me.moxun.dreamcatcher.connector.util.DreamCatcherCrashHandler;
import me.moxun.dreamcatcher.connector.util.LogUtil;
import me.moxun.dreamcatcher.connector.util.SocketServerManager;

/**
 * Created by moxun on 16/12/8.
 */

public class Connector {
    private static final String DEV_TOOLS_MAGIC_TAG = "_devtools_remote";

    private Connector() {

    }

    private static void initialize(final Initializer initializer) {
        loadInnerModule(initializer.mContext);
        initializer.start();
    }

    private static void loadInnerModule(Context context) {
        AELog.setLoggable(isDebuggable(context));
        setInternalLogEnabled(isDebuggable(context));

        if (!isDebuggable(context)) {
            AELog.setLoggable(false);
            setInternalLogEnabled(false);
        }
    }

    public static void open(final Context context) {
        initialize(new Initializer(context) {
            @Override
            protected Iterable<ChromeDevtoolsDomain> getInspectorModules() {
                return new DefaultInspectorModulesBuilder(context).finish();
            }
        });
    }

    public static void close() {
        SocketServerManager.stopServer();
        SimpleConnectorLifecycleManager.setCurrentState(Lifecycle.SHUTDOWN);
    }

    private static class PluginBuilder<T> {
        private final Set<String> mProvidedNames = new HashSet<>();
        private final Set<String> mRemovedNames = new HashSet<>();

        private final ArrayList<T> mPlugins = new ArrayList<>();

        private boolean mFinished;

        public void provide(String name, T plugin) {
            throwIfFinished();
            mPlugins.add(plugin);
            mProvidedNames.add(name);
        }

        public void provideIfDesired(String name, T plugin) {
            throwIfFinished();
            if (!mRemovedNames.contains(name)) {
                if (mProvidedNames.add(name)) {
                    mPlugins.add(plugin);
                }
            }
        }

        public void remove(String pluginName) {
            throwIfFinished();
            mRemovedNames.remove(pluginName);
        }

        private void throwIfFinished() {
            if (mFinished) {
                throw new IllegalStateException("Must not continue to build after finish()");
            }
        }

        public Iterable<T> finish() {
            mFinished = true;
            return mPlugins;
        }
    }

    private static final class DefaultInspectorModulesBuilder {
        private final Application mContext;
        private final PluginBuilder<ChromeDevtoolsDomain> mDelegate = new PluginBuilder<>();

        public DefaultInspectorModulesBuilder(Context context) {
            mContext = (Application) context.getApplicationContext();
        }

        private DefaultInspectorModulesBuilder provideIfDesired(ChromeDevtoolsDomain module) {
            mDelegate.provideIfDesired(module.getClass().getName(), module);
            return this;
        }

        public Iterable<ChromeDevtoolsDomain> finish() {
            provideIfDesired(new Network(mContext));
            provideIfDesired(new FileSystem(mContext));
            provideIfDesired(new Profiler());
            return mDelegate.finish();
        }
    }

    private static abstract class Initializer {
        private final Context mContext;

        protected Initializer(Context context) {
            mContext = context.getApplicationContext();
        }

        @Nullable
        protected abstract Iterable<ChromeDevtoolsDomain> getInspectorModules();

        final void start() {
            DreamCatcherCrashHandler.getInstance().attach();
            //create server to handle request.
            initServerManager();
            SocketServerManager.startServer(SocketServerManager.Type.LOCAL);

        }

        private void initServerManager() {
            LocalSocketServer localSocketServer = new LocalSocketServer(
                    "main",
                    AddressNameHelper.createCustomAddress(DEV_TOOLS_MAGIC_TAG),
                    new LazySocketHandler(new RealSocketHandlerFactory()));
            ServerManager serverManager = new ServerManager(localSocketServer);
            SocketServerManager.register(SocketServerManager.KEY_LOCAL_SERVER_MANAGER, serverManager);
        }

        private class RealSocketHandlerFactory implements SocketHandlerFactory {
            @Override
            public SocketHandler create() {
                ProtocolDetectingSocketHandler socketHandler = new ProtocolDetectingSocketHandler(mContext);
                //Create Http server to enable inspector
                Iterable<ChromeDevtoolsDomain> inspectorModules = getInspectorModules();
                if (inspectorModules != null) {
                    socketHandler.addHandler(
                            new ProtocolDetectingSocketHandler.AlwaysMatchMatcher(),
                            new DevtoolsSocketHandler(mContext, inspectorModules));
                }

                return socketHandler;
            }
        }
    }

    private static boolean isDebuggable(Context context) {
        ApplicationInfo info = context.getApplicationInfo();
        return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    }

    private static class InitializerBuilder {
        final Context mContext;

        @javax.annotation.Nullable
        InspectorModulesProvider mInspectorModules;


        private InitializerBuilder(Context context) {
            mContext = context.getApplicationContext();
        }

        public InitializerBuilder enableInspector(InspectorModulesProvider modules) {
            mInspectorModules = modules;
            return this;
        }

        public Initializer build() {
            return new BuilderBasedInitializer(this);
        }
    }

    private static class BuilderBasedInitializer extends Initializer {
        @javax.annotation.Nullable
        private final InspectorModulesProvider mInspectorModules;

        private BuilderBasedInitializer(InitializerBuilder b) {
            super(b.mContext);
            mInspectorModules = b.mInspectorModules;
        }

        @javax.annotation.Nullable
        @Override
        protected Iterable<ChromeDevtoolsDomain> getInspectorModules() {
            return mInspectorModules != null ? mInspectorModules.get() : null;
        }
    }

    //EXTRA SETTINGS
    public static void setInternalLogEnabled(boolean enabled) {
        LogUtil.setLoggable(enabled);
    }

}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/InspectorModulesProvider.java
================================================
package me.moxun.dreamcatcher.connector;


import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;

public interface InspectorModulesProvider {
  Iterable<ChromeDevtoolsDomain> get();
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/CLog.java
================================================

package me.moxun.dreamcatcher.connector.console;


import me.moxun.dreamcatcher.connector.inspector.helper.ChromePeerManager;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Console;

/**
 * Utility for reporting an event to the console
 * WARN:请勿在此类或其子类中以任何方式输出LogCat
 */
public class CLog {
    private static final String TAG = "CLog";

    public static void writeToConsole(
            ChromePeerManager chromePeerManager,
            Console.MessageLevel logLevel,
            Console.MessageSource messageSource,
            String messageText) {

        Console.ConsoleMessage message = new Console.ConsoleMessage();
        message.source = messageSource;
        message.level = logLevel;
        message.text = messageText;
        message.type = Console.MessageType.LOG;
        Console.MessageAddedRequest messageAddedRequest = new Console.MessageAddedRequest();
        messageAddedRequest.message = message;
        chromePeerManager.sendNotificationToPeers("Console.messageAdded", messageAddedRequest);
    }

    public static void writeToConsole(
            Console.MessageLevel logLevel,
            Console.MessageSource messageSource,
            String messageText
    ) {
        ConsolePeerManager peerManager = ConsolePeerManager.getInstanceOrNull();
        if (peerManager == null) {
            return;
        }

        writeToConsole(peerManager, logLevel, messageSource, messageText);
    }

    public static void log(String note) {
        writeToConsole(Console.MessageLevel.LOG, Console.MessageSource.CONSOLE_API, note);
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/ConsolePeerManager.java
================================================
package me.moxun.dreamcatcher.connector.console;


import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.inspector.helper.ChromePeerManager;

public class ConsolePeerManager extends ChromePeerManager {

  private static ConsolePeerManager sInstance;

  private ConsolePeerManager() {
    super();
  }

  @Nullable
  public static synchronized ConsolePeerManager getInstanceOrNull() {
    return sInstance;
  }

  public static synchronized ConsolePeerManager getOrCreateInstance() {
    if (sInstance == null) {
      sInstance = new ConsolePeerManager();
    }
    return sInstance;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeRepl.java
================================================
package me.moxun.dreamcatcher.connector.console;

public interface RuntimeRepl {
  Object evaluate(String expression) throws Throwable;
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeReplFactory.java
================================================
package me.moxun.dreamcatcher.connector.console;

/**
 * Allows callers to specify their own Console tab REPL for the DevTools UI.  This is part of
 * early support for a possible optionally included default implementation for Android.
 * <p />
 * A new {@link RuntimeRepl} instances is created for each unique peer such that memory
 * can be garbage collected when the peer disconnects.
 * <p />
 * This is provided as part of an experimental API.  Depend on it at your own risk...
 */
public interface RuntimeReplFactory {
  RuntimeRepl newInstance();
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/command/CommandHandler.java
================================================
package me.moxun.dreamcatcher.connector.console.command;

import android.support.annotation.Nullable;

/**
 * Created by moxun on 16/4/12.
 */
public interface CommandHandler {
    String desire();

    String help();

    @Nullable
    Object onCommand(@Nullable String param);
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDevtoolsServer.java
================================================
package me.moxun.dreamcatcher.connector.inspector;

import android.util.Log;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcException;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.PendingRequest;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcRequest;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcResponse;
import me.moxun.dreamcatcher.connector.manager.Lifecycle;
import me.moxun.dreamcatcher.connector.manager.SimpleConnectorLifecycleManager;
import me.moxun.dreamcatcher.connector.util.LogFilter;
import me.moxun.dreamcatcher.connector.util.LogUtil;
import me.moxun.dreamcatcher.connector.util.Util;
import me.moxun.dreamcatcher.connector.websocket.CloseCodes;
import me.moxun.dreamcatcher.connector.websocket.SimpleEndpoint;
import me.moxun.dreamcatcher.connector.websocket.SimpleSession;
import me.moxun.dreamcatcher.event.CaptureEvent;
import me.moxun.dreamcatcher.event.OperateEvent;

/**
 * Implements a limited version of the Chrome Debugger WebSocket protocol (using JSON-RPC 2.0).
 * The most up-to-date documentation can be found in the Blink source code:
 * <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/devtools/protocol.json&q=protocol.json&sq=package:chromium&type=cs">protocol.json</a>
 */
public class ChromeDevtoolsServer implements SimpleEndpoint {
    private static final String TAG = "ChromeDevtoolsServer";

    public static final String PATH = "/inspector";

    private final ObjectMapper mObjectMapper;
    private final MethodDispatcher mMethodDispatcher;
    private final Map<SimpleSession, JsonRpcPeer> mPeers =
            Collections.synchronizedMap(
                    new HashMap<SimpleSession, JsonRpcPeer>());

    public ChromeDevtoolsServer(Iterable<ChromeDevtoolsDomain> domainModules) {
        mObjectMapper = new ObjectMapper();
        mMethodDispatcher = new MethodDispatcher(mObjectMapper, domainModules);
    }

    @Override
    public void onOpen(SimpleSession session) {
        LogUtil.e(TAG, "Open session: " + session.toString());
        mPeers.put(session, new JsonRpcPeer(mObjectMapper, session));
        SimpleConnectorLifecycleManager.setCurrentState(Lifecycle.WAITING_FOR_DISCOVERY);
        CaptureEvent.send("Waiting for chrome discovery");
    }

    @Override
    public void onClose(SimpleSession session, int code, String reasonPhrase) {
        LogUtil.e(TAG, "Close session: " + session.toString() + ", cause: " + reasonPhrase + "(" + code + ")");

        JsonRpcPeer peer = mPeers.remove(session);
        if (peer != null) {
            peer.invokeDisconnectReceivers();
        }
    }

    @Override
    public void onMessage(SimpleSession session, byte[] message, int messageLen) {
        LogUtil.d(TAG, "Ignoring binary message of length " + messageLen);
    }

    @Override
    public void onMessage(SimpleSession session, String message) {
        if (LogUtil.isLoggable(TAG, Log.VERBOSE)) {
            LogUtil.v(TAG, "onMessage: message=" + message);
        }
        try {
            JsonRpcPeer peer = mPeers.get(session);
            Util.throwIfNull(peer);

            handleRemoteMessage(peer, message);
        } catch (IOException e) {
            if (LogUtil.isLoggable(TAG, Log.VERBOSE)) {
                LogUtil.v(TAG, "Unexpected I/O exception processing message: " + e);
            }
            closeSafely(session, CloseCodes.UNEXPECTED_CONDITION, e.getClass().getSimpleName());
        } catch (MessageHandlingException e) {
            LogUtil.i(TAG, "Message could not be processed by implementation: " + e);
            closeSafely(session, CloseCodes.UNEXPECTED_CONDITION, e.getClass().getSimpleName());
        } catch (JSONException e) {
            LogUtil.v(TAG, "Unexpected JSON exception processing message", e);
            closeSafely(session, CloseCodes.UNEXPECTED_CONDITION, e.getClass().getSimpleName());
        }
    }

    private void closeSafely(SimpleSession session, int code, String reasonPhrase) {
        session.close(code, reasonPhrase);
    }

    private void handleRemoteMessage(JsonRpcPeer peer, String message)
            throws IOException, MessageHandlingException, JSONException {
        // Parse as a generic JSONObject first since we don't know if this is a request or response.
        JSONObject messageNode = new JSONObject(message);
        if (messageNode.has("method")) {
            handleRemoteRequest(peer, messageNode);
        } else if (messageNode.has("result")) {
            handleRemoteResponse(peer, messageNode);
        } else {
            throw new MessageHandlingException("Improper JSON-RPC message: " + message);
        }
    }

    private void handleRemoteRequest(JsonRpcPeer peer, JSONObject requestNode)
            throws MessageHandlingException {
        JsonRpcRequest request;
        request = mObjectMapper.convertValue(
                requestNode,
                JsonRpcRequest.class);

        if (!request.method.equals("Runtime.evaluate")) {
            //LogUtil.w(TAG, "JsonRpcRequest received: " + request.toString());
        }

        JSONObject result = null;
        JSONObject error = null;

        try {
            result = mMethodDispatcher.dispatch(peer,
                    request.method,
                    request.params);
        } catch (JsonRpcException e) {
            logDispatchException(e);
            error = mObjectMapper.convertValue(e.getErrorMessage(), JSONObject.class);
        }
        if (request.id != null) {
            JsonRpcResponse response = new JsonRpcResponse();
            response.id = request.id;
            response.result = result;
            response.error = error;
            JSONObject jsonObject = mObjectMapper.convertValue(response, JSONObject.class);
            String responseString;
            try {
                responseString = jsonObject.toString();
            } catch (OutOfMemoryError e) {
                // JSONStringer can cause an OOM when the Json to handle is too big.
                response.result = null;
                response.error = mObjectMapper.convertValue(e.getMessage(), JSONObject.class);
                jsonObject = mObjectMapper.convertValue(response, JSONObject.class);
                responseString = jsonObject.toString();
            }
            JSONObject log = LogFilter.filter(requestNode, jsonObject);
            if (log != null) {
                LogUtil.w(log.toString());
            }
            peer.getWebSocket().sendText(responseString);
        }
    }

    private static void logDispatchException(JsonRpcException e) {
        JsonRpcError errorMessage = e.getErrorMessage();
        switch (errorMessage.code) {
            case METHOD_NOT_FOUND:
                LogUtil.e(TAG, "Method not implemented: " + errorMessage.message);
                break;
            default:
                LogUtil.w(TAG, "Error processing remote message", e);
        }
    }

    private void handleRemoteResponse(JsonRpcPeer peer, JSONObject responseNode)
            throws MismatchedResponseException {
        LogUtil.w(responseNode.toString());
        JsonRpcResponse response = mObjectMapper.convertValue(
                responseNode,
                JsonRpcResponse.class);
        PendingRequest pendingRequest = peer.getAndRemovePendingRequest(response.id);
        if (pendingRequest == null) {
            throw new MismatchedResponseException(response.id);
        }
        if (pendingRequest.callback != null) {
            pendingRequest.callback.onResponse(peer, response);
        }
    }

    @Override
    public void onError(SimpleSession session, Throwable ex) {
        LogUtil.w(TAG, "Session error: " + ex.toString());
        SimpleConnectorLifecycleManager.setCurrentState(Lifecycle.WEBSOCKET_SESSION_CLOSED);
        CaptureEvent.send("Websocket session closes unexpectedly");
        EventBus.getDefault().post(new OperateEvent(OperateEvent.TARGET_CONNECTOR, false, true, "Websocket session closed"));
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDiscoveryHandler.java
================================================
package me.moxun.dreamcatcher.connector.inspector;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.manager.Lifecycle;
import me.moxun.dreamcatcher.connector.manager.SimpleConnectorLifecycleManager;
import me.moxun.dreamcatcher.connector.server.SocketLike;
import me.moxun.dreamcatcher.connector.server.http.ExactPathMatcher;
import me.moxun.dreamcatcher.connector.server.http.HandlerRegistry;
import me.moxun.dreamcatcher.connector.server.http.HttpHandler;
import me.moxun.dreamcatcher.connector.server.http.HttpStatus;
import me.moxun.dreamcatcher.connector.server.http.LightHttpBody;
import me.moxun.dreamcatcher.connector.server.http.LightHttpRequest;
import me.moxun.dreamcatcher.connector.server.http.LightHttpResponse;
import me.moxun.dreamcatcher.connector.util.LogUtil;
import me.moxun.dreamcatcher.connector.util.ProcessUtil;
import me.moxun.dreamcatcher.event.CaptureEvent;

/**
 * Provides sufficient responses to convince Chrome's {@code chrome://inspect/devices} that we're
 * "one of them".  Note that we are being discovered automatically by the name of our socket
 * as defined in {@link android.net.LocalServerSocket}.  After discovery, we're required to provide
 * some context on how exactly to display and inspect what we have.
 */
public class ChromeDiscoveryHandler implements HttpHandler {
    private static final String PAGE_ID = "1";

    private static final String PATH_PAGE_LIST = "/json";
    private static final String PATH_VERSION = "/json/version";
    private static final String PATH_ACTIVATE = "/json/activate/" + PAGE_ID;
    private static final String PATH_SERVER_GET = "/json/remote";

    private static boolean INVALID = false;

    /**
     * Latest version of the WebKit Inspector UI that we've tested again (ideally).
     */
    private static final String WEBKIT_REV = "@188492";
    private static final String WEBKIT_VERSION = "537.36 (" + WEBKIT_REV + ")";

    private static final String USER_AGENT = "DreamCatcher";

    /**
     * Structured version of the WebKit Inspector protocol that we understand.
     */
    private static final String PROTOCOL_VERSION = "1.1";

    private final Context mContext;
    private final String mInspectorPath;

    @Nullable
    private LightHttpBody mVersionResponse;
    @Nullable
    private LightHttpBody mPageListResponse;

    public static void setInvalid(boolean invalid) {
        ChromeDiscoveryHandler.INVALID = invalid;
    }

    public ChromeDiscoveryHandler(Context context, String inspectorPath) {
        mContext = context;
        mInspectorPath = inspectorPath;
        SimpleConnectorLifecycleManager.setCurrentState(Lifecycle.CHROME_DISCOVERY_CONNECTED);
        CaptureEvent.send("Chrome discovery success");
    }

    public void register(HandlerRegistry registry) {
        registry.register(new ExactPathMatcher(PATH_PAGE_LIST), this);
        registry.register(new ExactPathMatcher(PATH_VERSION), this);
        registry.register(new ExactPathMatcher(PATH_ACTIVATE), this);
        registry.register(new ExactPathMatcher(PATH_SERVER_GET), this);
    }

    @Override
    public boolean handleRequest(SocketLike socket, LightHttpRequest request, LightHttpResponse response) {
        String path = request.uri.getPath();
        LogUtil.d(request.toString());
        try {
            if (PATH_VERSION.equals(path)) {
                handleVersion(response);
            } else if (PATH_PAGE_LIST.equals(path)) {
                handlePageList(response);
            } else if (PATH_ACTIVATE.equals(path)) {
                handleActivate(response);
            } else {
                response.code = HttpStatus.HTTP_NOT_IMPLEMENTED;
                response.reasonPhrase = "Not implemented";
                response.body = LightHttpBody.create("No support for " + path + "\n", "text/plain");
            }
        } catch (JSONException e) {
            response.code = HttpStatus.HTTP_INTERNAL_SERVER_ERROR;
            response.reasonPhrase = "Internal server error";
            response.body = LightHttpBody.create(e.toString() + "\n", "text/plain");
        }
        return true;
    }

    private void handleVersion(LightHttpResponse response)
            throws JSONException {
        if (mVersionResponse == null) {
            JSONObject reply = new JSONObject();
            reply.put("WebKit-Version", WEBKIT_VERSION);
            reply.put("User-Agent", USER_AGENT);
            reply.put("Protocol-Version", PROTOCOL_VERSION);
            reply.put("Browser", getAppLabelAndVersion());
            reply.put("Android-Package", mContext.getPackageName());
            mVersionResponse = LightHttpBody.create(reply.toString(), "application/json");
            LogUtil.d("Version: " + reply.toString());
        }
        setSuccessfulResponse(response, mVersionResponse);
    }

    private void handlePageList(LightHttpResponse response)
            throws JSONException {
        SimpleConnectorLifecycleManager.setCurrentState(Lifecycle.WAITING_FOR_WEBSOCKET);
        CaptureEvent.send("Waiting for websocket");
        if (mPageListResponse == null || INVALID) {
            JSONArray reply = new JSONArray();
            JSONObject page = new JSONObject();
            page.put("type", "app");
            page.put("title", makeTitle());
            page.put("id", PAGE_ID);
            page.put("description", "");

            page.put("webSocketDebuggerUrl", makeWSAddress());
            Uri chromeFrontendUrl = new Uri.Builder()
                    .scheme("http")
                    .authority("chrome-devtools-frontend.appspot.com")
                    .appendEncodedPath("serve_rev")
                    .appendEncodedPath(WEBKIT_REV)
                    .appendEncodedPath("devtools.html")
                    .appendQueryParameter("ws", mInspectorPath)
                    .build();
            page.put("devtoolsFrontendUrl", chromeFrontendUrl.toString());

            reply.put(page);
            mPageListResponse = LightHttpBody.create(reply.toString(), "application/json");
            LogUtil.w("PageList: " + reply.toString());
            INVALID = false;
        }
        setSuccessfulResponse(response, mPageListResponse);
    }

    private String makeWSAddress() {
        return "ws://" + mInspectorPath;
    }

    private String makeTitle() {
        StringBuilder b = new StringBuilder();
        b.append(getAppLabel());
        if (SimpleConnectorLifecycleManager.isProxyEnabled()) {
            b.append(" (Ready)");
        } else {
            b.append(" (Preparing ……)");
        }

        String processName = ProcessUtil.getProcessName();
        int colonIndex = processName.indexOf(':');
        if (colonIndex >= 0) {
            String nonDefaultProcessName = processName.substring(colonIndex);
            b.append(nonDefaultProcessName);
        }

        return b.toString();
    }

    private void handleActivate(LightHttpResponse response) {
        // Arbitrary response seem acceptable :)
        setSuccessfulResponse(
                response,
                LightHttpBody.create("Target activation ignored\n", "text/plain"));
    }

    private static void setSuccessfulResponse(
            LightHttpResponse response,
            LightHttpBody body) {
        response.code = HttpStatus.HTTP_OK;
        response.reasonPhrase = "OK";
        response.body = body;

        LogUtil.w(LogUtil.filter("ChromeDiscovery Response", response));
    }

    private String getAppLabelAndVersion() {
        StringBuilder b = new StringBuilder();
        PackageManager pm = mContext.getPackageManager();
        b.append(getAppLabel());
        b.append('/');
        try {
            PackageInfo info = pm.getPackageInfo(mContext.getPackageName(), 0 /* flags */);
            b.append(info.versionName);
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }
        return b.toString();
    }

    private CharSequence getAppLabel() {
        PackageManager pm = mContext.getPackageManager();
        return pm.getApplicationLabel(mContext.getApplicationInfo());
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/DevtoolsSocketHandler.java
================================================
package me.moxun.dreamcatcher.connector.inspector;

import android.content.Context;

import java.io.IOException;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.server.SocketLike;
import me.moxun.dreamcatcher.connector.server.SocketLikeHandler;
import me.moxun.dreamcatcher.connector.server.http.ExactPathMatcher;
import me.moxun.dreamcatcher.connector.server.http.HandlerRegistry;
import me.moxun.dreamcatcher.connector.server.http.LightHttpServer;
import me.moxun.dreamcatcher.connector.websocket.WebSocketHandler;

public class DevtoolsSocketHandler implements SocketLikeHandler {
  private final Context mContext;
  private final Iterable<ChromeDevtoolsDomain> mModules;
  private final LightHttpServer mServer;

  public DevtoolsSocketHandler(Context context, Iterable<ChromeDevtoolsDomain> modules) {
    mContext = context;
    mModules = modules;
    mServer = createServer();
  }

  private LightHttpServer createServer() {
    HandlerRegistry registry = new HandlerRegistry();
    ChromeDiscoveryHandler discoveryHandler =
        new ChromeDiscoveryHandler(
            mContext,
            ChromeDevtoolsServer.PATH);
    discoveryHandler.register(registry);
    registry.register(
        new ExactPathMatcher(ChromeDevtoolsServer.PATH),
        new WebSocketHandler(new ChromeDevtoolsServer(mModules)));

    return new LightHttpServer(registry);
  }

  @Override
  public void onAccepted(SocketLike socket) throws IOException {
    mServer.serve(socket);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MessageHandlingException.java
================================================
package me.moxun.dreamcatcher.connector.inspector;

public class MessageHandlingException extends Exception {
  public MessageHandlingException(Throwable cause) {
    super(cause);
  }

  public MessageHandlingException(String message) {
    super(message);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MethodDispatcher.java
================================================
package me.moxun.dreamcatcher.connector.inspector;


import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcException;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.EmptyResult;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;
import me.moxun.dreamcatcher.connector.util.ExceptionUtil;
import me.moxun.dreamcatcher.connector.util.Util;

@ThreadSafe
public class MethodDispatcher {
    @GuardedBy("this")
    private Map<String, MethodDispatchHelper> mMethods;

    private final ObjectMapper mObjectMapper;
    private final Iterable<ChromeDevtoolsDomain> mDomainHandlers;

    public MethodDispatcher(
            ObjectMapper objectMapper,
            Iterable<ChromeDevtoolsDomain> domainHandlers) {
        mObjectMapper = objectMapper;
        mDomainHandlers = domainHandlers;
    }

    private synchronized MethodDispatchHelper findMethodDispatcher(String methodName) {
        if (mMethods == null) {
            mMethods = buildDispatchTable(mObjectMapper, mDomainHandlers);
        }
        return mMethods.get(methodName);
    }

    public JSONObject dispatch(JsonRpcPeer peer, String methodName, @Nullable JSONObject params)
            throws JsonRpcException {
        MethodDispatchHelper dispatchHelper = findMethodDispatcher(methodName);
        if (dispatchHelper == null) {
            throw new JsonRpcException(new JsonRpcError(JsonRpcError.ErrorCode.METHOD_NOT_FOUND,
                    "Not implemented: " + methodName,
                    null /* data */));
        }
        if (!dispatchHelper.mMethod.getName().equals("evaluate")) {
            //LogUtil.w("Call method: " + dispatchHelper.mMethod.getName());
        }
        try {
            return dispatchHelper.invoke(peer, params);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            ExceptionUtil.propagateIfInstanceOf(cause, JsonRpcException.class);
            throw ExceptionUtil.propagate(cause);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (JSONException e) {
            throw new JsonRpcException(new JsonRpcError(JsonRpcError.ErrorCode.INTERNAL_ERROR,
                    e.toString(),
                    null /* data */));
        }
    }

    private static class MethodDispatchHelper {
        private final ObjectMapper mObjectMapper;
        private final ChromeDevtoolsDomain mInstance;
        private final Method mMethod;

        public MethodDispatchHelper(ObjectMapper objectMapper,
                                    ChromeDevtoolsDomain instance,
                                    Method method) {
            mObjectMapper = objectMapper;
            mInstance = instance;
            mMethod = method;
        }

        public JSONObject invoke(JsonRpcPeer peer, @Nullable JSONObject params)
                throws InvocationTargetException, IllegalAccessException, JSONException, JsonRpcException {
            Object internalResult = mMethod.invoke(mInstance, peer, params);
            if (internalResult == null || internalResult instanceof EmptyResult) {
                return new JSONObject();
            } else {
                JsonRpcResult convertableResult = (JsonRpcResult) internalResult;
                return mObjectMapper.convertValue(convertableResult, JSONObject.class);
            }
        }
    }

    private static Map<String, MethodDispatchHelper> buildDispatchTable(
            ObjectMapper objectMapper,
            Iterable<ChromeDevtoolsDomain> domainHandlers) {
        Util.throwIfNull(objectMapper);
        HashMap<String, MethodDispatchHelper> methods = new HashMap<String, MethodDispatchHelper>();
        for (ChromeDevtoolsDomain domainHandler : Util.throwIfNull(domainHandlers)) {
            Class<?> handlerClass = domainHandler.getClass();
            String domainName = handlerClass.getSimpleName();

            for (Method method : handlerClass.getDeclaredMethods()) {
                if (isDevtoolsMethod(method)) {
                    MethodDispatchHelper dispatchHelper = new MethodDispatchHelper(
                            objectMapper,
                            domainHandler,
                            method);
                    //LogUtil.e("DispatchTable", domainName + "." + method.getName() + " ==> " + dispatchHelper.mMethod.getName());
                    methods.put(domainName + "." + method.getName(), dispatchHelper);
                }
            }
        }
        return Collections.unmodifiableMap(methods);
    }

    /**
     * Determines if the method is a {@link ChromeDevtoolsMethod}, and validates accordingly
     * if it is.
     *
     * @throws IllegalArgumentException Thrown if it is a {@link ChromeDevtoolsMethod} but
     *                                  it otherwise fails to satisfy requirements.
     */
    private static boolean isDevtoolsMethod(Method method) throws IllegalArgumentException {
        if (!method.isAnnotationPresent(ChromeDevtoolsMethod.class)) {
            return false;
        } else {
            Class<?> args[] = method.getParameterTypes();
            String methodName = method.getDeclaringClass().getSimpleName() + "." + method.getName();
            Util.throwIfNot(args.length == 2,
                    "%s: expected 2 args, got %s",
                    methodName,
                    args.length);
            Util.throwIfNot(args[0].equals(JsonRpcPeer.class),
                    "%s: expected 1st arg of JsonRpcPeer, got %s",
                    methodName,
                    args[0].getName());
            Util.throwIfNot(args[1].equals(JSONObject.class),
                    "%s: expected 2nd arg of JSONObject, got %s",
                    methodName,
                    args[1].getName());

            Class<?> returnType = method.getReturnType();
            if (!returnType.equals(void.class)) {
                Util.throwIfNot(JsonRpcResult.class.isAssignableFrom(returnType),
                        "%s: expected JsonRpcResult return type, got %s",
                        methodName,
                        returnType.getName());
            }
            return true;
        }
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MismatchedResponseException.java
================================================
package me.moxun.dreamcatcher.connector.inspector;

public class MismatchedResponseException extends MessageHandlingException {
  public long mRequestId;

  public MismatchedResponseException(long requestId) {
    super("Response for request id " + requestId + ", but no such request is pending");
    mRequestId = requestId;
  }

  public long getRequestId() {
    return mRequestId;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ChromePeerManager.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;


import java.nio.channels.NotYetConnectedException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

import me.moxun.dreamcatcher.connector.jsonrpc.DisconnectReceiver;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.PendingRequestCallback;
import me.moxun.dreamcatcher.connector.util.LogUtil;
import me.moxun.dreamcatcher.connector.util.Util;

/**
 * Interface glue that allows a particular domain to manage the enabled peers.  The way the
 * WebKit inspector protocol works is that each functionality domain has an enable/disable JSON-RPC
 * method call which alerts the server (that's us) that we can now begin sending local events
 * to the peer to have them appear in the inspector UI.  This class simplifies managing those
 * enabled peers for each functionality domain.
 */
public class ChromePeerManager {
  private static final String TAG = "ChromePeerManager";

  /**
   * Set of registered peers, mapped to the disconnect receiver for automatic unregistration
   * purposes.
   */
  @GuardedBy("this")
  private final Map<JsonRpcPeer, DisconnectReceiver> mReceivingPeers = new HashMap<>();

  /**
   * This should be set to null anytime mReceivingPeers is changed. It should always be
   * retrieved by calling getReceivingPeersSnapshot().
   */
  @GuardedBy("this")
  private JsonRpcPeer[] mReceivingPeersSnapshot;

  @GuardedBy("this")
  private PeerRegistrationListener mListener;

  public ChromePeerManager() {
  }

  /**
   * Set a listener which can receive notifications of unique registration event (see
   * {@link #addPeer} and {@link #removePeer}).
   *
   * @param listener
   */
  public synchronized void setListener(PeerRegistrationListener listener) {
    mListener = listener;
  }

  /**
   * Register a new peer, adding them to an internal list of receivers.
   *
   * @param peer
   * @return True if this is a newly registered peer; false if it was already registered.
   */
  public synchronized boolean addPeer(JsonRpcPeer peer) {
    if (mReceivingPeers.containsKey(peer)) {
      return false;
    }

    DisconnectReceiver disconnectReceiver = new UnregisterOnDisconnect(peer);
    peer.registerDisconnectReceiver(disconnectReceiver);
    mReceivingPeers.put(peer, disconnectReceiver);
    mReceivingPeersSnapshot = null;
    if (mListener != null) {
      mListener.onPeerRegistered(peer);
    }
    return true;
  }

  /**
   * Unregister an existing peer.
   *
   * @param peer
   */
  public synchronized void removePeer(JsonRpcPeer peer) {
    if (mReceivingPeers.remove(peer) != null) {
      mReceivingPeersSnapshot = null;
      if (mListener != null) {
        mListener.onPeerUnregistered(peer);
      }
    }
  }

  public synchronized boolean hasRegisteredPeers() {
    return !mReceivingPeers.isEmpty();
  }

  private synchronized JsonRpcPeer[] getReceivingPeersSnapshot() {
    if (mReceivingPeersSnapshot == null) {
      mReceivingPeersSnapshot = mReceivingPeers.keySet().toArray(
          new JsonRpcPeer[mReceivingPeers.size()]);
    }
    return mReceivingPeersSnapshot;
  }

  public void sendNotificationToPeers(String method,
      Object params) {
    sendMessageToPeers(method, params, null /* callback */);
  }

  public void invokeMethodOnPeers(String method,
      Object params,
      PendingRequestCallback callback) {
    Util.throwIfNull(callback);
    sendMessageToPeers(method, params, callback);
  }

  private void sendMessageToPeers(String method,
      Object params,
      @Nullable PendingRequestCallback callback) {
    JsonRpcPeer[] peers = getReceivingPeersSnapshot();
    for (JsonRpcPeer peer : peers) {
      try {
        peer.invokeMethod(method, params, callback);
      } catch (NotYetConnectedException e) {
        LogUtil.e(TAG, "Error delivering data to Chrome", e);
      }
    }
  }

  private class UnregisterOnDisconnect implements DisconnectReceiver {
    private final JsonRpcPeer mPeer;

    public UnregisterOnDisconnect(JsonRpcPeer peer) {
      mPeer = peer;
    }

    @Override
    public void onDisconnect() {
      removePeer(mPeer);
    }
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ObjectIdMapper.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;

import android.util.SparseArray;

import java.util.IdentityHashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

public class ObjectIdMapper {
  protected final Object mSync = new Object();

  @GuardedBy("mSync")
  private int mNextId = 1;

  @GuardedBy("mSync")
  private final Map<Object, Integer> mObjectToIdMap = new IdentityHashMap<Object, Integer>();

  @GuardedBy("mSync")
  private SparseArray<Object> mIdToObjectMap = new SparseArray<Object>();

  public void clear() {
    SparseArray<Object> idToObjectMap;
    synchronized (mSync) {
      idToObjectMap = mIdToObjectMap;
      mObjectToIdMap.clear();
      mIdToObjectMap = new SparseArray<Object>();
    }

    int size = idToObjectMap.size();
    for (int i = 0; i < size; ++i) {
      int id = idToObjectMap.keyAt(i);
      Object object = idToObjectMap.valueAt(i);
      onUnmapped(object, id);
    }
  }

  public boolean containsId(int id) {
    synchronized (mSync) {
      return mIdToObjectMap.get(id) != null;
    }
  }

  public boolean containsObject(Object object) {
    synchronized (mSync) {
      return mObjectToIdMap.containsKey(object);
    }
  }

  @Nullable
  public Object getObjectForId(int id) {
    synchronized (mSync) {
      return mIdToObjectMap.get(id);
    }
  }

  @Nullable
  public Integer getIdForObject(Object object) {
    synchronized (mSync) {
      return mObjectToIdMap.get(object);
    }
  }

  public int putObject(Object object) {
    Integer id;

    synchronized (mSync) {
      id = mObjectToIdMap.get(object);
      if (id != null) {
        return id;
      }

      id = mNextId++;
      mObjectToIdMap.put(object, id);
      mIdToObjectMap.put(id, object);
    }

    onMapped(object, id);
    return id;
  }

  @Nullable
  public Object removeObjectById(int id) {
    Object object;

    synchronized (mSync) {
      object = mIdToObjectMap.get(id);
      if (object == null) {
        return null;
      }

      mIdToObjectMap.remove(id);
      mObjectToIdMap.remove(object);
    }

    onUnmapped(object, id);
    return object;
  }

  @Nullable
  public Integer removeObject(Object object) {
    Integer id;

    synchronized (mSync) {
      id = mObjectToIdMap.remove(object);
      if (id == null) {
        return null;
      }

      mIdToObjectMap.remove(id);
    }

    onUnmapped(object, id);
    return id;
  }

  public int size() {
    synchronized (mSync) {
      return mObjectToIdMap.size();
    }
  }

  public synchronized int getFirstId() {
    return mIdToObjectMap.keyAt(0);
  }

  protected void onMapped(Object object, int id) {
  }

  protected void onUnmapped(Object object, int id) {
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeerRegistrationListener.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;


import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;

public interface PeerRegistrationListener {
  void onPeerRegistered(JsonRpcPeer peer);
  void onPeerUnregistered(JsonRpcPeer peer);
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeersRegisteredListener.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;


import java.util.concurrent.atomic.AtomicInteger;

import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;

public abstract class PeersRegisteredListener implements PeerRegistrationListener {
  private AtomicInteger mPeers = new AtomicInteger(0);

  @Override
  public final void onPeerRegistered(JsonRpcPeer peer) {
    if (mPeers.incrementAndGet() == 1) {
      onFirstPeerRegistered();
    }
    onPeerAdded(peer);
  }

  @Override
  public final void onPeerUnregistered(JsonRpcPeer peer) {
    if (mPeers.decrementAndGet() == 0) {
      onLastPeerUnregistered();
    }
    onPeerRemoved(peer);
  }

  protected void onPeerAdded(JsonRpcPeer peer) {}
  protected void onPeerRemoved(JsonRpcPeer peer) {}

  protected abstract void onFirstPeerRegistered();
  protected abstract void onLastPeerUnregistered();
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ThreadBoundProxy.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;


import me.moxun.dreamcatcher.connector.util.ThreadBound;
import me.moxun.dreamcatcher.connector.util.UncheckedCallable;
import me.moxun.dreamcatcher.connector.util.Util;

/**
 * This class is for those cases when a class' threading
 * policy is determined by one of its member variables.
 */
public abstract class ThreadBoundProxy implements ThreadBound {
  private final ThreadBound mEnforcer;

  public ThreadBoundProxy(ThreadBound enforcer) {
    mEnforcer = Util.throwIfNull(enforcer);
  }

  @Override
  public final boolean checkThreadAccess() {
    return mEnforcer.checkThreadAccess();
  }

  @Override
  public final void verifyThreadAccess() {
    mEnforcer.verifyThreadAccess();
  }

  @Override
  public final <V> V postAndWait(UncheckedCallable<V> c) {
    return mEnforcer.postAndWait(c);
  }

  @Override
  public final void postAndWait(Runnable r) {
    mEnforcer.postAndWait(r);
  }

  @Override
  public final void postDelayed(Runnable r, long delayMillis) {
    mEnforcer.postDelayed(r, delayMillis);
  }

  @Override
  public final void removeCallbacks(Runnable r) {
    mEnforcer.removeCallbacks(r);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/TracingPeerManager.java
================================================
package me.moxun.dreamcatcher.connector.inspector.helper;

import javax.annotation.Nullable;

/**
 * Created by moxun on 16/4/26.
 */
public class TracingPeerManager extends ChromePeerManager {
    private static TracingPeerManager sInstance;

    @Nullable
    public static synchronized TracingPeerManager getInstanceOrNull() {
        return sInstance;
    }

    public static synchronized TracingPeerManager getOrCreateInstance() {
        if (sInstance == null) {
            sInstance = new TracingPeerManager();
        }
        return sInstance;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/ChromeDevtoolsDomain.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol;

/**
 * Created by moxun on 16/3/18.
 */
public interface ChromeDevtoolsDomain {
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/ChromeDevtoolsMethod.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by moxun on 16/3/18.
 */

@Retention(RetentionPolicy.RUNTIME)
public @interface ChromeDevtoolsMethod {
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleBooleanResult.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol;


import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

public class SimpleBooleanResult implements JsonRpcResult {
  @JsonProperty(required = true)
  public boolean result;

  public SimpleBooleanResult() {
  }

  public SimpleBooleanResult(boolean result) {
    this.result = result;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleIntegerResult.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol;


import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

/**
 * Created by moxun on 16/11/17.
 */

public class SimpleIntegerResult implements JsonRpcResult {
    @JsonProperty(required = true)
    public int result;

    public SimpleIntegerResult() {
    }

    public SimpleIntegerResult(int result) {
        this.result = result;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleStringResult.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol;


import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

/**
 * Created by moxun on 16/12/1.
 */

public class SimpleStringResult implements JsonRpcResult {
    @JsonProperty(required = true)
    public String data;

    public SimpleStringResult() {
    }

    public SimpleStringResult(String data) {
        this.data = data;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Console.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;

import android.annotation.SuppressLint;

import org.json.JSONObject;

import java.util.List;

import me.moxun.dreamcatcher.connector.console.ConsolePeerManager;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;

public class Console implements ChromeDevtoolsDomain {
    public Console() {
    }

    @ChromeDevtoolsMethod
    public void enable(JsonRpcPeer peer, JSONObject params) {
        ConsolePeerManager.getOrCreateInstance().addPeer(peer);
    }

    @ChromeDevtoolsMethod
    public void disable(JsonRpcPeer peer, JSONObject params) {
        ConsolePeerManager.getOrCreateInstance().removePeer(peer);
    }

    @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    public static class MessageAddedRequest {
        @JsonProperty(required = true)
        public ConsoleMessage message;
    }

    @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    public static class ConsoleMessage {
        @JsonProperty(required = true)
        public MessageSource source;

        @JsonProperty(required = true)
        public MessageLevel level;

        @JsonProperty(required = true)
        public String text;

        @JsonProperty(required = false)
        public MessageType type;

        @JsonProperty(required = false)
        public List<Runtime.RemoteObject> parameters;
    }

    public enum MessageSource {
        XML("xml"),
        JAVASCRIPT("javascript"),
        NETWORK("network"),
        CONSOLE_API("console-api"),
        STORAGE("storage"),
        APPCACHE("appcache"),
        RENDERING("rendering"),
        CSS("css"),
        SECURITY("security"),
        OTHER("other");

        private final String mProtocolValue;

        private MessageSource(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }

    public enum MessageLevel {
        LOG("log"),
        INFO("info"),
        WARNING("warning"),
        ERROR("error"),
        DEBUG("debug");

        private final String mProtocolValue;

        private MessageLevel(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }

    public enum MessageType {
        LOG("log"),
        TABLE("table"),
        GROUP_START("startGroup"),
        GROUP_END("endGroup"),
        DIR("dir");

        private final String mProtocolValue;

        private MessageType(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }

    @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    public static class CallFrame {
        @JsonProperty(required = true)
        public String functionName;

        @JsonProperty(required = true)
        public String url;

        @JsonProperty(required = true)
        public int lineNumber;

        @JsonProperty(required = true)
        public int columnNumber;

        public CallFrame() {
        }

        public CallFrame(String functionName, String url, int lineNumber, int columnNumber) {
            this.functionName = functionName;
            this.url = url;
            this.lineNumber = lineNumber;
            this.columnNumber = columnNumber;
        }
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/FileSystem.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;

import android.content.Context;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

/**
 * EXPERIMENTS
 * Created by moxun on 16/4/26.
 */
public class FileSystem implements ChromeDevtoolsDomain {

    private ObjectMapper mObjectMapper;
    private Context context;
    public static final String KEY_FS_ROOT = "FileSystem";
    private static boolean isFSEnabled = false;
    private List<String> textFile = new ArrayList<>();

    public static boolean isFSEnabled() {
        return isFSEnabled;
    }

    public FileSystem(Context context) {
        isFSEnabled = true;
        mObjectMapper = new ObjectMapper();
        this.context = context;

        textFile.add(".java");
        textFile.add(".txt");
        textFile.add(".html");
        textFile.add(".xml");
        textFile.add(".js");
        textFile.add(".json");
    }

    @ChromeDevtoolsMethod
    public void enable(JsonRpcPeer peer, JSONObject params) {

    }

    @ChromeDevtoolsMethod
    public void disable(JsonRpcPeer peer, JSONObject params) {

    }

    @ChromeDevtoolsMethod
    public JsonRpcResult requestFileSystemRoot(JsonRpcPeer peer, JSONObject params) {
        final RequestFileSystemRootRequest param = mObjectMapper.convertValue(params, RequestFileSystemRootRequest.class);
        if (param.origin.equals(KEY_FS_ROOT) && param.type.equals("persistent")) {
            return buildFileRoot();
        } else {
            return null;
        }
    }

    private RequestFileSystemRootResponse buildFileRoot() {
        RequestFileSystemRootResponse root = new RequestFileSystemRootResponse();
        root.errorCode = 0;
        Entry entry = new Entry();
        entry.name = "Data";
        entry.isDirectory = true;
        entry.url = context.getApplicationInfo().dataDir;
        root.root = entry;
        return root;
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult requestDirectoryContent(JsonRpcPeer peer, JSONObject params) {
        final RequestDirectoryContentRequest param = mObjectMapper.convertValue(params, RequestDirectoryContentRequest.class);
        File file = new File(param.url);
        if (file.exists() && file.isDirectory()) {
            final RequestDirectoryContentResponse response = new RequestDirectoryContentResponse();
            response.errorCode = 0;
            List<Entry> entries = new ArrayList<>();
            for (File f : file.listFiles()) {
                Entry entry = new Entry();
                entry.isDirectory = f.isDirectory();
                entry.url = f.getPath();
                entry.name = f.getName();
                entry.isTextFile = false;
                entry.resourceType = Page.ResourceType.OTHER;
                if (isImage(f)) {
                    entry.resourceType = Page.ResourceType.IMAGE;
                }
                if (isTextFile(f)) {
                    entry.resourceType = Page.ResourceType.DOCUMENT;
                    entry.isTextFile = isTextFile(f);
                }
                if (!entry.isDirectory) {
                    String[] strings = f.getName().split("\\.");
                    if (strings.length > 1) {
                        entry.mimeType = strings[strings.length - 1].toUpperCase();
                    } else {
                        entry.mimeType = "FILE";
                    }
                }
                entries.add(entry);
            }
            response.entries = entries;
            return response;
        }
        return null;
    }

    private boolean isTextFile(File file) {
        for (String s : textFile) {
            if (file.getName().toLowerCase().endsWith(s)) {
                return true;
            }
        }
        return false;
    }

    private boolean isImage(File file) {
        String[] images = {".jpg", ".jpeg", ".png", ".gif", ".webp"};
        for (String s : images) {
            if (file.getName().toLowerCase().endsWith(s)) {
                return true;
            }
        }
        return false;
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult requestMetadata(JsonRpcPeer peer, JSONObject params) {
        final RequestMetadataRequest param = mObjectMapper.convertValue(
                params,
                RequestMetadataRequest.class);
        File file = new File(param.url);
        if (file.exists()) {
            final RequestMetadataResponse response = new RequestMetadataResponse();
            response.errorCode = 0;
            Metadata meta = new Metadata();
            if (!file.isDirectory()) {
                meta.size = file.length();
            }
            meta.modificationTime = file.lastModified();
            response.metadata = meta;
            return response;
        } else {
            return null;
        }
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult requestFileContent(JsonRpcPeer peer, JSONObject params) {
        final RequestFileContentRequest param = mObjectMapper.convertValue(
                params,
                RequestFileContentRequest.class);
        final RequestFileContentResponse response = new RequestFileContentResponse();
        if (param.readAsText) {
            File file = new File(param.url);
            response.content = readFileAsText(file);
        }
        return response;
    }

    private String readFileAsText(File file) {
        String result = "";
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String s = null;
            while ((s = br.readLine()) != null) {
                result = result + "\n" + s;
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult deleteEntry(JsonRpcPeer peer, JSONObject params) {
        final DeleteEntryRequest param = mObjectMapper.convertValue(
                params,
                DeleteEntryRequest.class);
        final DeleteEntryResponse response = new DeleteEntryResponse();
        File file = new File(param.url);
        boolean success = file.delete();
        response.errorCode = success ? 0 : -1;
        return response;
    }

    public static class DeleteEntryRequest {
        @JsonProperty(required = true)
        public String url;
    }

    public static class DeleteEntryResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public int errorCode;
    }

    public static class RequestFileContentRequest {
        @JsonProperty(required = true)
        public String url;

        @JsonProperty(required = true)
        public boolean readAsText;

        @JsonProperty
        public Integer start;

        @JsonProperty
        public Integer end;

        @JsonProperty
        public String charset;
    }

    public static class RequestFileContentResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public int errorCode;

        @JsonProperty
        public String content;

        @JsonProperty
        public String charset;
    }

    public static class RequestMetadataRequest {
        @JsonProperty(required = true)
        public String url;
    }

    public static class RequestMetadataResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public int errorCode;

        @JsonProperty
        public Metadata metadata;
    }

    public static class Metadata {
        @JsonProperty(required = true)
        public double modificationTime;

        @JsonProperty(required = true)
        public double size;
    }

    public static class RequestDirectoryContentRequest {
        @JsonProperty(required = true)
        public String url;
    }

    public static class RequestDirectoryContentResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public int errorCode;

        @JsonProperty
        public List<Entry> entries;
    }

    public static class Entry {
        @JsonProperty(required = true)
        public String url;

        @JsonProperty(required = true)
        public String name;

        @JsonProperty(required = true)
        public boolean isDirectory;

        @JsonProperty
        public String mimeType;

        @JsonProperty
        public Page.ResourceType resourceType;

        @JsonProperty
        public Boolean isTextFile;
    }

    public static class RequestFileSystemRootRequest {
        @JsonProperty(required = true)
        public String origin;

        @JsonProperty(required = true)
        public String type;
    }

    public static class RequestFileSystemRootResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public int errorCode;

        @JsonProperty
        public Entry root;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Inspector.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;


import org.json.JSONObject;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;

public class Inspector implements ChromeDevtoolsDomain {
  public Inspector() {
  }

  @ChromeDevtoolsMethod
  public void enable(JsonRpcPeer peer, JSONObject params) {
  }

  @ChromeDevtoolsMethod
  public void disable(JsonRpcPeer peer, JSONObject params) {
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Network.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;

import android.content.Context;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.List;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcException;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;
import me.moxun.dreamcatcher.connector.reporter.AsyncPrettyPrinterInitializer;
import me.moxun.dreamcatcher.connector.reporter.NetworkPeerManager;
import me.moxun.dreamcatcher.connector.reporter.ResponseBodyData;
import me.moxun.dreamcatcher.connector.reporter.ResponseBodyFileManager;
import me.moxun.dreamcatcher.connector.util.Util;

public class Network implements ChromeDevtoolsDomain {
  private final NetworkPeerManager mNetworkPeerManager;
  private final ResponseBodyFileManager mResponseBodyFileManager;

  public Network(Context context) {
    mNetworkPeerManager = NetworkPeerManager.getOrCreateInstance(context);
    mResponseBodyFileManager = mNetworkPeerManager.getResponseBodyFileManager();
  }

  @ChromeDevtoolsMethod
  public void enable(JsonRpcPeer peer, JSONObject params) {
    mNetworkPeerManager.addPeer(peer);
  }

  @ChromeDevtoolsMethod
  public void disable(JsonRpcPeer peer, JSONObject params) {
    mNetworkPeerManager.removePeer(peer);
  }

  @ChromeDevtoolsMethod
  public void setUserAgentOverride(JsonRpcPeer peer, JSONObject params) {
    // Not implemented...
  }

  @ChromeDevtoolsMethod
  public JsonRpcResult getResponseBody(JsonRpcPeer peer, JSONObject params)
      throws JsonRpcException {
    try {
      String requestId = params.getString("requestId");
      return readResponseBody(requestId);
    } catch (IOException e) {
      throw new JsonRpcException(new JsonRpcError(JsonRpcError.ErrorCode.INTERNAL_ERROR,
          e.toString(),
          null /* data */));
    } catch (JSONException e) {
      throw new JsonRpcException(new JsonRpcError(JsonRpcError.ErrorCode.INTERNAL_ERROR,
          e.toString(),
          null /* data */));
    }
  }

  private GetResponseBodyResponse readResponseBody(String requestId)
      throws IOException, JsonRpcException {
    GetResponseBodyResponse response = new GetResponseBodyResponse();
    ResponseBodyData bodyData;
    try {
      bodyData = mResponseBodyFileManager.readFile(requestId);
    } catch (OutOfMemoryError e) {
      throw new JsonRpcException(new JsonRpcError(JsonRpcError.ErrorCode.INTERNAL_ERROR,
          e.toString(),
          null /* data */));
    }
    response.body = bodyData.data;
    response.base64Encoded = bodyData.base64Encoded;
    return response;
  }

  /**
   * Method that allows callers to provide an {@link AsyncPrettyPrinterInitializer} that is
   * responsible for registering all
   * Note that AsyncPrettyPrinterInitializer cannot be null and can only be set once.
   * @param initializer
   */
  public void setPrettyPrinterInitializer(AsyncPrettyPrinterInitializer initializer) {
    Util.throwIfNull(initializer);
    mNetworkPeerManager.setPrettyPrinterInitializer(initializer);
  }

  private static class GetResponseBodyResponse implements JsonRpcResult {
    @JsonProperty(required = true)
    public String body;

    @JsonProperty(required = true)
    public boolean base64Encoded;
  }

  public static class RequestWillBeSentParams {
    @JsonProperty(required = true)
    public String requestId;

    @JsonProperty(required = true)
    public String frameId;

    @JsonProperty(required = true)
    public String loaderId;

    @JsonProperty(required = true)
    public String documentURL;

    @JsonProperty(required = true)
    public Request request;

    @JsonProperty(required = true)
    public double timestamp;

    @JsonProperty(required = true)
    public Initiator initiator;

    @JsonProperty
    public Response redirectResponse;

    @JsonProperty
    public Page.ResourceType type;
  }

  public static class ResponseReceivedParams {
    @JsonProperty(required = true)
    public String requestId;

    @JsonProperty(required = true)
    public String frameId;

    @JsonProperty(required = true)
    public String loaderId;

    @JsonProperty(required = true)
    public double timestamp;

    @JsonProperty(required = true)
    public Page.ResourceType type;

    @JsonProperty(required = true)
    public Response response;
  }

  public static class LoadingFinishedParams {
    @JsonProperty(required = true)
    public String requestId;

    @JsonProperty(required = true)
    public double timestamp;
  }

  public static class LoadingFailedParams {
    @JsonProperty(required = true)
    public String requestId;

    @JsonProperty(required = true)
    public double timestamp;

    @JsonProperty(required = true)
    public String errorText;

    // Chrome introduced this undocumented new addition that, if not sent, will cause the row
    // to be removed from the UI and raise a JavaScript exception in the console.  This is
    // clearly an upstream bug that needs to be fixed, though we can work around it by
    // providing this new undocumented field.
    @JsonProperty
    public Page.ResourceType type;
  }

  public static class DataReceivedParams {
    @JsonProperty(required = true)
    public String requestId;

    @JsonProperty(required = true)
    public double timestamp;

    @JsonProperty(required = true)
    public int dataLength;

    @JsonProperty(required = true)
    public int encodedDataLength;
  }

  public static class Request {
    @JsonProperty(required = true)
    public String url;

    @JsonProperty(required = true)
    public String method;

    @JsonProperty(required = true)
    public JSONObject headers;

    @JsonProperty
    public String postData;
  }

  public static class Initiator {
    @JsonProperty(required = true)
    public InitiatorType type;

    @JsonProperty
    public List<Console.CallFrame> stackTrace;
  }

  public enum InitiatorType {
    PARSER("parser"),
    SCRIPT("script"),
    OTHER("other");

    private final String mProtocolValue;

    private InitiatorType(String protocolValue) {
      mProtocolValue = protocolValue;
    }

    @JsonValue
    public String getProtocolValue() {
      return mProtocolValue;
    }
  }

  public static class Response {
    @JsonProperty(required = true)
    public String url;

    @JsonProperty(required = true)
    public int status;

    @JsonProperty(required = true)
    public String statusText;

    @JsonProperty(required = true)
    public JSONObject headers;

    @JsonProperty
    public String headersText;

    @JsonProperty(required = true)
    public String mimeType;

    @JsonProperty
    public JSONObject requestHeaders;

    @JsonProperty
    public String requestHeadersTest;

    @JsonProperty(required = true)
    public boolean connectionReused;

    @JsonProperty(required = true)
    public int connectionId;

    @JsonProperty(required = true)
    public Boolean fromDiskCache;

    @JsonProperty
    public ResourceTiming timing;
  }

  public static class ResourceTiming {
    @JsonProperty(required = true)
    public double requestTime;

    @JsonProperty(required = true)
    public double proxyStart;

    @JsonProperty(required = true)
    public double proxyEnd;

    @JsonProperty(required = true)
    public double dnsStart;

    @JsonProperty(required = true)
    public double dnsEnd;

    @JsonProperty(required = true)
    public double connectStart;

    @JsonProperty(required = true)
    public double connectEnd;

    @JsonProperty(required = true)
    public double sslStart;

    @JsonProperty(required = true)
    public double sslEnd;

    @JsonProperty(required = true)
    public double sendStart;

    @JsonProperty(required = true)
    public double sendEnd;

    @JsonProperty(required = true)
    public double receiveHeadersEnd;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Page.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;

import android.content.Context;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.inspector.protocol.SimpleBooleanResult;
import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;
import me.moxun.dreamcatcher.connector.util.LogUtil;
import me.moxun.dreamcatcher.connector.util.ProcessUtil;

public class Page implements ChromeDevtoolsDomain {
    private final Context mContext;
    private final ObjectMapper mObjectMapper = new ObjectMapper();
    private int lastFrame = 0;

    public Page(Context context) {
        mContext = context;
    }

    @ChromeDevtoolsMethod
    public void enable(JsonRpcPeer peer, JSONObject params) {
        notifyExecutionContexts(peer);
        sendWelcomeMessage(peer);
    }

    @ChromeDevtoolsMethod
    public void disable(JsonRpcPeer peer, JSONObject params) {
    }

    private void notifyExecutionContexts(JsonRpcPeer peer) {
        ExecutionContextDescription context = new ExecutionContextDescription();
        context.frameId = "1";
        context.id = 1;
        ExecutionContextCreatedParams params = new ExecutionContextCreatedParams();
        params.context = context;
        peer.invokeMethod("Runtime.executionContextCreated", params, null /* callback */);
    }

    private void sendWelcomeMessage(JsonRpcPeer peer) {
        Console.ConsoleMessage message = new Console.ConsoleMessage();
        message.source = Console.MessageSource.JAVASCRIPT;
        message.level = Console.MessageLevel.LOG;
        String art = " Welcome to DreamCatcher\n Attached to process " + ProcessUtil.getProcessName() + "\n\n";
        message.text = art;
        // Note: not using Android resources so we can maintain .jar distribution for now.
        Console.MessageAddedRequest messageAddedRequest = new Console.MessageAddedRequest();
        messageAddedRequest.message = message;
        peer.invokeMethod("Console.messageAdded", messageAddedRequest, null /* callback */);
    }

    private static FrameResourceTree createSimpleFrameResourceTree(
            String id,
            String parentId,
            String name,
            String securityOrigin) {
        Frame frame = new Frame();
        frame.id = id;
        frame.parentId = parentId;
        frame.loaderId = "1";
        frame.name = name;
        frame.url = "";
        frame.securityOrigin = securityOrigin;
        frame.mimeType = "text/plain";
        FrameResourceTree tree = new FrameResourceTree();
        tree.frame = frame;
        tree.resources = Collections.emptyList();
        tree.childFrames = null;
        return tree;
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult canScreencast(JsonRpcPeer peer, JSONObject params) {
        return new SimpleBooleanResult(false);
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult hasTouchInputs(JsonRpcPeer peer, JSONObject params) {
        return new SimpleBooleanResult(false);
    }

    @ChromeDevtoolsMethod
    public void setDeviceMetricsOverride(JsonRpcPeer peer, JSONObject params) {
    }

    @ChromeDevtoolsMethod
    public void clearDeviceOrientationOverride(JsonRpcPeer peer, JSONObject params) {
    }

    @ChromeDevtoolsMethod
    public void startScreencast(final JsonRpcPeer peer, JSONObject params) {

    }

    @ChromeDevtoolsMethod
    public void stopScreencast(JsonRpcPeer peer, JSONObject params) {

    }

    @ChromeDevtoolsMethod
    public void screencastFrameAck(JsonRpcPeer peer, JSONObject params) {
        // Nothing to do here, just need to make sure Chrome doesn't get an error that this method
        // isn't implemented
        int ackFrame = 0;
        try {
            ackFrame = params.getInt("sessionId");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if ((ackFrame - lastFrame) != 1 ) {
            LogUtil.w("Screencast", "Lost " + (ackFrame - lastFrame) + " frame(s)! current frame is " + ackFrame);
        }
        lastFrame = ackFrame;
    }

    @ChromeDevtoolsMethod
    public void clearGeolocationOverride(JsonRpcPeer peer, JSONObject params) {
    }

    @ChromeDevtoolsMethod
    public void setTouchEmulationEnabled(JsonRpcPeer peer, JSONObject params) {
    }

    @ChromeDevtoolsMethod
    public void setEmulatedMedia(JsonRpcPeer peer, JSONObject params) {
    }

    @ChromeDevtoolsMethod
    public void setShowViewportSizeOnResize(JsonRpcPeer peer, JSONObject params) {
    }

    private static class GetResourceTreeParams implements JsonRpcResult {
        @JsonProperty(required = true)
        public FrameResourceTree frameTree;
    }

    private static class FrameResourceTree {
        @JsonProperty(required = true)
        public Frame frame;

        @JsonProperty
        public List<FrameResourceTree> childFrames;

        @JsonProperty(required = true)
        public List<Resource> resources;
    }

    private static class Frame {
        @JsonProperty(required = true)
        public String id;

        @JsonProperty
        public String parentId;

        @JsonProperty(required = true)
        public String loaderId;

        @JsonProperty
        public String name;

        @JsonProperty(required = true)
        public String url;

        @JsonProperty(required = true)
        public String securityOrigin;

        @JsonProperty(required = true)
        public String mimeType;
    }

    private static class Resource {
        // Incomplete...
    }

    public enum ResourceType {
        DOCUMENT("Document"),
        STYLESHEET("Stylesheet"),
        IMAGE("Image"),
        FONT("Font"),
        SCRIPT("Script"),
        XHR("XHR"),
        WEBSOCKET("WebSocket"),
        OTHER("Other");

        private final String mProtocolValue;

        private ResourceType(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }

    private static class ExecutionContextCreatedParams {
        @JsonProperty(required = true)
        public ExecutionContextDescription context;
    }

    private static class ExecutionContextDescription {
        @JsonProperty(required = true)
        public String frameId;

        @JsonProperty(required = true)
        public int id;
    }

    public static class ScreencastFrameEvent {
        @JsonProperty(required = true)
        public String data;

        @JsonProperty(required = true)
        public ScreencastFrameEventMetadata metadata;

        @JsonProperty(required = true)
        public int sessionId;

        private static AtomicInteger generator = new AtomicInteger();
        public void increment() {
            sessionId = generator.incrementAndGet();
        }
    }

    public static class ScreencastFrameEventMetadata {
        @JsonProperty(required = true)
        public float pageScaleFactor;
        @JsonProperty(required = true)
        public int offsetTop;
        @JsonProperty(required = true)
        public int deviceWidth;
        @JsonProperty(required = true)
        public int deviceHeight;
        @JsonProperty(required = true)
        public int scrollOffsetX;
        @JsonProperty(required = true)
        public int scrollOffsetY;
    }

    public static class StartScreencastRequest {
        @JsonProperty
        public String format;
        @JsonProperty
        public int quality;
        @JsonProperty
        public int maxWidth;
        @JsonProperty
        public int maxHeight;
    }

    public static class NavigationHistory implements JsonRpcResult {
        @JsonProperty(required = true)
        public int currentIndex;
        @JsonProperty(required = true)
        public List<NavigationEntry> entries;
    }

    public static class NavigationEntry {
        @JsonProperty(required = true)
        public int id;
        @JsonProperty(required = true)
        public String url;
        @JsonProperty(required = true)
        public String title;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Profiler.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;


import org.json.JSONObject;

import java.util.Collections;
import java.util.List;

import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

public class Profiler implements ChromeDevtoolsDomain {
  public Profiler() {
  }

  @ChromeDevtoolsMethod
  public void enable(JsonRpcPeer peer, JSONObject params) {
  }

  @ChromeDevtoolsMethod
  public void disable(JsonRpcPeer peer, JSONObject params) {
  }

  @ChromeDevtoolsMethod
  public void stop(JsonRpcPeer peer, JSONObject params) {
  }

  @ChromeDevtoolsMethod
  public void setSamplingInterval(JsonRpcPeer peer, JSONObject params) {
  }

  @ChromeDevtoolsMethod
  public JsonRpcResult getProfileHeaders(JsonRpcPeer peer, JSONObject params) {
    ProfileHeaderResponse response = new ProfileHeaderResponse();
    response.headers = Collections.emptyList();
    return response;
  }

  private static class ProfileHeaderResponse implements JsonRpcResult {
    @JsonProperty(required = true)
    public List<ProfileHeader> headers;
  }

  private static class ProfileHeader {
    @JsonProperty(required = true)
    String typeId;

    @JsonProperty(required = true)
    String title;

    @JsonProperty(required = true)
    int uid;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Runtime.java
================================================
package me.moxun.dreamcatcher.connector.inspector.protocol.module;


import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.console.RuntimeRepl;
import me.moxun.dreamcatcher.connector.console.RuntimeReplFactory;
import me.moxun.dreamcatcher.connector.inspector.helper.ObjectIdMapper;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomain;
import me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsMethod;
import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;
import me.moxun.dreamcatcher.connector.jsonrpc.DisconnectReceiver;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcException;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;
import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;
import me.moxun.dreamcatcher.connector.util.LogUtil;

/**
 * Created by moxun on 16/3/31.
 */
public class Runtime implements ChromeDevtoolsDomain {

    private final ObjectMapper mObjectMapper = new ObjectMapper();

    private static final Map<JsonRpcPeer, Session> sSessions =
            Collections.synchronizedMap(new HashMap<JsonRpcPeer, Session>());

    private final RuntimeReplFactory mReplFactory;

    /**
     * @see #Runtime(RuntimeReplFactory)
     * @deprecated Provided for ABI compatibility
     */
    @Deprecated
    public Runtime() {
        this(new RuntimeReplFactory() {
            @Override
            public RuntimeRepl newInstance() {
                return new RuntimeRepl() {
                    @Override
                    public Object evaluate(String expression) throws Throwable {
                        return "Not supported with legacy Runtime module";
                    }
                };
            }
        });
    }

    public Runtime(RuntimeReplFactory replFactory) {
        mReplFactory = replFactory;
    }

    public static int mapObject(JsonRpcPeer peer, Object object) {
        return getSession(peer).getObjects().putObject(object);
    }

    @Nonnull
    private static synchronized Session getSession(final JsonRpcPeer peer) {
        Session session = sSessions.get(peer);
        if (session == null) {
            session = new Session();
            sSessions.put(peer, session);
            peer.registerDisconnectReceiver(new DisconnectReceiver() {
                @Override
                public void onDisconnect() {
                    sSessions.remove(peer);
                }
            });
        }
        return session;
    }

    @ChromeDevtoolsMethod
    public void releaseObject(JsonRpcPeer peer, JSONObject params) throws JSONException {
        String objectId = params.getString("objectId");
        getSession(peer).getObjects().removeObjectById(Integer.parseInt(objectId));
    }

    @ChromeDevtoolsMethod
    public void releaseObjectGroup(JsonRpcPeer peer, JSONObject params) {
        LogUtil.w("Ignoring request to releaseObjectGroup: " + params);
    }

    @ChromeDevtoolsMethod
    public CallFunctionOnResponse callFunctionOn(JsonRpcPeer peer, JSONObject params)
            throws JsonRpcException {
        CallFunctionOnRequest args = mObjectMapper.convertValue(params, CallFunctionOnRequest.class);

        Session session = getSession(peer);
        Object object = session.getObjectOrThrow(args.objectId);

        // The DevTools UI thinks it can run arbitrary JavaScript against us in order to figure out
        // the class structure of an object.  That obviously won't fly, and there's no way to
        // translate without building a crude JavaScript parser so let's just go ahead and guess
        // what this function does by name.
        if (!args.functionDeclaration.startsWith("function protoList(")) {
            throw new JsonRpcException(
                    new JsonRpcError(
                            JsonRpcError.ErrorCode.INTERNAL_ERROR,
                            "Expected protoList, got: " + args.functionDeclaration,
                            null /* data */));
        }

        // Since this is really a function call we have to create this fake object to hold the
        // "result" of the function.
        ObjectProtoContainer objectContainer = new ObjectProtoContainer(object);
        RemoteObject result = new RemoteObject();
        result.type = ObjectType.OBJECT;
        result.subtype = ObjectSubType.NODE;
        result.className = object.getClass().getName();
        result.description = getPropertyClassName(object);
        result.objectId = String.valueOf(session.getObjects().putObject(objectContainer));

        CallFunctionOnResponse response = new CallFunctionOnResponse();
        response.result = result;
        response.wasThrown = false;

        return response;
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult evaluate(JsonRpcPeer peer, JSONObject params) {
        return getSession(peer).evaluate(mReplFactory, params);
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult getProperties(JsonRpcPeer peer, JSONObject params) throws JsonRpcException {
        return getSession(peer).getProperties(params);
    }

    private static String getPropertyClassName(Object o) {
        String name = o.getClass().getSimpleName();
        if (name == null || name.length() == 0) {
            // Looks better for anonymous classes.
            name = o.getClass().getName();
        }
        return name;
    }

    private static class ObjectProtoContainer {
        public final Object object;

        public ObjectProtoContainer(Object object) {
            this.object = object;
        }
    }

    /**
     * Object representing a session with a single client.
     * <p/>
     * <p>Clients inherently leak object references because they can expand any object in the UI
     * at any time.  Grouping references by client allows us to drop them when the client
     * disconnects.
     */
    private static class Session {
        private final ObjectIdMapper mObjects = new ObjectIdMapper();
        private final ObjectMapper mObjectMapper = new ObjectMapper();

        @Nullable
        private RuntimeRepl mRepl;

        public ObjectIdMapper getObjects() {
            return mObjects;
        }

        public Object getObjectOrThrow(String objectId) throws JsonRpcException {
            Object object = getObjects().getObjectForId(Integer.parseInt(objectId));
            if (object == null) {
                throw new JsonRpcException(new JsonRpcError(
                        JsonRpcError.ErrorCode.INVALID_REQUEST,
                        "No object found for " + objectId,
                        null /* data */));
            }
            return object;
        }

        public RemoteObject objectForRemote(Object value) {
            RemoteObject result = new RemoteObject();
            if (value == null) {
                result.type = ObjectType.OBJECT;
                result.subtype = ObjectSubType.NULL;
                result.value = JSONObject.NULL;
            } else if (value instanceof Boolean) {
                result.type = ObjectType.BOOLEAN;
                result.value = value;
            } else if (value instanceof Number) {
                result.type = ObjectType.NUMBER;
                result.value = value;
            } else if (value instanceof Character) {
                // Unclear whether we should expose these as strings, numbers, or something else.
                result.type = ObjectType.NUMBER;
                result.value = Integer.valueOf(((Character) value).charValue());
            } else if (value instanceof String) {
                result.type = ObjectType.STRING;
                result.value = String.valueOf(value);
            } else {
                result.type = ObjectType.OBJECT;
                result.className = "What??";  // I have no idea where this is used.
                result.objectId = String.valueOf(mObjects.putObject(value));

                if (value.getClass().isArray()) {
                    result.description = "array";
                } else if (value instanceof List) {
                    result.description = "List";
                } else if (value instanceof Set) {
                    result.description = "Set";
                } else if (value instanceof Map) {
                    result.description = "Map";
                } else {
                    result.description = getPropertyClassName(value);
                }

            }
            return result;
        }

        public EvaluateResponse evaluate(RuntimeReplFactory replFactory, JSONObject params) {
            EvaluateRequest request = mObjectMapper.convertValue(params, EvaluateRequest.class);

            try {
                if (!request.objectGroup.equals("console")) {
                    return buildExceptionResponse("Not supported by FAB");
                }

                RuntimeRepl repl = getRepl(replFactory);
                Object result = repl.evaluate(request.expression);
                if (result == null) {
                    return null;
                }
                return buildNormalResponse(result);
            } catch (Throwable t) {
                return buildExceptionResponse(t);
            }
        }

        @Nonnull
        private synchronized RuntimeRepl getRepl(RuntimeReplFactory replFactory) {
            if (mRepl == null) {
                mRepl = replFactory.newInstance();
            }
            return mRepl;
        }

        private EvaluateResponse buildNormalResponse(Object retval) {
            EvaluateResponse response = new EvaluateResponse();
            response.wasThrown = false;
            response.result = objectForRemote(retval);
            return response;
        }

        private EvaluateResponse buildExceptionResponse(Object retval) {
            EvaluateResponse response = new EvaluateResponse();
            response.wasThrown = true;
            response.result = objectForRemote(retval);
            response.exceptionDetails = new ExceptionDetails();
            response.exceptionDetails.text = retval.toString();
            return response;
        }

        public GetPropertiesResponse getProperties(JSONObject params) throws JsonRpcException {
            GetPropertiesRequest request = mObjectMapper.convertValue(params, GetPropertiesRequest.class);

            if (!request.ownProperties) {
                GetPropertiesResponse response = new GetPropertiesResponse();
                response.result = new ArrayList<>();
                return response;
            }

            Object object = getObjectOrThrow(request.objectId);

            if (object.getClass().isArray()) {
                object = arrayToList(object);
            }

            if (object instanceof ObjectProtoContainer) {
                return getPropertiesForProtoContainer((ObjectProtoContainer) object);
            } else if (object instanceof List) {
                return getPropertiesForIterable((List) object, /* enumerate */ true);
            } else if (object instanceof Set) {
                return getPropertiesForIterable((Set) object, /* enumerate */ false);
            } else if (object instanceof Map) {
                return getPropertiesForMap(object);
            } else {
                return getPropertiesForObject(object);
            }
        }

        private List<?> arrayToList(Object object) {
            Class<?> type = object.getClass();
            if (!type.isArray()) {
                throw new IllegalArgumentException("Argument must be an array.  Was " + type);
            }
            Class<?> component = type.getComponentType();

            if (!component.isPrimitive()) {
                return Arrays.asList((Object[]) object);
            }

            // Loop manually for primitives.
            int length = Array.getLength(object);
            List<Object> ret = new ArrayList<>(length);
            for (int i = 0; i < length; i++) {
                ret.add(Array.get(object, i));
            }
            return ret;
        }

        // Normally JavaScript will return the full class hierarchy as a list.  That seems less
        // useful for Java since it's more natural (IMO) to see all available member variables in one
        // big list.
        private GetPropertiesResponse getPropertiesForProtoContainer(ObjectProtoContainer proto) {
            Object target = proto.object;
            RemoteObject protoRemote = new RemoteObject();
            protoRemote.type = ObjectType.OBJECT;
            protoRemote.subtype = ObjectSubType.NODE;
            protoRemote.className = target.getClass().getName();
            protoRemote.description = getPropertyClassName(target);
            protoRemote.objectId = String.valueOf(mObjects.putObject(target));
            PropertyDescriptor descriptor = new PropertyDescriptor();
            descriptor.name = "1";
            descriptor.value = protoRemote;
            GetPropertiesResponse response = new GetPropertiesResponse();
            response.result = new ArrayList<>(1);
            response.result.add(descriptor);
            return response;
        }

        private GetPropertiesResponse getPropertiesForIterable(Iterable<?> object, boolean enumerate) {
            GetPropertiesResponse response = new GetPropertiesResponse();
            List<PropertyDescriptor> properties = new ArrayList<>();

            int index = 0;
            for (Object value : object) {
                PropertyDescriptor property = new PropertyDescriptor();
                property.name = enumerate ? String.valueOf(index++) : null;
                property.value = objectForRemote(value);
                properties.add(property);
            }

            response.result = properties;
            return response;
        }

        private GetPropertiesResponse getPropertiesForMap(Object object) {
            GetPropertiesResponse response = new GetPropertiesResponse();
            List<PropertyDescriptor> properties = new ArrayList<>();

            for (Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
                PropertyDescriptor property = new PropertyDescriptor();
                property.name = String.valueOf(entry.getKey());
                property.value = objectForRemote(entry.getValue());
                properties.add(property);
            }

            response.result = properties;
            return response;
        }

        private GetPropertiesResponse getPropertiesForObject(Object object) {
            GetPropertiesResponse response = new GetPropertiesResponse();
            List<PropertyDescriptor> properties = new ArrayList<>();
            for (
                    Class<?> declaringClass = object.getClass();
                    declaringClass != null;
                    declaringClass = declaringClass.getSuperclass()
                    ) {
                // Reverse the list of fields while going up the superclass chain.
                // When we're done, we'll reverse the full list so that the superclasses
                // appear at the top, but within each class they properties are in declared order.
                List<Field> fields =
                        new ArrayList<Field>(Arrays.asList(declaringClass.getDeclaredFields()));
                Collections.reverse(fields);
                String prefix = declaringClass == object.getClass()
                        ? ""
                        : declaringClass.getSimpleName() + ".";
                for (Field field : fields) {
                    if (Modifier.isStatic(field.getModifiers())) {
                        continue;
                    }
                    field.setAccessible(true);
                    try {
                        Object fieldValue = field.get(object);
                        PropertyDescriptor property = new PropertyDescriptor();
                        property.name = prefix + field.getName();
                        property.value = objectForRemote(fieldValue);
                        properties.add(property);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            Collections.reverse(properties);
            response.result = properties;
            return response;
        }
    }

    private static class CallFunctionOnRequest {
        @JsonProperty
        public String objectId;

        @JsonProperty
        public String functionDeclaration;

        @JsonProperty
        public List<CallArgument> arguments;

        @JsonProperty(required = false)
        public Boolean doNotPauseOnExceptionsAndMuteConsole;

        @JsonProperty(required = false)
        public Boolean returnByValue;

        @JsonProperty(required = false)
        public Boolean generatePreview;
    }

    private static class CallFunctionOnResponse implements JsonRpcResult {
        @JsonProperty
        public RemoteObject result;

        @JsonProperty(required = false)
        public Boolean wasThrown;
    }

    private static class CallArgument {
        @JsonProperty(required = false)
        public Object value;

        @JsonProperty(required = false)
        public String objectId;

        @JsonProperty(required = false)
        public ObjectType type;
    }

    private static class GetPropertiesRequest implements JsonRpcResult {
        @JsonProperty(required = true)
        public boolean ownProperties;

        @JsonProperty(required = true)
        public String objectId;
    }

    private static class GetPropertiesResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public List<PropertyDescriptor> result;
    }

    private static class EvaluateRequest implements JsonRpcResult {
        @JsonProperty(required = true)
        public String objectGroup;

        @JsonProperty(required = true)
        public String expression;
    }

    private static class EvaluateResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public RemoteObject result;

        @JsonProperty(required = true)
        public boolean wasThrown;

        @JsonProperty
        public ExceptionDetails exceptionDetails;
    }

    private static class ExceptionDetails {
        @JsonProperty(required = true)
        public String text;
    }

    public static class RemoteObject {
        @JsonProperty(required = true)
        public ObjectType type;

        @JsonProperty
        public ObjectSubType subtype;

        @JsonProperty
        public Object value;

        @JsonProperty
        public String className;

        @JsonProperty
        public String description;

        @JsonProperty
        public String objectId;
    }

    private static class PropertyDescriptor {
        @JsonProperty(required = true)
        public String name;

        @JsonProperty(required = true)
        public RemoteObject value;

        @JsonProperty(required = true)
        public final boolean isOwn = true;

        @JsonProperty(required = true)
        public final boolean configurable = false;

        @JsonProperty(required = true)
        public final boolean enumerable = true;

        @JsonProperty(required = true)
        public final boolean writable = false;
    }

    public static enum ObjectType {
        OBJECT("object"),
        FUNCTION("function"),
        UNDEFINED("undefined"),
        STRING("string"),
        NUMBER("number"),
        BOOLEAN("boolean"),
        SYMBOL("symbol");

        private final String mProtocolValue;

        private ObjectType(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }

    public static enum ObjectSubType {
        ARRAY("array"),
        NULL("null"),
        NODE("node"),
        REGEXP("regexp"),
        DATE("date"),
        MAP("map"),
        SET("set"),
        ITERATOR("iterator"),
        GENERATOR("generator"),
        ERROR("error");

        private final String mProtocolValue;

        private ObjectSubType(String protocolValue) {
            mProtocolValue = protocolValue;
        }

        @JsonValue
        public String getProtocolValue() {
            return mProtocolValue;
        }
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/runtime/DefaultRuntimeReplFactory.java
================================================
package me.moxun.dreamcatcher.connector.inspector.runtime;


import java.util.HashMap;
import java.util.Map;

import me.moxun.dreamcatcher.connector.console.RuntimeRepl;
import me.moxun.dreamcatcher.connector.console.RuntimeReplFactory;
import me.moxun.dreamcatcher.connector.console.command.CommandHandler;

/**
 * Created by moxun on 16/3/31.
 */
public class DefaultRuntimeReplFactory implements RuntimeReplFactory {
    private static Map<String, CommandHandler> handlerMap;

    @Override
    public RuntimeRepl newInstance() {
        if (handlerMap == null) {
            handlerMap = new HashMap<>();
            handlerMap.clear();
        }

        return new RuntimeRepl() {
            @Override
            public Object evaluate(String expression) throws Throwable {
                Object ret = null;
                try {
                    ret = processCommand(expression);
                } catch (Exception ex) {
                    //don't throw out
                    ret = ex.getMessage();
                    ex.printStackTrace();
                }
                return ret;
            }
        };
    }

    public static void register(String command, CommandHandler handler) {
        if (handlerMap == null) {
            handlerMap = new HashMap<>();
            handlerMap.clear();
        }
        handlerMap.put(command, handler);
    }

    private Command getCommand(String command) {
        Command c = new Command();
        if (command.contains(" ")) {
            int i = command.indexOf(" ");
            c.command = command.substring(0, i);
            c.param = command.substring(i + 1);
        } else {
            c.command = command;
            c.param = null;
        }
        return c;
    }

    private Object processCommand(String input) {
        Command command = getCommand(input);
        CommandHandler handler = handlerMap.get(command.command);
        if (handler != null) {
            return handler.onCommand(command.param);
        } else {
            return "command '" + input + "' not support now.";
        }
    }

    private class Command {
        String command;
        String param;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/json/ObjectMapper.java
================================================
package me.moxun.dreamcatcher.connector.json;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;
import me.moxun.dreamcatcher.connector.util.ExceptionUtil;

/**
 * This class is a lightweight version of Jackson's ObjectMapper. It is designed to have a minimal
 * subset of the functionality required for dreamcatcher.
 * <p>
 * It would be awesome if there were a lightweight library that supported converting between
 * arbitrary {@link Object} and {@link JSONObject} representations.
 * <p>
 * Admittedly the other approach would be to use an Annotation Processor to create static conversion
 * functions that discover something like a {@link JsonProperty} and create a function at compile
 * time however since this is just being used for a simple debug utility and Kit-Kat caches the
 * results of reflection this class is sufficient for dreamcatcher needs.
 */
public class ObjectMapper {

  @GuardedBy("mJsonValueMethodCache")
  private final Map<Class<?>, Method> mJsonValueMethodCache = new IdentityHashMap<>();

  /**
   * Support mapping between arbitrary classes and {@link JSONObject}.
   * <note>
   *   It is possible for a {@link Throwable} to be propagated out of this class if there is an
   *   {@link InvocationTargetException}.
   * </note>
   * @param fromValue
   * @param toValueType
   * @param <T>
   * @return
   * @throws IllegalArgumentException when there is an error converting. One of either
   * {@code fromValue.getClass()} or {@code toValueType} must be {@link JSONObject}.
   */
  public <T> T convertValue(Object fromValue, Class<T> toValueType)
      throws IllegalArgumentException {
    if (fromValue == null) {
      return null;
    }

    if (toValueType != Object.class
        && toValueType.isAssignableFrom(fromValue.getClass())) {
      return (T) fromValue;
    }

    try {
      if (fromValue instanceof JSONObject) {
        return _convertFromJSONObject((JSONObject) fromValue, toValueType);
      } else if (toValueType == JSONObject.class) {
        return (T) _convertToJSONObject(fromValue);
      } else {
        throw new IllegalArgumentException(
            "Expecting either fromValue or toValueType to be a JSONObject");
      }
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException(e);
    } catch (IllegalAccessException e) {
      throw new IllegalArgumentException(e);
    } catch (InstantiationException e) {
      throw new IllegalArgumentException(e);
    } catch (JSONException e) {
      throw new IllegalArgumentException(e);
    } catch (InvocationTargetException e) {
      throw ExceptionUtil.propagate(e.getCause());
    }
  }

  private <T> T _convertFromJSONObject(JSONObject jsonObject, Class<T> type)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
          InstantiationException, JSONException {
    Constructor<T> constructor = type.getDeclaredConstructor((Class[]) null);
    constructor.setAccessible(true);
    T instance = constructor.newInstance();
    Field[] fields = type.getFields();
    for (int i = 0; i < fields.length; ++i) {
      Field field = fields[i];
      Object value = jsonObject.opt(field.getName());
      Object setValue = getValueForField(field, value);
      try {
        field.set(instance, setValue);
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            "Class: " + type.getSimpleName() + " " +
            "Field: " + field.getName() + " type " + setValue.getClass().getName(),
            e);
      }
    }
    return instance;
  }

  private Object getValueForField(Field field, Object value)
      throws JSONException {
    try {
      if (value != null) {
        if (value == JSONObject.NULL) {
          return null;
        }
        if (value.getClass() == field.getType()) {
          return value;
        }
        if (value instanceof JSONObject) {
          return convertValue(value, field.getType());
        } else {
          if (field.getType().isEnum()) {
            return getEnumValue((String) value, field.getType().asSubclass(Enum.class));
          } else if (value instanceof JSONArray) {
            return convertArrayToList(field, (JSONArray) value);
          } else if (value instanceof Number) {
            // Need to convert value to Number This happens because json treats 1 as an Integer even
            // if the field is supposed to be a Long
            Number numberValue = (Number) value;
            Class<?> clazz = field.getType();
            if (clazz == Integer.class || clazz == int.class) {
              return numberValue.intValue();
            } else if (clazz == Long.class || clazz == long.class) {
              return numberValue.longValue();
            } else if (clazz == Double.class || clazz == double.class) {
              return numberValue.doubleValue();
            } else if (clazz == Float.class || clazz == float.class) {
              return numberValue.floatValue();
            } else if (clazz == Byte.class || clazz == byte.class) {
              return numberValue.byteValue();
            } else if (clazz == Short.class || clazz == short.class) {
              return numberValue.shortValue();
            } else {
              throw new IllegalArgumentException("Not setup to handle class " + clazz.getName());
            }
          }
        }
      }
    } catch (IllegalAccessException e) {
      throw new IllegalArgumentException("Unable to set value for field " + field.getName(), e);
    }
    return value;
  }

  private Enum getEnumValue(String value, Class<? extends Enum> clazz) {
    Method method = getJsonValueMethod(clazz);
    if (method != null) {
      return getEnumByMethod(value, clazz, method);
    } else {
      return Enum.valueOf(clazz, value);
    }
  }

  /**
   * In this case we know that there is an {@link Enum} decorated with {@link JsonValue}. This means
   * that we need to iterate through all of the values of the {@link Enum} returned by the given
   * {@link Method} to check the given value.
   * @param value
   * @param clazz
   * @param method
   * @return
   */
  private Enum getEnumByMethod(String value, Class<? extends Enum> clazz, Method method) {
    Enum[] enumValues = clazz.getEnumConstants();
    // Start at the front to ensure first always wins
    for (int i = 0; i < enumValues.length; ++i) {
      Enum enumValue = enumValues[i];
      try {
        Object o = method.invoke(enumValue);
        if (o != null) {
          if (o.toString().equals(value)) {
            return enumValue;
          }
        }
      } catch (Exception ex) {
        throw new IllegalArgumentException(ex);
      }
    }
    throw new IllegalArgumentException("No enum constant " + clazz.getName() + "." + value);
  }

  private List<Object> convertArrayToList(Field field, JSONArray array)
      throws IllegalAccessException, JSONException {
    if (List.class.isAssignableFrom(field.getType())) {
      ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
      Type[] types = parameterizedType.getActualTypeArguments();
      if (types.length != 1) {
        throw new IllegalArgumentException("Only able to handle a single type in a list " +
            field.getName());
      }
      Class arrayClass = (Class)types[0];
      List<Object> objectList = new ArrayList<Object>();
      for (int i = 0; i < array.length(); ++i) {
        if (arrayClass.isEnum()) {
          objectList.add(getEnumValue(array.getString(i), arrayClass));
        } else if (canDirectlySerializeClass(arrayClass)) {
          objectList.add(array.get(i));
        } else {
          JSONObject jsonObject = array.getJSONObject(i);
          if (jsonObject == null) {
            objectList.add(null);
          } else {
            objectList.add(convertValue(jsonObject, arrayClass));
          }
        }
      }
      return objectList;
    } else {
      throw new IllegalArgumentException("only know how to deserialize List<?> on field "
          + field.getName());
    }
  }

  private JSONObject _convertToJSONObject(Object fromValue)
      throws JSONException, InvocationTargetException, IllegalAccessException {
    JSONObject jsonObject = new JSONObject();
    Field[] fields = fromValue.getClass().getFields();
    for (int i = 0; i < fields.length; ++i) {
      JsonProperty property = fields[i].getAnnotation(JsonProperty.class);
      if (property != null) {
        // AutoBox here ...
        Object value = fields[i].get(fromValue);
        Class clazz = fields[i].getType();
        if (value != null) {
          clazz = value.getClass();
        }
        String name = fields[i].getName();
        if (property.required() && value == null) {
          value = JSONObject.NULL;
        } else if (value == JSONObject.NULL) {
          // Leave it as null in this case.
        } else {
          value = getJsonValue(value, clazz, fields[i]);
        }
        jsonObject.put(name, value);
      }
    }
    return jsonObject;
  }

  private Object getJsonValue(Object value, Class<?> clazz, Field field)
      throws InvocationTargetException, IllegalAccessException {
    if (value == null) {
      // Now technically we /could/ return JsonNode.NULL here but Chrome's webkit inspector croaks
      // if you pass a null "id"
      return null;
    }
    if (List.class.isAssignableFrom(clazz)) {
      return convertListToJsonArray(value);
    }
    // Finally check to see if there is a JsonValue present
    Method m = getJsonValueMethod(clazz);
    if (m != null) {
      return m.invoke(value);
    }
    if (!canDirectlySerializeClass(clazz)) {
      return convertValue(value, JSONObject.class);
    }
    // JSON has no support for NaN, Infinity or -Infinity, so we serialize
    // then as strings. Google Chrome's inspector will accept them just fine.
    if (clazz.equals(Double.class) || clazz.equals(Float.class)) {
      double doubleValue = ((Number) value).doubleValue();
      if (Double.isNaN(doubleValue)) {
        return "NaN";
      } else if (doubleValue == Double.POSITIVE_INFINITY) {
        return "Infinity";
      } else if (doubleValue == Double.NEGATIVE_INFINITY) {
        return "-Infinity";
      }
    }
    // hmm we should be able to directly serialize here...
    return value;
  }

  private JSONArray convertListToJsonArray(Object value)
      throws InvocationTargetException, IllegalAccessException {
    JSONArray array = new JSONArray();
    List<Object> list = (List<Object>) value;
    for(Object obj : list) {
      // Send null, if this is an array of arrays we are screwed
      array.put(obj != null ? getJsonValue(obj, obj.getClass(), null /* field */) : null);
    }
    return array;
  }

  /**
   *
   * @param clazz
   * @return the first method annotated with {@link JsonValue} or null if one does not exist.
   */
  @Nullable
  private Method getJsonValueMethod(Class<?> clazz) {
    synchronized (mJsonValueMethodCache) {
      Method method = mJsonValueMethodCache.get(clazz);
      if (method == null && !mJsonValueMethodCache.containsKey(clazz)) {
        method = getJsonValueMethodImpl(clazz);
        mJsonValueMethodCache.put(clazz, method);
      }
      return method;
    }
  }

  @Nullable
  private static Method getJsonValueMethodImpl(Class<?> clazz) {
    Method[] methods = clazz.getMethods();
    for(int i = 0; i < methods.length; ++i) {
      Annotation jsonValue = methods[i].getAnnotation(JsonValue.class);
      if (jsonValue != null) {
        return methods[i];
      }
    }
    return null;
  }

  private static boolean canDirectlySerializeClass(Class clazz)  {
    return isWrapperOrPrimitiveType(clazz) ||
        clazz.equals(String.class);
  }

  private static boolean isWrapperOrPrimitiveType(Class<?> clazz) {
    return clazz.isPrimitive() ||
        clazz.equals(Boolean.class) ||
        clazz.equals(Integer.class) ||
        clazz.equals(Character.class) ||
        clazz.equals(Byte.class) ||
        clazz.equals(Short.class) ||
        clazz.equals(Double.class) ||
        clazz.equals(Long.class) ||
        clazz.equals(Float.class);
  }

}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/json/annotation/JsonProperty.java
================================================
package me.moxun.dreamcatcher.connector.json.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface JsonProperty {

  boolean required() default false;

}



================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/json/annotation/JsonValue.java
================================================
package me.moxun.dreamcatcher.connector.json.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface JsonValue {
  
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/DisconnectReceiver.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;

/**
 * @see JsonRpcPeer#registerDisconnectReceiver(DisconnectReceiver)
 */
public interface DisconnectReceiver {
  /**
   * Invoked when a WebSocket peer disconnects.
   */
  void onDisconnect();
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcException.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;


import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;
import me.moxun.dreamcatcher.connector.util.Util;

public class JsonRpcException extends Exception {
  private final JsonRpcError mErrorMessage;

  public JsonRpcException(JsonRpcError errorMessage) {
    super(errorMessage.code + ": " + errorMessage.message);
    mErrorMessage = Util.throwIfNull(errorMessage);
  }

  public JsonRpcError getErrorMessage() {
    return mErrorMessage;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcPeer.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;

import android.database.Observable;

import org.json.JSONObject;

import java.nio.channels.NotYetConnectedException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;

import me.moxun.dreamcatcher.connector.json.ObjectMapper;
import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcRequest;
import me.moxun.dreamcatcher.connector.util.Util;
import me.moxun.dreamcatcher.connector.websocket.SimpleSession;

@ThreadSafe
public class JsonRpcPeer {
  private final SimpleSession mPeer;
  private final ObjectMapper mObjectMapper;

  @GuardedBy("this")
  private long mNextRequestId;

  @GuardedBy("this")
  private final Map<Long, PendingRequest> mPendingRequests = new HashMap<>();

  private final DisconnectObservable mDisconnectObservable = new DisconnectObservable();

  public JsonRpcPeer(ObjectMapper objectMapper, SimpleSession peer) {
    mObjectMapper = objectMapper;
    mPeer = Util.throwIfNull(peer);
  }

  public SimpleSession getWebSocket() {
    return mPeer;
  }

  public void invokeMethod(String method, Object paramsObject,
                           @Nullable PendingRequestCallback callback)
      throws NotYetConnectedException {
    Util.throwIfNull(method);

    Long requestId = (callback != null) ? preparePendingRequest(callback) : null;

    // magic, can basically convert anything for some amount of runtime overhead...
    JSONObject params = mObjectMapper.convertValue(paramsObject, JSONObject.class);

    JsonRpcRequest message = new JsonRpcRequest(requestId, method, params);
    String requestString;
    JSONObject jsonObject = mObjectMapper.convertValue(message, JSONObject.class);
    requestString = jsonObject.toString();
    mPeer.sendText(requestString);
  }

  public void registerDisconnectReceiver(DisconnectReceiver callback) {
    mDisconnectObservable.registerObserver(callback);
  }

  public void unregisterDisconnectReceiver(DisconnectReceiver callback) {
    mDisconnectObservable.unregisterObserver(callback);
  }

  public void invokeDisconnectReceivers() {
    mDisconnectObservable.onDisconnect();
  }

  private synchronized long preparePendingRequest(PendingRequestCallback callback) {
    long requestId = mNextRequestId++;
    mPendingRequests.put(requestId, new PendingRequest(requestId, callback));
    return requestId;
  }

  public synchronized PendingRequest getAndRemovePendingRequest(long requestId) {
    return mPendingRequests.remove(requestId);
  }

  private static class DisconnectObservable extends Observable<DisconnectReceiver> {
    public void onDisconnect() {
      for (int i = 0, N = mObservers.size(); i < N; ++i) {
        final DisconnectReceiver observer = mObservers.get(i);
        observer.onDisconnect();
      }
    }
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcResult.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;


import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcResponse;

/**
 * Marker interface used to denote a JSON-RPC result.  After conversion from Jackson,
 * this will be placed into {@link JsonRpcResponse#result}.
 */
public interface JsonRpcResult {
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequest.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;

import javax.annotation.Nullable;

/**
 * Represents an outstanding request to the peer (issued by us).  This callback will be
 * fired when the server responds.  Note that with JSON-RPC, there is a special kind of
 * request called a notification which does not require a callback (and thus won't use
 * this class).
 */
public class PendingRequest {
  public final long requestId;
  public final @Nullable PendingRequestCallback callback;

  public PendingRequest(long requestId, @Nullable PendingRequestCallback callback) {
    this.requestId = requestId;
    this.callback = callback;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequestCallback.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc;


import me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcResponse;

public interface PendingRequestCallback {
  void onResponse(JsonRpcPeer peer, JsonRpcResponse response);
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/EmptyResult.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc.protocol;


import me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult;

public class EmptyResult implements JsonRpcResult {
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcError.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc.protocol;

import android.annotation.SuppressLint;

import org.json.JSONObject;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;
import me.moxun.dreamcatcher.connector.json.annotation.JsonValue;

@SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })
public class JsonRpcError {
  @JsonProperty(required = true)
  public ErrorCode code;

  @JsonProperty(required = true)
  public String message;

  @JsonProperty
  public JSONObject data;

  public JsonRpcError() {
  }

  public JsonRpcError(ErrorCode code, String message, @Nullable JSONObject data) {
    this.code = code;
    this.message = message;
    this.data = data;
  }

  public enum ErrorCode {
    PARSER_ERROR(-32700),
    INVALID_REQUEST(-32600),
    METHOD_NOT_FOUND(-32601),
    INVALID_PARAMS(-32602),
    INTERNAL_ERROR(-32603);

    private final int mProtocolValue;

    private ErrorCode(int protocolValue) {
      mProtocolValue = protocolValue;
    }

    @JsonValue
    public int getProtocolValue() {
      return mProtocolValue;
    }
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcEvent.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc.protocol;

import android.annotation.SuppressLint;

import org.json.JSONObject;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;

@SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })
public class JsonRpcEvent {
  @JsonProperty(required = true)
  public String method;

  @JsonProperty
  public JSONObject params;

  public JsonRpcEvent() {
  }

  public JsonRpcEvent(String method, @Nullable JSONObject params) {
    this.method = method;
    this.params = params;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcRequest.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc.protocol;

import android.annotation.SuppressLint;

import org.json.JSONObject;

import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;

@SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
public class JsonRpcRequest {
    /**
     * This field is not required so that we can support JSON-RPC "notification" requests.
     */
    @JsonProperty
    public Long id;

    @JsonProperty(required = true)
    public String method;

    @JsonProperty
    public JSONObject params;

    public JsonRpcRequest() {
    }

    @Override
    public String toString() {
        return "Id:" + id + ",method:" + method + ",params:" + params;
    }

    public JsonRpcRequest(Long id, String method, JSONObject params) {
        this.id = id;
        this.method = method;
        this.params = params;
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcResponse.java
================================================
package me.moxun.dreamcatcher.connector.jsonrpc.protocol;

import android.annotation.SuppressLint;

import org.json.JSONObject;

import me.moxun.dreamcatcher.connector.json.annotation.JsonProperty;

@SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })
public class JsonRpcResponse {
  @JsonProperty(required = true)
  public long id;

  @JsonProperty
  public JSONObject result;

  @JsonProperty
  public JSONObject error;
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/AELog.java
================================================
package me.moxun.dreamcatcher.connector.log;

/**
 * 输出日志到Chrome控制台
 * Created by moxun on 16/4/25.
 */
public class AELog {
    private static final IAELog log;
    private static boolean isLoggable = true;

    static {
        log = new AELogImpl();
    }

    public static void setLoggable(boolean isLoggable) {
        AELog.isLoggable = isLoggable;
    }

    public static void l(String msg) {
        if (isLoggable) {
            log.l(msg);
        }
    }

    public static void i(String msg) {
        if (isLoggable) {
            log.i(msg);
        }
    }

    public static void d(String msg) {
        if (isLoggable) {
            log.d(msg);
        }
    }

    public static void w(String msg) {
        if (isLoggable) {
            log.w(msg);
        }
    }

    public static void e(String msg) {
        if (isLoggable) {
            log.e(msg);
        }
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/AELogImpl.java
================================================
package me.moxun.dreamcatcher.connector.log;


import me.moxun.dreamcatcher.connector.console.CLog;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Console;

/**
 * Created by moxun on 16/4/25.
 */
final class AELogImpl implements IAELog {

    @Override
    public boolean isLoggable() {
        return true;
    }

    @Override
    public void l(String msg) {
        if (isLoggable()) {
            log(Console.MessageLevel.LOG, msg);
        }
    }

    @Override
    public void i(String msg) {
        if (isLoggable()) {
            log(Console.MessageLevel.INFO, msg);
        }
    }

    @Override
    public void d(String msg) {
        if (isLoggable()) {
            log(Console.MessageLevel.DEBUG, msg);
        }
    }

    @Override
    public void w(String msg) {
        if (isLoggable()) {
            log(Console.MessageLevel.WARNING, msg);
        }
    }

    @Override
    public void e(String msg) {
        if (isLoggable()) {
            log(Console.MessageLevel.ERROR, msg);
        }
    }

    private static void log(Console.MessageLevel level, String note) {
        CLog.writeToConsole(level, Console.MessageSource.CONSOLE_API, note);
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/IAELog.java
================================================
package me.moxun.dreamcatcher.connector.log;

/**
 * Created by moxun on 16/4/25.
 */
public interface IAELog {
    boolean isLoggable();
    void l(String msg);
    void i(String msg);
    void d(String msg);
    void w(String msg);
    void e(String msg);
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/manager/Lifecycle.java
================================================
package me.moxun.dreamcatcher.connector.manager;

/**
 * Created by moxun on 16/12/9.
 */

public interface Lifecycle {
    int SHUTDOWN = 1;
    int LOCAL_SERVER_SOCKET_OPENING = 2;
    int WAITING_FOR_DISCOVERY = 3;
    int CHROME_DISCOVERY_CONNECTED = 4;
    int WAITING_FOR_WEBSOCKET = 5;
    int WEBSOCKET_SESSION_OPENING = 6;
    int WEBSOCKET_SESSION_CLOSED = 7;
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/manager/SimpleConnectorLifecycleManager.java
================================================
package me.moxun.dreamcatcher.connector.manager;

import me.moxun.dreamcatcher.connector.inspector.ChromeDiscoveryHandler;

/**
 * Created by moxun on 16/12/9.
 */

public class SimpleConnectorLifecycleManager {
    private static int CURRENT_STATE = Lifecycle.SHUTDOWN;
    private static boolean PROXY_ENABLED = false;

    public static void setCurrentState(int state) {
        CURRENT_STATE = state;
    }

    public static int getCurrentState() {
        return CURRENT_STATE;
    }

    public static boolean isSessionActive() {
        return CURRENT_STATE == Lifecycle.WEBSOCKET_SESSION_OPENING;
    }

    public static boolean isProxyEnabled() {
        return PROXY_ENABLED;
    }

    public static void setProxyEnabled(boolean proxyEnabled) {
        PROXY_ENABLED = proxyEnabled;
        ChromeDiscoveryHandler.setInvalid(true);
    }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinter.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

/**
 * Interface that callers need to implement in order to pretty print binary payload received by DreamCatcher
 */
public interface AsyncPrettyPrinter {
  /**
   * Prints the prettified version of payload to output. This method can block
   * for a certain period of time. Note that DreamCatcher may impose arbitrary
   * time out on this method.
   *
   * @param output Writes the prettified version of payload
   * @param payload Response stream that has the raw data to be prettified
   * @throws IOException
   */
  public void printTo(PrintWriter output, InputStream payload) throws IOException;

  /**
   * Specifies the type of pretty printed content. Note that this method is called
   * before the content is actually pretty printed. DreamCatcher uses this
   * method to make a hopeful guess of the type of prettified content
   *
   * @return an enum defined by PrettyPrinterDisplayType class
   */
  public PrettyPrinterDisplayType getPrettifiedType();
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterExecutorHolder.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Nullable;

/**
 * A holder class for the executor service used for pretty printing related tasks
 */
final class AsyncPrettyPrinterExecutorHolder {

  private static ExecutorService sExecutorService;

  private AsyncPrettyPrinterExecutorHolder() {
  }
  
  public static void ensureInitialized() {
    if (sExecutorService == null) {
      sExecutorService = Executors.newCachedThreadPool();
    }
  }

  @Nullable
  public static ExecutorService getExecutorService() {
    return sExecutorService;
  }

  public static void shutdown() {
    sExecutorService.shutdown();
    sExecutorService = null;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterFactory.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

/**
 * Interface for creating a factory for asynchronous pretty printers
 */
public interface AsyncPrettyPrinterFactory {

  /**
   * Creates an asynchronous pretty printer. This method must not be blocking.
   *
   * @param headerName header name of a response which is used to associate
   * with an asynchronous pretty printer
   * @param headerValue header value of a response which contains the URI for
   * the schema data needed to pretty print the response body
   * @return an asynchronous pretty printer to prettify the response body
   */
  public AsyncPrettyPrinter getInstance(String headerName, String headerValue);
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterInitializer.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

/**
 * Interface that is called if AsyncPrettyPrinterRegistry is unpopulated when
 * the first peer connects to DreamCatcher. It is responsible for registering header
 * names and their corresponding pretty printers
 */
public interface AsyncPrettyPrinterInitializer {

  /**
   * Populates AsyncPrettyPrinterRegistry with header names and their corresponding pretty
   * printers. This is responsible for registering all {@link AsyncPrettyPrinter} to the
   * provided registry.
   * @param registry
   */
  void populatePrettyPrinters(AsyncPrettyPrinterRegistry registry);

}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterRegistry.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class AsyncPrettyPrinterRegistry {

  private final Map<String, AsyncPrettyPrinterFactory> mRegistry = new HashMap<>();

  public synchronized void register(String headerName, AsyncPrettyPrinterFactory factory) {
    mRegistry.put(headerName, factory);
  }

  @Nullable
  public synchronized AsyncPrettyPrinterFactory lookup(String headerName) {
    return mRegistry.get(headerName);
  }

  public synchronized boolean unregister(String headerName) {
    return mRegistry.remove(headerName) != null;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/CountingOutputStream.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

class CountingOutputStream extends FilterOutputStream {
  private long mCount;

  public CountingOutputStream(OutputStream out) {
    super(out);
  }

  public long getCount() {
    return mCount;
  }

  @Override
  public void write(int oneByte) throws IOException {
    out.write(oneByte);
    mCount++;
  }

  @Override
  public void write(byte[] buffer) throws IOException {
    write(buffer, 0, buffer.length);
  }

  @Override
  public void write(byte[] buffer, int offset, int length) throws IOException {
    out.write(buffer, offset, length);
    mCount += length;
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DecompressionHelper.java
================================================
package me.moxun.dreamcatcher.connector.reporter;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.InflaterOutputStream;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.console.CLog;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Console;

// @VisibleForTest
public class DecompressionHelper {
  static final String GZIP_ENCODING = "gzip";
  static final String DEFLATE_ENCODING = "deflate";

  public static InputStream teeInputWithDecompression(
      NetworkPeerManager peerManager,
      String requestId,
      InputStream availableInputStream,
      OutputStream decompressedOutput,
      @Nullable String contentEncoding,
      ResponseHandler responseHandler) throws IOException {
    OutputStream output = decompressedOutput;
    CountingOutputStream decompressedCounter = null;

    if (contentEncoding != null) {
      boolean gzipEncoding = GZIP_ENCODING.equals(contentEncoding);
      boolean deflateEncoding = DEFLATE_ENCODING.equals(contentEncoding);

      if (gzipEncoding || deflateEncoding) {
        decompressedCounter = new CountingOutputStream(decompressedOutput);
        if (gzipEncoding) {
          output = GunzippingOutputStream.create(decompressedCounter);
        } else if (deflateEncoding) {
          output = new InflaterOutputStream(decompressedCounter);
        }
      } else {
        CLog.writeToConsole(
            peerManager,
            Console.MessageLevel.WARNING,
            Console.MessageSource.NETWORK,
            "Unsupported Content-Encoding in response for request #" + requestId +
                ": " + contentEncoding);
      }
    }

    return new ResponseHandlingInputStream(
        availableInputStream,
        requestId,
        output,
        decompressedCounter,
        peerManager,
        responseHandler);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DefaultResponseHandler.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.io.IOException;

/**
 * Simple interceptor that delegates response read events to {@link NetworkEventReporter}.
 */
public class DefaultResponseHandler implements ResponseHandler {
  private final NetworkEventReporter mEventReporter;
  private final String mRequestId;

  private int mBytesRead = 0;
  private int mDecodedBytesRead = -1;

  public DefaultResponseHandler(NetworkEventReporter eventReporter, String requestId) {
    mEventReporter = eventReporter;
    mRequestId = requestId;
  }

  @Override
  public void onRead(int numBytes) {
    mBytesRead += numBytes;
  }

  @Override
  public void onReadDecoded(int numBytes) {
    if (mDecodedBytesRead == -1) {
      mDecodedBytesRead = 0;
    }
    mDecodedBytesRead += numBytes;
  }

  public void onEOF() {
    reportDataReceived();
    mEventReporter.responseReadFinished(mRequestId);
  }

  public void onError(IOException e) {
    reportDataReceived();
    mEventReporter.responseReadFailed(mRequestId, e.toString());
  }

  private void reportDataReceived() {
    mEventReporter.dataReceived(
        mRequestId,
        mBytesRead,
        mDecodedBytesRead >= 0 ? mDecodedBytesRead : mBytesRead);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DownloadingAsyncPrettyPrinterFactory.java
================================================
package me.moxun.dreamcatcher.connector.reporter;


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.util.ExceptionUtil;
import me.moxun.dreamcatcher.connector.util.Util;

/**
 * Abstract class for pretty printer factory that asynchronously downloads schema needed for
 * pretty printing the payload
 */
public abstract class DownloadingAsyncPrettyPrinterFactory implements AsyncPrettyPrinterFactory {

  @Override
  public AsyncPrettyPrinter getInstance(final String headerName, final String headerValue) {

    final MatchResult result = matchAndParseHeader(headerName, headerValue);
    if (result == null) {
      return null;
    }
    String uri = result.getSchemaUri();
    URL schemaURL = parseURL(uri);
    if (schemaURL == null) {
      return getErrorAsyncPrettyPrinter(headerName, headerValue);
    } else {
      ExecutorService executorService = AsyncPrettyPrinterExecutorHolder.getExecutorService();
      if (executorService == null) {
        //last peer is unregistered...
        return null;
      }
      final Future<String> response = executorService.submit(new Request(schemaURL));
      return new AsyncPrettyPrinter() {
        public void printTo(PrintWriter output, InputStream payload)
            throws IOException {
          try {
            String schema;
            try {
              schema = response.get();
            } catch (ExecutionException e) {
              Throwable cause = e.getCause();
              if (IOException.class.isInstance(cause)) {
                doErrorPrint(
                    output,
                    payload,
                    "Cannot successfully download schema: "
                        + e.getMessage());
                return;
              } else {
                throw e;
              }
            }
            doPrint(output, payload, schema);
          } catch (InterruptedException e) {
            doErrorPrint(
                output,
                payload,
                "Encountered spurious interrupt while downloading schema for pretty printing: "
                    + e.getMessage());
          } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            throw ExceptionUtil.propagate(cause);
          }
        }

        public PrettyPrinterDisplayType getPrettifiedType() {
          return result.getDisplayType();
        }
      };
    }
  }

  /**
   * Match the correct header that contains information about the schema uri
   * @param headerName header name of a response that needs to be pretty printed
   * @param headerValue header value which contains the URI for
   * the schema data needed to pretty print the response body
   * @return MatchResult that has the schema uri and the type of prettified result. Null
   * if there is no correct header match.
   */
  @Nullable
  protected abstract MatchResult matchAndParseHeader(String headerName, String headerValue);

  /**
   * Note that the IOException thrown by this method will be propagated all the way up and
   * yield an error to the chrome devtools
   */
  protected abstract void doPrint(PrintWriter output, InputStream payload, String schema)
      throws IOException;

  @Nullable
  private static URL parseURL(String uri) {
    try {
      return new URL(uri);
    } catch (MalformedURLException e) {
      return null;
    }
  }

  private static void doErrorPrint(PrintWriter output, InputStream payload, String errorMessage)
      throws IOException {
    output.print(errorMessage + "\n" + Util.readAsUTF8(payload));
  }

  private static AsyncPrettyPrinter getErrorAsyncPrettyPrinter(
      final String headerName,
      final String headerValue) {
    return new AsyncPrettyPrinter() {
      @Override
      public void printTo(PrintWriter output, InputStream payload) throws IOException {
        String errorMessage = "[Failed to parse header: "
            + headerName + " : " + headerValue + " ]";
        doErrorPrint(output, payload, errorMessage);
      }

      @Override
      public PrettyPrinterDisplayType getPrettifiedType() {
        return PrettyPrinterDisplayType.TEXT;
      }
    };
  }


  protected class MatchResult {
    private final String mSchemaUri;
    private final PrettyPrinterDisplayType mDisplayType;

    public MatchResult(String schemaUri, PrettyPrinterDisplayType displayType) {
      mSchemaUri = schemaUri;
      mDisplayType = displayType;
    }

    public String getSchemaUri() {
      return mSchemaUri;
    }

    public PrettyPrinterDisplayType getDisplayType() {
      return mDisplayType;
    }
  }

  private static class Request implements Callable<String> {
    private URL url;

    public Request(URL url) {
      this.url = url;
    }

    @Override
    public String call() throws IOException {
      HttpURLConnection connection = (HttpURLConnection)url.openConnection();
      int statusCode = connection.getResponseCode();
      if (statusCode != 200) {
        throw new IOException("Got status code: " + statusCode + " while downloading " +
            "schema with url: " + url.toString());
      }
      InputStream urlStream = connection.getInputStream();
      try {
        return Util.readAsUTF8(urlStream);
      } finally {
        urlStream.close();
      }
    }
  }
}



================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/GunzippingOutputStream.java
================================================
package me.moxun.dreamcatcher.connector.reporter;


import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.zip.GZIPInputStream;

import me.moxun.dreamcatcher.connector.util.ExceptionUtil;
import me.moxun.dreamcatcher.connector.util.Util;

/**
 * An {@link OutputStream} filter which decompresses gzip data before it is written to the
 * specified destination output stream.  This is functionally equivalent to
 * {@link java.util.zip.InflaterOutputStream} but provides gzip header awareness.  The
 * implementation however is very different to avoid actually interpreting the gzip header.
 */
class GunzippingOutputStream extends FilterOutputStream {
  private final Future<Void> mCopyFuture;

  private static final ExecutorService sExecutor = Executors.newCachedThreadPool();

  public static GunzippingOutputStream create(OutputStream finalOut) throws IOException {
    PipedInputStream pipeIn = new PipedInputStream();
    PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);

    Future<Void> copyFuture = sExecutor.submit(
        new GunzippingCallable(pipeIn, finalOut));

    return new GunzippingOutputStream(pipeOut, copyFuture);
  }

  private GunzippingOutputStream(OutputStream out, Future<Void> copyFuture) throws IOException {
    super(out);
    mCopyFuture = copyFuture;
  }

  @Override
  public void close() throws IOException {
    boolean success = false;
    try {
      super.close();
      success = true;
    } finally {
      try {
        getAndRethrow(mCopyFuture);
      } catch (IOException e) {
        if (success) {
          throw e;
        }
      }
    }
  }

  private static <T> T getAndRethrow(Future<T> future) throws IOException {
    while (true) {
      try {
        return future.get();
      } catch (InterruptedException e) {
        // Continue...
      } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        ExceptionUtil.propagateIfInstanceOf(cause, IOException.class);
        ExceptionUtil.propagate(cause);
      }
    }
  }

  private static class GunzippingCallable implements Callable<Void> {
    private final InputStream mIn;
    private final OutputStream mOut;

    public GunzippingCallable(InputStream in, OutputStream out) {
      mIn = in;
      mOut = out;
    }

    @Override
    public Void call() throws IOException {
      GZIPInputStream in = new GZIPInputStream(mIn);
      try {
        Util.copy(in, mOut, new byte[1024]);
      } finally {
        in.close();
        mOut.close();
      }
      return null;
    }
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/MimeMatcher.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import android.annotation.SuppressLint;

import java.util.ArrayList;

import javax.annotation.Nullable;

public class MimeMatcher<T> {
  private final ArrayList<MimeMatcherRule> mRuleMap = new ArrayList<MimeMatcherRule>();

  /**
   * Add a matching rule in the canonical MIME T form such as "image/*" or a MIME T
   * literal such as "text/html".
   *
   * @param ruleExpression Expression to match, in the order it was added.
   * @param resultIfMatched Result if this expression matches.
   */
  public void addRule(String ruleExpression, T resultIfMatched) {
    mRuleMap.add(new MimeMatcherRule(ruleExpression, resultIfMatched));
  }

  public void clear() {
    mRuleMap.clear();
  }

  @Nullable
  public T match(String mimeT) {
    int ruleMapN = mRuleMap.size();
    for (int i = 0; i < ruleMapN; i++) {
      MimeMatcherRule rule = mRuleMap.get(i);
      if (rule.match(mimeT)) {
        return rule.getResultIfMatched();
      }
    }
    return null;
  }

  @SuppressLint("BadMethodUse-java.lang.String.length")
  private class MimeMatcherRule {
    private final boolean mHasWildcard;
    private final String mMatchPrefix;
    private final T mResultIfMatched;

    public MimeMatcherRule(String ruleExpression, T resultIfMatched) {
      if (ruleExpression.endsWith("*")) {
        mHasWildcard = true;
        mMatchPrefix = ruleExpression.substring(0, ruleExpression.length() - 1);
      } else {
        mHasWildcard = false;
        mMatchPrefix = ruleExpression;
      }
      if (mMatchPrefix.contains("*")) {
        throw new IllegalArgumentException("Multiple wildcards present in rule expression " +
            ruleExpression);
      }
      mResultIfMatched = resultIfMatched;
    }

    public boolean match(String mimeType) {
      // Make sure the string literal matches.
      if (!mimeType.startsWith(mMatchPrefix)) {
        return false;
      }

      // If we have a wildcard and the prefix matches, then we've matched; otherwise if the
      // string literal and the mime T are the same length then we must have a match.
      return (mHasWildcard || mimeType.length() == mMatchPrefix.length());
    }

    public T getResultIfMatched() {
      return mResultIfMatched;
    }
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporter.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.inspector.protocol.module.Network;

/**
 * Interface that callers must invoke in order to supply data to the Network tab in
 * the WebKit Inspector.
 *
 * <pre>
 * requestWillBeSent +---> responseHeadersReceived +---> interpretResponseStream
 *                   |           |                 |
 *                   |           `---> dataSent    |
 *                   |                             |
 *                   `-----------------------------`--------> httpExchangeFailed
 * </pre>
 *
 * Note that {@link #interpretResponseStream} combined with {@link DefaultResponseHandler}
 * will automatically invoke {@link #dataReceived}, {@link #responseReadFailed} and
 * {@link #responseReadFinished}.  If you use your own custom {@link ResponseHandler} you
 * must be sure to invoke these methods manually.
 */
public interface NetworkEventReporter {
  /**
   * Returns true if there is at least one peer listening for network events; false otherwise.
   * This value is provided as an optimization to avoid expensive work when the WebKit Inspector is
   * not being used.  It is otherwise safe to invoke methods defined in this interface when
   * the value is false.
   */
  boolean isEnabled();

  /**
   * Indicates that a request is about to be sent, but has not yet been delivered over the wire.
   *
   * @param request Request descriptor.
   */
  void requestWillBeSent(InspectorRequest request);

  /**
   * Indicates that a response message was just received from the network, but the body
   * has not yet been read.
   *
   * @param response Response descriptor.
   */
  void responseHeadersReceived(InspectorResponse response);

 /**
  * Indicates that communication with the server has failed. You are expected to call this for any
  * exception before you call {@link #interpretResponseStream}. After
  * {@link #interpretResponseStream} is called we will reporting any
  * {@link IOException} during reading from the {@link InputStream}.
  *
  * @param requestId Unique identifier for the request as per {@link InspectorRequest#id()}
  * @param errorText Text to report for the error; using {@link IOException#toString()} is
  *     recommended.
   */
  void httpExchangeFailed(String requestId, String errorText);

  /**
   * Intercept the stream as given by the underlying HTTP library that contains the body of the
   * response. In order to have the response show up in inspector (and to have the request be
   * completed successfully) you need to call this AND read until exhaustion/EOF of the returned
   * stream.
   *
   * <p>
   * We will internally signal a failure if there is an {@link IOException} received while reading
   * from the stream.
   *
   * <p>
   * Do not invoke {@link #httpExchangeFailed(String, String)} after calling this method.
   *
   * @param requestId Unique identifier for the request as per {@link InspectorRequest#id()}
   * @param contentType The {@code Content-Type} header value that was specified in
   *     {@link InspectorResponse}.  This header is used to determine the appropriate
   *     storage format for the body.  For instance, {@code image/*} is necessary to cause
   *     images to appear in the Inspector UI.
   * @param contentEncoding The {@code Content-Encoding} header value that was specified in
   *     {@link InspectorResponse}.  This header is used to determine what type of decompression
   *     is to be applied when delivering the raw response stream to the debugging interface.
   *     If null, no decompression will be used.
   * @param inputStream Response stream if applicable ("HEAD" for instance does not have a body).
   *     {@code null} otherwise.
   * @param responseHandler Callback to forward stream events back to the relevant event reporter
   *     methods.  Recommend using {@link DefaultResponseHandler} for most callers.
   *
   * @return {@link InputStream} that has been intercepted if WebkitInspector is active and enabled
   *     otherwise it will return {@code inputStream}
   */
  @Nullable
  InputStream interpretResponseStream(
          String requestId,
          @Nullable String contentType,
          @Nullable String contentEncoding,
          @Nullable InputStream inputStream,
          ResponseHandler responseHandler);

  /**
   * Indicates that there was a failure while reading from response stream.  If you use
   * {@link #interpretResponseStream} with {@link DefaultResponseHandler} (as is recommended),
   * this method will be invoked automatically for you.
   *
   * @param requestId Unique identifier for the request as per {@link InspectorRequest#id()}
   * @param errorText Text to report for the error; using {@link IOException#toString()} is
   *     recommended.
   */
  void responseReadFailed(String requestId, String errorText);

  /**
   * Indicates that the response stream has been fully exhausted and the request is now
   * complete.  If you use {@link #interpretResponseStream} with {@link DefaultResponseHandler}
   * (as is recommended), this method will be invoked automatically for you.
   *
   * @param requestId Unique identifier for the request as per {@link InspectorRequest#id()}
   */
  void responseReadFinished(String requestId);

  /**
   * Indicates that raw data was sent over the network.  It is permissible to invoke this
   * method just once after the full size of the request is known.
   * <p>
   * Invoking this method is optional and merely provides additional timing metrics and actual
   * payload sizes to the Inspector UI.
   *
   * @param requestId Unique identifier for the request as per {@link InspectorRequest#id()}
   * @param dataLength Uncompressed data segment length
   * @param encodedDataLength Compressed data segment length
   */
  void dataSent(String requestId, int dataLength, int encodedDataLength);

  /**
   * Indicates that raw data was received from the network.
   *
   * @see #dataSent
   */
  void dataReceived(String requestId, int dataLength, int encodedDataLength);

  /**
   * Represents the request that will be sent over HTTP.  Note that for many implementations
   * of HTTP the request constructed may differ from the request actually sent over the wire.
   * For instance, additional headers like {@code Host}, {@code User-Agent}, {@code Content-Type},
   * etc may not be part of this request but should be injected if necessary.  Some stacks offer
   * inspection of the raw request about to be sent to the server which is preferable.
   */
  interface InspectorRequest extends InspectorHeaders {
    /**
     * Unique identifier for this request.  This identifier must be used in all other network
     * events corresponding to this request.  Identifiers may be re-used after
     * {@link NetworkEventReporter#httpExchangeFailed} or {@link NetworkEventReporter#loadingFinished}
     * are invoked.
     */
    String id();

    /**
     * Arbitrary debug-friendly name of the request.
     */
    String friendlyName();

    /**
     * Provide an extra integer to decorate the {@link #friendlyName()}.  This shows up next to
     * it in the WebKit Inspector UI and can be used to indicate things like request priority.
     */
    @Nullable
    Integer friendlyNameExtra();

    String url();

    /**
     * HTTP method ("GET", "POST", "DELETE", etc).
     */
    String method();

    /**
     * Provide the body if part of an entity-enclosing request (like "POST" or "PUT").  May
     * return null otherwise.
     */
    @Nullable
    byte[] body() throws IOException;
  }

  interface InspectorResponse extends InspectorHeaders {
    /** @see InspectorRequest#id() */
    String requestId();

    String url();

    int statusCode();
    String reasonPhrase();

    /**
     * True if the response was furnished on a re-used socket; false otherwise or if unknown.
     */
    boolean connectionReused();

    /**
     * Unique connection identifier representing the socket that was used to furnish the response.
     */
    int connectionId();

    /**
     * True if the response was furnished by disk cache; false otherwise or if unknown.
     */
    boolean fromDiskCache();

    @Nullable Network.ResourceTiming getTiming();
  }

  interface InspectorHeaders {
    int headerCount();
    String headerName(int index);
    String headerValue(int index);

    @Nullable
    String firstHeaderValue(String name);
  }
}


================================================
FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporterImpl.java
================================================
package me.moxun.dreamcatcher.connector.reporter;

import android.os.SystemClock;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import me.moxun.dreamcatcher.connector.console.CLog;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Console;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Network;
import me.moxun.dreamcatcher.connector.inspector.protocol.module.Page;
import me.moxun.dreamcatcher.connector.util.Utf8Charset;

/**
 * Implementation of {@link NetworkEventReporter} which allows callers to inform the DreamCatcher
 * system of network traffic.  Callers can safely eagerly access this class and store a
 * reference if they wish.  When WebKit Inspector clients are connected, the internal
 * implementation will be automatically wired up to them.
 */
public class NetworkEventReporterImpl implements NetworkEventReporter {
    @Nullable
    private ResourceTypeHelper mResourceTypeHelper;

    private static NetworkEventReporter sInstance;

    private NetworkEventReporterImpl() {
    }

    /**
     * Static accessor allowing callers to easily hook into the WebKit Inspector system without
     * creating dependencies on the main DreamCatcher initialization code path.
     */
    public static synchronized NetworkEventReporter get() {
        if (sInstance == null) {
            sInstance = new NetworkEventReporterImpl();
        }
        return sInstance;
    }

    @Override
    public boolean isEnabled() {
        NetworkPeerManager peerManager = getPeerManagerIfEnabled();
        return peerManager != null;
    }

    @Nullable
    private NetworkPeerManager getPeerManagerIfEnabled() {
        NetworkPeerManager peerManager = NetworkPeerManager.getInstanceOrNull();
        if (peerManager != null && peerManager.hasRegisteredPeers()) {
            return peerManager;
        }
        return null;
    }

    @Override
    public void requestWillBeSent(InspectorRequest request) {
        NetworkPeerManager peerManager = getPeerManagerIfEnabled();
        if (peerManager != null) {
            Network.Request requestJSON = new Network.Request();
            requestJSON.url = request.url();
            requestJSON.method = request.method();
            requestJSON.headers = formatHeadersAsJSON(request);
            requestJSON.postData = readBodyAsString(peerManager, request);

            // Hack to use the initiator of SCRIPT to generate a fake call stack that includes
            // the request's "friendly" name.
            String requestFriendlyName = request.friendlyName();
            Integer requestPriority = request.friendlyNameExtra();
            Network.Initiator initiatorJSON = new Network.Initiator();
            initiatorJSON.type = Network.InitiatorType.SCRIPT;
            initiatorJSON.stackTrace = new ArrayList<Console.CallFrame>();
            initiatorJSON.stackTrace.add(new Console.CallFrame(requestFriendlyName,
                    requestFriendlyName,
                    requestPriority != null ? requestPriority : 0 /* lineNumber */,
                    0 /* columnNumber */));

            Network.RequestWillBeSentParams params = new Network.RequestWillBeSentParams();
            params.requestId = request.id();
            params.frameId = "1";
            params.loaderId = "1";
            params.documentURL = request.url();
            params.request = requestJSON;
            params.timestamp = DreamCatcherNow() / 1000.0;
            params.initiator = initiatorJSON;
            params.redirectResponse = null;

            // Type is now required as of at least WebKit Inspector rev @188492.  If you don't send
            // it, Chrome will refuse to draw the row in the Network tab until the response is
            // received (providing the type).  This delay is very noticable on slow networks.
            params.type = Page.ResourceType.OTHER;

            peerManager.sendNotificationToPeers("Network.requestWillBeSent", params);
        }
    }

    @Nullable
    private 
Download .txt
gitextract_4zj9hsfj/

├── .gitignore
├── .idea/
│   ├── compiler.xml
│   ├── copyright/
│   │   └── profiles_settings.xml
│   ├── encodings.xml
│   ├── gradle.xml
│   ├── misc.xml
│   ├── modules.xml
│   └── runConfigurations.xml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── dream_catcher-1.0.1.apk
│   ├── dream_catcher-1.1.0.apk
│   ├── dream_catcher-1.2.0.apk
│   ├── libs/
│   │   └── netty-android.jar
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── me/
│       │           └── moxun/
│       │               └── dreamcatcher/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   ├── me/
│       │   │   │   └── moxun/
│       │   │   │       └── dreamcatcher/
│       │   │   │           ├── CaptureActivity.java
│       │   │   │           ├── DCApplication.java
│       │   │   │           ├── State.java
│       │   │   │           ├── connector/
│       │   │   │           │   ├── Connector.java
│       │   │   │           │   ├── InspectorModulesProvider.java
│       │   │   │           │   ├── console/
│       │   │   │           │   │   ├── CLog.java
│       │   │   │           │   │   ├── ConsolePeerManager.java
│       │   │   │           │   │   ├── RuntimeRepl.java
│       │   │   │           │   │   ├── RuntimeReplFactory.java
│       │   │   │           │   │   └── command/
│       │   │   │           │   │       └── CommandHandler.java
│       │   │   │           │   ├── inspector/
│       │   │   │           │   │   ├── ChromeDevtoolsServer.java
│       │   │   │           │   │   ├── ChromeDiscoveryHandler.java
│       │   │   │           │   │   ├── DevtoolsSocketHandler.java
│       │   │   │           │   │   ├── MessageHandlingException.java
│       │   │   │           │   │   ├── MethodDispatcher.java
│       │   │   │           │   │   ├── MismatchedResponseException.java
│       │   │   │           │   │   ├── helper/
│       │   │   │           │   │   │   ├── ChromePeerManager.java
│       │   │   │           │   │   │   ├── ObjectIdMapper.java
│       │   │   │           │   │   │   ├── PeerRegistrationListener.java
│       │   │   │           │   │   │   ├── PeersRegisteredListener.java
│       │   │   │           │   │   │   ├── ThreadBoundProxy.java
│       │   │   │           │   │   │   └── TracingPeerManager.java
│       │   │   │           │   │   ├── protocol/
│       │   │   │           │   │   │   ├── ChromeDevtoolsDomain.java
│       │   │   │           │   │   │   ├── ChromeDevtoolsMethod.java
│       │   │   │           │   │   │   ├── SimpleBooleanResult.java
│       │   │   │           │   │   │   ├── SimpleIntegerResult.java
│       │   │   │           │   │   │   ├── SimpleStringResult.java
│       │   │   │           │   │   │   └── module/
│       │   │   │           │   │   │       ├── Console.java
│       │   │   │           │   │   │       ├── FileSystem.java
│       │   │   │           │   │   │       ├── Inspector.java
│       │   │   │           │   │   │       ├── Network.java
│       │   │   │           │   │   │       ├── Page.java
│       │   │   │           │   │   │       ├── Profiler.java
│       │   │   │           │   │   │       └── Runtime.java
│       │   │   │           │   │   └── runtime/
│       │   │   │           │   │       └── DefaultRuntimeReplFactory.java
│       │   │   │           │   ├── json/
│       │   │   │           │   │   ├── ObjectMapper.java
│       │   │   │           │   │   └── annotation/
│       │   │   │           │   │       ├── JsonProperty.java
│       │   │   │           │   │       └── JsonValue.java
│       │   │   │           │   ├── jsonrpc/
│       │   │   │           │   │   ├── DisconnectReceiver.java
│       │   │   │           │   │   ├── JsonRpcException.java
│       │   │   │           │   │   ├── JsonRpcPeer.java
│       │   │   │           │   │   ├── JsonRpcResult.java
│       │   │   │           │   │   ├── PendingRequest.java
│       │   │   │           │   │   ├── PendingRequestCallback.java
│       │   │   │           │   │   └── protocol/
│       │   │   │           │   │       ├── EmptyResult.java
│       │   │   │           │   │       ├── JsonRpcError.java
│       │   │   │           │   │       ├── JsonRpcEvent.java
│       │   │   │           │   │       ├── JsonRpcRequest.java
│       │   │   │           │   │       └── JsonRpcResponse.java
│       │   │   │           │   ├── log/
│       │   │   │           │   │   ├── AELog.java
│       │   │   │           │   │   ├── AELogImpl.java
│       │   │   │           │   │   └── IAELog.java
│       │   │   │           │   ├── manager/
│       │   │   │           │   │   ├── Lifecycle.java
│       │   │   │           │   │   └── SimpleConnectorLifecycleManager.java
│       │   │   │           │   ├── reporter/
│       │   │   │           │   │   ├── AsyncPrettyPrinter.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterExecutorHolder.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterFactory.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterInitializer.java
│       │   │   │           │   │   ├── AsyncPrettyPrinterRegistry.java
│       │   │   │           │   │   ├── CountingOutputStream.java
│       │   │   │           │   │   ├── DecompressionHelper.java
│       │   │   │           │   │   ├── DefaultResponseHandler.java
│       │   │   │           │   │   ├── DownloadingAsyncPrettyPrinterFactory.java
│       │   │   │           │   │   ├── GunzippingOutputStream.java
│       │   │   │           │   │   ├── MimeMatcher.java
│       │   │   │           │   │   ├── NetworkEventReporter.java
│       │   │   │           │   │   ├── NetworkEventReporterImpl.java
│       │   │   │           │   │   ├── NetworkPeerManager.java
│       │   │   │           │   │   ├── PrettyPrinterDisplayType.java
│       │   │   │           │   │   ├── RequestBodyHelper.java
│       │   │   │           │   │   ├── ResourceTypeHelper.java
│       │   │   │           │   │   ├── ResponseBodyData.java
│       │   │   │           │   │   ├── ResponseBodyFileManager.java
│       │   │   │           │   │   ├── ResponseHandler.java
│       │   │   │           │   │   └── ResponseHandlingInputStream.java
│       │   │   │           │   ├── server/
│       │   │   │           │   │   ├── AddressNameHelper.java
│       │   │   │           │   │   ├── CompositeInputStream.java
│       │   │   │           │   │   ├── LazySocketHandler.java
│       │   │   │           │   │   ├── LeakyBufferedInputStream.java
│       │   │   │           │   │   ├── LocalSocketServer.java
│       │   │   │           │   │   ├── PeerAuthorizationException.java
│       │   │   │           │   │   ├── ProtocolDetectingSocketHandler.java
│       │   │   │           │   │   ├── SecureSocketHandler.java
│       │   │   │           │   │   ├── ServerManager.java
│       │   │   │           │   │   ├── SocketHandler.java
│       │   │   │           │   │   ├── SocketHandlerFactory.java
│       │   │   │           │   │   ├── SocketLike.java
│       │   │   │           │   │   ├── SocketLikeHandler.java
│       │   │   │           │   │   └── http/
│       │   │   │           │   │       ├── ExactPathMatcher.java
│       │   │   │           │   │       ├── HandlerRegistry.java
│       │   │   │           │   │       ├── HttpHandler.java
│       │   │   │           │   │       ├── HttpHeaders.java
│       │   │   │           │   │       ├── HttpStatus.java
│       │   │   │           │   │       ├── LightHttpBody.java
│       │   │   │           │   │       ├── LightHttpMessage.java
│       │   │   │           │   │       ├── LightHttpRequest.java
│       │   │   │           │   │       ├── LightHttpResponse.java
│       │   │   │           │   │       ├── LightHttpServer.java
│       │   │   │           │   │       ├── PathMatcher.java
│       │   │   │           │   │       └── RegexpPathMatcher.java
│       │   │   │           │   ├── util/
│       │   │   │           │   │   ├── Accumulator.java
│       │   │   │           │   │   ├── ArrayListAccumulator.java
│       │   │   │           │   │   ├── ColorStringUtil.java
│       │   │   │           │   │   ├── DreamCatcherCrashHandler.java
│       │   │   │           │   │   ├── ExceptionUtil.java
│       │   │   │           │   │   ├── IServerManager.java
│       │   │   │           │   │   ├── KLog.java
│       │   │   │           │   │   ├── KLogImpl.java
│       │   │   │           │   │   ├── Keys.java
│       │   │   │           │   │   ├── ListUtil.java
│       │   │   │           │   │   ├── LogFilter.java
│       │   │   │           │   │   ├── LogInterface.java
│       │   │   │           │   │   ├── LogUtil.java
│       │   │   │           │   │   ├── Predicate.java
│       │   │   │           │   │   ├── ProcessUtil.java
│       │   │   │           │   │   ├── ReflectionUtil.java
│       │   │   │           │   │   ├── SocketServerManager.java
│       │   │   │           │   │   ├── StringUtil.java
│       │   │   │           │   │   ├── ThreadBound.java
│       │   │   │           │   │   ├── UncheckedCallable.java
│       │   │   │           │   │   ├── Utf8Charset.java
│       │   │   │           │   │   └── Util.java
│       │   │   │           │   └── websocket/
│       │   │   │           │       ├── CloseCodes.java
│       │   │   │           │       ├── Frame.java
│       │   │   │           │       ├── FrameHelper.java
│       │   │   │           │       ├── MaskingHelper.java
│       │   │   │           │       ├── ReadCallback.java
│       │   │   │           │       ├── ReadHandler.java
│       │   │   │           │       ├── SimpleEndpoint.java
│       │   │   │           │       ├── SimpleSession.java
│       │   │   │           │       ├── WebSocketHandler.java
│       │   │   │           │       ├── WebSocketSession.java
│       │   │   │           │       ├── WriteCallback.java
│       │   │   │           │       └── WriteHandler.java
│       │   │   │           ├── event/
│       │   │   │           │   ├── CaptureEvent.java
│       │   │   │           │   └── OperateEvent.java
│       │   │   │           ├── misc/
│       │   │   │           │   └── X509ExtendedTrustManager.java
│       │   │   │           ├── service/
│       │   │   │           │   ├── ConnectorService.java
│       │   │   │           │   └── ProxyService.java
│       │   │   │           └── wrapper/
│       │   │   │               ├── DCHeader.java
│       │   │   │               ├── DCRequest.java
│       │   │   │               ├── DCResponse.java
│       │   │   │               └── ProxyManager.java
│       │   │   └── net/
│       │   │       └── lightbody/
│       │   │           └── bmp/
│       │   │               ├── BrowserMobProxy.java
│       │   │               ├── BrowserMobProxyServer.java
│       │   │               ├── client/
│       │   │               │   └── ClientUtil.java
│       │   │               ├── core/
│       │   │               │   ├── har/
│       │   │               │   │   ├── Har.java
│       │   │               │   │   ├── HarCache.java
│       │   │               │   │   ├── HarCacheStatus.java
│       │   │               │   │   ├── HarContent.java
│       │   │               │   │   ├── HarCookie.java
│       │   │               │   │   ├── HarEntry.java
│       │   │               │   │   ├── HarLog.java
│       │   │               │   │   ├── HarNameValuePair.java
│       │   │               │   │   ├── HarNameVersion.java
│       │   │               │   │   ├── HarPage.java
│       │   │               │   │   ├── HarPageTimings.java
│       │   │               │   │   ├── HarPostData.java
│       │   │               │   │   ├── HarPostDataParam.java
│       │   │               │   │   ├── HarRequest.java
│       │   │               │   │   ├── HarResponse.java
│       │   │               │   │   └── HarTimings.java
│       │   │               │   └── json/
│       │   │               │       ├── ISO8601DateFormatter.java
│       │   │               │       └── ISO8601WithTDZDateFormatter.java
│       │   │               ├── exception/
│       │   │               │   ├── DecompressionException.java
│       │   │               │   └── UnsupportedCharsetException.java
│       │   │               ├── filters/
│       │   │               │   ├── AddHeadersFilter.java
│       │   │               │   ├── AutoBasicAuthFilter.java
│       │   │               │   ├── BlacklistFilter.java
│       │   │               │   ├── BrowserMobHttpFilterChain.java
│       │   │               │   ├── ClientRequestCaptureFilter.java
│       │   │               │   ├── HarCaptureFilter.java
│       │   │               │   ├── HttpConnectHarCaptureFilter.java
│       │   │               │   ├── HttpsAwareFiltersAdapter.java
│       │   │               │   ├── HttpsHostCaptureFilter.java
│       │   │               │   ├── HttpsOriginalHostCaptureFilter.java
│       │   │               │   ├── LatencyFilter.java
│       │   │               │   ├── ModifiedRequestAwareFilter.java
│       │   │               │   ├── RegisterRequestFilter.java
│       │   │               │   ├── RequestFilter.java
│       │   │               │   ├── RequestFilterAdapter.java
│       │   │               │   ├── ResolvedHostnameCacheFilter.java
│       │   │               │   ├── ResponseFilter.java
│       │   │               │   ├── ResponseFilterAdapter.java
│       │   │               │   ├── RewriteUrlFilter.java
│       │   │               │   ├── ServerResponseCaptureFilter.java
│       │   │               │   ├── UnregisterRequestFilter.java
│       │   │               │   ├── WhitelistFilter.java
│       │   │               │   ├── support/
│       │   │               │   │   └── HttpConnectTiming.java
│       │   │               │   └── util/
│       │   │               │       └── HarCaptureUtil.java
│       │   │               ├── mitm/
│       │   │               │   ├── CertificateAndKey.java
│       │   │               │   ├── CertificateAndKeySource.java
│       │   │               │   ├── CertificateInfo.java
│       │   │               │   ├── CertificateInfoGenerator.java
│       │   │               │   ├── ExistingCertificateSource.java
│       │   │               │   ├── HostnameCertificateInfoGenerator.java
│       │   │               │   ├── KeyStoreCertificateSource.java
│       │   │               │   ├── KeyStoreFileCertificateSource.java
│       │   │               │   ├── PemFileCertificateSource.java
│       │   │               │   ├── RootCertificateGenerator.java
│       │   │               │   ├── TrustSource.java
│       │   │               │   ├── exception/
│       │   │               │   │   ├── CertificateCreationException.java
│       │   │               │   │   ├── CertificateSourceException.java
│       │   │               │   │   ├── ExportException.java
│       │   │               │   │   ├── ImportException.java
│       │   │               │   │   ├── KeyGeneratorException.java
│       │   │               │   │   ├── KeyStoreAccessException.java
│       │   │               │   │   ├── MitmException.java
│       │   │               │   │   ├── SslContextInitializationException.java
│       │   │               │   │   ├── TrustSourceException.java
│       │   │               │   │   └── UncheckedIOException.java
│       │   │               │   ├── keys/
│       │   │               │   │   ├── ECKeyGenerator.java
│       │   │               │   │   ├── KeyGenerator.java
│       │   │               │   │   └── RSAKeyGenerator.java
│       │   │               │   ├── manager/
│       │   │               │   │   └── ImpersonatingMitmManager.java
│       │   │               │   ├── stats/
│       │   │               │   │   └── CertificateGenerationStatistics.java
│       │   │               │   ├── tools/
│       │   │               │   │   ├── BouncyCastleSecurityProviderTool.java
│       │   │               │   │   ├── DefaultSecurityProviderTool.java
│       │   │               │   │   └── SecurityProviderTool.java
│       │   │               │   ├── trustmanager/
│       │   │               │   │   ├── InsecureExtendedTrustManager.java
│       │   │               │   │   └── InsecureTrustManagerFactory.java
│       │   │               │   └── util/
│       │   │               │       ├── EncryptionUtil.java
│       │   │               │       ├── KeyStoreUtil.java
│       │   │               │       ├── MitmConstants.java
│       │   │               │       ├── SslUtil.java
│       │   │               │       └── TrustUtil.java
│       │   │               ├── proxy/
│       │   │               │   ├── ActivityMonitor.java
│       │   │               │   ├── BlacklistEntry.java
│       │   │               │   ├── CaptureType.java
│       │   │               │   ├── RewriteRule.java
│       │   │               │   ├── Whitelist.java
│       │   │               │   ├── auth/
│       │   │               │   │   └── AuthType.java
│       │   │               │   └── dns/
│       │   │               │       ├── AbstractHostNameRemapper.java
│       │   │               │       ├── AdvancedHostResolver.java
│       │   │               │       ├── BasicHostResolver.java
│       │   │               │       ├── ChainedHostResolver.java
│       │   │               │       ├── DelegatingHostResolver.java
│       │   │               │       ├── DnsJavaResolver.java
│       │   │               │       ├── HostResolver.java
│       │   │               │       ├── NativeCacheManipulatingResolver.java
│       │   │               │       └── NativeResolver.java
│       │   │               └── util/
│       │   │                   ├── BrowserMobHttpUtil.java
│       │   │                   ├── BrowserMobProxyUtil.java
│       │   │                   ├── ClasspathResourceUtil.java
│       │   │                   ├── HttpMessageContents.java
│       │   │                   ├── HttpMessageInfo.java
│       │   │                   ├── HttpObjectUtil.java
│       │   │                   └── HttpUtil.java
│       │   ├── res/
│       │   │   ├── layout/
│       │   │   │   └── activity_capture.xml
│       │   │   ├── menu/
│       │   │   │   └── menu_main.xml
│       │   │   ├── values/
│       │   │   │   ├── colors.xml
│       │   │   │   ├── dimens.xml
│       │   │   │   ├── strings.xml
│       │   │   │   └── styles.xml
│       │   │   └── values-w820dp/
│       │   │       └── dimens.xml
│       │   └── resources/
│       │       ├── cacerts.pem
│       │       ├── default-ciphers.txt
│       │       ├── net/
│       │       │   └── lightbody/
│       │       │       └── bmp/
│       │       │           └── version
│       │       └── sslSupport/
│       │           ├── ca-certificate-ec.cer
│       │           ├── ca-certificate-rsa.cer
│       │           ├── ca-keystore-ec.p12
│       │           └── ca-keystore-rsa.p12
│       └── test/
│           └── java/
│               └── me/
│                   └── moxun/
│                       └── dreamcatcher/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Download .txt
SYMBOL INDEX (2091 symbols across 247 files)

FILE: app/src/androidTest/java/me/moxun/dreamcatcher/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: app/src/main/java/me/moxun/dreamcatcher/CaptureActivity.java
  class CaptureActivity (line 27) | public class CaptureActivity extends AppCompatActivity {
    method onCreate (line 40) | @Override
    method performProgress (line 110) | private void performProgress(@NonNull final IndeterminateProgressButto...
    method $px (line 126) | private int $px(float dpValue) {
    method morphToSuccess (line 131) | private void morphToSuccess(final IndeterminateProgressButton btnMorph...
    method morphToFailure (line 145) | private void morphToFailure(final IndeterminateProgressButton btnMorph...
    method morphToIdle (line 158) | private void morphToIdle(final IndeterminateProgressButton btnMorph, i...
    method onEvent (line 171) | @Subscribe(threadMode = ThreadMode.MAIN)
    method onDestroy (line 228) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/DCApplication.java
  class DCApplication (line 12) | public class DCApplication extends MultiDexApplication {
    method onCreate (line 17) | @Override
    method onTerminate (line 23) | @Override
    method getPort (line 29) | public int getPort() {
    method setPort (line 33) | public void setPort(int port) {

FILE: app/src/main/java/me/moxun/dreamcatcher/State.java
  type State (line 7) | public interface State {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/Connector.java
  class Connector (line 35) | public class Connector {
    method Connector (line 38) | private Connector() {
    method initialize (line 42) | private static void initialize(final Initializer initializer) {
    method loadInnerModule (line 47) | private static void loadInnerModule(Context context) {
    method open (line 57) | public static void open(final Context context) {
    method close (line 66) | public static void close() {
    class PluginBuilder (line 71) | private static class PluginBuilder<T> {
      method provide (line 79) | public void provide(String name, T plugin) {
      method provideIfDesired (line 85) | public void provideIfDesired(String name, T plugin) {
      method remove (line 94) | public void remove(String pluginName) {
      method throwIfFinished (line 99) | private void throwIfFinished() {
      method finish (line 105) | public Iterable<T> finish() {
    class DefaultInspectorModulesBuilder (line 111) | private static final class DefaultInspectorModulesBuilder {
      method DefaultInspectorModulesBuilder (line 115) | public DefaultInspectorModulesBuilder(Context context) {
      method provideIfDesired (line 119) | private DefaultInspectorModulesBuilder provideIfDesired(ChromeDevtoo...
      method finish (line 124) | public Iterable<ChromeDevtoolsDomain> finish() {
    class Initializer (line 132) | private static abstract class Initializer {
      method Initializer (line 135) | protected Initializer(Context context) {
      method getInspectorModules (line 139) | @Nullable
      method start (line 142) | final void start() {
      method initServerManager (line 150) | private void initServerManager() {
      class RealSocketHandlerFactory (line 159) | private class RealSocketHandlerFactory implements SocketHandlerFacto...
        method create (line 160) | @Override
    method isDebuggable (line 176) | private static boolean isDebuggable(Context context) {
    class InitializerBuilder (line 181) | private static class InitializerBuilder {
      method InitializerBuilder (line 188) | private InitializerBuilder(Context context) {
      method enableInspector (line 192) | public InitializerBuilder enableInspector(InspectorModulesProvider m...
      method build (line 197) | public Initializer build() {
    class BuilderBasedInitializer (line 202) | private static class BuilderBasedInitializer extends Initializer {
      method BuilderBasedInitializer (line 206) | private BuilderBasedInitializer(InitializerBuilder b) {
      method getInspectorModules (line 211) | @javax.annotation.Nullable
    method setInternalLogEnabled (line 219) | public static void setInternalLogEnabled(boolean enabled) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/InspectorModulesProvider.java
  type InspectorModulesProvider (line 6) | public interface InspectorModulesProvider {
    method get (line 7) | Iterable<ChromeDevtoolsDomain> get();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/CLog.java
  class CLog (line 12) | public class CLog {
    method writeToConsole (line 15) | public static void writeToConsole(
    method writeToConsole (line 31) | public static void writeToConsole(
    method log (line 44) | public static void log(String note) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/ConsolePeerManager.java
  class ConsolePeerManager (line 8) | public class ConsolePeerManager extends ChromePeerManager {
    method ConsolePeerManager (line 12) | private ConsolePeerManager() {
    method getInstanceOrNull (line 16) | @Nullable
    method getOrCreateInstance (line 21) | public static synchronized ConsolePeerManager getOrCreateInstance() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeRepl.java
  type RuntimeRepl (line 3) | public interface RuntimeRepl {
    method evaluate (line 4) | Object evaluate(String expression) throws Throwable;

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeReplFactory.java
  type RuntimeReplFactory (line 12) | public interface RuntimeReplFactory {
    method newInstance (line 13) | RuntimeRepl newInstance();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/console/command/CommandHandler.java
  type CommandHandler (line 8) | public interface CommandHandler {
    method desire (line 9) | String desire();
    method help (line 11) | String help();
    method onCommand (line 13) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDevtoolsServer.java
  class ChromeDevtoolsServer (line 38) | public class ChromeDevtoolsServer implements SimpleEndpoint {
    method ChromeDevtoolsServer (line 49) | public ChromeDevtoolsServer(Iterable<ChromeDevtoolsDomain> domainModul...
    method onOpen (line 54) | @Override
    method onClose (line 62) | @Override
    method onMessage (line 72) | @Override
    method onMessage (line 77) | @Override
    method closeSafely (line 101) | private void closeSafely(SimpleSession session, int code, String reaso...
    method handleRemoteMessage (line 105) | private void handleRemoteMessage(JsonRpcPeer peer, String message)
    method handleRemoteRequest (line 118) | private void handleRemoteRequest(JsonRpcPeer peer, JSONObject requestN...
    method logDispatchException (line 164) | private static void logDispatchException(JsonRpcException e) {
    method handleRemoteResponse (line 175) | private void handleRemoteResponse(JsonRpcPeer peer, JSONObject respons...
    method onError (line 190) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDiscoveryHandler.java
  class ChromeDiscoveryHandler (line 34) | public class ChromeDiscoveryHandler implements HttpHandler {
    method setInvalid (line 65) | public static void setInvalid(boolean invalid) {
    method ChromeDiscoveryHandler (line 69) | public ChromeDiscoveryHandler(Context context, String inspectorPath) {
    method register (line 76) | public void register(HandlerRegistry registry) {
    method handleRequest (line 83) | @Override
    method handleVersion (line 107) | private void handleVersion(LightHttpResponse response)
    method handlePageList (line 122) | private void handlePageList(LightHttpResponse response)
    method makeWSAddress (line 153) | private String makeWSAddress() {
    method makeTitle (line 157) | private String makeTitle() {
    method handleActivate (line 176) | private void handleActivate(LightHttpResponse response) {
    method setSuccessfulResponse (line 183) | private static void setSuccessfulResponse(
    method getAppLabelAndVersion (line 193) | private String getAppLabelAndVersion() {
    method getAppLabel (line 207) | private CharSequence getAppLabel() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/DevtoolsSocketHandler.java
  class DevtoolsSocketHandler (line 15) | public class DevtoolsSocketHandler implements SocketLikeHandler {
    method DevtoolsSocketHandler (line 20) | public DevtoolsSocketHandler(Context context, Iterable<ChromeDevtoolsD...
    method createServer (line 26) | private LightHttpServer createServer() {
    method onAccepted (line 40) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MessageHandlingException.java
  class MessageHandlingException (line 3) | public class MessageHandlingException extends Exception {
    method MessageHandlingException (line 4) | public MessageHandlingException(Throwable cause) {
    method MessageHandlingException (line 8) | public MessageHandlingException(String message) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MethodDispatcher.java
  class MethodDispatcher (line 28) | @ThreadSafe
    method MethodDispatcher (line 36) | public MethodDispatcher(
    method findMethodDispatcher (line 43) | private synchronized MethodDispatchHelper findMethodDispatcher(String ...
    method dispatch (line 50) | public JSONObject dispatch(JsonRpcPeer peer, String methodName, @Nulla...
    class MethodDispatchHelper (line 76) | private static class MethodDispatchHelper {
      method MethodDispatchHelper (line 81) | public MethodDispatchHelper(ObjectMapper objectMapper,
      method invoke (line 89) | public JSONObject invoke(JsonRpcPeer peer, @Nullable JSONObject params)
    method buildDispatchTable (line 101) | private static Map<String, MethodDispatchHelper> buildDispatchTable(
    method isDevtoolsMethod (line 131) | private static boolean isDevtoolsMethod(Method method) throws IllegalA...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MismatchedResponseException.java
  class MismatchedResponseException (line 3) | public class MismatchedResponseException extends MessageHandlingException {
    method MismatchedResponseException (line 6) | public MismatchedResponseException(long requestId) {
    method getRequestId (line 11) | public long getRequestId() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ChromePeerManager.java
  class ChromePeerManager (line 24) | public class ChromePeerManager {
    method ChromePeerManager (line 44) | public ChromePeerManager() {
    method setListener (line 53) | public synchronized void setListener(PeerRegistrationListener listener) {
    method addPeer (line 63) | public synchronized boolean addPeer(JsonRpcPeer peer) {
    method removePeer (line 83) | public synchronized void removePeer(JsonRpcPeer peer) {
    method hasRegisteredPeers (line 92) | public synchronized boolean hasRegisteredPeers() {
    method getReceivingPeersSnapshot (line 96) | private synchronized JsonRpcPeer[] getReceivingPeersSnapshot() {
    method sendNotificationToPeers (line 104) | public void sendNotificationToPeers(String method,
    method invokeMethodOnPeers (line 109) | public void invokeMethodOnPeers(String method,
    method sendMessageToPeers (line 116) | private void sendMessageToPeers(String method,
    class UnregisterOnDisconnect (line 129) | private class UnregisterOnDisconnect implements DisconnectReceiver {
      method UnregisterOnDisconnect (line 132) | public UnregisterOnDisconnect(JsonRpcPeer peer) {
      method onDisconnect (line 136) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ObjectIdMapper.java
  class ObjectIdMapper (line 11) | public class ObjectIdMapper {
    method clear (line 23) | public void clear() {
    method containsId (line 39) | public boolean containsId(int id) {
    method containsObject (line 45) | public boolean containsObject(Object object) {
    method getObjectForId (line 51) | @Nullable
    method getIdForObject (line 58) | @Nullable
    method putObject (line 65) | public int putObject(Object object) {
    method removeObjectById (line 83) | @Nullable
    method removeObject (line 101) | @Nullable
    method size (line 118) | public int size() {
    method getFirstId (line 124) | public synchronized int getFirstId() {
    method onMapped (line 128) | protected void onMapped(Object object, int id) {
    method onUnmapped (line 131) | protected void onUnmapped(Object object, int id) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeerRegistrationListener.java
  type PeerRegistrationListener (line 6) | public interface PeerRegistrationListener {
    method onPeerRegistered (line 7) | void onPeerRegistered(JsonRpcPeer peer);
    method onPeerUnregistered (line 8) | void onPeerUnregistered(JsonRpcPeer peer);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeersRegisteredListener.java
  class PeersRegisteredListener (line 8) | public abstract class PeersRegisteredListener implements PeerRegistratio...
    method onPeerRegistered (line 11) | @Override
    method onPeerUnregistered (line 19) | @Override
    method onPeerAdded (line 27) | protected void onPeerAdded(JsonRpcPeer peer) {}
    method onPeerRemoved (line 28) | protected void onPeerRemoved(JsonRpcPeer peer) {}
    method onFirstPeerRegistered (line 30) | protected abstract void onFirstPeerRegistered();
    method onLastPeerUnregistered (line 31) | protected abstract void onLastPeerUnregistered();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ThreadBoundProxy.java
  class ThreadBoundProxy (line 12) | public abstract class ThreadBoundProxy implements ThreadBound {
    method ThreadBoundProxy (line 15) | public ThreadBoundProxy(ThreadBound enforcer) {
    method checkThreadAccess (line 19) | @Override
    method verifyThreadAccess (line 24) | @Override
    method postAndWait (line 29) | @Override
    method postAndWait (line 34) | @Override
    method postDelayed (line 39) | @Override
    method removeCallbacks (line 44) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/TracingPeerManager.java
  class TracingPeerManager (line 8) | public class TracingPeerManager extends ChromePeerManager {
    method getInstanceOrNull (line 11) | @Nullable
    method getOrCreateInstance (line 16) | public static synchronized TracingPeerManager getOrCreateInstance() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/ChromeDevtoolsDomain.java
  type ChromeDevtoolsDomain (line 6) | public interface ChromeDevtoolsDomain {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleBooleanResult.java
  class SimpleBooleanResult (line 7) | public class SimpleBooleanResult implements JsonRpcResult {
    method SimpleBooleanResult (line 11) | public SimpleBooleanResult() {
    method SimpleBooleanResult (line 14) | public SimpleBooleanResult(boolean result) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleIntegerResult.java
  class SimpleIntegerResult (line 11) | public class SimpleIntegerResult implements JsonRpcResult {
    method SimpleIntegerResult (line 15) | public SimpleIntegerResult() {
    method SimpleIntegerResult (line 18) | public SimpleIntegerResult(int result) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleStringResult.java
  class SimpleStringResult (line 11) | public class SimpleStringResult implements JsonRpcResult {
    method SimpleStringResult (line 15) | public SimpleStringResult() {
    method SimpleStringResult (line 18) | public SimpleStringResult(String data) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Console.java
  class Console (line 16) | public class Console implements ChromeDevtoolsDomain {
    method Console (line 17) | public Console() {
    method enable (line 20) | @ChromeDevtoolsMethod
    method disable (line 25) | @ChromeDevtoolsMethod
    class MessageAddedRequest (line 30) | @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    class ConsoleMessage (line 36) | @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    type MessageSource (line 54) | public enum MessageSource {
      method MessageSource (line 68) | private MessageSource(String protocolValue) {
      method getProtocolValue (line 72) | @JsonValue
    type MessageLevel (line 78) | public enum MessageLevel {
      method MessageLevel (line 87) | private MessageLevel(String protocolValue) {
      method getProtocolValue (line 91) | @JsonValue
    type MessageType (line 97) | public enum MessageType {
      method MessageType (line 106) | private MessageType(String protocolValue) {
      method getProtocolValue (line 110) | @JsonValue
    class CallFrame (line 116) | @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
      method CallFrame (line 130) | public CallFrame() {
      method CallFrame (line 133) | public CallFrame(String functionName, String url, int lineNumber, in...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/FileSystem.java
  class FileSystem (line 24) | public class FileSystem implements ChromeDevtoolsDomain {
    method isFSEnabled (line 32) | public static boolean isFSEnabled() {
    method FileSystem (line 36) | public FileSystem(Context context) {
    method enable (line 49) | @ChromeDevtoolsMethod
    method disable (line 54) | @ChromeDevtoolsMethod
    method requestFileSystemRoot (line 59) | @ChromeDevtoolsMethod
    method buildFileRoot (line 69) | private RequestFileSystemRootResponse buildFileRoot() {
    method requestDirectoryContent (line 80) | @ChromeDevtoolsMethod
    method isTextFile (line 118) | private boolean isTextFile(File file) {
    method isImage (line 127) | private boolean isImage(File file) {
    method requestMetadata (line 137) | @ChromeDevtoolsMethod
    method requestFileContent (line 158) | @ChromeDevtoolsMethod
    method readFileAsText (line 171) | private String readFileAsText(File file) {
    method deleteEntry (line 186) | @ChromeDevtoolsMethod
    class DeleteEntryRequest (line 198) | public static class DeleteEntryRequest {
    class DeleteEntryResponse (line 203) | public static class DeleteEntryResponse implements JsonRpcResult {
    class RequestFileContentRequest (line 208) | public static class RequestFileContentRequest {
    class RequestFileContentResponse (line 225) | public static class RequestFileContentResponse implements JsonRpcResult {
    class RequestMetadataRequest (line 236) | public static class RequestMetadataRequest {
    class RequestMetadataResponse (line 241) | public static class RequestMetadataResponse implements JsonRpcResult {
    class Metadata (line 249) | public static class Metadata {
    class RequestDirectoryContentRequest (line 257) | public static class RequestDirectoryContentRequest {
    class RequestDirectoryContentResponse (line 262) | public static class RequestDirectoryContentResponse implements JsonRpc...
    class Entry (line 270) | public static class Entry {
    class RequestFileSystemRootRequest (line 290) | public static class RequestFileSystemRootRequest {
    class RequestFileSystemRootResponse (line 298) | public static class RequestFileSystemRootResponse implements JsonRpcRe...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Inspector.java
  class Inspector (line 10) | public class Inspector implements ChromeDevtoolsDomain {
    method Inspector (line 11) | public Inspector() {
    method enable (line 14) | @ChromeDevtoolsMethod
    method disable (line 18) | @ChromeDevtoolsMethod

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Network.java
  class Network (line 25) | public class Network implements ChromeDevtoolsDomain {
    method Network (line 29) | public Network(Context context) {
    method enable (line 34) | @ChromeDevtoolsMethod
    method disable (line 39) | @ChromeDevtoolsMethod
    method setUserAgentOverride (line 44) | @ChromeDevtoolsMethod
    method getResponseBody (line 49) | @ChromeDevtoolsMethod
    method readResponseBody (line 66) | private GetResponseBodyResponse readResponseBody(String requestId)
    method setPrettyPrinterInitializer (line 88) | public void setPrettyPrinterInitializer(AsyncPrettyPrinterInitializer ...
    class GetResponseBodyResponse (line 93) | private static class GetResponseBodyResponse implements JsonRpcResult {
    class RequestWillBeSentParams (line 101) | public static class RequestWillBeSentParams {
    class ResponseReceivedParams (line 130) | public static class ResponseReceivedParams {
    class LoadingFinishedParams (line 150) | public static class LoadingFinishedParams {
    class LoadingFailedParams (line 158) | public static class LoadingFailedParams {
    class DataReceivedParams (line 176) | public static class DataReceivedParams {
    class Request (line 190) | public static class Request {
    class Initiator (line 204) | public static class Initiator {
    type InitiatorType (line 212) | public enum InitiatorType {
      method InitiatorType (line 219) | private InitiatorType(String protocolValue) {
      method getProtocolValue (line 223) | @JsonValue
    class Response (line 229) | public static class Response {
    class ResourceTiming (line 267) | public static class ResourceTiming {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Page.java
  class Page (line 23) | public class Page implements ChromeDevtoolsDomain {
    method Page (line 28) | public Page(Context context) {
    method enable (line 32) | @ChromeDevtoolsMethod
    method disable (line 38) | @ChromeDevtoolsMethod
    method notifyExecutionContexts (line 42) | private void notifyExecutionContexts(JsonRpcPeer peer) {
    method sendWelcomeMessage (line 51) | private void sendWelcomeMessage(JsonRpcPeer peer) {
    method createSimpleFrameResourceTree (line 63) | private static FrameResourceTree createSimpleFrameResourceTree(
    method canScreencast (line 83) | @ChromeDevtoolsMethod
    method hasTouchInputs (line 88) | @ChromeDevtoolsMethod
    method setDeviceMetricsOverride (line 93) | @ChromeDevtoolsMethod
    method clearDeviceOrientationOverride (line 97) | @ChromeDevtoolsMethod
    method startScreencast (line 101) | @ChromeDevtoolsMethod
    method stopScreencast (line 106) | @ChromeDevtoolsMethod
    method screencastFrameAck (line 111) | @ChromeDevtoolsMethod
    method clearGeolocationOverride (line 127) | @ChromeDevtoolsMethod
    method setTouchEmulationEnabled (line 131) | @ChromeDevtoolsMethod
    method setEmulatedMedia (line 135) | @ChromeDevtoolsMethod
    method setShowViewportSizeOnResize (line 139) | @ChromeDevtoolsMethod
    class GetResourceTreeParams (line 143) | private static class GetResourceTreeParams implements JsonRpcResult {
    class FrameResourceTree (line 148) | private static class FrameResourceTree {
    class Frame (line 159) | private static class Frame {
    class Resource (line 182) | private static class Resource {
    type ResourceType (line 186) | public enum ResourceType {
      method ResourceType (line 198) | private ResourceType(String protocolValue) {
      method getProtocolValue (line 202) | @JsonValue
    class ExecutionContextCreatedParams (line 208) | private static class ExecutionContextCreatedParams {
    class ExecutionContextDescription (line 213) | private static class ExecutionContextDescription {
    class ScreencastFrameEvent (line 221) | public static class ScreencastFrameEvent {
      method increment (line 232) | public void increment() {
    class ScreencastFrameEventMetadata (line 237) | public static class ScreencastFrameEventMetadata {
    class StartScreencastRequest (line 252) | public static class StartScreencastRequest {
    class NavigationHistory (line 263) | public static class NavigationHistory implements JsonRpcResult {
    class NavigationEntry (line 270) | public static class NavigationEntry {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Profiler.java
  class Profiler (line 15) | public class Profiler implements ChromeDevtoolsDomain {
    method Profiler (line 16) | public Profiler() {
    method enable (line 19) | @ChromeDevtoolsMethod
    method disable (line 23) | @ChromeDevtoolsMethod
    method stop (line 27) | @ChromeDevtoolsMethod
    method setSamplingInterval (line 31) | @ChromeDevtoolsMethod
    method getProfileHeaders (line 35) | @ChromeDevtoolsMethod
    class ProfileHeaderResponse (line 42) | private static class ProfileHeaderResponse implements JsonRpcResult {
    class ProfileHeader (line 47) | private static class ProfileHeader {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Runtime.java
  class Runtime (line 39) | public class Runtime implements ChromeDevtoolsDomain {
    method Runtime (line 52) | @Deprecated
    method Runtime (line 67) | public Runtime(RuntimeReplFactory replFactory) {
    method mapObject (line 71) | public static int mapObject(JsonRpcPeer peer, Object object) {
    method getSession (line 75) | @Nonnull
    method releaseObject (line 91) | @ChromeDevtoolsMethod
    method releaseObjectGroup (line 97) | @ChromeDevtoolsMethod
    method callFunctionOn (line 102) | @ChromeDevtoolsMethod
    method evaluate (line 139) | @ChromeDevtoolsMethod
    method getProperties (line 144) | @ChromeDevtoolsMethod
    method getPropertyClassName (line 149) | private static String getPropertyClassName(Object o) {
    class ObjectProtoContainer (line 158) | private static class ObjectProtoContainer {
      method ObjectProtoContainer (line 161) | public ObjectProtoContainer(Object object) {
    class Session (line 173) | private static class Session {
      method getObjects (line 180) | public ObjectIdMapper getObjects() {
      method getObjectOrThrow (line 184) | public Object getObjectOrThrow(String objectId) throws JsonRpcExcept...
      method objectForRemote (line 195) | public RemoteObject objectForRemote(Object value) {
      method evaluate (line 235) | public EvaluateResponse evaluate(RuntimeReplFactory replFactory, JSO...
      method getRepl (line 254) | @Nonnull
      method buildNormalResponse (line 262) | private EvaluateResponse buildNormalResponse(Object retval) {
      method buildExceptionResponse (line 269) | private EvaluateResponse buildExceptionResponse(Object retval) {
      method getProperties (line 278) | public GetPropertiesResponse getProperties(JSONObject params) throws...
      method arrayToList (line 306) | private List<?> arrayToList(Object object) {
      method getPropertiesForProtoContainer (line 329) | private GetPropertiesResponse getPropertiesForProtoContainer(ObjectP...
      method getPropertiesForIterable (line 346) | private GetPropertiesResponse getPropertiesForIterable(Iterable<?> o...
      method getPropertiesForMap (line 362) | private GetPropertiesResponse getPropertiesForMap(Object object) {
      method getPropertiesForObject (line 377) | private GetPropertiesResponse getPropertiesForObject(Object object) {
    class CallFunctionOnRequest (line 416) | private static class CallFunctionOnRequest {
    class CallFunctionOnResponse (line 436) | private static class CallFunctionOnResponse implements JsonRpcResult {
    class CallArgument (line 444) | private static class CallArgument {
    class GetPropertiesRequest (line 455) | private static class GetPropertiesRequest implements JsonRpcResult {
    class GetPropertiesResponse (line 463) | private static class GetPropertiesResponse implements JsonRpcResult {
    class EvaluateRequest (line 468) | private static class EvaluateRequest implements JsonRpcResult {
    class EvaluateResponse (line 476) | private static class EvaluateResponse implements JsonRpcResult {
    class ExceptionDetails (line 487) | private static class ExceptionDetails {
    class RemoteObject (line 492) | public static class RemoteObject {
    class PropertyDescriptor (line 512) | private static class PropertyDescriptor {
    type ObjectType (line 532) | public static enum ObjectType {
      method ObjectType (line 543) | private ObjectType(String protocolValue) {
      method getProtocolValue (line 547) | @JsonValue
    type ObjectSubType (line 553) | public static enum ObjectSubType {
      method ObjectSubType (line 567) | private ObjectSubType(String protocolValue) {
      method getProtocolValue (line 571) | @JsonValue

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/inspector/runtime/DefaultRuntimeReplFactory.java
  class DefaultRuntimeReplFactory (line 14) | public class DefaultRuntimeReplFactory implements RuntimeReplFactory {
    method newInstance (line 17) | @Override
    method register (line 40) | public static void register(String command, CommandHandler handler) {
    method getCommand (line 48) | private Command getCommand(String command) {
    method processCommand (line 61) | private Object processCommand(String input) {
    class Command (line 71) | private class Command {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/json/ObjectMapper.java
  class ObjectMapper (line 39) | public class ObjectMapper {
    method convertValue (line 57) | public <T> T convertValue(Object fromValue, Class<T> toValueType)
    method _convertFromJSONObject (line 90) | private <T> T _convertFromJSONObject(JSONObject jsonObject, Class<T> t...
    method getValueForField (line 113) | private Object getValueForField(Field field, Object value)
    method getEnumValue (line 159) | private Enum getEnumValue(String value, Class<? extends Enum> clazz) {
    method getEnumByMethod (line 177) | private Enum getEnumByMethod(String value, Class<? extends Enum> clazz...
    method convertArrayToList (line 196) | private List<Object> convertArrayToList(Field field, JSONArray array)
    method _convertToJSONObject (line 228) | private JSONObject _convertToJSONObject(Object fromValue)
    method getJsonValue (line 255) | private Object getJsonValue(Object value, Class<?> clazz, Field field)
    method convertListToJsonArray (line 289) | private JSONArray convertListToJsonArray(Object value)
    method getJsonValueMethod (line 305) | @Nullable
    method getJsonValueMethodImpl (line 317) | @Nullable
    method canDirectlySerializeClass (line 329) | private static boolean canDirectlySerializeClass(Class clazz)  {
    method isWrapperOrPrimitiveType (line 334) | private static boolean isWrapperOrPrimitiveType(Class<?> clazz) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/DisconnectReceiver.java
  type DisconnectReceiver (line 6) | public interface DisconnectReceiver {
    method onDisconnect (line 10) | void onDisconnect();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcException.java
  class JsonRpcException (line 7) | public class JsonRpcException extends Exception {
    method JsonRpcException (line 10) | public JsonRpcException(JsonRpcError errorMessage) {
    method getErrorMessage (line 15) | public JsonRpcError getErrorMessage() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcPeer.java
  class JsonRpcPeer (line 20) | @ThreadSafe
    method JsonRpcPeer (line 33) | public JsonRpcPeer(ObjectMapper objectMapper, SimpleSession peer) {
    method getWebSocket (line 38) | public SimpleSession getWebSocket() {
    method invokeMethod (line 42) | public void invokeMethod(String method, Object paramsObject,
    method registerDisconnectReceiver (line 59) | public void registerDisconnectReceiver(DisconnectReceiver callback) {
    method unregisterDisconnectReceiver (line 63) | public void unregisterDisconnectReceiver(DisconnectReceiver callback) {
    method invokeDisconnectReceivers (line 67) | public void invokeDisconnectReceivers() {
    method preparePendingRequest (line 71) | private synchronized long preparePendingRequest(PendingRequestCallback...
    method getAndRemovePendingRequest (line 77) | public synchronized PendingRequest getAndRemovePendingRequest(long req...
    class DisconnectObservable (line 81) | private static class DisconnectObservable extends Observable<Disconnec...
      method onDisconnect (line 82) | public void onDisconnect() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcResult.java
  type JsonRpcResult (line 10) | public interface JsonRpcResult {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequest.java
  class PendingRequest (line 11) | public class PendingRequest {
    method PendingRequest (line 15) | public PendingRequest(long requestId, @Nullable PendingRequestCallback...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequestCallback.java
  type PendingRequestCallback (line 6) | public interface PendingRequestCallback {
    method onResponse (line 7) | void onResponse(JsonRpcPeer peer, JsonRpcResponse response);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/EmptyResult.java
  class EmptyResult (line 6) | public class EmptyResult implements JsonRpcResult {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcError.java
  class JsonRpcError (line 12) | @SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })
    method JsonRpcError (line 23) | public JsonRpcError() {
    method JsonRpcError (line 26) | public JsonRpcError(ErrorCode code, String message, @Nullable JSONObje...
    type ErrorCode (line 32) | public enum ErrorCode {
      method ErrorCode (line 41) | private ErrorCode(int protocolValue) {
      method getProtocolValue (line 45) | @JsonValue

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcEvent.java
  class JsonRpcEvent (line 11) | @SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })
    method JsonRpcEvent (line 19) | public JsonRpcEvent() {
    method JsonRpcEvent (line 22) | public JsonRpcEvent(String method, @Nullable JSONObject params) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcRequest.java
  class JsonRpcRequest (line 9) | @SuppressLint({"UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse"})
    method JsonRpcRequest (line 23) | public JsonRpcRequest() {
    method toString (line 26) | @Override
    method JsonRpcRequest (line 31) | public JsonRpcRequest(Long id, String method, JSONObject params) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcResponse.java
  class JsonRpcResponse (line 9) | @SuppressLint({ "UsingDefaultJsonDeserializer", "EmptyJsonPropertyUse" })

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/AELog.java
  class AELog (line 7) | public class AELog {
    method setLoggable (line 15) | public static void setLoggable(boolean isLoggable) {
    method l (line 19) | public static void l(String msg) {
    method i (line 25) | public static void i(String msg) {
    method d (line 31) | public static void d(String msg) {
    method w (line 37) | public static void w(String msg) {
    method e (line 43) | public static void e(String msg) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/AELogImpl.java
  class AELogImpl (line 10) | final class AELogImpl implements IAELog {
    method isLoggable (line 12) | @Override
    method l (line 17) | @Override
    method i (line 24) | @Override
    method d (line 31) | @Override
    method w (line 38) | @Override
    method e (line 45) | @Override
    method log (line 52) | private static void log(Console.MessageLevel level, String note) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/log/IAELog.java
  type IAELog (line 6) | public interface IAELog {
    method isLoggable (line 7) | boolean isLoggable();
    method l (line 8) | void l(String msg);
    method i (line 9) | void i(String msg);
    method d (line 10) | void d(String msg);
    method w (line 11) | void w(String msg);
    method e (line 12) | void e(String msg);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/manager/Lifecycle.java
  type Lifecycle (line 7) | public interface Lifecycle {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/manager/SimpleConnectorLifecycleManager.java
  class SimpleConnectorLifecycleManager (line 9) | public class SimpleConnectorLifecycleManager {
    method setCurrentState (line 13) | public static void setCurrentState(int state) {
    method getCurrentState (line 17) | public static int getCurrentState() {
    method isSessionActive (line 21) | public static boolean isSessionActive() {
    method isProxyEnabled (line 25) | public static boolean isProxyEnabled() {
    method setProxyEnabled (line 29) | public static void setProxyEnabled(boolean proxyEnabled) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinter.java
  type AsyncPrettyPrinter (line 10) | public interface AsyncPrettyPrinter {
    method printTo (line 20) | public void printTo(PrintWriter output, InputStream payload) throws IO...
    method getPrettifiedType (line 29) | public PrettyPrinterDisplayType getPrettifiedType();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterExecutorHolder.java
  class AsyncPrettyPrinterExecutorHolder (line 11) | final class AsyncPrettyPrinterExecutorHolder {
    method AsyncPrettyPrinterExecutorHolder (line 15) | private AsyncPrettyPrinterExecutorHolder() {
    method ensureInitialized (line 18) | public static void ensureInitialized() {
    method getExecutorService (line 24) | @Nullable
    method shutdown (line 29) | public static void shutdown() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterFactory.java
  type AsyncPrettyPrinterFactory (line 6) | public interface AsyncPrettyPrinterFactory {
    method getInstance (line 17) | public AsyncPrettyPrinter getInstance(String headerName, String header...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterInitializer.java
  type AsyncPrettyPrinterInitializer (line 8) | public interface AsyncPrettyPrinterInitializer {
    method populatePrettyPrinters (line 16) | void populatePrettyPrinters(AsyncPrettyPrinterRegistry registry);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterRegistry.java
  class AsyncPrettyPrinterRegistry (line 9) | @ThreadSafe
    method register (line 14) | public synchronized void register(String headerName, AsyncPrettyPrinte...
    method lookup (line 18) | @Nullable
    method unregister (line 23) | public synchronized boolean unregister(String headerName) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/CountingOutputStream.java
  class CountingOutputStream (line 7) | class CountingOutputStream extends FilterOutputStream {
    method CountingOutputStream (line 10) | public CountingOutputStream(OutputStream out) {
    method getCount (line 14) | public long getCount() {
    method write (line 18) | @Override
    method write (line 24) | @Override
    method write (line 29) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DecompressionHelper.java
  class DecompressionHelper (line 15) | public class DecompressionHelper {
    method teeInputWithDecompression (line 19) | public static InputStream teeInputWithDecompression(

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DefaultResponseHandler.java
  class DefaultResponseHandler (line 8) | public class DefaultResponseHandler implements ResponseHandler {
    method DefaultResponseHandler (line 15) | public DefaultResponseHandler(NetworkEventReporter eventReporter, Stri...
    method onRead (line 20) | @Override
    method onReadDecoded (line 25) | @Override
    method onEOF (line 33) | public void onEOF() {
    method onError (line 38) | public void onError(IOException e) {
    method reportDataReceived (line 43) | private void reportDataReceived() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DownloadingAsyncPrettyPrinterFactory.java
  class DownloadingAsyncPrettyPrinterFactory (line 24) | public abstract class DownloadingAsyncPrettyPrinterFactory implements As...
    method getInstance (line 26) | @Override
    method matchAndParseHeader (line 92) | @Nullable
    method doPrint (line 99) | protected abstract void doPrint(PrintWriter output, InputStream payloa...
    method parseURL (line 102) | @Nullable
    method doErrorPrint (line 111) | private static void doErrorPrint(PrintWriter output, InputStream paylo...
    method getErrorAsyncPrettyPrinter (line 116) | private static AsyncPrettyPrinter getErrorAsyncPrettyPrinter(
    class MatchResult (line 135) | protected class MatchResult {
      method MatchResult (line 139) | public MatchResult(String schemaUri, PrettyPrinterDisplayType displa...
      method getSchemaUri (line 144) | public String getSchemaUri() {
      method getDisplayType (line 148) | public PrettyPrinterDisplayType getDisplayType() {
    class Request (line 153) | private static class Request implements Callable<String> {
      method Request (line 156) | public Request(URL url) {
      method call (line 160) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/GunzippingOutputStream.java
  class GunzippingOutputStream (line 26) | class GunzippingOutputStream extends FilterOutputStream {
    method create (line 31) | public static GunzippingOutputStream create(OutputStream finalOut) thr...
    method GunzippingOutputStream (line 41) | private GunzippingOutputStream(OutputStream out, Future<Void> copyFutu...
    method close (line 46) | @Override
    method getAndRethrow (line 63) | private static <T> T getAndRethrow(Future<T> future) throws IOException {
    class GunzippingCallable (line 77) | private static class GunzippingCallable implements Callable<Void> {
      method GunzippingCallable (line 81) | public GunzippingCallable(InputStream in, OutputStream out) {
      method call (line 86) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/MimeMatcher.java
  class MimeMatcher (line 9) | public class MimeMatcher<T> {
    method addRule (line 19) | public void addRule(String ruleExpression, T resultIfMatched) {
    method clear (line 23) | public void clear() {
    method match (line 27) | @Nullable
    class MimeMatcherRule (line 39) | @SuppressLint("BadMethodUse-java.lang.String.length")
      method MimeMatcherRule (line 45) | public MimeMatcherRule(String ruleExpression, T resultIfMatched) {
      method match (line 60) | public boolean match(String mimeType) {
      method getResultIfMatched (line 71) | public T getResultIfMatched() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporter.java
  type NetworkEventReporter (line 27) | public interface NetworkEventReporter {
    method isEnabled (line 34) | boolean isEnabled();
    method requestWillBeSent (line 41) | void requestWillBeSent(InspectorRequest request);
    method responseHeadersReceived (line 49) | void responseHeadersReceived(InspectorResponse response);
    method httpExchangeFailed (line 61) | void httpExchangeFailed(String requestId, String errorText);
    method interpretResponseStream (line 93) | @Nullable
    method responseReadFailed (line 110) | void responseReadFailed(String requestId, String errorText);
    method responseReadFinished (line 119) | void responseReadFinished(String requestId);
    method dataSent (line 132) | void dataSent(String requestId, int dataLength, int encodedDataLength);
    method dataReceived (line 139) | void dataReceived(String requestId, int dataLength, int encodedDataLen...
    type InspectorRequest (line 148) | interface InspectorRequest extends InspectorHeaders {
      method id (line 155) | String id();
      method friendlyName (line 160) | String friendlyName();
      method friendlyNameExtra (line 166) | @Nullable
      method url (line 169) | String url();
      method method (line 174) | String method();
      method body (line 180) | @Nullable
    type InspectorResponse (line 184) | interface InspectorResponse extends InspectorHeaders {
      method requestId (line 186) | String requestId();
      method url (line 188) | String url();
      method statusCode (line 190) | int statusCode();
      method reasonPhrase (line 191) | String reasonPhrase();
      method connectionReused (line 196) | boolean connectionReused();
      method connectionId (line 201) | int connectionId();
      method fromDiskCache (line 206) | boolean fromDiskCache();
      method getTiming (line 208) | @Nullable Network.ResourceTiming getTiming();
    type InspectorHeaders (line 211) | interface InspectorHeaders {
      method headerCount (line 212) | int headerCount();
      method headerName (line 213) | String headerName(int index);
      method headerValue (line 214) | String headerValue(int index);
      method firstHeaderValue (line 216) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporterImpl.java
  class NetworkEventReporterImpl (line 28) | public class NetworkEventReporterImpl implements NetworkEventReporter {
    method NetworkEventReporterImpl (line 34) | private NetworkEventReporterImpl() {
    method get (line 41) | public static synchronized NetworkEventReporter get() {
    method isEnabled (line 48) | @Override
    method getPeerManagerIfEnabled (line 54) | @Nullable
    method requestWillBeSent (line 63) | @Override
    method readBodyAsString (line 104) | @Nullable
    method responseHeadersReceived (line 123) | @Override
    method initAsyncPrettyPrinterForResponse (line 157) | @Nullable
    method determineResourceType (line 171) | private static Page.ResourceType determineResourceType(
    method createPrettyPrinterForResponse (line 185) | @Nullable
    method interpretResponseStream (line 203) | @Override
    method httpExchangeFailed (line 251) | @Override
    method responseReadFinished (line 256) | @Override
    method loadingFinished (line 261) | private void loadingFinished(String requestId) {
    method responseReadFailed (line 271) | @Override
    method loadingFailed (line 276) | private void loadingFailed(String requestId, String errorText) {
    method dataSent (line 288) | @Override
    method dataReceived (line 299) | @Override
    method getContentType (line 315) | @Nullable
    method formatHeadersAsJSON (line 322) | private static JSONObject formatHeadersAsJSON(InspectorHeaders headers) {
    method getResourceTypeHelper (line 341) | @Nonnull
    method DreamCatcherNow (line 349) | private static long DreamCatcherNow() {
    method now (line 353) | public static double now() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkPeerManager.java
  class NetworkPeerManager (line 11) | public class NetworkPeerManager extends ChromePeerManager {
    method getInstanceOrNull (line 18) | @Nullable
    method getOrCreateInstance (line 23) | public static synchronized NetworkPeerManager getOrCreateInstance(Cont...
    method NetworkPeerManager (line 32) | public NetworkPeerManager(
    method getResponseBodyFileManager (line 38) | public ResponseBodyFileManager getResponseBodyFileManager() {
    method getAsyncPrettyPrinterRegistry (line 42) | @Nullable
    method setPrettyPrinterInitializer (line 47) | public void setPrettyPrinterInitializer(AsyncPrettyPrinterInitializer ...
    method onFirstPeerRegistered (line 53) | @Override
    method onLastPeerUnregistered (line 63) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/PrettyPrinterDisplayType.java
  type PrettyPrinterDisplayType (line 6) | public enum PrettyPrinterDisplayType {
    method PrettyPrinterDisplayType (line 13) | private PrettyPrinterDisplayType(Page.ResourceType resourceType) {
    method getResourceType (line 21) | public Page.ResourceType getResourceType() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/RequestBodyHelper.java
  class RequestBodyHelper (line 20) | public class RequestBodyHelper {
    method RequestBodyHelper (line 27) | public RequestBodyHelper(NetworkEventReporter eventReporter, String re...
    method createBodySink (line 32) | public OutputStream createBodySink(@Nullable String contentEncoding) t...
    method getDisplayBody (line 49) | public byte[] getDisplayBody() {
    method hasBody (line 54) | public boolean hasBody() {
    method reportDataSent (line 58) | public void reportDataSent() {
    method throwIfNoBody (line 66) | private void throwIfNoBody() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResourceTypeHelper.java
  class ResourceTypeHelper (line 6) | public class ResourceTypeHelper {
    method ResourceTypeHelper (line 9) | public ResourceTypeHelper() {
    method determineResourceType (line 28) | public Page.ResourceType determineResourceType(String contentType) {
    method stripContentExtras (line 38) | public String stripContentExtras(String contentType) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseBodyData.java
  class ResponseBodyData (line 7) | public class ResponseBodyData {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseBodyFileManager.java
  class ResponseBodyFileManager (line 31) | public class ResponseBodyFileManager {
    method ResponseBodyFileManager (line 40) | public ResponseBodyFileManager(Context context) {
    method cleanupFiles (line 44) | public void cleanupFiles() {
    method readFile (line 55) | public ResponseBodyData readFile(String requestId) throws IOException {
    method prettyPrintContentWithTimeOut (line 80) | private String prettyPrintContentWithTimeOut(
    method openResponseBodyFile (line 105) | public OutputStream openResponseBodyFile(String requestId, boolean bas...
    method getFilename (line 116) | private static String getFilename(String requestId) {
    method associateAsyncPrettyPrinterWithId (line 129) | public void associateAsyncPrettyPrinterWithId(
    class AsyncPrettyPrintingCallable (line 138) | private class AsyncPrettyPrintingCallable implements Callable<String> {
      method AsyncPrettyPrintingCallable (line 142) | public AsyncPrettyPrintingCallable(
      method call (line 149) | @Override
      method prettyPrintContent (line 154) | private String prettyPrintContent(InputStream in, AsyncPrettyPrinter...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseHandler.java
  type ResponseHandler (line 9) | public interface ResponseHandler {
    method onRead (line 16) | void onRead(int numBytes);
    method onReadDecoded (line 27) | void onReadDecoded(int numBytes);
    method onEOF (line 33) | void onEOF();
    method onError (line 38) | void onError(IOException e);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseHandlingInputStream.java
  class ResponseHandlingInputStream (line 24) | public final class ResponseHandlingInputStream extends FilterInputStream {
    method ResponseHandlingInputStream (line 63) | public ResponseHandlingInputStream(
    method checkEOF (line 79) | private synchronized int checkEOF(int n) {
    method read (line 88) | @Override
    method read (line 102) | @Override
    method read (line 107) | @Override
    method skip (line 121) | @Override
    method getSkipBufferLocked (line 137) | @Nonnull
    method markSupported (line 146) | @Override
    method mark (line 152) | @Override
    method reset (line 157) | @Override
    method close (line 162) | @Override
    method closeOutputStreamQuietly (line 190) | private synchronized void closeOutputStreamQuietly() {
    method handleIOException (line 213) | private IOException handleIOException(IOException ex) {
    method reportDecodedSizeIfApplicable (line 218) | private void reportDecodedSizeIfApplicable() {
    method writeToOutputStream (line 232) | private synchronized void writeToOutputStream(int oneByte) {
    method writeToOutputStream (line 248) | private synchronized void writeToOutputStream(byte[] b, int offset, in...
    method handleIOExceptionWritingToStream (line 261) | private void handleIOExceptionWritingToStream(IOException e) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/AddressNameHelper.java
  class AddressNameHelper (line 6) | public class AddressNameHelper {
    method createCustomAddress (line 9) | public static String createCustomAddress(String suffix) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/CompositeInputStream.java
  class CompositeInputStream (line 11) | @NotThreadSafe
    method CompositeInputStream (line 16) | public CompositeInputStream(InputStream[] streams) {
    method available (line 24) | @Override
    method close (line 29) | @Override
    method closeAll (line 34) | private void closeAll(int mostImportantIndex) throws IOException {
    method mark (line 51) | @Override
    method markSupported (line 56) | @Override
    method reset (line 61) | @Override
    method read (line 66) | @Override
    method read (line 71) | @Override
    method read (line 82) | @Override
    method tryMoveToNextStream (line 93) | private boolean tryMoveToNextStream() {
    method skip (line 101) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/LazySocketHandler.java
  class LazySocketHandler (line 15) | public class LazySocketHandler implements SocketHandler {
    method LazySocketHandler (line 21) | public LazySocketHandler(SocketHandlerFactory socketHandlerFactory) {
    method onAccepted (line 25) | @Override
    method getSocketHandler (line 30) | @Nonnull

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/LeakyBufferedInputStream.java
  class LeakyBufferedInputStream (line 10) | @ThreadSafe
    method LeakyBufferedInputStream (line 15) | public LeakyBufferedInputStream(InputStream in, int bufSize) {
    method mark (line 19) | @Override
    method reset (line 26) | @Override
    method markSupported (line 33) | @Override
    method leakBufferAndStream (line 38) | public synchronized InputStream leakBufferAndStream() {
    method clearBufferLocked (line 49) | private byte[] clearBufferLocked() {
    method throwIfLeaked (line 57) | private void throwIfLeaked() {
    method throwIfMarked (line 63) | private void throwIfMarked() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/LocalSocketServer.java
  class LocalSocketServer (line 17) | public class LocalSocketServer {
    method LocalSocketServer (line 36) | public LocalSocketServer(
    method getName (line 45) | public String getName() {
    method run (line 58) | public void run() throws IOException {
    method reset (line 70) | public void reset() {
    method listenOnAddress (line 75) | private void listenOnAddress(String address) throws IOException {
    method stop (line 116) | public void stop() {
    method bindToSocket (line 137) | @Nonnull
    class WorkerThread (line 157) | private static class WorkerThread extends Thread {
      method WorkerThread (line 161) | public WorkerThread(LocalSocket socket, SocketHandler socketHandler) {
      method run (line 166) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/PeerAuthorizationException.java
  class PeerAuthorizationException (line 3) | public class PeerAuthorizationException extends Exception {
    method PeerAuthorizationException (line 4) | public PeerAuthorizationException(String message) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/ProtocolDetectingSocketHandler.java
  class ProtocolDetectingSocketHandler (line 23) | public class ProtocolDetectingSocketHandler extends SecureSocketHandler {
    method ProtocolDetectingSocketHandler (line 28) | public ProtocolDetectingSocketHandler(Context context) {
    method addHandler (line 32) | public void addHandler(MagicMatcher magicMatcher, SocketLikeHandler ha...
    method onSecured (line 38) | @Override
    type MagicMatcher (line 64) | public interface MagicMatcher {
      method matches (line 65) | boolean matches(InputStream in) throws IOException;
    class ExactMagicMatcher (line 68) | public static class ExactMagicMatcher implements MagicMatcher {
      method ExactMagicMatcher (line 71) | public ExactMagicMatcher(byte[] magic) {
      method matches (line 75) | @Override
    class AlwaysMatchMatcher (line 83) | public static class AlwaysMatchMatcher implements MagicMatcher {
      method matches (line 84) | @Override
    class HandlerInfo (line 90) | private static class HandlerInfo {
      method HandlerInfo (line 94) | private HandlerInfo(MagicMatcher magicMatcher, SocketLikeHandler han...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/SecureSocketHandler.java
  class SecureSocketHandler (line 14) | public abstract class SecureSocketHandler implements SocketHandler {
    method SecureSocketHandler (line 17) | public SecureSocketHandler(Context context) {
    method onAccepted (line 21) | @Override
    method onSecured (line 31) | protected abstract void onSecured(LocalSocket socket) throws IOException;
    method enforcePermission (line 33) | private static void enforcePermission(Context context, LocalSocket peer)

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/ServerManager.java
  class ServerManager (line 15) | public class ServerManager implements IServerManager {
    method ServerManager (line 22) | public ServerManager(LocalSocketServer server) {
    method start (line 26) | @Override
    method stop (line 36) | @Override
    method restart (line 45) | @Override
    method startServer (line 51) | private void startServer(final LocalSocketServer server) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketHandler.java
  type SocketHandler (line 10) | public interface SocketHandler {
    method onAccepted (line 16) | void onAccepted(LocalSocket socket) throws IOException;

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketHandlerFactory.java
  type SocketHandlerFactory (line 4) | public interface SocketHandlerFactory {
    method create (line 5) | SocketHandler create();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketLike.java
  class SocketLike (line 15) | public class SocketLike {
    method SocketLike (line 19) | public SocketLike(SocketLike socketLike, LeakyBufferedInputStream leak...
    method SocketLike (line 23) | public SocketLike(OutputStream output, LeakyBufferedInputStream leakyI...
    method SocketLike (line 28) | public SocketLike(LocalSocket socket, LeakyBufferedInputStream leakyIn...
    method getInput (line 39) | public InputStream getInput() throws IOException {
    method getOutput (line 43) | public OutputStream getOutput() throws IOException {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketLikeHandler.java
  type SocketLikeHandler (line 14) | public interface SocketLikeHandler {
    method onAccepted (line 16) | void onAccepted(SocketLike socket) throws IOException;

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/ExactPathMatcher.java
  class ExactPathMatcher (line 3) | public class ExactPathMatcher implements PathMatcher {
    method ExactPathMatcher (line 6) | public ExactPathMatcher(String path) {
    method toString (line 10) | @Override
    method match (line 17) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HandlerRegistry.java
  class HandlerRegistry (line 7) | public class HandlerRegistry {
    method register (line 11) | public synchronized void register(PathMatcher path, HttpHandler handle...
    method unregister (line 16) | public synchronized boolean unregister(PathMatcher path, HttpHandler h...
    method lookup (line 28) | @Nullable
    method toString (line 38) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpHandler.java
  type HttpHandler (line 8) | public interface HttpHandler {
    method handleRequest (line 9) | boolean handleRequest(

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpHeaders.java
  type HttpHeaders (line 3) | public interface HttpHeaders {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpStatus.java
  type HttpStatus (line 3) | public interface HttpStatus {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpBody.java
  class LightHttpBody (line 7) | public abstract class LightHttpBody {
    method create (line 10) | public static LightHttpBody create(String body, String contentType) {
    method create (line 19) | public static LightHttpBody create(final byte[] body, final String con...
    method toString (line 38) | @Override
    method contentType (line 43) | public abstract String contentType();
    method contentLength (line 45) | public abstract int contentLength();
    method writeTo (line 47) | public abstract void writeTo(OutputStream output) throws IOException;

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpMessage.java
  class LightHttpMessage (line 7) | public class LightHttpMessage {
    method addHeader (line 11) | public void addHeader(String name, String value) {
    method getFirstHeaderValue (line 16) | @Nullable
    method reset (line 26) | public void reset() {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpRequest.java
  class LightHttpRequest (line 5) | public class LightHttpRequest extends LightHttpMessage {
    method toString (line 10) | @Override
    method reset (line 19) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpResponse.java
  class LightHttpResponse (line 3) | public class LightHttpResponse extends LightHttpMessage {
    method toString (line 8) | @Override
    method prepare (line 17) | public void prepare() {
    method reset (line 24) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpServer.java
  class LightHttpServer (line 26) | public class LightHttpServer {
    method LightHttpServer (line 31) | public LightHttpServer(HandlerRegistry handlerRegistry) {
    method serve (line 35) | public void serve(SocketLike socket) throws IOException {
    method dispatchToHandler (line 64) | private boolean dispatchToHandler(
    method build404Body (line 97) | private String build404Body(String request) {
    method readRequestMessage (line 110) | @Nullable
    method readHeaders (line 137) | private static void readHeaders(
    method writeFullResponse (line 161) | private static void writeFullResponse(
    method writeResponseMessage (line 173) | public static void writeResponseMessage(LightHttpResponse response, Ht...
    class HttpMessageReader (line 191) | private static class HttpMessageReader {
      method HttpMessageReader (line 196) | public HttpMessageReader(BufferedInputStream in) {
      method readLine (line 200) | @Nullable
      class NewLineDetector (line 225) | private static class NewLineDetector {
        method accept (line 232) | public void accept(char c) {
        method state (line 258) | public int state() {
    class HttpMessageWriter (line 270) | public static class HttpMessageWriter {
      method HttpMessageWriter (line 274) | public HttpMessageWriter(BufferedOutputStream out) {
      method writeLine (line 278) | public void writeLine(String line) throws IOException {
      method writeLine (line 286) | public void writeLine() throws IOException {
      method flush (line 290) | public void flush() throws IOException {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/PathMatcher.java
  type PathMatcher (line 3) | public interface PathMatcher {
    method match (line 4) | boolean match(String path);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/server/http/RegexpPathMatcher.java
  class RegexpPathMatcher (line 5) | public class RegexpPathMatcher implements PathMatcher {
    method RegexpPathMatcher (line 8) | public RegexpPathMatcher(Pattern pattern) {
    method match (line 12) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/Accumulator.java
  type Accumulator (line 3) | public interface Accumulator<E> {
    method store (line 4) | void store(E object);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ArrayListAccumulator.java
  class ArrayListAccumulator (line 5) | public final class ArrayListAccumulator<E> extends ArrayList<E> implemen...
    method store (line 6) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ColorStringUtil.java
  class ColorStringUtil (line 6) | public class ColorStringUtil {
    method toHexString (line 7) | public static String toHexString(int c) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/DreamCatcherCrashHandler.java
  class DreamCatcherCrashHandler (line 9) | public class DreamCatcherCrashHandler implements Thread.UncaughtExceptio...
    method DreamCatcherCrashHandler (line 14) | private DreamCatcherCrashHandler() {
    method getInstance (line 18) | public static DreamCatcherCrashHandler getInstance() {
    method attach (line 22) | public void attach() {
    method uncaughtException (line 27) | @Override
    method dumpException (line 36) | private String dumpException(Throwable ex) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ExceptionUtil.java
  class ExceptionUtil (line 3) | public class ExceptionUtil {
    method propagateIfInstanceOf (line 4) | @SuppressWarnings("unchecked")
    method propagate (line 12) | public static RuntimeException propagate(Throwable t) {
    method sneakyThrow (line 18) | @SuppressWarnings("unchecked")

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/IServerManager.java
  type IServerManager (line 6) | public interface IServerManager {
    method start (line 7) | void start();
    method stop (line 8) | void stop();
    method restart (line 9) | void restart();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/KLog.java
  class KLog (line 30) | public class KLog {
    method setLoggable (line 46) | public static void setLoggable(boolean loggable) {
    method v (line 50) | public static void v() {
    method v (line 54) | public static void v(String msg) {
    method v (line 58) | public static void v(String tag, String msg) {
    method d (line 62) | public static void d() {
    method d (line 66) | public static void d(String msg) {
    method d (line 70) | public static void d(String tag, String msg) {
    method i (line 74) | public static void i() {
    method i (line 78) | public static void i(String msg) {
    method i (line 82) | public static void i(String tag, String msg) {
    method w (line 86) | public static void w() {
    method w (line 90) | public static void w(String msg) {
    method w (line 94) | public static void w(String tag, String msg) {
    method e (line 98) | public static void e() {
    method e (line 102) | public static void e(String msg) {
    method e (line 106) | public static void e(String tag, String msg) {
    method a (line 110) | public static void a() {
    method a (line 114) | public static void a(String msg) {
    method a (line 118) | public static void a(String tag, String msg) {
    method json (line 123) | public static void json(String jsonFormat) {
    method json (line 127) | public static void json(String tag, String jsonFormat) {
    method printLog (line 132) | private static void printLog(int type, String tagStr, String msg) {
    method printLine (line 223) | private static void printLine(String tag, boolean isTop) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/KLogImpl.java
  class KLogImpl (line 3) | public class KLogImpl implements LogInterface {
    method setLoggable (line 4) | @Override
    method v (line 9) | @Override
    method v (line 13) | @Override
    method v (line 18) | @Override
    method v (line 23) | @Override
    method d (line 28) | @Override
    method d (line 33) | @Override
    method d (line 38) | @Override
    method d (line 43) | @Override
    method i (line 48) | @Override
    method i (line 53) | @Override
    method i (line 58) | @Override
    method i (line 63) | @Override
    method w (line 68) | @Override
    method w (line 73) | @Override
    method w (line 78) | @Override
    method w (line 83) | @Override
    method e (line 88) | @Override
    method e (line 93) | @Override
    method e (line 98) | @Override
    method e (line 103) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/Keys.java
  type Keys (line 6) | public interface Keys {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ListUtil.java
  class ListUtil (line 8) | public final class ListUtil {
    method ListUtil (line 9) | private ListUtil() {
    method identityEquals (line 15) | public static <T> boolean identityEquals(List<? extends T> list1, List...
    method copyToImmutableList (line 34) | public static <T> List<T> copyToImmutableList(List<T> list) {
    method newImmutableList (line 59) | public static <T> List<T> newImmutableList(T item) {
    type ImmutableList (line 63) | private static interface ImmutableList<E> extends List<E>, RandomAccess {
    class ImmutableArrayList (line 66) | private static final class ImmutableArrayList<E>
      method ImmutableArrayList (line 70) | public ImmutableArrayList(Object[] array) {
      method get (line 74) | @Override
      method size (line 80) | @Override
    class OneItemImmutableList (line 86) | private static final class OneItemImmutableList<E>
      method OneItemImmutableList (line 90) | public OneItemImmutableList(E item) {
      method get (line 94) | @Override
      method size (line 103) | @Override
    class TwoItemImmutableList (line 109) | private static final class TwoItemImmutableList<E>
      method TwoItemImmutableList (line 114) | public TwoItemImmutableList(E item0, E item1) {
      method get (line 119) | @Override
      method size (line 131) | @Override
    class ThreeItemImmutableList (line 137) | private static final class ThreeItemImmutableList<E>
      method ThreeItemImmutableList (line 143) | public ThreeItemImmutableList(E item0, E item1, E item2) {
      method get (line 149) | @Override
      method size (line 163) | @Override
    class FourItemImmutableList (line 169) | private static final class FourItemImmutableList<E>
      method FourItemImmutableList (line 176) | public FourItemImmutableList(E item0, E item1, E item2, E item3) {
      method get (line 183) | @Override
      method size (line 199) | @Override
    class FiveItemImmutableList (line 205) | private static final class FiveItemImmutableList<E>
      method FiveItemImmutableList (line 213) | public FiveItemImmutableList(E item0, E item1, E item2, E item3, E i...
      method get (line 221) | @Override
      method size (line 239) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/LogFilter.java
  class LogFilter (line 9) | public class LogFilter {
    method filter (line 10) | public static JSONObject filter(JSONObject request, JSONObject respons...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/LogInterface.java
  type LogInterface (line 12) | public interface LogInterface {
    method setLoggable (line 14) | void setLoggable(boolean loggable);
    method v (line 16) | public void v(String msg);
    method v (line 17) | public void v(String tag, String msg);
    method v (line 18) | public void v(String tag, Throwable tr);
    method v (line 19) | public void v(String tag, String msg, Throwable tr);
    method d (line 21) | public void d(String msg);
    method d (line 22) | public void d(String tag, String msg);
    method d (line 23) | public void d(String tag, Throwable tr);
    method d (line 24) | public void d(String tag, String msg, Throwable tr);
    method i (line 26) | public void i(String msg);
    method i (line 27) | public void i(String tag, String msg);
    method i (line 28) | public void i(String tag, Throwable tr);
    method i (line 29) | public void i(String tag, String msg, Throwable tr);
    method w (line 31) | public void w(String msg);
    method w (line 32) | public void w(String tag, String msg);
    method w (line 33) | public void w(String tag, Throwable tr);
    method w (line 34) | public void w(String tag, String msg, Throwable tr);
    method e (line 36) | public void e(String msg);
    method e (line 37) | public void e(String tag, String msg);
    method e (line 38) | public void e(String tag, Throwable tr);
    method e (line 39) | public void e(String tag, String msg, Throwable tr);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/LogUtil.java
  class LogUtil (line 16) | public class LogUtil {
    method setLoggable (line 31) | public static void setLoggable(boolean loggable) {
    method filter (line 36) | public static String filter(@NonNull LightHttpRequest request, @NonNul...
    method filter (line 48) | public static String filter(String title, @NonNull LightHttpResponse r...
    method filter (line 57) | public static String filter(String title, @NonNull LightHttpRequest re...
    method e (line 65) | public static void e(String format, Object... args) {
    method e (line 69) | public static void e(Throwable t, String format, Object... args) {
    method e (line 74) | public static void e(Throwable t, String message) {
    method w (line 80) | public static void w(String format, Object... args) {
    method w (line 84) | public static void w(Throwable t, String format, Object... args) {
    method w (line 89) | public static void w(Throwable t, String message) {
    method i (line 95) | public static void i(String format, Object... args) {
    method i (line 99) | public static void i(Throwable t, String format, Object... args) {
    method i (line 103) | public static void i(Throwable t, String message) {
    method d (line 109) | public static void d(String format, Object... args) {
    method d (line 113) | public static void d(Throwable t, String format, Object... args) {
    method d (line 117) | public static void d(Throwable t, String message) {
    method v (line 123) | public static void v(String format, Object... args) {
    method v (line 127) | public static void v(Throwable t, String format, Object... args) {
    method v (line 131) | public static void v(Throwable t, String message) {
    method format (line 137) | private static String format(String format, Object... args) {
    method isLoggable (line 141) | public static boolean isLoggable(int priority) {
    method isLoggable (line 151) | public static boolean isLoggable(String tag, int priority) {
    method v (line 155) | public static void v(String msg) {
    method v (line 159) | public static void v(String tag, String msg) {
    method v (line 163) | public static void v(String tag, Throwable tr) {
    method v (line 167) | public static void v(String tag, String msg, Throwable tr) {
    method d (line 172) | public static void d(String msg) {
    method d (line 176) | public static void d(String tag, String msg) {
    method d (line 180) | public static void d(String tag, Throwable tr) {
    method d (line 184) | public static void d(String tag, String msg, Throwable tr) {
    method i (line 189) | public static void i(String msg) {
    method i (line 193) | public static void i(String tag, String msg) {
    method i (line 197) | public static void i(String tag, Throwable tr) {
    method i (line 201) | public static void i(String tag, String msg, Throwable tr) {
    method w (line 206) | public static void w(String msg) {
    method w (line 210) | public static void w(String tag, String msg) {
    method w (line 214) | public static void w(String tag, Throwable tr) {
    method w (line 218) | public static void w(String tag, String msg, Throwable tr) {
    method e (line 223) | public static void e(String msg) {
    method e (line 227) | public static void e(String tag, String msg) {
    method e (line 231) | public static void e(String tag, Throwable tr) {
    method e (line 235) | public static void e(String tag, String msg, Throwable tr) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/Predicate.java
  type Predicate (line 3) | public interface Predicate<T> {
    method apply (line 4) | boolean apply(T t);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ProcessUtil.java
  class ProcessUtil (line 8) | public class ProcessUtil {
    method getProcessName (line 25) | @Nullable
    method readProcessName (line 37) | private static String readProcessName() throws IOException {
    method indexOf (line 53) | private static int indexOf(byte[] haystack, int offset, int length, by...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ReflectionUtil.java
  class ReflectionUtil (line 15) | public final class ReflectionUtil {
    method ReflectionUtil (line 16) | private ReflectionUtil() {
    method invokeMethod (line 19) | public static Object invokeMethod(Object receiver, String name) {
    method tryGetClassForName (line 34) | @Nullable
    method tryGetDeclaredField (line 43) | @Nullable
    method getFieldValue (line 58) | @Nullable
    method getAllPairMethodsByView (line 67) | public static Set<String> getAllPairMethodsByView(View target) {
    method getAllPairMethods (line 71) | public static Set<String> getAllPairMethods(Class<? extends View> claz...
    method getAllPairDeclaredMethods (line 99) | public static Set<String> getAllPairDeclaredMethods(Class<? extends Vi...
    method main (line 125) | public static void main(String args[]) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/SocketServerManager.java
  class SocketServerManager (line 10) | public class SocketServerManager {
    type Type (line 16) | public enum Type {
      method Type (line 22) | Type(String key) {
      method getKey (line 26) | public String getKey() {
    method register (line 31) | public static void register(String key, IServerManager manager) {
    method startServer (line 35) | public static void startServer(Type type) {
    method stopServer (line 45) | public static void stopServer() {
    method doStart (line 51) | private static void doStart(IServerManager manager) {
    method getManager (line 63) | public static IServerManager getManager(String key) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/StringUtil.java
  class StringUtil (line 3) | public final class StringUtil {
    method StringUtil (line 4) | private StringUtil() {
    method removePrefix (line 7) | @SuppressWarnings("StringEquality")
    method removePrefix (line 16) | public static String removePrefix(String string, String prefix) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/ThreadBound.java
  type ThreadBound (line 9) | public interface ThreadBound {
    method checkThreadAccess (line 14) | boolean checkThreadAccess();
    method verifyThreadAccess (line 20) | void verifyThreadAccess();
    method postAndWait (line 32) | <V> V postAndWait(UncheckedCallable<V> c);
    method postAndWait (line 41) | void postAndWait(Runnable r);
    method postDelayed (line 50) | void postDelayed(Runnable r, long delayMillis);
    method removeCallbacks (line 56) | void removeCallbacks(Runnable r);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/UncheckedCallable.java
  type UncheckedCallable (line 12) | public interface UncheckedCallable<V> {
    method call (line 13) | V call();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/Utf8Charset.java
  class Utf8Charset (line 6) | public class Utf8Charset {
    method encodeUTF8 (line 11) | public static byte[] encodeUTF8(String str) {
    method decodeUTF8 (line 19) | public static String decodeUTF8(byte[] bytes) {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/util/Util.java
  class Util (line 14) | public class Util {
    method throwIfNull (line 15) | public static <T> T throwIfNull(T item) {
    method throwIfNull (line 22) | public static <T1, T2> void throwIfNull(T1 item1, T2 item2) {
    method throwIfNull (line 27) | public static <T1, T2, T3> void throwIfNull(T1 item1, T2 item2, T3 ite...
    method throwIfNotNull (line 33) | public static void throwIfNotNull(Object item) {
    method throwIf (line 39) | public static void throwIf(boolean condition) {
    method throwIfNot (line 45) | public static void throwIfNot(boolean condition) {
    method throwIfNot (line 51) | public static void throwIfNot(boolean condition, String format, Object...
    method copy (line 58) | public static void copy(InputStream input, OutputStream output, byte[]...
    method close (line 66) | public static void close(Closeable closeable, boolean hideException) t...
    method sleepUninterruptibly (line 80) | public static void sleepUninterruptibly(long millis) {
    method joinUninterruptibly (line 94) | public static void joinUninterruptibly(Thread t) {
    method awaitUninterruptibly (line 105) | public static void awaitUninterruptibly(CountDownLatch latch) {
    method getUninterruptibly (line 116) | public static <T> T getUninterruptibly(
    method getUninterruptibly (line 132) | public static <T> T getUninterruptibly(Future<T> future)
    method readAsUTF8 (line 143) | public static String readAsUTF8(InputStream in) throws IOException {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/CloseCodes.java
  type CloseCodes (line 6) | public interface CloseCodes {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/Frame.java
  class Frame (line 12) | class Frame {
    method readFrom (line 29) | public void readFrom(BufferedInputStream input) throws IOException {
    method writeTo (line 40) | public void writeTo(BufferedOutputStream output) throws IOException {
    method decodeFirstByte (line 54) | private void decodeFirstByte(byte b) {
    method encodeFirstByte (line 62) | private byte encodeFirstByte() {
    method decodeLength (line 80) | private long decodeLength(byte firstLenByte, InputStream in) throws IO...
    method encodeLength (line 97) | private static byte[] encodeLength(long len) {
    method decodeMaskingKey (line 121) | private static byte[] decodeMaskingKey(InputStream in) throws IOExcept...
    method readBytesOrThrow (line 127) | private static void readBytesOrThrow(InputStream in, byte[] buf, int o...
    method readByteOrThrow (line 139) | private static byte readByteOrThrow(InputStream in) throws IOException {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/FrameHelper.java
  class FrameHelper (line 6) | class FrameHelper {
    method createTextFrame (line 7) | public static Frame createTextFrame(String payload) {
    method createBinaryFrame (line 11) | public static Frame createBinaryFrame(byte[] payload) {
    method createCloseFrame (line 15) | public static Frame createCloseFrame(int closeCode, String reasonPhras...
    method createPingFrame (line 31) | public static Frame createPingFrame(byte[] payload, int payloadLen) {
    method createPongFrame (line 35) | public static Frame createPongFrame(byte[] payload, int payloadLen) {
    method createSimpleFrame (line 39) | private static Frame createSimpleFrame(byte opcode, byte[] payload) {
    method createSimpleFrame (line 43) | private static Frame createSimpleFrame(byte opCode, byte[] payload, in...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/MaskingHelper.java
  class MaskingHelper (line 3) | class MaskingHelper {
    method unmask (line 4) | public static void unmask(byte[] key, byte[] data, int offset, int cou...

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/ReadCallback.java
  type ReadCallback (line 3) | interface ReadCallback {
    method onCompleteFrame (line 4) | void onCompleteFrame(byte opcode, byte[] payload, int payloadLen);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/ReadHandler.java
  class ReadHandler (line 8) | class ReadHandler {
    method ReadHandler (line 17) | public ReadHandler(InputStream bufferedInput, SimpleEndpoint endpoint) {
    method readLoop (line 28) | public void readLoop(ReadCallback readCallback) throws IOException {

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/SimpleEndpoint.java
  type SimpleEndpoint (line 6) | public interface SimpleEndpoint {
    method onOpen (line 13) | void onOpen(SimpleSession session);
    method onMessage (line 22) | void onMessage(SimpleSession session, String message);
    method onMessage (line 32) | void onMessage(SimpleSession session, byte[] message, int messageLen);
    method onClose (line 42) | void onClose(SimpleSession session, int closeReasonCode, String closeR...
    method onError (line 52) | void onError(SimpleSession session, Throwable t);

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/SimpleSession.java
  type SimpleSession (line 6) | public interface SimpleSession {
    method sendText (line 7) | void sendText(String payload);
    method sendBinary (line 8) | void sendBinary(byte[] payload);
    method close (line 16) | void close(int closeReason, String reasonPhrase);
    method isOpen (line 18) | boolean isOpen();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WebSocketHandler.java
  class WebSocketHandler (line 38) | public class WebSocketHandler implements HttpHandler {
    method WebSocketHandler (line 59) | public WebSocketHandler(SimpleEndpoint endpoint) {
    method handleRequest (line 63) | @Override
    method isSupportableUpgradeRequest (line 85) | private static boolean isSupportableUpgradeRequest(LightHttpRequest re...
    method doUpgrade (line 92) | private void doUpgrade(
    method generateServerKey (line 121) | private static String generateServerKey(String clientKey) {
    method getFirstHeaderValue (line 132) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WebSocketSession.java
  class WebSocketSession (line 14) | class WebSocketSession implements SimpleSession {
    method WebSocketSession (line 22) | public WebSocketSession(
    method handle (line 31) | public void handle() throws IOException {
    method sendText (line 47) | @Override
    method sendBinary (line 52) | @Override
    method close (line 57) | @Override
    method sendClose (line 63) | private void sendClose(int closeReason, String reasonPhrase) {
    method markSentClose (line 68) | void markSentClose() {
    method markAndSignalOpen (line 72) | void markAndSignalOpen() {
    method markAndSignalClosed (line 78) | void markAndSignalClosed(int closeReason, String reasonPhrase) {
    method isOpen (line 84) | @Override
    method doWrite (line 89) | private void doWrite(Frame frame) {
    method signalErrorIfNotOpen (line 101) | private boolean signalErrorIfNotOpen() {
    method signalError (line 109) | private void signalError(IOException e) {
    method onCompleteFrame (line 114) | @Override
    method handleClose (line 138) | private void handleClose(byte[] payload, int payloadLen) {
    method handlePing (line 158) | private void handlePing(byte[] payload, int payloadLen) {
    method handlePong (line 162) | private void handlePong(byte[] payload, int payloadLen) {
    method handleTextFrame (line 166) | private void handleTextFrame(byte[] payload, int payloadLen) {
    method handleBinaryFrame (line 170) | private void handleBinaryFrame(byte[] payload, int payloadLen) {
    method onFailure (line 176) | @Override
    method onSuccess (line 181) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WriteCallback.java
  type WriteCallback (line 5) | interface WriteCallback {
    method onFailure (line 6) | void onFailure(IOException e);
    method onSuccess (line 7) | void onSuccess();

FILE: app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WriteHandler.java
  class WriteHandler (line 9) | @ThreadSafe
    method WriteHandler (line 13) | public WriteHandler(OutputStream rawSocketOutput) {
    method write (line 17) | public synchronized void write(Frame frame, WriteCallback callback) {

FILE: app/src/main/java/me/moxun/dreamcatcher/event/CaptureEvent.java
  class CaptureEvent (line 9) | public class CaptureEvent {
    method CaptureEvent (line 13) | public CaptureEvent(String cause) {
    method send (line 17) | public static void send(String msg) {

FILE: app/src/main/java/me/moxun/dreamcatcher/event/OperateEvent.java
  class OperateEvent (line 7) | public class OperateEvent {
    method OperateEvent (line 16) | public OperateEvent(int target, boolean active, boolean error) {
    method OperateEvent (line 20) | public OperateEvent(int target, boolean active) {
    method OperateEvent (line 24) | public OperateEvent(int target, boolean active, boolean error, String ...
    method toString (line 31) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/misc/X509ExtendedTrustManager.java
  class X509ExtendedTrustManager (line 36) | public abstract class X509ExtendedTrustManager implements X509TrustManag...
    method checkClientTrusted (line 54) | public abstract void checkClientTrusted(X509Certificate[] chain, Strin...
    method checkServerTrusted (line 74) | public abstract void checkServerTrusted(X509Certificate[] chain, Strin...
    method checkClientTrusted (line 94) | public abstract void checkClientTrusted(X509Certificate[] chain, Strin...
    method checkServerTrusted (line 114) | public abstract void checkServerTrusted(X509Certificate[] chain, Strin...

FILE: app/src/main/java/me/moxun/dreamcatcher/service/ConnectorService.java
  class ConnectorService (line 14) | public class ConnectorService extends Service {
    method onBind (line 15) | @Nullable
    method onCreate (line 21) | @Override
    method onDestroy (line 32) | @Override

FILE: app/src/main/java/me/moxun/dreamcatcher/service/ProxyService.java
  class ProxyService (line 25) | public class ProxyService extends Service {
    method onDestroy (line 28) | @Override
    method onCreate (line 37) | @Override
    method onBind (line 66) | @Nullable
    method postEvent (line 72) | private void postEvent(String s) {

FILE: app/src/main/java/me/moxun/dreamcatcher/wrapper/DCHeader.java
  class DCHeader (line 15) | public class DCHeader implements NetworkEventReporter.InspectorHeaders {
    method addHeader (line 20) | public void addHeader(String key, String value) {
    method getContentType (line 28) | public String getContentType() {
    method headerCount (line 32) | @Override
    method headerName (line 37) | @Override
    method headerValue (line 42) | @Override
    method firstHeaderValue (line 47) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/wrapper/DCRequest.java
  class DCRequest (line 18) | public class DCRequest extends DCHeader implements NetworkEventReporter....
    method attachBodyHelper (line 23) | public void attachBodyHelper(RequestBodyHelper helper) {
    method DCRequest (line 27) | public DCRequest(HarEntry entry) {
    method getRequest (line 31) | public HarRequest getRequest() {
    method id (line 35) | @Override
    method friendlyName (line 40) | @Override
    method friendlyNameExtra (line 45) | @Nullable
    method url (line 51) | @Override
    method method (line 56) | @Override
    method body (line 61) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/wrapper/DCResponse.java
  class DCResponse (line 16) | public class DCResponse extends DCHeader implements NetworkEventReporter...
    method notifyResponse (line 18) | void notifyResponse() {
    method DCResponse (line 24) | public DCResponse(HarEntry entry) {
    method getResponse (line 28) | public HarResponse getResponse() {
    method requestId (line 32) | @Override
    method url (line 37) | @Override
    method statusCode (line 42) | @Override
    method reasonPhrase (line 47) | @Override
    method connectionReused (line 52) | @Override
    method connectionId (line 57) | @Override
    method fromDiskCache (line 62) | @Override
    method getTiming (line 67) | @Nullable

FILE: app/src/main/java/me/moxun/dreamcatcher/wrapper/ProxyManager.java
  class ProxyManager (line 23) | public class ProxyManager {
    method ProxyManager (line 34) | private ProxyManager() {
    method getRequestBodyHelper (line 40) | public RequestBodyHelper getRequestBodyHelper() {
    method newInstance (line 44) | public static ProxyManager newInstance() {
    method requestWillBeSent (line 49) | public void requestWillBeSent(DCRequest request) {
    method responseHeadersReceived (line 54) | public void responseHeadersReceived(DCResponse response) {
    method httpExchangeFailed (line 59) | public void httpExchangeFailed(String errorText) {
    method interpretResponseStream (line 63) | public void interpretResponseStream(DCResponse response) {
    method read (line 78) | private byte[] read(InputStream in) throws IOException {
    method responseReadFailed (line 91) | public void responseReadFailed(String errorText) {
    method responseReadFinished (line 95) | public void responseReadFinished() {
    method dataSent (line 99) | public void dataSent(DCRequest request) {
    method dataReceived (line 104) | public void dataReceived(int bodySize) {
    method getDCRequestId (line 108) | public String getDCRequestId() {

FILE: app/src/main/java/net/lightbody/bmp/BrowserMobProxy.java
  type BrowserMobProxy (line 22) | public interface BrowserMobProxy {
    method start (line 28) | void start();
    method start (line 36) | void start(int port);
    method start (line 46) | void start(int port, InetAddress bindAddress);
    method start (line 57) | void start(int port, InetAddress clientBindAddress, InetAddress server...
    method isStarted (line 62) | boolean isStarted();
    method stop (line 70) | void stop();
    method abort (line 79) | void abort();
    method getClientBindAddress (line 86) | InetAddress getClientBindAddress();
    method getPort (line 93) | int getPort();
    method getServerBindAddress (line 101) | InetAddress getServerBindAddress();
    method getHar (line 108) | Har getHar();
    method newHar (line 115) | Har newHar();
    method newHar (line 123) | Har newHar(String initialPageRef);
    method newHar (line 132) | Har newHar(String initialPageRef, String initialPageTitle);
    method setHarCaptureTypes (line 145) | void setHarCaptureTypes(Set<CaptureType> captureTypes);
    method setHarCaptureTypes (line 158) | void setHarCaptureTypes(CaptureType... captureTypes);
    method getHarCaptureTypes (line 163) | EnumSet<CaptureType> getHarCaptureTypes();
    method enableHarCaptureTypes (line 170) | void enableHarCaptureTypes(Set<CaptureType> captureTypes);
    method enableHarCaptureTypes (line 177) | void enableHarCaptureTypes(CaptureType... captureTypes);
    method disableHarCaptureTypes (line 184) | void disableHarCaptureTypes(Set<CaptureType> captureTypes);
    method disableHarCaptureTypes (line 191) | void disableHarCaptureTypes(CaptureType... captureTypes);
    method newPage (line 202) | Har newPage();
    method newPage (line 212) | Har newPage(String pageRef);
    method newPage (line 223) | Har newPage(String pageRef, String pageTitle);
    method endHar (line 231) | Har endHar();
    method setReadBandwidthLimit (line 238) | void setReadBandwidthLimit(long bytesPerSecond);
    method getReadBandwidthLimit (line 243) | long getReadBandwidthLimit();
    method setWriteBandwidthLimit (line 250) | void setWriteBandwidthLimit(long bytesPerSecond);
    method getWriteBandwidthLimit (line 255) | long getWriteBandwidthLimit();
    method setLatency (line 264) | void setLatency(long latency, TimeUnit timeUnit);
    method setConnectTimeout (line 273) | void setConnectTimeout(int connectionTimeout, TimeUnit timeUnit);
    method setIdleConnectionTimeout (line 284) | void setIdleConnectionTimeout(int idleConnectionTimeout, TimeUnit time...
    method setRequestTimeout (line 295) | void setRequestTimeout(int requestTimeout, TimeUnit timeUnit);
    method autoAuthorization (line 306) | void autoAuthorization(String domain, String username, String password...
    method stopAutoAuthorization (line 313) | void stopAutoAuthorization(String domain);
    method chainedProxyAuthorization (line 323) | void chainedProxyAuthorization(String username, String password, AuthT...
    method rewriteUrl (line 359) | void rewriteUrl(String urlPattern, String replacementExpression);
    method rewriteUrls (line 369) | void rewriteUrls(Map<String, String> rewriteRules);
    method getRewriteRules (line 377) | Map<String, String> getRewriteRules();
    method removeRewriteRule (line 384) | void removeRewriteRule(String urlPattern);
    method clearRewriteRules (line 389) | void clearRewriteRules();
    method blacklistRequests (line 403) | void blacklistRequests(String urlPattern, int statusCode);
    method blacklistRequests (line 417) | void blacklistRequests(String urlPattern, int statusCode, String httpM...
    method setBlacklist (line 425) | void setBlacklist(Collection<BlacklistEntry> blacklist);
    method getBlacklist (line 433) | Collection<BlacklistEntry> getBlacklist();
    method clearBlacklist (line 438) | void clearBlacklist();
    method whitelistRequests (line 452) | void whitelistRequests(Collection<String> urlPatterns, int statusCode);
    method addWhitelistPattern (line 460) | void addWhitelistPattern(String urlPattern);
    method enableEmptyWhitelist (line 467) | void enableEmptyWhitelist(int statusCode);
    method disableWhitelist (line 472) | void disableWhitelist();
    method getWhitelistUrls (line 480) | Collection<String> getWhitelistUrls();
    method getWhitelistStatusCode (line 487) | int getWhitelistStatusCode();
    method isWhitelistEnabled (line 492) | boolean isWhitelistEnabled();
    method addHeaders (line 499) | void addHeaders(Map<String, String> headers);
    method addHeader (line 507) | void addHeader(String name, String value);
    method removeHeader (line 514) | void removeHeader(String name);
    method removeAllHeaders (line 519) | void removeAllHeaders();
    method getAllHeaders (line 526) | Map<String, String> getAllHeaders();
    method setHostNameResolver (line 534) | void setHostNameResolver(AdvancedHostResolver resolver);
    method getHostNameResolver (line 541) | AdvancedHostResolver getHostNameResolver();
    method waitForQuiescence (line 552) | boolean waitForQuiescence(long quietPeriod, long timeout, TimeUnit tim...
    method setChainedProxy (line 559) | void setChainedProxy(InetSocketAddress chainedProxyAddress);
    method getChainedProxy (line 566) | InetSocketAddress getChainedProxy();
    method addFirstHttpFilterFactory (line 578) | void addFirstHttpFilterFactory(HttpFiltersSource filterFactory);
    method addLastHttpFilterFactory (line 590) | void addLastHttpFilterFactory(HttpFiltersSource filterFactory);
    method addResponseFilter (line 597) | void addResponseFilter(ResponseFilter filter);
    method addRequestFilter (line 604) | void addRequestFilter(RequestFilter filter);
    method setMitmDisabled (line 613) | void setMitmDisabled(boolean mitmDisabled);
    method setMitmManager (line 623) | void setMitmManager(MitmManager mitmManager);
    method setTrustAllServers (line 632) | void setTrustAllServers(boolean trustAllServers);
    method setTrustSource (line 640) | void setTrustSource(TrustSource trustSource);

FILE: app/src/main/java/net/lightbody/bmp/BrowserMobProxyServer.java
  class BrowserMobProxyServer (line 89) | public class BrowserMobProxyServer implements BrowserMobProxy {
    method BrowserMobProxyServer (line 259) | public BrowserMobProxyServer() {
    method start (line 262) | @Override
    method isStarted (line 366) | @Override
    method start (line 371) | @Override
    method start (line 376) | @Override
    method start (line 382) | @Override
    method stop (line 387) | @Override
    method abort (line 392) | @Override
    method stop (line 397) | protected void stop(boolean graceful) {
    method getClientBindAddress (line 417) | @Override
    method getPort (line 426) | @Override
    method getServerBindAddress (line 435) | @Override
    method getHar (line 440) | @Override
    method newHar (line 445) | @Override
    method newHar (line 450) | @Override
    method newHar (line 455) | @Override
    method setHarCaptureTypes (line 470) | @Override
    method setHarCaptureTypes (line 479) | @Override
    method getHarCaptureTypes (line 488) | @Override
    method enableHarCaptureTypes (line 493) | @Override
    method enableHarCaptureTypes (line 498) | @Override
    method disableHarCaptureTypes (line 507) | @Override
    method disableHarCaptureTypes (line 513) | @Override
    method newPage (line 522) | @Override
    method newPage (line 527) | @Override
    method newPage (line 532) | @Override
    method endHar (line 566) | @Override
    method setReadBandwidthLimit (line 578) | @Override
    method getReadBandwidthLimit (line 587) | @Override
    method setWriteBandwidthLimit (line 592) | @Override
    method getWriteBandwidthLimit (line 601) | @Override
    method endPage (line 606) | public void endPage() {
    method addHeaders (line 621) | @Override
    method setLatency (line 629) | @Override
    method autoAuthorization (line 634) | @Override
    method stopAutoAuthorization (line 649) | @Override
    method chainedProxyAuthorization (line 654) | @Override
    method setConnectTimeout (line 666) | @Override
    method setIdleConnectionTimeout (line 679) | @Override
    method setRequestTimeout (line 693) | @Override
    method rewriteUrl (line 702) | @Override
    method rewriteUrls (line 707) | @Override
    method clearRewriteRules (line 718) | @Override
    method blacklistRequests (line 723) | @Override
    method blacklistRequests (line 728) | @Override
    method setBlacklist (line 733) | @Override
    method getBlacklist (line 738) | @Override
    method isWhitelistEnabled (line 743) | @Override
    method getWhitelistUrls (line 748) | @Override
    method getWhitelistStatusCode (line 758) | @Override
    method clearBlacklist (line 763) | @Override
    method whitelistRequests (line 768) | @Override
    method addWhitelistPattern (line 773) | @Override
    method whitelistRequests (line 809) | public void whitelistRequests(String[] patterns, int responseCode) {
    method enableEmptyWhitelist (line 817) | @Override
    method disableWhitelist (line 822) | @Override
    method addHeader (line 827) | @Override
    method removeHeader (line 832) | @Override
    method removeAllHeaders (line 837) | @Override
    method getAllHeaders (line 842) | @Override
    method setHostNameResolver (line 847) | @Override
    method getHostNameResolver (line 852) | @Override
    method waitForQuiescence (line 857) | @Override
    method setChainedProxy (line 870) | @Override
    method getChainedProxy (line 875) | @Override
    method setChainedProxyManager (line 886) | public void setChainedProxyManager(ChainedProxyManager chainedProxyMan...
    method setThreadPoolConfiguration (line 899) | public void setThreadPoolConfiguration(ThreadPoolConfiguration threadP...
    method addFirstHttpFilterFactory (line 907) | @Override
    method addLastHttpFilterFactory (line 912) | @Override
    method addResponseFilter (line 922) | @Override
    method addRequestFilter (line 932) | @Override
    method getRewriteRules (line 937) | @Override
    method removeRewriteRule (line 947) | @Override
    method isStopped (line 958) | public boolean isStopped() {
    method getCurrentHarPage (line 962) | public HarPage getCurrentHarPage() {
    method addHttpFilterFactory (line 966) | public void addHttpFilterFactory(HttpFiltersSource filterFactory) {
    method getFilterFactories (line 970) | public List<HttpFiltersSource> getFilterFactories() {
    method setMitmDisabled (line 974) | @Override
    method setMitmManager (line 983) | @Override
    method setTrustAllServers (line 988) | @Override
    method setTrustSource (line 1003) | @Override
    method isMitmDisabled (line 1012) | public boolean isMitmDisabled() {
    method setUseEcc (line 1016) | public void setUseEcc(boolean useEcc) {
    method addBrowserMobFilters (line 1023) | protected void addBrowserMobFilters() {
    method getMaximumRequestBufferSize (line 1103) | private int getMaximumRequestBufferSize() {
    method getMaximumResponseBufferSize (line 1115) | private int getMaximumResponseBufferSize() {
    method addHarCaptureFilter (line 1131) | protected void addHarCaptureFilter() {

FILE: app/src/main/java/net/lightbody/bmp/client/ClientUtil.java
  class ClientUtil (line 19) | public class ClientUtil {
    method createNativeCacheManipulatingResolver (line 26) | public static AdvancedHostResolver createNativeCacheManipulatingResolv...
    method createNativeResolver (line 36) | public static AdvancedHostResolver createNativeResolver() {
    method createDnsJavaResolver (line 46) | public static AdvancedHostResolver createDnsJavaResolver() {
    method createDnsJavaWithNativeFallbackResolver (line 57) | public static AdvancedHostResolver createDnsJavaWithNativeFallbackReso...
    method getConnectableAddress (line 110) | public static InetAddress getConnectableAddress() {

FILE: app/src/main/java/net/lightbody/bmp/core/har/Har.java
  class Har (line 10) | public class Har {
    method Har (line 16) | public Har() {
    method Har (line 19) | public Har(HarLog log) {
    method getLog (line 23) | public HarLog getLog() {
    method setLog (line 27) | public void setLog(HarLog log) {
    method writeTo (line 31) | public void writeTo(Writer writer) throws IOException {
    method writeTo (line 35) | public void writeTo(OutputStream os) throws IOException {
    method writeTo (line 39) | public void writeTo(File file) throws IOException {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarCache.java
  class HarCache (line 5) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getBeforeRequest (line 10) | public HarCacheStatus getBeforeRequest() {
    method setBeforeRequest (line 14) | public void setBeforeRequest(HarCacheStatus beforeRequest) {
    method getAfterRequest (line 18) | public HarCacheStatus getAfterRequest() {
    method setAfterRequest (line 22) | public void setAfterRequest(HarCacheStatus afterRequest) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarCacheStatus.java
  class HarCacheStatus (line 10) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getExpires (line 18) | @JsonSerialize(using = ISO8601DateFormatter.class)
    method setExpires (line 23) | public void setExpires(Date expires) {
    method getLastAccess (line 27) | @JsonSerialize(using = ISO8601DateFormatter.class)
    method setLastAccess (line 32) | public void setLastAccess(Date lastAccess) {
    method geteTag (line 36) | public String geteTag() {
    method seteTag (line 40) | public void seteTag(String eTag) {
    method getHitCount (line 44) | public int getHitCount() {
    method setHitCount (line 48) | public void setHitCount(int hitCount) {
    method getComment (line 52) | public String getComment() {
    method setComment (line 56) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarContent.java
  class HarContent (line 5) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getBinaryContent (line 19) | public byte[] getBinaryContent() {
    method setBinaryContent (line 23) | public void setBinaryContent(byte[] binaryContent) {
    method getSize (line 27) | public long getSize() {
    method setSize (line 31) | public void setSize(long size) {
    method getCompression (line 35) | public Long getCompression() {
    method setCompression (line 39) | public void setCompression(Long compression) {
    method getMimeType (line 43) | public String getMimeType() {
    method setMimeType (line 47) | public void setMimeType(String mimeType) {
    method getText (line 51) | public String getText() {
    method setText (line 55) | public void setText(String text) {
    method getEncoding (line 59) | public String getEncoding() {
    method setEncoding (line 63) | public void setEncoding(String encoding) {
    method getComment (line 67) | public String getComment() {
    method setComment (line 71) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarCookie.java
  class HarCookie (line 11) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getName (line 22) | public String getName() {
    method setName (line 26) | public void setName(String name) {
    method getValue (line 30) | public String getValue() {
    method getDecodeValue (line 34) | public String getDecodeValue() {
    method setValue (line 42) | public void setValue(String value) {
    method getPath (line 46) | public String getPath() {
    method setPath (line 50) | public void setPath(String path) {
    method getDomain (line 54) | public String getDomain() {
    method setDomain (line 58) | public void setDomain(String domain) {
    method getExpires (line 62) | @JsonSerialize(using = ISO8601WithTDZDateFormatter.class)
    method setExpires (line 67) | public void setExpires(Date expires) {
    method getHttpOnly (line 71) | public Boolean getHttpOnly() {
    method setHttpOnly (line 75) | public void setHttpOnly(Boolean httpOnly) {
    method getSecure (line 79) | public Boolean getSecure() {
    method setSecure (line 83) | public void setSecure(Boolean secure) {
    method getComment (line 87) | public String getComment() {
    method setComment (line 91) | public void setComment(String comment) {
    method toString (line 95) | @Override

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarEntry.java
  class HarEntry (line 14) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarEntry (line 30) | public HarEntry(String pageref) {
    method getRequestTime (line 34) | public double getRequestTime() {
    method getTotalTime (line 38) | public double getTotalTime() {
    method setId (line 42) | public void setId(String id) {
    method getId (line 46) | public String getId() {
    method getPageref (line 50) | public String getPageref() {
    method setPageref (line 54) | public void setPageref(String pageref) {
    method getStartedDateTime (line 58) | @JsonSerialize(using = ISO8601WithTDZDateFormatter.class)
    method setStartedDateTime (line 63) | public void setStartedDateTime(Date startedDateTime) {
    method responseFinish (line 68) | public void responseFinish() {
    method getTime (line 86) | public long getTime() {
    method getTime (line 96) | public long getTime(TimeUnit timeUnit) {
    method getRequest (line 130) | public HarRequest getRequest() {
    method setRequest (line 134) | public void setRequest(HarRequest request) {
    method getResponse (line 138) | public HarResponse getResponse() {
    method setResponse (line 142) | public void setResponse(HarResponse response) {
    method getCache (line 146) | public HarCache getCache() {
    method setCache (line 150) | public void setCache(HarCache cache) {
    method getTimings (line 154) | public HarTimings getTimings() {
    method setTimings (line 158) | public void setTimings(HarTimings timings) {
    method getServerIPAddress (line 162) | public String getServerIPAddress() {
    method setServerIPAddress (line 166) | public void setServerIPAddress(String serverIPAddress) {
    method getComment (line 170) | public String getComment() {
    method setComment (line 174) | public void setComment(String comment) {
    method getConnection (line 178) | public String getConnection() {
    method setConnection (line 182) | public void setConnection(String connection) {
    method toString (line 186) | @Override

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarLog.java
  class HarLog (line 8) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarLog (line 19) | public HarLog() {
    method HarLog (line 22) | public HarLog(HarNameVersion creator) {
    method addPage (line 26) | public void addPage(HarPage page) {
    method addEntry (line 33) | public void addEntry(HarEntry entry) {
    method getVersion (line 41) | public String getVersion() {
    method getCreator (line 45) | public HarNameVersion getCreator() {
    method setCreator (line 49) | public void setCreator(HarNameVersion creator) {
    method getBrowser (line 53) | public HarNameVersion getBrowser() {
    method setBrowser (line 57) | public void setBrowser(HarNameVersion browser) {
    method getPages (line 61) | public List<HarPage> getPages() {
    method getEntries (line 65) | public List<HarEntry> getEntries() {
    method getComment (line 69) | public String getComment() {
    method setComment (line 73) | public void setComment(String comment) {
    method getEntryCount (line 77) | public long getEntryCount() {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarNameValuePair.java
  class HarNameValuePair (line 5) | public final class HarNameValuePair {
    method HarNameValuePair (line 9) | public HarNameValuePair(String name, String value) {
    method getName (line 14) | public String getName() {
    method getValue (line 18) | public String getValue() {
    method getDecodeValue (line 22) | public String getDecodeValue(){
    method toString (line 30) | public String toString() {
    method equals (line 34) | @Override
    method hashCode (line 47) | @Override

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarNameVersion.java
  class HarNameVersion (line 3) | public class HarNameVersion {
    method HarNameVersion (line 8) | public HarNameVersion(String name, String version) {
    method getName (line 13) | public String getName() {
    method getVersion (line 17) | public String getVersion() {
    method getComment (line 21) | public String getComment() {
    method setComment (line 25) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarPage.java
  class HarPage (line 10) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarPage (line 18) | public HarPage() {
    method HarPage (line 21) | public HarPage(String id) {
    method HarPage (line 25) | public HarPage(String id, String title) {
    method getId (line 31) | public String getId() {
    method setId (line 35) | public void setId(String id) {
    method getStartedDateTime (line 39) | @JsonSerialize(using = ISO8601WithTDZDateFormatter.class)
    method setStartedDateTime (line 44) | public void setStartedDateTime(Date startedDateTime) {
    method getTitle (line 48) | public String getTitle() {
    method setTitle (line 52) | public void setTitle(String title) {
    method getPageTimings (line 56) | public HarPageTimings getPageTimings() {
    method getComment (line 60) | public String getComment() {
    method setComment (line 64) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarPageTimings.java
  class HarPageTimings (line 5) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarPageTimings (line 11) | public HarPageTimings() {
    method HarPageTimings (line 14) | public HarPageTimings(Long onContentLoad, Long onLoad) {
    method getOnContentLoad (line 19) | public Long getOnContentLoad() {
    method setOnContentLoad (line 23) | public void setOnContentLoad(Long onContentLoad) {
    method getOnLoad (line 27) | public Long getOnLoad() {
    method setOnLoad (line 31) | public void setOnLoad(Long onLoad) {
    method getComment (line 35) | public String getComment() {
    method setComment (line 39) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarPostData.java
  class HarPostData (line 7) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getMimeType (line 14) | public String getMimeType() {
    method setMimeType (line 18) | public void setMimeType(String mimeType) {
    method getParams (line 22) | public List<HarPostDataParam> getParams() {
    method setParams (line 26) | public void setParams(List<HarPostDataParam> params) {
    method getText (line 30) | public String getText() {
    method setText (line 34) | public void setText(String text) {
    method getComment (line 41) | public String getComment() {
    method setComment (line 45) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarPostDataParam.java
  class HarPostDataParam (line 5) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarPostDataParam (line 13) | public HarPostDataParam() {
    method HarPostDataParam (line 16) | public HarPostDataParam(String name, String value) {
    method getName (line 21) | public String getName() {
    method setName (line 25) | public void setName(String name) {
    method getValue (line 29) | public String getValue() {
    method setValue (line 33) | public void setValue(String value) {
    method getFileName (line 37) | public String getFileName() {
    method setFileName (line 41) | public void setFileName(String fileName) {
    method getContentType (line 45) | public String getContentType() {
    method setContentType (line 49) | public void setContentType(String contentType) {
    method getComment (line 53) | public String getComment() {
    method setComment (line 57) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarRequest.java
  class HarRequest (line 8) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarRequest (line 22) | public HarRequest() {
    method HarRequest (line 25) | public HarRequest(String method, String url, String httpVersion) {
    method getContent (line 31) | public HarContent getContent() {
    method getMethod (line 35) | public String getMethod() {
    method setMethod (line 39) | public void setMethod(String method) {
    method getUrl (line 43) | public String getUrl() {
    method setUrl (line 47) | public void setUrl(String url) {
    method getHttpVersion (line 51) | public String getHttpVersion() {
    method setHttpVersion (line 55) | public void setHttpVersion(String httpVersion) {
    method getCookies (line 59) | public List<HarCookie> getCookies() {
    method getHeaders (line 63) | public List<HarNameValuePair> getHeaders() {
    method getQueryString (line 67) | public List<HarNameValuePair> getQueryString() {
    method getPostData (line 71) | public HarPostData getPostData() {
    method setPostData (line 75) | public void setPostData(HarPostData postData) {
    method getHeadersSize (line 79) | public long getHeadersSize() {
    method setHeadersSize (line 83) | public void setHeadersSize(long headersSize) {
    method getBodySize (line 87) | public long getBodySize() {
    method setBodySize (line 91) | public void setBodySize(long bodySize) {
    method getComment (line 95) | public String getComment() {
    method setComment (line 99) | public void setComment(String comment) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarResponse.java
  class HarResponse (line 9) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method HarResponse (line 33) | public HarResponse() {
    method HarResponse (line 36) | public HarResponse(int status, String statusText, String httpVersion) {
    method getStatus (line 42) | public int getStatus() {
    method setStatus (line 46) | public void setStatus(int status) {
    method getStatusText (line 50) | public String getStatusText() {
    method setStatusText (line 54) | public void setStatusText(String statusText) {
    method getHttpVersion (line 58) | public String getHttpVersion() {
    method setHttpVersion (line 62) | public void setHttpVersion(String httpVersion) {
    method getCookies (line 66) | public List<HarCookie> getCookies() {
    method getHeaders (line 70) | public List<HarNameValuePair> getHeaders() {
    method getContent (line 74) | public HarContent getContent() {
    method getRedirectURL (line 78) | public String getRedirectURL() {
    method setRedirectURL (line 82) | public void setRedirectURL(String redirectURL) {
    method getHeadersSize (line 86) | public long getHeadersSize() {
    method setHeadersSize (line 90) | public void setHeadersSize(long headersSize) {
    method getBodySize (line 94) | public long getBodySize() {
    method setBodySize (line 98) | public void setBodySize(long bodySize) {
    method getComment (line 102) | public String getComment() {
    method setComment (line 106) | public void setComment(String comment) {
    method getError (line 110) | public String getError() {
    method setError (line 114) | public void setError(String error) {

FILE: app/src/main/java/net/lightbody/bmp/core/har/HarTimings.java
  class HarTimings (line 5) | public class HarTimings {
    method getComment (line 16) | public String getComment() {
    method setComment (line 20) | public void setComment(String comment) {
    method getBlocked (line 25) | public long getBlocked(TimeUnit timeUnit) {
    method setBlocked (line 33) | public void setBlocked(long blocked, TimeUnit timeUnit) {
    method getDns (line 41) | public long getDns(TimeUnit timeUnit) {
    method setDns (line 49) | public void setDns(long dns, TimeUnit timeUnit) {
    method getConnect (line 57) | public long getConnect(TimeUnit timeUnit) {
    method setConnect (line 65) | public void setConnect(long connect, TimeUnit timeUnit) {
    method getSend (line 77) | public long getSend(TimeUnit timeUnit) {
    method setSend (line 81) | public void setSend(long send, TimeUnit timeUnit) {
    method getWait (line 85) | public long getWait(TimeUnit timeUnit) {
    method setWait (line 89) | public void setWait(long wait, TimeUnit timeUnit) {
    method getReceive (line 93) | public long getReceive(TimeUnit timeUnit) {
    method setReceive (line 97) | public void setReceive(long receive, TimeUnit timeUnit) {
    method getSsl (line 101) | public long getSsl(TimeUnit timeUnit) {
    method setSsl (line 109) | public void setSsl(long ssl, TimeUnit timeUnit) {
    method getBlocked (line 121) | public Long getBlocked() {
    method setBlocked (line 125) | public void setBlocked(long blocked) {
    method getDns (line 129) | public Long getDns() {
    method setDns (line 133) | public void setDns(long dns) {
    method getConnect (line 137) | public Long getConnect() {
    method setConnect (line 141) | public void setConnect(long connect) {
    method getSend (line 145) | public long getSend() {
    method setSend (line 149) | public void setSend(long send) {
    method getWait (line 153) | public long getWait() {
    method setWait (line 157) | public void setWait(long wait) {
    method getReceive (line 161) | public long getReceive() {
    method setReceive (line 165) | public void setReceive(long receive) {
    method getSsl (line 169) | public Long getSsl() {
    method setSsl (line 173) | public void setSsl(long ssl) {

FILE: app/src/main/java/net/lightbody/bmp/core/json/ISO8601DateFormatter.java
  class ISO8601DateFormatter (line 12) | public class ISO8601DateFormatter extends JsonSerializer<Date> {
    method serialize (line 15) | @Override

FILE: app/src/main/java/net/lightbody/bmp/core/json/ISO8601WithTDZDateFormatter.java
  class ISO8601WithTDZDateFormatter (line 19) | public class ISO8601WithTDZDateFormatter extends JsonSerializer<Date> {
    method serialize (line 21) | @Override
    method format (line 26) | private String format(Date date) {

FILE: app/src/main/java/net/lightbody/bmp/exception/DecompressionException.java
  class DecompressionException (line 6) | public class DecompressionException extends RuntimeException {
    method DecompressionException (line 9) | public DecompressionException() {
    method DecompressionException (line 12) | public DecompressionException(String message) {
    method DecompressionException (line 16) | public DecompressionException(String message, Throwable cause) {
    method DecompressionException (line 20) | public DecompressionException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/exception/UnsupportedCharsetException.java
  class UnsupportedCharsetException (line 8) | public class UnsupportedCharsetException extends Exception {
    method UnsupportedCharsetException (line 9) | public UnsupportedCharsetException(java.nio.charset.UnsupportedCharset...
    method getUnsupportedCharsetExceptionCause (line 20) | public java.nio.charset.UnsupportedCharsetException getUnsupportedChar...

FILE: app/src/main/java/net/lightbody/bmp/filters/AddHeadersFilter.java
  class AddHeadersFilter (line 16) | public class AddHeadersFilter extends HttpFiltersAdapter {
    method AddHeadersFilter (line 19) | public AddHeadersFilter(HttpRequest originalRequest, Map<String, Strin...
    method clientToProxyRequest (line 29) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java
  class AutoBasicAuthFilter (line 21) | public class AutoBasicAuthFilter extends HttpsAwareFiltersAdapter {
    method AutoBasicAuthFilter (line 24) | public AutoBasicAuthFilter(HttpRequest originalRequest, ChannelHandler...
    method clientToProxyRequest (line 30) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java
  class BlacklistFilter (line 21) | public class BlacklistFilter extends HttpsAwareFiltersAdapter {
    method BlacklistFilter (line 24) | public BlacklistFilter(HttpRequest originalRequest, ChannelHandlerCont...
    method clientToProxyRequest (line 34) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/BrowserMobHttpFilterChain.java
  class BrowserMobHttpFilterChain (line 27) | public class BrowserMobHttpFilterChain extends HttpFiltersAdapter {
    method BrowserMobHttpFilterChain (line 34) | public BrowserMobHttpFilterChain(BrowserMobProxyServer proxyServer, Ht...
    method clientToProxyRequest (line 56) | @Override
    method proxyToServerRequest (line 91) | @Override
    method proxyToServerRequestSending (line 107) | @Override
    method serverToProxyResponse (line 119) | @Override
    method serverToProxyResponseTimedOut (line 137) | @Override
    method serverToProxyResponseReceiving (line 148) | @Override
    method proxyToServerResolutionStarted (line 159) | @Override
    method proxyToServerResolutionFailed (line 179) | @Override
    method proxyToServerResolutionSucceeded (line 190) | @Override
    method proxyToServerConnectionStarted (line 203) | @Override
    method proxyToServerConnectionSSLHandshakeStarted (line 214) | @Override
    method proxyToServerConnectionFailed (line 225) | @Override
    method proxyToServerConnectionSucceeded (line 236) | @Override
    method proxyToServerRequestSent (line 247) | @Override
    method serverToProxyResponseReceived (line 258) | @Override
    method proxyToClientResponse (line 269) | @Override
    method proxyToServerConnectionQueued (line 286) | @Override
    method updateFiltersWithModifiedResponse (line 303) | private void updateFiltersWithModifiedResponse(HttpRequest modifiedReq...

FILE: app/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java
  class ClientRequestCaptureFilter (line 26) | public class ClientRequestCaptureFilter extends HttpFiltersAdapter {
    method ClientRequestCaptureFilter (line 44) | public ClientRequestCaptureFilter(HttpRequest originalRequest) {
    method ClientRequestCaptureFilter (line 48) | public ClientRequestCaptureFilter(HttpRequest originalRequest, Channel...
    method clientToProxyRequest (line 52) | @Override
    method storeRequestContent (line 72) | protected void storeRequestContent(HttpContent httpContent) {
    method getHttpRequest (line 83) | public HttpRequest getHttpRequest() {
    method getFullRequestContents (line 87) | public byte[] getFullRequestContents() {
    method getTrailingHeaders (line 91) | public HttpHeaders getTrailingHeaders() {

FILE: app/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java
  class HarCaptureFilter (line 53) | public class HarCaptureFilter extends HttpsAwareFiltersAdapter {
    method HarCaptureFilter (line 148) | public HarCaptureFilter(HttpRequest originalRequest, ChannelHandlerCon...
    method clientToProxyRequest (line 192) | @Override
    method serverToProxyResponse (line 262) | @Override
    method serverToProxyResponseTimedOut (line 295) | @Override
    method createHarRequestForHttpRequest (line 329) | private HarRequest createHarRequestForHttpRequest(HttpRequest httpRequ...
    method captureQueryParameters (line 341) | protected void captureQueryParameters(HttpRequest httpRequest) {
    method captureRequestHeaderSize (line 362) | protected void captureRequestHeaderSize(HttpRequest httpRequest) {
    method captureRequestCookies (line 374) | protected void captureRequestCookies(HttpRequest httpRequest) {
    method captureRequestHeaders (line 394) | protected void captureRequestHeaders(HttpRequest httpRequest) {
    method captureTrailingHeaders (line 401) | protected void captureTrailingHeaders(LastHttpContent lastHttpContent) {
    method captureHeaders (line 408) | protected void captureHeaders(HttpHeaders headers) {
    method captureRequestContent (line 416) | protected void captureRequestContent(HttpRequest httpRequest, byte[] f...
    method captureResponseContent (line 481) | protected void captureResponseContent(HttpResponse httpResponse, byte[...
    method captureResponse (line 526) | protected void captureResponse(HttpResponse httpResponse) {
    method captureResponseMimeType (line 548) | protected void captureResponseMimeType(HttpResponse httpResponse) {
    method captureResponseCookies (line 557) | protected void captureResponseCookies(HttpResponse httpResponse) {
    method captureResponseHeaderSize (line 597) | protected void captureResponseHeaderSize(HttpResponse httpResponse) {
    method captureResponseHeaders (line 608) | protected void captureResponseHeaders(HttpResponse httpResponse) {
    method captureRedirectUrl (line 617) | protected void captureRedirectUrl(HttpResponse httpResponse) {
    method captureRequestSize (line 630) | protected void captureRequestSize(HttpContent httpContent) {
    method captureResponseSize (line 642) | protected void captureResponseSize(HttpContent httpContent) {
    method captureConnectTiming (line 653) | protected void captureConnectTiming() {
    method populateAddressFromCache (line 669) | protected void populateAddressFromCache(HttpRequest httpRequest) {
    method proxyToServerResolutionStarted (line 688) | @Override
    method proxyToServerResolutionFailed (line 703) | @Override
    method proxyToServerResolutionSucceeded (line 717) | @Override
    method proxyToServerConnectionQueued (line 737) | @Override
    method proxyToServerConnectionStarted (line 743) | @Override
    method proxyToServerConnectionFailed (line 749) | @Override
    method proxyToServerConnectionSucceeded (line 764) | @Override
    method proxyToServerRequestSending (line 777) | @Override
    method proxyToServerRequestSent (line 789) | @Override
    method serverToProxyResponseReceiving (line 803) | @Override
    method serverToProxyResponseReceived (line 818) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/HttpConnectHarCaptureFilter.java
  class HttpConnectHarCaptureFilter (line 39) | public class HttpConnectHarCaptureFilter extends HttpsAwareFiltersAdapte...
    method HttpConnectHarCaptureFilter (line 122) | public HttpConnectHarCaptureFilter(HttpRequest originalRequest, Channe...
    method clientToProxyRequest (line 143) | @Override
    method proxyToServerResolutionFailed (line 153) | @Override
    method proxyToServerConnectionFailed (line 168) | @Override
    method proxyToServerConnectionSucceeded (line 183) | @Override
    method proxyToServerConnectionSSLHandshakeStarted (line 200) | @Override
    method serverToProxyResponseTimedOut (line 205) | @Override
    method proxyToServerConnectionQueued (line 227) | @Override
    method proxyToServerResolutionStarted (line 233) | @Override
    method proxyToServerResolutionSucceeded (line 246) | @Override
    method proxyToServerConnectionStarted (line 260) | @Override
    method proxyToServerRequestSending (line 265) | @Override
    method proxyToServerRequestSent (line 270) | @Override
    method serverToProxyResponseReceiving (line 275) | @Override
    method populateTimingsForFailedCONNECT (line 286) | private void populateTimingsForFailedCONNECT(HarEntry harEntry) {
    method createHarEntryForFailedCONNECT (line 327) | private HarEntry createHarEntryForFailedCONNECT(String errorMessage) {
    method populateServerIpAddress (line 347) | private void populateServerIpAddress(HarEntry harEntry) {
    method createRequestForFailedConnect (line 376) | private HarRequest createRequestForFailedConnect(HttpRequest httpConne...
    method consumeConnectTimingForConnection (line 388) | public static HttpConnectTiming consumeConnectTimingForConnection(Inet...
    method setModifiedHttpRequest (line 392) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/HttpsAwareFiltersAdapter.java
  class HttpsAwareFiltersAdapter (line 23) | public class HttpsAwareFiltersAdapter extends HttpFiltersAdapter {
    method HttpsAwareFiltersAdapter (line 28) | public HttpsAwareFiltersAdapter(HttpRequest originalRequest, ChannelHa...
    method isHttps (line 37) | public boolean isHttps() {
    method getFullUrl (line 56) | public String getFullUrl(HttpRequest modifiedRequest) {
    method getOriginalUrl (line 92) | public String getOriginalUrl() {
    method getHost (line 104) | public String getHost(HttpRequest modifiedRequest) {
    method getHostAndPort (line 123) | public String getHostAndPort(HttpRequest modifiedRequest) {
    method getHttpsRequestHostAndPort (line 140) | private String getHttpsRequestHostAndPort() throws IllegalStateExcepti...
    method getHttpsOriginalRequestHostAndPort (line 157) | private String getHttpsOriginalRequestHostAndPort() throws IllegalStat...

FILE: app/src/main/java/net/lightbody/bmp/filters/HttpsHostCaptureFilter.java
  class HttpsHostCaptureFilter (line 21) | public class HttpsHostCaptureFilter extends HttpFiltersAdapter {
    method HttpsHostCaptureFilter (line 22) | public HttpsHostCaptureFilter(HttpRequest originalRequest, ChannelHand...
    method clientToProxyRequest (line 26) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/HttpsOriginalHostCaptureFilter.java
  class HttpsOriginalHostCaptureFilter (line 18) | public class HttpsOriginalHostCaptureFilter extends HttpsHostCaptureFilt...
    method HttpsOriginalHostCaptureFilter (line 19) | public HttpsOriginalHostCaptureFilter(HttpRequest originalRequest, Cha...

FILE: app/src/main/java/net/lightbody/bmp/filters/LatencyFilter.java
  class LatencyFilter (line 17) | public class LatencyFilter extends HttpFiltersAdapter {
    method LatencyFilter (line 22) | public LatencyFilter(HttpRequest originalRequest, int latencyMs) {
    method proxyToClientResponse (line 28) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/ModifiedRequestAwareFilter.java
  type ModifiedRequestAwareFilter (line 11) | public interface ModifiedRequestAwareFilter {
    method setModifiedHttpRequest (line 18) | void setModifiedHttpRequest(HttpRequest modifiedHttpRequest);

FILE: app/src/main/java/net/lightbody/bmp/filters/RegisterRequestFilter.java
  class RegisterRequestFilter (line 15) | public class RegisterRequestFilter extends HttpFiltersAdapter {
    method RegisterRequestFilter (line 18) | public RegisterRequestFilter(HttpRequest originalRequest, ChannelHandl...
    method clientToProxyRequest (line 24) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/RequestFilter.java
  type RequestFilter (line 12) | public interface RequestFilter {
    method filterRequest (line 24) | HttpResponse filterRequest(HttpRequest request, HttpMessageContents co...

FILE: app/src/main/java/net/lightbody/bmp/filters/RequestFilterAdapter.java
  class RequestFilterAdapter (line 19) | public class RequestFilterAdapter extends HttpsAwareFiltersAdapter {
    method RequestFilterAdapter (line 22) | public RequestFilterAdapter(HttpRequest originalRequest, ChannelHandle...
    method clientToProxyRequest (line 28) | @Override
    class FilterSource (line 59) | public static class FilterSource extends HttpFiltersSourceAdapter {
      method FilterSource (line 71) | public FilterSource(RequestFilter filter) {
      method FilterSource (line 86) | public FilterSource(RequestFilter filter, int maximumRequestBufferSi...
      method filterRequest (line 91) | @Override
      method getMaximumRequestBufferSizeInBytes (line 96) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/ResolvedHostnameCacheFilter.java
  class ResolvedHostnameCacheFilter (line 21) | public class ResolvedHostnameCacheFilter extends HttpFiltersAdapter {
    method ResolvedHostnameCacheFilter (line 46) | public ResolvedHostnameCacheFilter(HttpRequest originalRequest, Channe...
    method proxyToServerResolutionSucceeded (line 50) | @Override
    method getPreviouslyResolvedAddressForHost (line 72) | public static String getPreviouslyResolvedAddressForHost(String host) {

FILE: app/src/main/java/net/lightbody/bmp/filters/ResponseFilter.java
  type ResponseFilter (line 11) | public interface ResponseFilter {
    method filterResponse (line 22) | void filterResponse(HttpResponse response, HttpMessageContents content...

FILE: app/src/main/java/net/lightbody/bmp/filters/ResponseFilterAdapter.java
  class ResponseFilterAdapter (line 19) | public class ResponseFilterAdapter extends HttpsAwareFiltersAdapter impl...
    method ResponseFilterAdapter (line 27) | public ResponseFilterAdapter(HttpRequest originalRequest, ChannelHandl...
    method serverToProxyResponse (line 33) | @Override
    method setModifiedHttpRequest (line 57) | @Override
    class FilterSource (line 66) | public static class FilterSource extends HttpFiltersSourceAdapter {
      method FilterSource (line 78) | public FilterSource(ResponseFilter filter) {
      method FilterSource (line 93) | public FilterSource(ResponseFilter filter, int maximumResponseBuffer...
      method filterRequest (line 98) | @Override
      method getMaximumResponseBufferSizeInBytes (line 103) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/RewriteUrlFilter.java
  class RewriteUrlFilter (line 28) | public class RewriteUrlFilter extends HttpsAwareFiltersAdapter {
    method RewriteUrlFilter (line 33) | public RewriteUrlFilter(HttpRequest originalRequest, ChannelHandlerCon...
    method clientToProxyRequest (line 43) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/ServerResponseCaptureFilter.java
  class ServerResponseCaptureFilter (line 28) | public class ServerResponseCaptureFilter extends HttpFiltersAdapter {
    method ServerResponseCaptureFilter (line 73) | public ServerResponseCaptureFilter(HttpRequest originalRequest, boolea...
    method ServerResponseCaptureFilter (line 79) | public ServerResponseCaptureFilter(HttpRequest originalRequest, Channe...
    method serverToProxyResponse (line 85) | @Override
    method captureFullResponseContents (line 108) | protected void captureFullResponseContents() {
    method decompressContents (line 130) | protected void decompressContents() {
    method captureContentEncoding (line 143) | protected void captureContentEncoding(HttpResponse httpResponse) {
    method captureTrailingHeaders (line 147) | protected void captureTrailingHeaders(LastHttpContent lastContent) {
    method storeResponseContent (line 160) | protected void storeResponseContent(HttpContent httpContent) {
    method getHttpResponse (line 171) | public HttpResponse getHttpResponse() {
    method getFullResponseContents (line 181) | public byte[] getFullResponseContents() {
    method getRawResponseContents (line 190) | public byte[] getRawResponseContents() {
    method getTrailingHeaders (line 194) | public HttpHeaders getTrailingHeaders() {
    method isResponseCompressed (line 198) | public boolean isResponseCompressed() {
    method isDecompressionSuccessful (line 205) | public boolean isDecompressionSuccessful() {
    method getContentEncoding (line 213) | public String getContentEncoding() {

FILE: app/src/main/java/net/lightbody/bmp/filters/UnregisterRequestFilter.java
  class UnregisterRequestFilter (line 15) | public class UnregisterRequestFilter extends HttpFiltersAdapter {
    method UnregisterRequestFilter (line 18) | public UnregisterRequestFilter(HttpRequest originalRequest, ChannelHan...
    method proxyToClientResponse (line 24) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/WhitelistFilter.java
  class WhitelistFilter (line 22) | public class WhitelistFilter extends HttpsAwareFiltersAdapter {
    method WhitelistFilter (line 27) | public WhitelistFilter(HttpRequest originalRequest, ChannelHandlerCont...
    method clientToProxyRequest (line 40) | @Override

FILE: app/src/main/java/net/lightbody/bmp/filters/support/HttpConnectTiming.java
  class HttpConnectTiming (line 14) | public class HttpConnectTiming {
    method setConnectTimeNanos (line 20) | public void setConnectTimeNanos(long connectTimeNanos) {
    method setSslHandshakeTimeNanos (line 24) | public void setSslHandshakeTimeNanos(long sslHandshakeTimeNanos) {
    method setBlockedTimeNanos (line 28) | public void setBlockedTimeNanos(long blockedTimeNanos) {
    method setDnsTimeNanos (line 32) | public void setDnsTimeNanos(long dnsTimeNanos) {
    method getConnectTimeNanos (line 36) | public long getConnectTimeNanos() {
    method getSslHandshakeTimeNanos (line 40) | public long getSslHandshakeTimeNanos() {
    method getBlockedTimeNanos (line 44) | public long getBlockedTimeNanos() {
    method getDnsTimeNanos (line 48) | public long getDnsTimeNanos() {

FILE: app/src/main/java/net/lightbody/bmp/filters/util/HarCaptureUtil.java
  class HarCaptureUtil (line 8) | public class HarCaptureUtil {
    method createHarResponseForFailure (line 55) | public static HarResponse createHarResponseForFailure() {
    method getResolutionFailedErrorMessage (line 65) | public static String getResolutionFailedErrorMessage(String hostAndPor...
    method getConnectionFailedErrorMessage (line 74) | public static String getConnectionFailedErrorMessage() {
    method getResponseTimedOutErrorMessage (line 83) | public static String getResponseTimedOutErrorMessage() {
    method getNoResponseReceivedErrorMessage (line 93) | public static String getNoResponseReceivedErrorMessage() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/CertificateAndKey.java
  class CertificateAndKey (line 9) | public class CertificateAndKey {
    method CertificateAndKey (line 13) | public CertificateAndKey(X509Certificate certificate, PrivateKey priva...
    method getCertificate (line 18) | public X509Certificate getCertificate() {
    method getPrivateKey (line 22) | public PrivateKey getPrivateKey() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/CertificateAndKeySource.java
  type CertificateAndKeySource (line 8) | public interface CertificateAndKeySource {
    method load (line 15) | CertificateAndKey load();

FILE: app/src/main/java/net/lightbody/bmp/mitm/CertificateInfo.java
  class CertificateInfo (line 10) | public class CertificateInfo {
    method getCommonName (line 25) | public String getCommonName() {
    method getOrganization (line 29) | public String getOrganization() {
    method getOrganizationalUnit (line 33) | public String getOrganizationalUnit() {
    method getNotBefore (line 37) | public Date getNotBefore() {
    method getNotAfter (line 41) | public Date getNotAfter() {
    method getEmail (line 45) | public String getEmail() {
    method getLocality (line 49) | public String getLocality() {
    method getState (line 53) | public String getState() {
    method getCountryCode (line 57) | public String getCountryCode() {
    method getSubjectAlternativeNames (line 61) | public List<String> getSubjectAlternativeNames() {
    method commonName (line 65) | public CertificateInfo commonName(String commonName) {
    method organization (line 70) | public CertificateInfo organization(String organization) {
    method organizationalUnit (line 75) | public CertificateInfo organizationalUnit(String organizationalUnit) {
    method notBefore (line 80) | public CertificateInfo notBefore(Date notBefore) {
    method notAfter (line 85) | public CertificateInfo notAfter(Date notAfter) {
    method email (line 90) | public CertificateInfo email(String email) {
    method locality (line 95) | public CertificateInfo locality(String locality) {
    method state (line 100) | public CertificateInfo state(String state) {
    method countryCode (line 105) | public CertificateInfo countryCode(String countryCode) {
    method subjectAlternativeNames (line 110) | public CertificateInfo subjectAlternativeNames(List<String> subjectAlt...

FILE: app/src/main/java/net/lightbody/bmp/mitm/CertificateInfoGenerator.java
  type CertificateInfoGenerator (line 10) | public interface CertificateInfoGenerator {
    method generate (line 18) | CertificateInfo generate(List<String> hostnames, X509Certificate origi...

FILE: app/src/main/java/net/lightbody/bmp/mitm/ExistingCertificateSource.java
  class ExistingCertificateSource (line 10) | public class ExistingCertificateSource implements CertificateAndKeySource {
    method ExistingCertificateSource (line 14) | public ExistingCertificateSource(X509Certificate rootCertificate, Priv...
    method load (line 27) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/HostnameCertificateInfoGenerator.java
  class HostnameCertificateInfoGenerator (line 11) | public class HostnameCertificateInfoGenerator implements CertificateInfo...
    method generate (line 23) | @Override
    method getNotBefore (line 44) | protected Date getNotBefore() {
    method getNotAfter (line 51) | protected Date getNotAfter() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/KeyStoreCertificateSource.java
  class KeyStoreCertificateSource (line 19) | public class KeyStoreCertificateSource implements CertificateAndKeySource {
    method KeyStoreCertificateSource (line 24) | public KeyStoreCertificateSource(KeyStore keyStore, String privateKeyA...
    method load (line 42) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/KeyStoreFileCertificateSource.java
  class KeyStoreFileCertificateSource (line 23) | public class KeyStoreFileCertificateSource implements CertificateAndKeyS...
    method get (line 37) | @Override
    method KeyStoreFileCertificateSource (line 50) | public KeyStoreFileCertificateSource(String keyStoreType, String keySt...
    method KeyStoreFileCertificateSource (line 78) | public KeyStoreFileCertificateSource(String keyStoreType, File keyStor...
    method certificateTool (line 102) | public KeyStoreFileCertificateSource certificateTool(SecurityProviderT...
    method load (line 107) | @Override
    method loadKeyStore (line 116) | private CertificateAndKey loadKeyStore() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/PemFileCertificateSource.java
  class PemFileCertificateSource (line 22) | public class PemFileCertificateSource implements CertificateAndKeySource {
    method get (line 32) | @Override
    method PemFileCertificateSource (line 45) | public PemFileCertificateSource(File certificateFile, File privateKeyF...
    method certificateTool (line 54) | public PemFileCertificateSource certificateTool(SecurityProviderTool s...
    method load (line 59) | @Override
    method loadCertificateAndKeyFiles (line 64) | private CertificateAndKey loadCertificateAndKeyFiles() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/RootCertificateGenerator.java
  class RootCertificateGenerator (line 37) | public class RootCertificateGenerator implements CertificateAndKeySource {
    method get (line 58) | @Override
    method RootCertificateGenerator (line 64) | public RootCertificateGenerator(CertificateInfo rootCertificateInfo,
    method load (line 90) | @Override
    method generateRootCertificate (line 101) | private CertificateAndKey generateRootCertificate() {
    method encodeRootCertificateAsPem (line 124) | public String encodeRootCertificateAsPem() {
    method encodePrivateKeyAsPem (line 134) | public String encodePrivateKeyAsPem(String privateKeyPassword) {
    method saveRootCertificateAsPemFile (line 141) | public void saveRootCertificateAsPemFile(File file) {
    method savePrivateKeyAsPemFile (line 155) | public void savePrivateKeyAsPemFile(File file, String passwordForPriva...
    method saveRootCertificateAndKey (line 169) | public void saveRootCertificateAndKey(String keyStoreType,
    method builder (line 183) | public static Builder builder() {
    class Builder (line 190) | public static class Builder {
      method certificateInfo (line 207) | public Builder certificateInfo(CertificateInfo certificateInfo) {
      method keyGenerator (line 215) | public Builder keyGenerator(KeyGenerator keyGenerator) {
      method messageDigest (line 223) | public Builder messageDigest(String messageDigest) {
      method certificateTool (line 231) | public Builder certificateTool(SecurityProviderTool securityProvider...
      method build (line 236) | public RootCertificateGenerator build() {
    method getDefaultCommonName (line 244) | private static String getDefaultCommonName() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/TrustSource.java
  class TrustSource (line 36) | public class TrustSource {
    method TrustSource (line 50) | protected TrustSource() {
    method TrustSource (line 60) | protected TrustSource(X509Certificate... trustedCAs) {
    method getTrustedCAs (line 72) | public X509Certificate[] getTrustedCAs() {
    method empty (line 80) | public static TrustSource empty() {
    method defaultTrustSource (line 88) | public static TrustSource defaultTrustSource() {
    method builtinTrustSource (line 96) | public static TrustSource builtinTrustSource() {
    method javaTrustSource (line 103) | public static TrustSource javaTrustSource() {
    method add (line 116) | public TrustSource add(String trustedPemEncodedCAs) {
    method add (line 133) | public TrustSource add(X509Certificate... trustedCertificates) {
    method add (line 152) | public TrustSource add(KeyStore trustStore) {
    method add (line 171) | public TrustSource add(File trustedCAPemFile) {
    method add (line 193) | public TrustSource add(TrustSource trustSource) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/CertificateCreationException.java
  class CertificateCreationException (line 6) | public class CertificateCreationException extends RuntimeException {
    method CertificateCreationException (line 9) | public CertificateCreationException() {
    method CertificateCreationException (line 12) | public CertificateCreationException(String message) {
    method CertificateCreationException (line 16) | public CertificateCreationException(String message, Throwable cause) {
    method CertificateCreationException (line 20) | public CertificateCreationException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/CertificateSourceException.java
  class CertificateSourceException (line 7) | public class CertificateSourceException extends RuntimeException {
    method CertificateSourceException (line 10) | public CertificateSourceException() {
    method CertificateSourceException (line 13) | public CertificateSourceException(String message) {
    method CertificateSourceException (line 17) | public CertificateSourceException(String message, Throwable cause) {
    method CertificateSourceException (line 21) | public CertificateSourceException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/ExportException.java
  class ExportException (line 6) | public class ExportException extends RuntimeException {
    method ExportException (line 9) | public ExportException() {
    method ExportException (line 12) | public ExportException(String message) {
    method ExportException (line 16) | public ExportException(String message, Throwable cause) {
    method ExportException (line 20) | public ExportException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/ImportException.java
  class ImportException (line 6) | public class ImportException extends RuntimeException {
    method ImportException (line 9) | public ImportException() {
    method ImportException (line 12) | public ImportException(String message) {
    method ImportException (line 16) | public ImportException(String message, Throwable cause) {
    method ImportException (line 20) | public ImportException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/KeyGeneratorException.java
  class KeyGeneratorException (line 6) | public class KeyGeneratorException extends RuntimeException {
    method KeyGeneratorException (line 9) | public KeyGeneratorException() {
    method KeyGeneratorException (line 12) | public KeyGeneratorException(String message) {
    method KeyGeneratorException (line 16) | public KeyGeneratorException(String message, Throwable cause) {
    method KeyGeneratorException (line 20) | public KeyGeneratorException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/KeyStoreAccessException.java
  class KeyStoreAccessException (line 6) | public class KeyStoreAccessException extends RuntimeException {
    method KeyStoreAccessException (line 9) | public KeyStoreAccessException() {
    method KeyStoreAccessException (line 12) | public KeyStoreAccessException(String message) {
    method KeyStoreAccessException (line 16) | public KeyStoreAccessException(String message, Throwable cause) {
    method KeyStoreAccessException (line 20) | public KeyStoreAccessException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/MitmException.java
  class MitmException (line 7) | public class MitmException extends RuntimeException {
    method MitmException (line 10) | public MitmException() {
    method MitmException (line 13) | public MitmException(String message) {
    method MitmException (line 17) | public MitmException(String message, Throwable cause) {
    method MitmException (line 21) | public MitmException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/SslContextInitializationException.java
  class SslContextInitializationException (line 6) | public class SslContextInitializationException extends RuntimeException {
    method SslContextInitializationException (line 9) | public SslContextInitializationException() {
    method SslContextInitializationException (line 12) | public SslContextInitializationException(String message) {
    method SslContextInitializationException (line 16) | public SslContextInitializationException(String message, Throwable cau...
    method SslContextInitializationException (line 20) | public SslContextInitializationException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/TrustSourceException.java
  class TrustSourceException (line 6) | public class TrustSourceException extends RuntimeException {
    method TrustSourceException (line 7) | public TrustSourceException() {
    method TrustSourceException (line 10) | public TrustSourceException(String message) {
    method TrustSourceException (line 14) | public TrustSourceException(String message, Throwable cause) {
    method TrustSourceException (line 18) | public TrustSourceException(Throwable cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/exception/UncheckedIOException.java
  class UncheckedIOException (line 9) | public class UncheckedIOException extends RuntimeException {
    method UncheckedIOException (line 10) | public UncheckedIOException(String message, IOException cause) {
    method UncheckedIOException (line 14) | public UncheckedIOException(IOException cause) {

FILE: app/src/main/java/net/lightbody/bmp/mitm/keys/ECKeyGenerator.java
  class ECKeyGenerator (line 14) | public class ECKeyGenerator implements KeyGenerator {
    method ECKeyGenerator (line 25) | public ECKeyGenerator() {
    method ECKeyGenerator (line 32) | public ECKeyGenerator(String namedCurve) {
    method generate (line 36) | @Override
    method toString (line 51) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/keys/KeyGenerator.java
  type KeyGenerator (line 8) | public interface KeyGenerator {
    method generate (line 14) | KeyPair generate();

FILE: app/src/main/java/net/lightbody/bmp/mitm/keys/RSAKeyGenerator.java
  class RSAKeyGenerator (line 12) | public class RSAKeyGenerator implements KeyGenerator {
    method RSAKeyGenerator (line 26) | public RSAKeyGenerator() {
    method RSAKeyGenerator (line 33) | public RSAKeyGenerator(int keySize) {
    method generate (line 37) | @Override
    method toString (line 51) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/manager/ImpersonatingMitmManager.java
  class ImpersonatingMitmManager (line 61) | public class ImpersonatingMitmManager implements MitmManager {
    method get (line 78) | @Override
    method get (line 128) | @Override
    method ImpersonatingMitmManager (line 143) | public ImpersonatingMitmManager(CertificateAndKeySource rootCertificat...
    method serverSslEngine (line 197) | @Override
    method serverSslEngine (line 208) | @Override
    method clientSslEngineFor (line 226) | @Override
    method getHostnameImpersonatingSslContext (line 248) | private SslContext getHostnameImpersonatingSslContext(final String hos...
    method createImpersonatingSslContext (line 272) | private SslContext createImpersonatingSslContext(SSLSession sslSession...
    method createImpersonatingSslContext (line 291) | private SslContext createImpersonatingSslContext(CertificateInfo certi...
    method getStatistics (line 346) | public CertificateGenerationStatistics getStatistics() {
    method builder (line 354) | public static Builder builder() {
    method builderWithECC (line 362) | public static Builder builderWithECC() {
    class Builder (line 373) | public static class Builder {
      method rootCertificateSource (line 401) | public Builder rootCertificateSource(CertificateAndKeySource certifi...
      method serverMessageDigest (line 409) | public Builder serverMessageDigest(String serverMessageDigest) {
      method trustAllServers (line 421) | public Builder trustAllServers(boolean trustAllServers) {
      method trustSource (line 437) | public Builder trustSource(TrustSource trustSource) {
      method serverKeyGenerator (line 445) | public Builder serverKeyGenerator(KeyGenerator serverKeyGenerator) {
      method cacheConcurrencyLevel (line 453) | public Builder cacheConcurrencyLevel(int cacheConcurrencyLevel) {
      method cacheExpirationInterval (line 461) | public Builder cacheExpirationInterval(long cacheExpirationInterval,...
      method certificateInfoGenerator (line 470) | public Builder certificateInfoGenerator(CertificateInfoGenerator cer...
      method serverCiphers (line 480) | public Builder serverCiphers(Collection<String> serverCiphers) {
      method clientCiphers (line 490) | public Builder clientCiphers(Collection<String> clientCiphers) {
      method certificateTool (line 498) | public Builder certificateTool(SecurityProviderTool securityProvider...
      method build (line 503) | public ImpersonatingMitmManager build() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/stats/CertificateGenerationStatistics.java
  class CertificateGenerationStatistics (line 9) | public class CertificateGenerationStatistics {
    method certificateCreated (line 18) | public void certificateCreated(long startTimeMs, long finishTimeMs) {
    method getCertificatesGenerated (line 29) | public int getCertificatesGenerated() {
    method getTotalCertificateGenerationTimeMs (line 36) | public long getTotalCertificateGenerationTimeMs() {
    method getAvgCertificateGenerationTimeMs (line 43) | public long getAvgCertificateGenerationTimeMs() {
    method firstCertificateGeneratedTimestamp (line 54) | public long firstCertificateGeneratedTimestamp() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/tools/BouncyCastleSecurityProviderTool.java
  class BouncyCastleSecurityProviderTool (line 64) | public class BouncyCastleSecurityProviderTool implements SecurityProvide...
    method createServerCertificate (line 74) | @Override
    method createServerKeyStore (line 131) | @Override
    method createRootCertificateKeyStore (line 136) | @Override
    method createCARootCertificate (line 141) | @Override
    method encodePrivateKeyAsPem (line 199) | @Override
    method encodeCertificateAsPem (line 211) | @Override
    method decodePemEncodedPrivateKey (line 216) | @Override
    method decodePemEncodedCertificate (line 245) | @Override
    method loadKeyStore (line 251) | @Override
    method saveKeyStore (line 256) | @Override
    method getKeyManagers (line 261) | @Override
    method createX500NameForCertificate (line 273) | private static X500Name createX500NameForCertificate(CertificateInfo c...
    method getDomainNameSANsAsASN1Encodable (line 316) | private static GeneralNames getDomainNameSANsAsASN1Encodable(List<Stri...
    method getCertificateSigner (line 335) | private static ContentSigner getCertificateSigner(PrivateKey certAutho...
    method convertToJcaCertificate (line 350) | private static X509Certificate convertToJcaCertificate(X509Certificate...
    method createSubjectKeyIdentifier (line 365) | private static SubjectKeyIdentifier createSubjectKeyIdentifier(Key key) {
    method encodeObjectAsPemString (line 379) | private static String encodeObjectAsPemString(Object object, PEMEncryp...

FILE: app/src/main/java/net/lightbody/bmp/mitm/tools/DefaultSecurityProviderTool.java
  class DefaultSecurityProviderTool (line 35) | public class DefaultSecurityProviderTool implements SecurityProviderTool {
    method createCARootCertificate (line 38) | @Override
    method createServerCertificate (line 43) | @Override
    method createServerKeyStore (line 48) | @Override
    method createRootCertificateKeyStore (line 79) | @Override
    method encodePrivateKeyAsPem (line 84) | @Override
    method encodeCertificateAsPem (line 89) | @Override
    method decodePemEncodedPrivateKey (line 94) | @Override
    method decodePemEncodedCertificate (line 99) | @Override
    method loadKeyStore (line 129) | @Override
    method saveKeyStore (line 157) | @Override
    method getKeyManagers (line 167) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/tools/SecurityProviderTool.java
  type SecurityProviderTool (line 19) | public interface SecurityProviderTool {
    method createCARootCertificate (line 28) | CertificateAndKey createCARootCertificate(CertificateInfo certificateI...
    method createServerCertificate (line 43) | CertificateAndKey createServerCertificate(CertificateInfo certificateI...
    method createServerKeyStore (line 60) | KeyStore createServerKeyStore(String keyStoreType,
    method createRootCertificateKeyStore (line 75) | KeyStore createRootCertificateKeyStore(String keyStoreType,
    method encodePrivateKeyAsPem (line 89) | String encodePrivateKeyAsPem(PrivateKey privateKey, String passwordFor...
    method encodeCertificateAsPem (line 97) | String encodeCertificateAsPem(Certificate certificate);
    method decodePemEncodedPrivateKey (line 106) | PrivateKey decodePemEncodedPrivateKey(Reader privateKeyReader, String ...
    method decodePemEncodedCertificate (line 114) | X509Certificate decodePemEncodedCertificate(Reader certificateReader);
    method loadKeyStore (line 124) | KeyStore loadKeyStore(File file, String keyStoreType, String password);
    method saveKeyStore (line 133) | void saveKeyStore(File file, KeyStore keyStore, String keystorePassword);
    method getKeyManagers (line 142) | KeyManager[] getKeyManagers(KeyStore keyStore, String keyStorePassword);

FILE: app/src/main/java/net/lightbody/bmp/mitm/trustmanager/InsecureExtendedTrustManager.java
  class InsecureExtendedTrustManager (line 25) | public class InsecureExtendedTrustManager extends X509ExtendedTrustManag...
    method checkClientTrusted (line 37) | @Override
    method checkServerTrusted (line 41) | @Override
    method checkClientTrusted (line 45) | @Override
    method checkServerTrusted (line 49) | @Override
    method checkClientTrusted (line 53) | @Override
    method checkServerTrusted (line 57) | @Override
    method getAcceptedIssuers (line 61) | @Override
    method checkClientTrusted (line 67) | @Override
    method checkServerTrusted (line 76) | @Override
    method checkClientTrusted (line 85) | @Override
    method checkServerTrusted (line 94) | @Override
    method checkClientTrusted (line 103) | @Override
    method checkServerTrusted (line 112) | @Override
    method getAcceptedIssuers (line 121) | @Override
    method getDefaultExtendedTrustManager (line 129) | private static X509ExtendedTrustManager getDefaultExtendedTrustManager...

FILE: app/src/main/java/net/lightbody/bmp/mitm/trustmanager/InsecureTrustManagerFactory.java
  class InsecureTrustManagerFactory (line 40) | public class InsecureTrustManagerFactory extends SimpleTrustManagerFacto...
    method engineInit (line 46) | @Override
    method engineInit (line 50) | @Override
    method engineGetTrustManagers (line 54) | @Override

FILE: app/src/main/java/net/lightbody/bmp/mitm/util/EncryptionUtil.java
  class EncryptionUtil (line 24) | public class EncryptionUtil {
    method getSignatureAlgorithm (line 39) | public static String getSignatureAlgorithm(String messageDigest, Key s...
    method getDigitalSignatureType (line 49) | public static String getDigitalSignatureType(Key signingKey) {
    method getRandomBigInteger (line 68) | public static BigInteger getRandomBigInteger(int bits) {
    method isRsaKey (line 75) | public static boolean isRsaKey(Key key) {
    method isEcKey (line 82) | public static boolean isEcKey(Key key) {
    method writePemStringToFile (line 92) | public static void writePemStringToFile(File file, String pemDataToWri...
    method readPemStringFromFile (line 106) | public static String readPemStringFromFile(File file) {
    method isUnlimitedStrengthAllowed (line 121) | public static boolean isUnlimitedStrengthAllowed() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/util/KeyStoreUtil.java
  class KeyStoreUtil (line 22) | public class KeyStoreUtil {
    method createEmptyKeyStore (line 30) | public static KeyStore createEmptyKeyStore(String keyStoreType, String...
    method createRootCertificateKeyStore (line 60) | public static KeyStore createRootCertificateKeyStore(String keyStoreTy...
    method getKeyManagers (line 84) | public static KeyManager[] getKeyManagers(KeyStore keyStore, String ke...

FILE: app/src/main/java/net/lightbody/bmp/mitm/util/MitmConstants.java
  class MitmConstants (line 6) | public class MitmConstants {
    method is32BitJvm (line 28) | private static boolean is32BitJvm() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/util/SslUtil.java
  class SslUtil (line 39) | public class SslUtil {
    method get (line 55) | @Override
    method getUpstreamServerSslContext (line 85) | public static SslContext getUpstreamServerSslContext(Collection<String...
    method getServerCertificate (line 111) | public static X509Certificate getServerCertificate(SSLSession sslSessi...
    method getEnabledJdkCipherSuites (line 136) | public static List<String> getEnabledJdkCipherSuites() {
    method getDefaultCipherList (line 161) | public static List<String> getDefaultCipherList() {
    method getBuiltInCipherList (line 170) | public static List<String> getBuiltInCipherList() {

FILE: app/src/main/java/net/lightbody/bmp/mitm/util/TrustUtil.java
  class TrustUtil (line 37) | public class TrustUtil {
    method get (line 65) | @Override
    method get (line 83) | @Override
    method getBuiltinTrustedCAs (line 101) | public static X509Certificate[] getBuiltinTrustedCAs() {
    method getJavaTrustedCAs (line 109) | public static  X509Certificate[] getJavaTrustedCAs() {
    method readX509CertificatesFromPem (line 120) | public static X509Certificate[] readX509CertificatesFromPem(String pem...
    method readSingleX509Certificate (line 141) | public static X509Certificate readSingleX509Certificate(String x509Cer...
    method getDefaultJavaTrustManager (line 149) | public static X509TrustManager getDefaultJavaTrustManager() {
    method extractTrustedCertificateEntries (line 177) | public static List<X509Certificate> extractTrustedCertificateEntries(K...

FILE: app/src/main/java/net/lightbody/bmp/proxy/ActivityMonitor.java
  class ActivityMonitor (line 13) | public class ActivityMonitor {
    method isSatisfied (line 22) | @Override
    method isSatisfied (line 29) | @Override
    method requestStarted (line 35) | public void requestStarted() {
    method requestFinished (line 46) | public void requestFinished() {
    method getActiveRequests (line 57) | public int getActiveRequests() {
    method getTotalRequests (line 61) | public int getTotalRequests() {
    method waitForQuiescence (line 65) | public boolean waitForQuiescence(long quietPeriod, long timeout, TimeU...

FILE: app/src/main/java/net/lightbody/bmp/proxy/BlacklistEntry.java
  class BlacklistEntry (line 9) | public class BlacklistEntry {
    method BlacklistEntry (line 20) | public BlacklistEntry(String urlPattern, int statusCode) {
    method BlacklistEntry (line 31) | public BlacklistEntry(String urlPattern, int statusCode, String httpMe...
    method matches (line 49) | public boolean matches(String url, String httpMethod) {
    method getUrlPattern (line 57) | public Pattern getUrlPattern() {
    method getStatusCode (line 61) | public int getStatusCode() {
    method getHttpMethodPattern (line 65) | public Pattern getHttpMethodPattern() {
    method getPattern (line 69) | @Deprecated
    method getResponseCode (line 77) | @Deprecated
    method getMethod (line 85) | @Deprecated

FILE: app/src/main/java/net/lightbody/bmp/proxy/CaptureType.java
  type CaptureType (line 9) | public enum CaptureType {
    method getRequestCaptureTypes (line 67) | public static EnumSet<CaptureType> getRequestCaptureTypes() {
    method getResponseCaptureTypes (line 74) | public static EnumSet<CaptureType> getResponseCaptureTypes() {
    method getHeaderCaptureTypes (line 81) | public static EnumSet<CaptureType> getHeaderCaptureTypes() {
    method getNonBinaryContentCaptureTypes (line 88) | public static EnumSet<CaptureType> getNonBinaryContentCaptureTypes() {
    method getBinaryContentCaptureTypes (line 95) | public static EnumSet<CaptureType> getBinaryContentCaptureTypes() {
    method getAllContentCaptureTypes (line 102) | public static EnumSet<CaptureType> getAllContentCaptureTypes() {
    method getCookieCaptureTypes (line 109) | public static EnumSet<CaptureType> getCookieCaptureTypes() {

FILE: app/src/main/java/net/lightbody/bmp/proxy/RewriteRule.java
  class RewriteRule (line 8) | public class RewriteRule {
    method RewriteRule (line 12) | public RewriteRule(String pattern, String replace) {
    method getPattern (line 17) | public Pattern getPattern() {
    method getReplace (line 21) | public String getReplace() {
    method equals (line 25) | @Override
    method hashCode (line 38) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/Whitelist.java
  class Whitelist (line 17) | public class Whitelist {
    method Whitelist (line 30) | public Whitelist() {
    method Whitelist (line 41) | public Whitelist(int statusCode) {
    method Whitelist (line 50) | @Deprecated
    method Whitelist (line 62) | public Whitelist(Collection<String> patterns, int statusCode) {
    method isEnabled (line 82) | public boolean isEnabled() {
    method getPatterns (line 89) | public Collection<Pattern> getPatterns() {
    method getStatusCode (line 96) | public int getStatusCode() {
    method getResponseCode (line 103) | @Deprecated
    method matches (line 115) | public boolean matches(String url) {

FILE: app/src/main/java/net/lightbody/bmp/proxy/auth/AuthType.java
  type AuthType (line 6) | public enum AuthType {

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/AbstractHostNameRemapper.java
  class AbstractHostNameRemapper (line 17) | public abstract class AbstractHostNameRemapper implements AdvancedHostRe...
    method remapHosts (line 28) | @Override
    method remapHost (line 37) | @Override
    method removeHostRemapping (line 53) | @Override
    method clearHostRemappings (line 69) | @Override
    method getHostRemappings (line 76) | @Override
    method getOriginalHostnames (line 81) | @Override
    method applyRemapping (line 104) | public String applyRemapping(String originalHost) {
    method resolveRemapped (line 121) | public abstract Collection<InetAddress> resolveRemapped(String remappe...
    method resolve (line 129) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/AdvancedHostResolver.java
  type AdvancedHostResolver (line 12) | public interface AdvancedHostResolver extends HostResolver {
    method remapHosts (line 21) | void remapHosts(Map<String, String> hostRemappings);
    method remapHost (line 31) | void remapHost(String originalHost, String remappedHost);
    method removeHostRemapping (line 38) | void removeHostRemapping(String originalHost);
    method clearHostRemappings (line 43) | void clearHostRemappings();
    method getHostRemappings (line 51) | Map<String, String> getHostRemappings();
    method getOriginalHostnames (line 60) | Collection<String> getOriginalHostnames(String remappedHost);
    method clearDNSCache (line 65) | void clearDNSCache();
    method setPositiveDNSCacheTimeout (line 77) | void setPositiveDNSCacheTimeout(int timeout, TimeUnit timeUnit);
    method setNegativeDNSCacheTimeout (line 89) | void setNegativeDNSCacheTimeout(int timeout, TimeUnit timeUnit);

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/BasicHostResolver.java
  class BasicHostResolver (line 12) | public abstract class BasicHostResolver implements AdvancedHostResolver {
    method remapHosts (line 13) | @Override
    method remapHost (line 18) | @Override
    method removeHostRemapping (line 23) | @Override
    method clearHostRemappings (line 28) | @Override
    method getHostRemappings (line 33) | @Override
    method getOriginalHostnames (line 38) | @Override
    method clearDNSCache (line 43) | @Override
    method setPositiveDNSCacheTimeout (line 48) | @Override
    method setNegativeDNSCacheTimeout (line 53) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/ChainedHostResolver.java
  class ChainedHostResolver (line 37) | public class ChainedHostResolver implements AdvancedHostResolver {
    method ChainedHostResolver (line 50) | public ChainedHostResolver(Collection<? extends AdvancedHostResolver> ...
    method getResolvers (line 64) | public Collection<? extends AdvancedHostResolver> getResolvers() {
    method remapHosts (line 68) | @Override
    method remapHost (line 80) | @Override
    method removeHostRemapping (line 92) | @Override
    method clearHostRemappings (line 104) | @Override
    method getHostRemappings (line 116) | @Override
    method getOriginalHostnames (line 130) | @Override
    method clearDNSCache (line 144) | @Override
    method setPositiveDNSCacheTimeout (line 156) | @Override
    method setNegativeDNSCacheTimeout (line 168) | @Override
    method resolve (line 180) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/DelegatingHostResolver.java
  class DelegatingHostResolver (line 14) | public class DelegatingHostResolver implements org.littleshoot.proxy.Hos...
    method DelegatingHostResolver (line 22) | public DelegatingHostResolver(AdvancedHostResolver resolver) {
    method getResolver (line 26) | public AdvancedHostResolver getResolver() {
    method setResolver (line 30) | public void setResolver(AdvancedHostResolver resolver) {
    method resolve (line 34) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/DnsJavaResolver.java
  class DnsJavaResolver (line 28) | public class DnsJavaResolver extends AbstractHostNameRemapper implements...
    method clearDNSCache (line 41) | @Override
    method setPositiveDNSCacheTimeout (line 46) | @Override
    method setNegativeDNSCacheTimeout (line 51) | @Override
    method resolveRemapped (line 56) | @Override
    method resolveHostByType (line 84) | protected Collection<InetAddress> resolveHostByType(String host, int t...

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/HostResolver.java
  type HostResolver (line 9) | public interface HostResolver {
    method resolve (line 19) | Collection<InetAddress> resolve(String host);

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/NativeCacheManipulatingResolver.java
  class NativeCacheManipulatingResolver (line 22) | public class NativeCacheManipulatingResolver extends NativeResolver {
    method clearDNSCache (line 25) | @Override
    method setPositiveDNSCacheTimeout (line 49) | @Override
    method setNegativeDNSCacheTimeout (line 69) | @Override

FILE: app/src/main/java/net/lightbody/bmp/proxy/dns/NativeResolver.java
  class NativeResolver (line 20) | public class NativeResolver extends AbstractHostNameRemapper implements ...
    method clearDNSCache (line 23) | @Override
    method setPositiveDNSCacheTimeout (line 28) | @Override
    method setNegativeDNSCacheTimeout (line 33) | @Override
    method resolveRemapped (line 38) | @Override

FILE: app/src/main/java/net/lightbody/bmp/util/BrowserMobHttpUtil.java
  class BrowserMobHttpUtil (line 32) | public class BrowserMobHttpUtil {
    method getHeaderSize (line 68) | public static long getHeaderSize(HttpHeaders headers) {
    method decompressContents (line 84) | public static byte[] decompressContents(byte[] fullMessage) throws Dec...
    method hasTextualContent (line 128) | public static boolean hasTextualContent(String contentType) {
    method extractReadableBytes (line 145) | public static byte[] extractReadableBytes(ByteBuf content) {
    method getContentAsString (line 163) | public static String getContentAsString(byte[] content, Charset charse...
    method readCharsetInContentTypeHeader (line 179) | public static Charset readCharsetInContentTypeHeader(String contentTyp...
    method getRawPathAndParamsFromRequest (line 207) | public static String getRawPathAndParamsFromRequest(HttpRequest httpRe...
    method getRawPathAndParamsFromUri (line 229) | public static String getRawPathAndParamsFromUri(String uriString) thro...
    method isRedirect (line 247) | public static boolean isRedirect(HttpResponse httpResponse) {
    method removeMatchingPort (line 274) | public static String removeMatchingPort(String hostWithPort, int portN...
    method base64EncodeBasicCredentials (line 292) | public static String base64EncodeBasicCredentials(String username, Str...

FILE: app/src/main/java/net/lightbody/bmp/util/BrowserMobProxyUtil.java
  class BrowserMobProxyUtil (line 22) | public class BrowserMobProxyUtil {
    method get (line 39) | @Override
    method copyHarThroughPageRef (line 54) | public static Har copyHarThroughPageRef(Har har, String pageRef) {
    method getVersionString (line 101) | public static String getVersionString() {
    method readVersionFileOnClasspath (line 110) | private static String readVersionFileOnClasspath() {

FILE: app/src/main/java/net/lightbody/bmp/util/ClasspathResourceUtil.java
  class ClasspathResourceUtil (line 17) | public class ClasspathResourceUtil {
    method classpathResourceToString (line 29) | public static String classpathResourceToString(String resource, Charse...

FILE: app/src/main/java/net/lightbody/bmp/util/HttpMessageContents.java
  class HttpMessageContents (line 19) | public class HttpMessageContents {
    method HttpMessageContents (line 28) | public HttpMessageContents(FullHttpMessage httpMessage) {
    method setTextContents (line 39) | public void setTextContents(String newContents) {
    method setBinaryContents (line 54) | public void setBinaryContents(byte[] newBinaryContents) {
    method getTextContents (line 70) | public String getTextContents() throws java.nio.charset.UnsupportedCha...
    method getBinaryContents (line 85) | public byte[] getBinaryContents() {
    method getContentType (line 100) | public String getContentType() {
    method getCharset (line 118) | public Charset getCharset() throws java.nio.charset.UnsupportedCharset...
    method isText (line 143) | public boolean isText() {

FILE: app/src/main/java/net/lightbody/bmp/util/HttpMessageInfo.java
  class HttpMessageInfo (line 9) | public class HttpMessageInfo {
    method HttpMessageInfo (line 16) | public HttpMessageInfo(HttpRequest originalRequest, ChannelHandlerCont...
    method getOriginalRequest (line 27) | public HttpRequest getOriginalRequest() {
    method getChannelHandlerContext (line 34) | public ChannelHandlerContext getChannelHandlerContext() {
    method isHttps (line 41) | public boolean isHttps() {
    method getOriginalUrl (line 49) | public String getOriginalUrl() {
    method getUrl (line 58) | public String getUrl() {

FILE: app/src/main/java/net/lightbody/bmp/util/HttpObjectUtil.java
  class HttpObjectUtil (line 19) | public class HttpObjectUtil {
    method replaceTextHttpEntityBody (line 33) | public static void replaceTextHttpEntityBody(FullHttpMessage message, ...
    method replaceBinaryHttpEntityBody (line 64) | public static void replaceBinaryHttpEntityBody(FullHttpMessage message...
    method extractHttpEntityBody (line 83) | public static String extractHttpEntityBody(HttpContent httpContent, Ch...
    method extractHttpEntityBody (line 101) | public static String extractHttpEntityBody(FullHttpMessage httpMessage) {
    method getCharsetFromMessage (line 128) | public static Charset getCharsetFromMessage(HttpMessage httpMessage) t...
    method extractBinaryHttpEntityBody (line 145) | public static byte[] extractBinaryHttpEntityBody(HttpContent httpConte...

FILE: app/src/main/java/net/lightbody/bmp/util/HttpUtil.java
  class HttpUtil (line 16) | public class HttpUtil {
    method getHostFromRequest (line 24) | public static String getHostFromRequest(HttpRequest httpRequest) {
    method getHostAndPortFromRequest (line 51) | public static String getHostAndPortFromRequest(HttpRequest httpRequest) {
    method startsWithHttpOrHttps (line 69) | public static boolean startsWithHttpOrHttps(String uri) {
    method getHostAndPortFromUri (line 92) | public static String getHostAndPortFromUri(String uriString) throws UR...
    method parseHostHeader (line 108) | private static String parseHostHeader(HttpRequest httpRequest, boolean...

FILE: app/src/test/java/me/moxun/dreamcatcher/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test
Condensed preview — 289 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,148K chars).
[
  {
    "path": ".gitignore",
    "chars": 118,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n"
  },
  {
    "path": ".idea/compiler.xml",
    "chars": 686,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <resourceExt"
  },
  {
    "path": ".idea/copyright/profiles_settings.xml",
    "chars": 74,
    "preview": "<component name=\"CopyrightManager\">\n  <settings default=\"\" />\n</component>"
  },
  {
    "path": ".idea/encodings.xml",
    "chars": 159,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"PROJECT\" chars"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 626,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linke"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 3187,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"EntryPointsManager\">\n    <entry_points v"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 361,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2016 moxun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "README.md",
    "chars": 3156,
    "preview": "# Dream-Catcher\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Dream%20Catcher-green.svg?style=flat)"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 2586,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"24.0.3\"\n    defaultCo"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 663,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/androidTest/java/me/moxun/dreamcatcher/ExampleInstrumentedTest.java",
    "chars": 746,
    "preview": "package me.moxun.dreamcatcher;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimp"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 952,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          pa"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/CaptureActivity.java",
    "chars": 9228,
    "preview": "package me.moxun.dreamcatcher;\n\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android.os.Bundle;\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/DCApplication.java",
    "chars": 728,
    "preview": "package me.moxun.dreamcatcher;\n\nimport android.content.Intent;\nimport android.support.multidex.MultiDexApplication;\n\nimp"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/State.java",
    "chars": 161,
    "preview": "package me.moxun.dreamcatcher;\n\n/**\n * Created by moxun on 16/12/12.\n */\n\npublic interface State {\n    int IDLE = 0;\n   "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/Connector.java",
    "chars": 7820,
    "preview": "package me.moxun.dreamcatcher.connector;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/InspectorModulesProvider.java",
    "chars": 210,
    "preview": "package me.moxun.dreamcatcher.connector;\n\n\nimport me.moxun.dreamcatcher.connector.inspector.protocol.ChromeDevtoolsDomai"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/console/CLog.java",
    "chars": 1585,
    "preview": "\npackage me.moxun.dreamcatcher.connector.console;\n\n\nimport me.moxun.dreamcatcher.connector.inspector.helper.ChromePeerMa"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/console/ConsolePeerManager.java",
    "chars": 610,
    "preview": "package me.moxun.dreamcatcher.connector.console;\n\n\nimport javax.annotation.Nullable;\n\nimport me.moxun.dreamcatcher.conne"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeRepl.java",
    "chars": 138,
    "preview": "package me.moxun.dreamcatcher.connector.console;\n\npublic interface RuntimeRepl {\n  Object evaluate(String expression) th"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/console/RuntimeReplFactory.java",
    "chars": 556,
    "preview": "package me.moxun.dreamcatcher.connector.console;\n\n/**\n * Allows callers to specify their own Console tab REPL for the De"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/console/command/CommandHandler.java",
    "chars": 281,
    "preview": "package me.moxun.dreamcatcher.connector.console.command;\n\nimport android.support.annotation.Nullable;\n\n/**\n * Created by"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDevtoolsServer.java",
    "chars": 8503,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\nimport android.util.Log;\n\nimport org.greenrobot.eventbus.EventBus;\ni"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/ChromeDiscoveryHandler.java",
    "chars": 8375,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\nimport android.content.Context;\nimport android.content.pm.PackageInf"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/DevtoolsSocketHandler.java",
    "chars": 1549,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\nimport android.content.Context;\n\nimport java.io.IOException;\n\nimport"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MessageHandlingException.java",
    "chars": 264,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\npublic class MessageHandlingException extends Exception {\n  public M"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MethodDispatcher.java",
    "chars": 6889,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/MismatchedResponseException.java",
    "chars": 391,
    "preview": "package me.moxun.dreamcatcher.connector.inspector;\n\npublic class MismatchedResponseException extends MessageHandlingExce"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ChromePeerManager.java",
    "chars": 4250,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\n\nimport java.nio.channels.NotYetConnectedException;\nimport ja"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ObjectIdMapper.java",
    "chars": 2749,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\nimport android.util.SparseArray;\n\nimport java.util.IdentityHa"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeerRegistrationListener.java",
    "chars": 255,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\n\nimport me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcPeer;\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/PeersRegisteredListener.java",
    "chars": 875,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport me"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/ThreadBoundProxy.java",
    "chars": 1187,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\n\nimport me.moxun.dreamcatcher.connector.util.ThreadBound;\nimp"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/helper/TracingPeerManager.java",
    "chars": 564,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.helper;\n\nimport javax.annotation.Nullable;\n\n/**\n * Created by moxun on"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/ChromeDevtoolsDomain.java",
    "chars": 143,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol;\n\n/**\n * Created by moxun on 16/3/18.\n */\npublic interface Ch"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/ChromeDevtoolsMethod.java",
    "chars": 266,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol;\n\nimport java.lang.annotation.Retention;\nimport java.lang.ann"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleBooleanResult.java",
    "chars": 430,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol;\n\n\nimport me.moxun.dreamcatcher.connector.json.annotation.Jso"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleIntegerResult.java",
    "chars": 480,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol;\n\n\nimport me.moxun.dreamcatcher.connector.json.annotation.Jso"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/SimpleStringResult.java",
    "chars": 474,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol;\n\n\nimport me.moxun.dreamcatcher.connector.json.annotation.Jso"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Console.java",
    "chars": 3854,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\nimport android.annotation.SuppressLint;\n\nimport org."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/FileSystem.java",
    "chars": 9355,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\nimport android.content.Context;\n\nimport org.json.JSO"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Inspector.java",
    "chars": 584,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\n\nimport org.json.JSONObject;\n\nimport me.moxun.dreamc"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Network.java",
    "chars": 8242,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\nimport android.content.Context;\n\nimport org.json.JSO"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Page.java",
    "chars": 8584,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\nimport android.content.Context;\n\nimport org.json.JSO"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Profiler.java",
    "chars": 1553,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\n\nimport org.json.JSONObject;\n\nimport java.util.Colle"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/protocol/module/Runtime.java",
    "chars": 20923,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.protocol.module;\n\n\nimport org.json.JSONException;\nimport org.json.JSON"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/inspector/runtime/DefaultRuntimeReplFactory.java",
    "chars": 2173,
    "preview": "package me.moxun.dreamcatcher.connector.inspector.runtime;\n\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport me."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/json/ObjectMapper.java",
    "chars": 12766,
    "preview": "package me.moxun.dreamcatcher.connector.json;\n\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.jso"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/json/annotation/JsonProperty.java",
    "chars": 253,
    "preview": "package me.moxun.dreamcatcher.connector.json.annotation;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annota"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/json/annotation/JsonValue.java",
    "chars": 214,
    "preview": "package me.moxun.dreamcatcher.connector.json.annotation;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annota"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/DisconnectReceiver.java",
    "chars": 248,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\n/**\n * @see JsonRpcPeer#registerDisconnectReceiver(DisconnectReceiver)"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcException.java",
    "chars": 513,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\n\nimport me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcError;"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcPeer.java",
    "chars": 2898,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\nimport android.database.Observable;\n\nimport org.json.JSONObject;\n\nimpo"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/JsonRpcResult.java",
    "chars": 314,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\n\nimport me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcRespon"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequest.java",
    "chars": 645,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\nimport javax.annotation.Nullable;\n\n/**\n * Represents an outstanding re"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/PendingRequestCallback.java",
    "chars": 232,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc;\n\n\nimport me.moxun.dreamcatcher.connector.jsonrpc.protocol.JsonRpcRespon"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/EmptyResult.java",
    "chars": 177,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc.protocol;\n\n\nimport me.moxun.dreamcatcher.connector.jsonrpc.JsonRpcResult"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcError.java",
    "chars": 1141,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc.protocol;\n\nimport android.annotation.SuppressLint;\n\nimport org.json.JSON"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcEvent.java",
    "chars": 596,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc.protocol;\n\nimport android.annotation.SuppressLint;\n\nimport org.json.JSON"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcRequest.java",
    "chars": 879,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc.protocol;\n\nimport android.annotation.SuppressLint;\n\nimport org.json.JSON"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/jsonrpc/protocol/JsonRpcResponse.java",
    "chars": 446,
    "preview": "package me.moxun.dreamcatcher.connector.jsonrpc.protocol;\n\nimport android.annotation.SuppressLint;\n\nimport org.json.JSON"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/log/AELog.java",
    "chars": 894,
    "preview": "package me.moxun.dreamcatcher.connector.log;\n\n/**\n * 输出日志到Chrome控制台\n * Created by moxun on 16/4/25.\n */\npublic class AEL"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/log/AELogImpl.java",
    "chars": 1194,
    "preview": "package me.moxun.dreamcatcher.connector.log;\n\n\nimport me.moxun.dreamcatcher.connector.console.CLog;\nimport me.moxun.drea"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/log/IAELog.java",
    "chars": 260,
    "preview": "package me.moxun.dreamcatcher.connector.log;\n\n/**\n * Created by moxun on 16/4/25.\n */\npublic interface IAELog {\n    bool"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/manager/Lifecycle.java",
    "chars": 372,
    "preview": "package me.moxun.dreamcatcher.connector.manager;\n\n/**\n * Created by moxun on 16/12/9.\n */\n\npublic interface Lifecycle {\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/manager/SimpleConnectorLifecycleManager.java",
    "chars": 853,
    "preview": "package me.moxun.dreamcatcher.connector.manager;\n\nimport me.moxun.dreamcatcher.connector.inspector.ChromeDiscoveryHandle"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinter.java",
    "chars": 1105,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.i"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterExecutorHolder.java",
    "chars": 766,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurr"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterFactory.java",
    "chars": 683,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n/**\n * Interface for creating a factory for asynchronous pretty print"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterInitializer.java",
    "chars": 629,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n/**\n * Interface that is called if AsyncPrettyPrinterRegistry is unpo"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/AsyncPrettyPrinterRegistry.java",
    "chars": 707,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport javax.annotat"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/CountingOutputStream.java",
    "chars": 724,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.FilterOutputStream;\nimport java.io.IOException;\nimport"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DecompressionHelper.java",
    "chars": 1889,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DefaultResponseHandler.java",
    "chars": 1233,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.IOException;\n\n/**\n * Simple interceptor that delegates"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/DownloadingAsyncPrettyPrinterFactory.java",
    "chars": 5629,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/GunzippingOutputStream.java",
    "chars": 2885,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport java.io.FilterOutputStream;\nimport java.io.IOException;\nimpor"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/MimeMatcher.java",
    "chars": 2271,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport android.annotation.SuppressLint;\n\nimport java.util.ArrayList;\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporter.java",
    "chars": 8526,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport javax"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkEventReporterImpl.java",
    "chars": 14402,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport android.os.SystemClock;\n\nimport org.json.JSONException;\nimport"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/NetworkPeerManager.java",
    "chars": 2332,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport android.content.Context;\n\nimport javax.annotation.Nullable;\n\ni"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/PrettyPrinterDisplayType.java",
    "chars": 652,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport me.moxun.dreamcatcher.connector.inspector.protocol.module.Pag"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/RequestBodyHelper.java",
    "chars": 2360,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimp"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResourceTypeHelper.java",
    "chars": 1668,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport me.moxun.dreamcatcher.connector.inspector.protocol.module.Pag"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseBodyData.java",
    "chars": 285,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n/**\n * Special file data necessary to comply with the Chrome DevTools"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseBodyFileManager.java",
    "chars": 5783,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport android.content.Context;\nimport android.util.Base64;\nimport an"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseHandler.java",
    "chars": 1205,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\nimport java.io.IOException;\n\n/**\n * Custom hook to intercept read eve"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/reporter/ResponseHandlingInputStream.java",
    "chars": 7760,
    "preview": "package me.moxun.dreamcatcher.connector.reporter;\n\n\nimport java.io.FilterInputStream;\nimport java.io.IOException;\nimport"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/AddressNameHelper.java",
    "chars": 346,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\n\nimport me.moxun.dreamcatcher.connector.util.ProcessUtil;\n\npublic class"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/CompositeInputStream.java",
    "chars": 2588,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport javax."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/LazySocketHandler.java",
    "chars": 1099,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.net.LocalSocket;\n\nimport java.io.IOException;\n\nimport ja"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/LeakyBufferedInputStream.java",
    "chars": 1470,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayInputStream"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/LocalSocketServer.java",
    "chars": 5073,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.net.LocalServerSocket;\nimport android.net.LocalSocket;\n\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/PeerAuthorizationException.java",
    "chars": 189,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\npublic class PeerAuthorizationException extends Exception {\n  public Pe"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/ProtocolDetectingSocketHandler.java",
    "chars": 3267,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.content.Context;\nimport android.net.LocalSocket;\n\nimport"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/SecureSocketHandler.java",
    "chars": 1569,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/ServerManager.java",
    "chars": 2214,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\n\nimport org.greenrobot.eventbus.EventBus;\n\nimport java.io.IOException;\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketHandler.java",
    "chars": 534,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.net.LocalSocket;\n\nimport java.io.IOException;\n\n/**\n * @s"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketHandlerFactory.java",
    "chars": 147,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\n/** @see LazySocketHandler */\npublic interface SocketHandlerFactory {\n "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketLike.java",
    "chars": 1417,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.net.LocalSocket;\n\nimport java.io.IOException;\nimport jav"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/SocketLikeHandler.java",
    "chars": 488,
    "preview": "package me.moxun.dreamcatcher.connector.server;\n\nimport android.net.LocalSocket;\n\nimport java.io.IOException;\n\n/**\n * Si"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/ExactPathMatcher.java",
    "chars": 418,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\npublic class ExactPathMatcher implements PathMatcher {\n  private f"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HandlerRegistry.java",
    "chars": 1208,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport android.support.annotation.Nullable;\n\nimport java.util.Arra"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpHandler.java",
    "chars": 330,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\n\nimport java.io.IOException;\n\nimport me.moxun.dreamcatcher.connect"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpHeaders.java",
    "chars": 171,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\npublic interface HttpHeaders {\n  String CONTENT_TYPE = \"Content-Ty"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/HttpStatus.java",
    "chars": 247,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\npublic interface HttpStatus {\n  int HTTP_SWITCHING_PROTOCOLS = 101"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpBody.java",
    "chars": 1126,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport ja"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpMessage.java",
    "chars": 727,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport android.support.annotation.Nullable;\n\nimport java.util.Arra"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpRequest.java",
    "chars": 534,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport android.net.Uri;\n\npublic class LightHttpRequest extends Lig"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpResponse.java",
    "chars": 832,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\npublic class LightHttpResponse extends LightHttpMessage {\n    publ"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/LightHttpServer.java",
    "chars": 10801,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport android.net.Uri;\nimport android.support.annotation.Nullable"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/PathMatcher.java",
    "chars": 117,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\npublic interface PathMatcher {\n  boolean match(String path);\n}\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/server/http/RegexpPathMatcher.java",
    "chars": 354,
    "preview": "package me.moxun.dreamcatcher.connector.server.http;\n\nimport java.util.regex.Pattern;\n\npublic class RegexpPathMatcher im"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/Accumulator.java",
    "chars": 107,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\npublic interface Accumulator<E> {\n  void store(E object);\n}\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ArrayListAccumulator.java",
    "chars": 235,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport java.util.ArrayList;\n\npublic final class ArrayListAccumulator<E> e"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ColorStringUtil.java",
    "chars": 216,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n/**\n * Created by moxun on 16/4/8.\n */\npublic class ColorStringUtil {\n   "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/DreamCatcherCrashHandler.java",
    "chars": 1361,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n\nimport me.moxun.dreamcatcher.connector.log.AELog;\n\n/**\n * Created by mox"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ExceptionUtil.java",
    "chars": 607,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\npublic class ExceptionUtil {\n  @SuppressWarnings(\"unchecked\")\n  public st"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/IServerManager.java",
    "chars": 177,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n/**\n * Created by moxun on 16/7/1.\n */\npublic interface IServerManager {\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/KLog.java",
    "chars": 6503,
    "preview": "/*\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BS"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/KLogImpl.java",
    "chars": 2450,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\npublic class KLogImpl implements LogInterface {\n    @Override\n    public "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/Keys.java",
    "chars": 469,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n/**\n * Created by moxun on 16/6/20.\n */\npublic interface Keys {\n    Strin"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ListUtil.java",
    "chars": 5583,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport java.util.AbstractList;\nimport java.util.Collections;\nimport java."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/LogFilter.java",
    "chars": 717,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\n/**\n * Create"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/LogInterface.java",
    "chars": 1317,
    "preview": "/*\n * Copyright (c) 2014-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BS"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/LogUtil.java",
    "chars": 5968,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport android.support.annotation.NonNull;\nimport android.util.Log;\n\nimpo"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/Predicate.java",
    "chars": 103,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\npublic interface Predicate<T> {\n  boolean apply(T t);\n}\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ProcessUtil.java",
    "chars": 1798,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\nimport javax"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ReflectionUtil.java",
    "chars": 5033,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport android.view.View;\nimport android.widget.TextView;\n\nimport java.la"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/SocketServerManager.java",
    "chars": 1821,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Created by moxun"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/StringUtil.java",
    "chars": 572,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\npublic final class StringUtil {\n  private StringUtil() {\n  }\n\n  @Suppress"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/ThreadBound.java",
    "chars": 2420,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n/**\n * Implemented by an object whose methods must be called on a specifi"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/UncheckedCallable.java",
    "chars": 392,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\n/**\n * A task that returns a result. Implementers define a single method "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/Utf8Charset.java",
    "chars": 546,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport java.io.UnsupportedEncodingException;\nimport java.nio.charset.Char"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/util/Util.java",
    "chars": 3749,
    "preview": "package me.moxun.dreamcatcher.connector.util;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.Closeable;\nimport ja"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/CloseCodes.java",
    "chars": 255,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\n/**\n * Close codes as defined by RFC6455.\n */\npublic interface Close"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/Frame.java",
    "chars": 4031,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStr"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/FrameHelper.java",
    "chars": 1790,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\n\nimport me.moxun.dreamcatcher.connector.util.Utf8Charset;\n\nclass Fra"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/MaskingHelper.java",
    "chars": 260,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nclass MaskingHelper {\n  public static void unmask(byte[] key, byte[]"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/ReadCallback.java",
    "chars": 148,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\ninterface ReadCallback {\n  void onCompleteFrame(byte opcode, byte[] "
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/ReadHandler.java",
    "chars": 1394,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputSt"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/SimpleEndpoint.java",
    "chars": 1877,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\n/**\n * Alternative to JSR-356's Endpoint class but with a less insan"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/SimpleSession.java",
    "chars": 494,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\n/**\n * Alternative to JSR-356's Session class but with a less insane"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WebSocketHandler.java",
    "chars": 5915,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport android.util.Base64;\n\nimport java.io.BufferedOutputStream;\nim"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WebSocketSession.java",
    "chars": 5486,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport java.io.EOFException;\nimport java.io.IOException;\nimport java"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WriteCallback.java",
    "chars": 162,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport java.io.IOException;\n\ninterface WriteCallback {\n  void onFail"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/connector/websocket/WriteHandler.java",
    "chars": 663,
    "preview": "package me.moxun.dreamcatcher.connector.websocket;\n\nimport java.io.BufferedOutputStream;\nimport java.io.IOException;\nimp"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/event/CaptureEvent.java",
    "chars": 448,
    "preview": "package me.moxun.dreamcatcher.event;\n\nimport org.greenrobot.eventbus.EventBus;\n\n/**\n * Created by moxun on 16/12/9.\n */\n"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/event/OperateEvent.java",
    "chars": 1056,
    "preview": "package me.moxun.dreamcatcher.event;\n\n/**\n * Created by moxun on 16/12/12.\n */\n\npublic class OperateEvent {\n    public s"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/misc/X509ExtendedTrustManager.java",
    "chars": 5600,
    "preview": "package me.moxun.dreamcatcher.misc;\n\n/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apach"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/service/ConnectorService.java",
    "chars": 767,
    "preview": "package me.moxun.dreamcatcher.service;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.IBi"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/service/ProxyService.java",
    "chars": 2653,
    "preview": "package me.moxun.dreamcatcher.service;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.Asy"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/wrapper/DCHeader.java",
    "chars": 1322,
    "preview": "package me.moxun.dreamcatcher.wrapper;\n\nimport android.util.Pair;\n\nimport java.util.ArrayList;\n\nimport javax.annotation."
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/wrapper/DCRequest.java",
    "chars": 1764,
    "preview": "package me.moxun.dreamcatcher.wrapper;\n\nimport net.lightbody.bmp.core.har.HarEntry;\nimport net.lightbody.bmp.core.har.Ha"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/wrapper/DCResponse.java",
    "chars": 2437,
    "preview": "package me.moxun.dreamcatcher.wrapper;\n\nimport net.lightbody.bmp.core.har.HarEntry;\nimport net.lightbody.bmp.core.har.Ha"
  },
  {
    "path": "app/src/main/java/me/moxun/dreamcatcher/wrapper/ProxyManager.java",
    "chars": 3550,
    "preview": "package me.moxun.dreamcatcher.wrapper;\n\nimport android.util.Log;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.By"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/BrowserMobProxy.java",
    "chars": 30415,
    "preview": "package net.lightbody.bmp;\n\nimport net.lightbody.bmp.core.har.Har;\nimport net.lightbody.bmp.filters.RequestFilter;\nimpor"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/BrowserMobProxyServer.java",
    "chars": 42816,
    "preview": "package net.lightbody.bmp;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMa"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/client/ClientUtil.java",
    "chars": 5986,
    "preview": "package net.lightbody.bmp.client;\n\nimport com.google.common.collect.ImmutableList;\n\nimport net.lightbody.bmp.proxy.dns.A"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/Har.java",
    "chars": 869,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\nimport java.io.File;\nimport ja"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarCache.java",
    "chars": 655,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\n@JsonInclude(JsonInclude.Incl"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarCacheStatus.java",
    "chars": 1338,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.d"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarContent.java",
    "chars": 1691,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\n@JsonInclude(JsonInclude.Incl"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarCookie.java",
    "chars": 2446,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.d"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarEntry.java",
    "chars": 5932,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonAutoDetect;\nimport com.fasterxml.jackso"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarLog.java",
    "chars": 1825,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\nimport java.util.List;\nimport"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarNameValuePair.java",
    "chars": 1262,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport java.net.URLDecoder;\n\npublic final class HarNameValuePair {\n    private fina"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarNameVersion.java",
    "chars": 568,
    "preview": "package net.lightbody.bmp.core.har;\n\npublic class HarNameVersion {\n    private final String name;\n    private final Stri"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarPage.java",
    "chars": 1507,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.d"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarPageTimings.java",
    "chars": 929,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\n@JsonInclude(JsonInclude.Incl"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarPostData.java",
    "chars": 1087,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\nimport java.util.List;\n\n@Json"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarPostDataParam.java",
    "chars": 1255,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\n@JsonInclude(JsonInclude.Incl"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarRequest.java",
    "chars": 2457,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\n\nimport java.util.List;\nimport"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarResponse.java",
    "chars": 3113,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.a"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/har/HarTimings.java",
    "chars": 5190,
    "preview": "package net.lightbody.bmp.core.har;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class HarTimings {\n    // optional va"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/json/ISO8601DateFormatter.java",
    "chars": 773,
    "preview": "package net.lightbody.bmp.core.json;\n\nimport com.fasterxml.jackson.core.JsonGenerationException;\nimport com.fasterxml.ja"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/core/json/ISO8601WithTDZDateFormatter.java",
    "chars": 1136,
    "preview": "package net.lightbody.bmp.core.json;\n\nimport com.fasterxml.jackson.core.JsonGenerationException;\nimport com.fasterxml.ja"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/exception/DecompressionException.java",
    "chars": 564,
    "preview": "package net.lightbody.bmp.exception;\n\n/**\n * Indicates that an error occurred while decompressing content.\n */\npublic cl"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/exception/UnsupportedCharsetException.java",
    "chars": 1119,
    "preview": "package net.lightbody.bmp.exception;\n\n/**\n * A checked exception wrapper for {@link java.nio.charset.UnsupportedCharsetE"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/AddHeadersFilter.java",
    "chars": 1439,
    "preview": "package net.lightbody.bmp.filters;\n\nimport org.littleshoot.proxy.HttpFiltersAdapter;\n\nimport java.util.Collections;\nimpo"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java",
    "chars": 2213,
    "preview": "package net.lightbody.bmp.filters;\n\nimport org.littleshoot.proxy.impl.ProxyUtils;\n\nimport java.util.Map;\n\nimport io.nett"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java",
    "chars": 2362,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.proxy.BlacklistEntry;\n\nimport java.util.Collection;\nimport "
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/BrowserMobHttpFilterChain.java",
    "chars": 11953,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.BrowserMobProxyServer;\n\nimport org.littleshoot.proxy.HttpFi"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java",
    "chars": 3243,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.BrowserMobHttpUtil;\n\nimport org.littleshoot.proxy.Http"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java",
    "chars": 39199,
    "preview": "package net.lightbody.bmp.filters;\n\nimport android.util.Log;\n\nimport com.google.common.collect.ImmutableList;\n\nimport ne"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/HttpConnectHarCaptureFilter.java",
    "chars": 17534,
    "preview": "package net.lightbody.bmp.filters;\n\nimport com.google.common.cache.CacheBuilder;\n\nimport net.lightbody.bmp.core.har.Har;"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/HttpsAwareFiltersAdapter.java",
    "chars": 7675,
    "preview": "package net.lightbody.bmp.filters;\n\nimport com.google.common.net.HostAndPort;\n\nimport net.lightbody.bmp.util.BrowserMobH"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/HttpsHostCaptureFilter.java",
    "chars": 2022,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.BrowserMobHttpUtil;\n\nimport org.littleshoot.proxy.Http"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/HttpsOriginalHostCaptureFilter.java",
    "chars": 2084,
    "preview": "package net.lightbody.bmp.filters;\n\nimport org.littleshoot.proxy.impl.ProxyUtils;\n\nimport io.netty.channel.ChannelHandle"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/LatencyFilter.java",
    "chars": 1407,
    "preview": "package net.lightbody.bmp.filters;\n\nimport org.littleshoot.proxy.HttpFiltersAdapter;\nimport org.slf4j.Logger;\nimport org"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/ModifiedRequestAwareFilter.java",
    "chars": 854,
    "preview": "package net.lightbody.bmp.filters;\n\nimport io.netty.handler.codec.http.HttpRequest;\n\n/**\n * Indicates that a filter wish"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/RegisterRequestFilter.java",
    "chars": 1054,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.proxy.ActivityMonitor;\n\nimport org.littleshoot.proxy.HttpFi"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/RequestFilter.java",
    "chars": 1439,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.HttpMessageContents;\nimport net.lightbody.bmp.util.Htt"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/RequestFilterAdapter.java",
    "chars": 4447,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.HttpMessageContents;\nimport net.lightbody.bmp.util.Htt"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/ResolvedHostnameCacheFilter.java",
    "chars": 3557,
    "preview": "package net.lightbody.bmp.filters;\n\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\ni"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/ResponseFilter.java",
    "chars": 1179,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.HttpMessageContents;\nimport net.lightbody.bmp.util.Htt"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/ResponseFilterAdapter.java",
    "chars": 4780,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.util.HttpMessageContents;\nimport net.lightbody.bmp.util.Htt"
  },
  {
    "path": "app/src/main/java/net/lightbody/bmp/filters/RewriteUrlFilter.java",
    "chars": 6532,
    "preview": "package net.lightbody.bmp.filters;\n\nimport net.lightbody.bmp.proxy.RewriteRule;\nimport net.lightbody.bmp.util.BrowserMob"
  }
]

// ... and 89 more files (download for full content)

About this extraction

This page contains the full source code of the misakuo/Dream-Catcher GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 289 files (1.0 MB), approximately 348.9k tokens, and a symbol index with 2091 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!