[
  {
    "path": ".gitignore",
    "content": "### Gradle ###\n.gradle\nbuild/\n\n### Intellij ###\n\n## Directory-based project format\n.idea/\n\n## File-based project format\n*.ipr\n*.iml\n*.iws\n\n## Additional for IntelliJ\nout/\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: java\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "NOTICE.txt",
    "content": ""
  },
  {
    "path": "README.md",
    "content": "A prototype Netty embedded servlet bridge for Spring Boot.\n\nIncludes basic filter and servlet support. I'm fairly new to Spring Boot, but this approach seems to fit it's opinionated view of the servlet container. Async servlet support isn't yet completed.\n\n[![Build Status](https://travis-ci.org/DanielThomas/spring-boot-starter-netty.svg?branch=master)](https://travis-ci.org/DanielThomas/spring-boot-starter-netty)\n\nPerformance\n=============\n\nUse the `runTestApp` Gradle task to start the server with the same configuration used here. Tests run with `wrk` with the following arguments:\n\n    wrk -H 'Host: localhost' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Connection: keep-alive' -d 120 -c 32 -t 2 http://localhost:8080/plaintext\n\nTomcat 7.0.55\n-------------\n\n    Running 2m test @ http://localhost:8080/plaintext\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency    22.96ms  115.34ms 628.47ms   96.50%\n        Req/Sec    16.33k     4.74k   34.44k    83.57%\n      3691775 requests in 2.00m, 497.09MB read\n    Requests/sec:  30764.62\n    Transfer/sec:      4.14MB\n\nTomcat 8.0.9\n-------------\n\n    Running 2m test @ http://localhost:8080/plaintext\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency   114.10ms  745.91ms   5.04s    97.75%\n        Req/Sec    15.67k     2.99k   27.56k    91.68%\n      3553322 requests in 2.00m, 478.45MB read\n      Socket errors: connect 0, read 0, write 0, timeout 3\n    Requests/sec:  29611.00\n    Transfer/sec:      3.99MB\n\nPrototype Netty 4.0 Bridge\n-------------\n\n    Running 2m test @ http://localhost:8080/plaintext\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     1.14ms    6.64ms 128.33ms   99.33%\n        Req/Sec    19.64k     4.16k   45.22k    83.96%\n      4459068 requests in 2.00m, 331.69MB read\n    Requests/sec:  37158.91\n    Transfer/sec:      2.76MB\n\nNote: Difference in transfer/sec is due to Server and Date headers returned by Tomcat\n\nPrototype Netty 4.1 Beta 1 Bridge\n-------------\n\n    Running 2m test @ http://localhost:8080/plaintext\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     1.09ms    7.58ms 200.99ms   99.80%\n        Req/Sec    19.14k     2.19k   39.89k    84.44%\n      4366902 requests in 2.00m, 408.12MB read\n    Requests/sec:  36390.84\n    Transfer/sec:      3.40MB\n\nWhen compared to a null servlet:\n\n    Running 2m test @ http://localhost:8080/null\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency   820.84us    3.47ms  66.04ms   99.70%\n        Req/Sec    26.03k     4.27k   45.44k    69.68%\n      5894335 requests in 2.00m, 505.91MB read\n    Requests/sec:  49119.58\n\nAnd to serving the response directly from Netty:\n\n    Running 2m test @ http://localhost:8080/nullnetty\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     2.01ms   23.54ms 400.01ms   99.65%\n        Req/Sec    27.21k     4.26k   41.44k    66.08%\n      6164886 requests in 2.00m, 223.41MB read\n    Requests/sec:  51374.16\n\nPrototype Netty 4.1 Beta 3 Bridge (Commit eb531c6)\n-------------\n\n    Running 2m test @ http://localhost:8080/plaintext\n      2 threads and 32 connections\n      Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     1.95ms   18.62ms 289.53ms   99.57%\n        Req/Sec    20.48k     2.55k   37.78k    86.51%\n      4637061 requests in 2.00m, 698.71MB read\n    Requests/sec:  38642.24\n    Transfer/sec:      5.82MB\n"
  },
  {
    "path": "build.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id 'java'\n    id 'groovy'\n    id 'com.github.ben-manes.versions' version '0.11.3'\n}\n\nversion '1.0-SNAPSHOT'\ndescription 'Spring Boot Netty Starter'\n\napply from: 'gradle/dependencies.gradle'\napply from: 'gradle/idea.gradle'\napply from: 'gradle/maven.gradle'\napply from: 'gradle/test.gradle'\n\ndependencies {\n    compile libraries.guava\n    compile libraries.netty\n    compile libraries.servletapi\n    compile libraries.springboot\n\n    testCompile libraries.testlibs\n}\n\njar {\n    manifest {\n        attributes('Implementation-Title': description, 'Implementation-Version': version)\n    }\n}\n\ntask wrapper(type: Wrapper) { gradleVersion = '2.8' }\n\nrepositories {\n    jcenter()\n}\n"
  },
  {
    "path": "gradle/benchmark.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\ndependencies {\n    testCompile 'org.openjdk.jmh:jmh-generator-annprocess:1.11.2'\n}\n\ntask(benchmark, type: JavaExec) {\n    classpath sourceSets.test.runtimeClasspath\n    main = 'org.openjdk.jmh.Main'\n}\n\ntask(integBenchmark, type: JavaExec) {\n    classpath sourceSets.integTest.runtimeClasspath\n    main = 'org.openjdk.jmh.Main'\n}\n"
  },
  {
    "path": "gradle/dependencies.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\next {\n    libraries = [:]\n    versions = [:]\n}\n\nversions.guava = '18.0'\nversions.spock = '1.0-groovy-2.4'\nversions.springboot = '1.2.7.RELEASE'\n\nconfigurations.all {\n    resolutionStrategy {\n        eachDependency { details ->\n            switch (details.requested.name) {\n                case 'junit':\n                case 'junit-dep':\n                    details.useTarget 'junit:junit:4.11'\n                    break\n            }\n            if (details.requested.group == 'org.apache.tomcat.embed') {\n                details.useVersion '8.0.9'\n            }\n        }\n        def isCiServer = System.getenv().containsKey('HUDSON_HOME')\n        if (isCiServer) {\n            cacheChangingModulesFor 0, 'seconds'\n        }\n    }\n}\n\n\nlibraries.guava = [\n        \"com.google.guava:guava:$versions.guava\",\n        'com.google.code.findbugs:jsr305:3.0.1'\n]\nlibraries.netty = [\n        'io.netty:netty-all:4.1.0.Beta7',\n        'org.javassist:javassist:3.20.0-GA',\n        'com.jcraft:jzlib:1.1.3',\n        'javax.el:javax.el-api:2.2.5'\n]\nlibraries.servletapi = 'javax.servlet:javax.servlet-api:3.1.0'\n\nlibraries.springboot = [\n        dependencies.create(\"org.springframework.boot:spring-boot-starter-web:$versions.springboot\") {\n            exclude module: 'spring-boot-starter-tomcat'\n        }\n]\n\nlibraries.guavatest = \"com.google.guava:guava-testlib:$versions.guava\"\nlibraries.spock = [\n        \"org.spockframework:spock-core:$versions.spock\",\n        'cglib:cglib-nodep:3.2.0',\n        'org.objenesis:objenesis:2.2'\n]\n\nlibraries.testlibs = [\n        libraries.guavatest,\n        libraries.spock\n]\n"
  },
  {
    "path": "gradle/idea-codestyle.xml",
    "content": "<!--\n  ~ Copyright 2014 the original author or authors.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~   http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  -->\n\n<component name=\"ProjectCodeStyleSettingsManager\">\n  <option name=\"PER_PROJECT_SETTINGS\">\n    <value>\n      <option name=\"IMPORT_LAYOUT_TABLE\">\n        <value>\n          <package name=\"io.groundhog\" withSubpackages=\"true\" static=\"false\"/>\n          <emptyLine/>\n          <package name=\"\" withSubpackages=\"true\" static=\"false\"/>\n          <emptyLine/>\n          <package name=\"javax\" withSubpackages=\"true\" static=\"false\"/>\n          <package name=\"java\" withSubpackages=\"true\" static=\"false\"/>\n          <emptyLine/>\n          <package name=\"\" withSubpackages=\"true\" static=\"true\"/>\n        </value>\n      </option>\n      <codeStyleSettings language=\"Groovy\">\n        <indentOptions>\n          <option name=\"INDENT_SIZE\" value=\"4\"/>\n          <option name=\"CONTINUATION_INDENT_SIZE\" value=\"8\"/>\n          <option name=\"TAB_SIZE\" value=\"4\"/>\n        </indentOptions>\n      </codeStyleSettings>\n      <codeStyleSettings language=\"JAVA\">\n        <indentOptions>\n          <option name=\"INDENT_SIZE\" value=\"4\"/>\n          <option name=\"CONTINUATION_INDENT_SIZE\" value=\"8\"/>\n          <option name=\"TAB_SIZE\" value=\"4\"/>\n        </indentOptions>\n        <arrangement>\n          <groups>\n            <group>\n              <type>GETTERS_AND_SETTERS</type>\n              <order>KEEP</order>\n            </group>\n          </groups>\n          <rules>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PUBLIC/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PROTECTED/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PACKAGE_PRIVATE/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PRIVATE/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PUBLIC/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PROTECTED/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PACKAGE_PRIVATE/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PRIVATE/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PUBLIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PROTECTED/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PACKAGE_PRIVATE/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <FINAL/>\n                  <PRIVATE/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PUBLIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PROTECTED/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PACKAGE_PRIVATE/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <FIELD/>\n                  <PRIVATE/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <FIELD/>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <CONSTRUCTOR/>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <METHOD/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <METHOD/>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <ENUM/>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <INTERFACE/>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <AND>\n                  <CLASS/>\n                  <STATIC/>\n                </AND>\n              </match>\n            </rule>\n            <rule>\n              <match>\n                <CLASS/>\n              </match>\n            </rule>\n          </rules>\n        </arrangement>\n      </codeStyleSettings>\n      <XML>\n        <option name=\"XML_LEGACY_SETTINGS_IMPORTED\" value=\"true\"/>\n      </XML>\n      <codeStyleSettings language=\"XML\">\n        <indentOptions>\n          <option name=\"INDENT_SIZE\" value=\"2\"/>\n          <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n          <option name=\"TAB_SIZE\" value=\"2\"/>\n        </indentOptions>\n        <arrangement>\n          <rules>\n            <rule>\n              <match>\n                <NAME>xmlns:.*</NAME>\n              </match>\n            </rule>\n          </rules>\n        </arrangement>\n      </codeStyleSettings>\n    </value>\n  </option>\n  <option name=\"USE_PER_PROJECT_SETTINGS\" value=\"true\"/>\n</component>\n"
  },
  {
    "path": "gradle/idea-copyright.xml",
    "content": "<!--\n  ~ Copyright 2014 the original author or authors.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~   http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  -->\n\n<component name=\"CopyrightManager\" default=\"Apache 2\">\n  <copyright>\n    <option name=\"notice\"\n            value=\"Copyright $today.year the original author or authors.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;&#32;&#32;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License.&#10;\"/>\n    <option name=\"keyword\" value=\"Copyright\"/>\n    <option name=\"allowReplaceKeyword\" value=\"\"/>\n    <option name=\"myName\" value=\"Apache 2\"/>\n    <option name=\"myLocal\" value=\"true\"/>\n  </copyright>\n  <module2copyright>\n    <element module=\"Project Files\" copyright=\"Apache 2\"/>\n  </module2copyright>\n</component>\n"
  },
  {
    "path": "gradle/idea-entrypoints.xml",
    "content": "<component name=\"EntryPointsManager\">\n  <entry_points version=\"2.0\"/>\n  <list size=\"4\">\n    <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.openjdk.jmh.annotations.Benchmark\"/>\n    <item index=\"1\" class=\"java.lang.String\" itemvalue=\"org.openjdk.jmh.annotations.Setup\"/>\n    <item index=\"2\" class=\"java.lang.String\" itemvalue=\"org.openjdk.jmh.annotations.TearDown\"/>\n    <item index=\"3\" class=\"java.lang.String\" itemvalue=\"org.springframework.web.bind.annotation.RequestMapping\"/>\n  </list>\n</component>\n"
  },
  {
    "path": "gradle/idea-inspections.xml",
    "content": "<!--\n  ~ Copyright 2014 the original author or authors.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~   http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  -->\n\n<component name=\"InspectionProjectProfileManager\">\n  <profiles>\n    <profile version=\"1.0\" is_locked=\"false\">\n      <option name=\"myName\" value=\"Project Default\"/>\n      <option name=\"myLocal\" value=\"false\"/>\n      <inspection_tool class=\"RawUseOfParameterizedType\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n        <option name=\"ignoreObjectConstruction\" value=\"false\"/>\n      </inspection_tool>\n      <inspection_tool class=\"UnusedImport\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\"/>\n      <inspection_tool class=\"MissingOverrideAnnotation\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n        <option name=\"ignoreObjectMethods\" value=\"false\"/>\n        <option name=\"ignoreAnonymousClassMethods\" value=\"false\"/>\n      </inspection_tool>\n    </profile>\n  </profiles>\n  <option name=\"PROJECT_PROFILE\" value=\"Project Default\"/>\n  <option name=\"USE_PROJECT_PROFILE\" value=\"true\"/>\n  <version value=\"1.0\"/>\n</component>\n"
  },
  {
    "path": "gradle/idea.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\napply plugin: 'idea'\n\nidea {\n    project {\n        jdkName = targetCompatibility\n        languageLevel = targetCompatibility\n        wildcards += 'logback.groovy'\n\n        ipr {\n            withXml { provider ->\n                def node = provider.asNode()\n\n                def codestyle = new XmlParser().parse(file('gradle/idea-codestyle.xml'))\n                node.append(codestyle)\n\n                def inspections = new XmlParser().parse(file('gradle/idea-inspections.xml'))\n                node.append(inspections)\n\n                def entrypoints = new XmlParser().parse(file('gradle/idea-entrypoints.xml'))\n                node.append(entrypoints)\n\n                def compilerConfig = node.component.find { it.'@name' == 'CompilerConfiguration' }\n                compilerConfig.getByName('annotationProcessing').each { compilerConfig.remove(it) }\n                def annotationProcessing = compilerConfig.appendNode('annotationProcessing')\n                annotationProcessing.appendNode('profile', ['default': true, 'name': 'Default', 'enabled': true]).appendNode('processorPath', ['useClasspath': true])\n\n                def copyrightManager = node.component.find { it.'@name' == 'CopyrightManager' }\n                node.remove(copyrightManager)\n                def copyright = new XmlParser().parse(file('gradle/idea-copyright.xml'))\n                node.append(copyright)\n\n                def vcsDirectoryMappings = node.component.find { it.'@name' == 'VcsDirectoryMappings' }\n                def mappings = vcsDirectoryMappings.iterator()\n                while (mappings.hasNext()) {\n                    mappings.next()\n                    mappings.remove()\n                }\n\n                def gitRoot = file('.git')\n                if (gitRoot.exists()) {\n                    vcsDirectoryMappings.appendNode('mapping', ['directory': gitRoot.parentFile, 'vcs': 'Git'])\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gradle/integTest.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nsourceSets {\n    integTest {\n        compileClasspath += main.output + test.output\n        runtimeClasspath += main.output + test.output\n    }\n}\n\nconfigurations {\n    integTestCompile.extendsFrom testCompile\n    integTestRuntime.extendsFrom testRuntime\n}\n\ntask integTest(type: Test) {\n    testClassesDir = sourceSets.integTest.output.classesDir\n    classpath = sourceSets.integTest.runtimeClasspath\n    testSrcDirs = []\n}\n\ncheck.dependsOn(integTest)\n\nplugins.withType(org.gradle.plugins.ide.idea.IdeaPlugin) {\n    idea {\n        module {\n            testSourceDirs += sourceSets.integTest.java.srcDirs\n            testSourceDirs += sourceSets.integTest.groovy.srcDirs\n            testSourceDirs += sourceSets.integTest.resources.srcDirs\n            scopes.TEST.plus.add(configurations.integTestCompile)\n            scopes.TEST.plus.add(configurations.integTestRuntime)\n        }\n    }\n}\n\nplugins.withType(org.gradle.plugins.ide.eclipse.EclipsePlugin) {\n    eclipse {\n        classpath {\n            plusConfigurations.add(configurations.integTestCompile)\n            plusConfigurations.add(configurations.integTestRuntime)\n        }\n    }\n}\n\ntask(runTestApp, type: JavaExec) {\n    classpath sourceSets.integTest.runtimeClasspath\n    main = 'org.springframework.boot.context.embedded.netty.TestApplication'\n}\n"
  },
  {
    "path": "gradle/maven.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\napply plugin: 'maven'\n\nrepositories {\n    mavenCentral()\n}\n"
  },
  {
    "path": "gradle/test.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\napply plugin: 'jacoco'\n\napply from: 'gradle/integTest.gradle'\napply from: 'gradle/benchmark.gradle'\n\ntask('checkSourceFiles') << {\n    def sourceSet = sourceSets.main.java\n    for (File srcDir : sourceSet.srcDirs) {\n        def tree = fileTree(srcDir).matching(sourceSet.filter)\n        def packageDirs = new TreeSet<File>()\n        tree.visit { details ->\n            if (!details.isDirectory()) {\n                packageDirs.add(details.getFile().getParentFile())\n            }\n        }\n        for (File packageDir : packageDirs) {\n            def packageInfoFile = new File(packageDir, 'package-info.java')\n            assert packageInfoFile.exists(): packageInfoFile.absolutePath + ' is missing. All packages must have a package-info file'\n\n            def sanityTestFile = new File(packageDir.absolutePath.replace('\\\\', '/').replace('src/main/java', 'src/test/groovy'), 'PackageSanityTest.groovy')\n            assert sanityTestFile.exists(): sanityTestFile.absolutePath + ' is missing. All packages must have a Guava package sanity check'\n        }\n    }\n}\ncompileJava.dependsOn checkSourceFiles\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Nov 24 15:05:30 GMT 2014\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.2-bin.zip\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "settings.gradle",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/*\n * This settings file was auto generated by the Gradle buildInit task\n * by 'dthomas' at '07/08/14 18:11' with Gradle 2.0\n *\n * The settings file is used to specify which projects to include in your build.\n * In a single project build this file can be empty or even removed.\n *\n * Detailed information about configuring a multi-project build in Gradle can be found\n * in the user guide at http://gradle.org/docs/2.0/userguide/multi_project_builds.html\n */\n\n/*\n// To declare projects as part of a multi-project build use the 'include' method\ninclude 'shared'\ninclude 'api'\ninclude 'services:webservice'\n*/\n\nrootProject.name = 'spring-boot-starter-netty'\n"
  },
  {
    "path": "src/integTest/groovy/org/springframework/boot/context/embedded/netty/NettyEmbeddedServletContainerAutoConfigurationIntegrationTest.groovy",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty\n\nimport org.springframework.boot.SpringApplication\nimport org.springframework.boot.context.embedded.EmbeddedServletContainerFactory\nimport org.springframework.context.ConfigurableApplicationContext\nimport spock.lang.Specification\n\nclass NettyEmbeddedServletContainerAutoConfigurationIntegrationTest extends Specification {\n    def 'application autoconfigures netty factory'() {\n        given:\n        def String[] args = []\n        ConfigurableApplicationContext context = SpringApplication.run(TestApplication, args)\n\n        expect:\n        context.getBean(EmbeddedServletContainerFactory) instanceof NettyEmbeddedServletContainerFactory\n    }\n}\n"
  },
  {
    "path": "src/integTest/java/org/springframework/boot/context/embedded/netty/HttpContentInputStreamBenchmark.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.buffer.Unpooled;\nimport io.netty.channel.embedded.EmbeddedChannel;\nimport io.netty.handler.codec.http.DefaultHttpContent;\nimport org.openjdk.jmh.annotations.*;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\nimport java.io.IOException;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Benchmarks for {@link HttpContentInputStream}.\n */\n@State(Scope.Group)\n@OutputTimeUnit(TimeUnit.MILLISECONDS)\npublic class HttpContentInputStreamBenchmark {\n    private HttpContentInputStream stream;\n    private byte[] b;\n\n    @Param(\"8192\")\n    private int size;\n\n    @Setup\n    public void setup() {\n        stream = new HttpContentInputStream(new EmbeddedChannel());\n        b = new byte[size];\n    }\n\n    @Benchmark\n    @Group(\"handler\")\n    public void addContent() {\n        stream.addContent(new DefaultHttpContent(Unpooled.buffer(size)));\n    }\n\n    @Benchmark\n    @Group(\"handler\")\n    public int read() throws IOException {\n        return stream.read(b);\n    }\n\n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder()\n                .include(\".*\" + HttpContentInputStream.class.getSimpleName() + \".*\")\n                .warmupIterations(5)\n                .measurementIterations(5)\n                .forks(0)\n                .build();\n\n        new Runner(opt).run();\n    }\n}\n"
  },
  {
    "path": "src/integTest/java/org/springframework/boot/context/embedded/netty/HttpResponseOutputStreamBenchmark.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.handler.codec.http.DefaultHttpResponse;\nimport io.netty.handler.codec.http.HttpResponse;\nimport io.netty.handler.codec.http.HttpResponseStatus;\nimport io.netty.handler.codec.http.HttpVersion;\nimport org.openjdk.jmh.annotations.*;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\nimport java.io.IOException;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Benchmarks for {@link HttpResponseOutputStream}.\n */\n@State(Scope.Benchmark)\n@OutputTimeUnit(TimeUnit.NANOSECONDS)\n@BenchmarkMode(Mode.AverageTime)\npublic class HttpResponseOutputStreamBenchmark {\n    private HttpResponseOutputStream stream;\n    private byte[] input;\n\n    @Param({\"1024\", \"2048\", \"4096\", \"8192\", \"16384\", \"32768\"})\n    public int size;\n\n    @Setup\n    public void setup() {\n        HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false);\n        ChannelHandlerContext ctx = new StubChannelHandlerContext();\n        NettyEmbeddedContext context = new NettyEmbeddedContext(\"/\", Thread.currentThread().getContextClassLoader(), \"Server\");\n        NettyHttpServletResponse servletResponse = new NettyHttpServletResponse(ctx, context, httpResponse);\n        stream = new HttpResponseOutputStream(ctx, servletResponse);\n        input = new byte[size];\n    }\n\n    @Benchmark\n    public void writeByte() throws IOException {\n        for (int i = 0; i < size; i++) {\n            stream.write(0);\n        }\n    }\n\n    @Benchmark\n    public void writeBytes() throws IOException {\n        stream.write(input);\n    }\n\n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder()\n                .include(\".*\" + HttpResponseOutputStreamBenchmark.class.getSimpleName() + \".*\")\n                .warmupIterations(5)\n                .measurementIterations(5)\n                .forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n}\n"
  },
  {
    "path": "src/integTest/java/org/springframework/boot/context/embedded/netty/NettyHttpServletResponseBenchmark.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.handler.codec.http.*;\nimport org.openjdk.jmh.annotations.*;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Sample benchmark to check that the Gradle configuration is working.\n */\n@State(Scope.Benchmark)\n@BenchmarkMode(Mode.AverageTime)\n@OutputTimeUnit(TimeUnit.NANOSECONDS)\npublic class NettyHttpServletResponseBenchmark {\n    private NettyHttpServletResponse response;\n\n    @Setup\n    public void setup() {\n        StubChannelHandlerContext cxt = new StubChannelHandlerContext();\n        HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false);\n        NettyEmbeddedContext context = new NettyEmbeddedContext(\"/\", Thread.currentThread().getContextClassLoader(), \"Server\");\n        response = new NettyHttpServletResponse(cxt, context, httpResponse);\n    }\n\n    @Benchmark\n    public void setContentType() {\n        response.setContentType(\"text/html\");\n    }\n\n    @Benchmark\n    public void setContentTypeHeader() {\n        response.setHeader(HttpHeaders.Names.CONTENT_TYPE, \"text/html\");\n    }\n\n    @Benchmark\n    public CharSequence getFormattedDate() {\n        return response.getFormattedDate();\n    }\n\n    public static void main(String[] args) throws RunnerException {\n        Options opt = new OptionsBuilder()\n                .include(\".*\" + NettyHttpServletResponseBenchmark.class.getSimpleName() + \".*\")\n                .warmupIterations(5)\n                .measurementIterations(5)\n                .forks(1)\n                .build();\n\n        new Runner(opt).run();\n    }\n}\n"
  },
  {
    "path": "src/integTest/java/org/springframework/boot/context/embedded/netty/StubChannelHandlerContext.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.buffer.ByteBufAllocator;\nimport io.netty.channel.*;\nimport io.netty.channel.embedded.EmbeddedChannel;\nimport io.netty.util.Attribute;\nimport io.netty.util.AttributeKey;\nimport io.netty.util.ReferenceCounted;\nimport io.netty.util.concurrent.EventExecutor;\n\nimport java.net.SocketAddress;\n\n/**\n * A stub {@link ChannelHandlerContext} for benchmarks, as dynamic mocks introduce far too many side effects.\n */\npublic class StubChannelHandlerContext implements ChannelHandlerContext {\n    private final Channel channel = new EmbeddedChannel();\n\n    @Override\n    public ByteBufAllocator alloc() {\n        return channel.alloc();\n    }\n\n    @Override\n    public ChannelFuture write(Object msg) {\n        write(msg, null);\n        return null;\n    }\n\n    @Override\n    public ChannelFuture write(Object msg, ChannelPromise promise) {\n        if (msg instanceof ReferenceCounted) {\n            ((ReferenceCounted) msg).release();\n        }\n        return null;\n    }\n\n    // Default implementations follow\n\n    @Override\n    public Channel channel() {\n        return null;\n    }\n\n    @Override\n    public EventExecutor executor() {\n        return null;\n    }\n\n    @Override\n    public String name() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandler handler() {\n        return null;\n    }\n\n    @Override\n    public boolean isRemoved() {\n        return false;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelRegistered() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelUnregistered() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelActive() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelInactive() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireExceptionCaught(Throwable cause) {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireUserEventTriggered(Object event) {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelRead(Object msg) {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelReadComplete() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext fireChannelWritabilityChanged() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture bind(SocketAddress localAddress) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture connect(SocketAddress remoteAddress) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture disconnect() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture close() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture deregister() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture disconnect(ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture close(ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture deregister(ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext read() {\n        return null;\n    }\n\n    @Override\n    public ChannelHandlerContext flush() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture writeAndFlush(Object msg) {\n        return null;\n    }\n\n    @Override\n    public ChannelPipeline pipeline() {\n        return null;\n    }\n\n    @Override\n    public ChannelPromise newPromise() {\n        return null;\n    }\n\n    @Override\n    public ChannelProgressivePromise newProgressivePromise() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture newSucceededFuture() {\n        return null;\n    }\n\n    @Override\n    public ChannelFuture newFailedFuture(Throwable cause) {\n        return null;\n    }\n\n    @Override\n    public ChannelPromise voidPromise() {\n        return null;\n    }\n\n    @Override\n    public <T> Attribute<T> attr(AttributeKey<T> key) {\n        return null;\n    }\n\n    @Override\n    public <T> boolean hasAttr(AttributeKey<T> key) {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/integTest/java/org/springframework/boot/context/embedded/netty/TestApplication.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.EnableAutoConfiguration;\nimport org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;\nimport org.springframework.boot.context.embedded.ServletRegistrationBean;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.servlet.config.annotation.EnableWebMvc;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.ServletInputStream;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.util.concurrent.Callable;\n\n/**\n * A {@link org.springframework.boot.SpringApplication} harness for integration tests.\n * </p>\n * Implemented in Java to avoid currency issues caused by repeated annotation scanning of Groovy controllers.\n */\n@Controller\n@EnableAutoConfiguration(exclude = WebMvcAutoConfiguration.class)\n@ComponentScan\n@EnableWebMvc\nclass TestApplication {\n    private static final String MESSAGE = \"Hello, World!\";\n    private static final Callable<String> MESSAGE_CALLABLE = new Callable<String>() {\n        @Override\n        public String call() throws Exception {\n            return MESSAGE;\n        }\n    };\n\n    @RequestMapping(value = \"/plaintext\", produces = \"text/plain\")\n    @ResponseBody\n    public String plaintext() {\n        return MESSAGE;\n    }\n\n    @RequestMapping(value = \"/async\", produces = \"text/plain\")\n    @ResponseBody\n    public Callable<String> async() {\n        return MESSAGE_CALLABLE;\n    }\n\n    @RequestMapping(value = \"/json\", produces = \"application/json\")\n    @ResponseBody\n    public Message json() {\n        return new Message(MESSAGE);\n    }\n\n    @RequestMapping(value = \"/upload\", method = RequestMethod.POST)\n    @ResponseBody\n    public String upload(HttpServletRequest request) throws IOException {\n        ServletInputStream inputStream = request.getInputStream();\n        int total = 0;\n        while (true) {\n            byte[] bytes = new byte[8192];\n            int read = inputStream.read(bytes);\n            if (read == -1) {\n                break;\n            }\n            total += read;\n        }\n        return \"Total bytes received: \" + total;\n    }\n\n    @RequestMapping(\"/sleepy\")\n    @ResponseBody\n    public String sleepy() throws InterruptedException {\n        int millis = 500;\n        Thread.sleep(millis);\n        return \"Yawn! I slept for \" + millis + \"ms\";\n    }\n\n    @Bean\n    public ServletRegistrationBean nullServletRegistration() {\n        return new ServletRegistrationBean(new NullHttpServlet(), \"/null\");\n    }\n\n    public static void main(String[] args) {\n        SpringApplication.run(TestApplication.class, args);\n    }\n\n    private static class Message {\n        private final String message;\n\n        public Message(String message) {\n            this.message = message;\n        }\n\n        public String getMessage() {\n            return message;\n        }\n    }\n\n    private class NullHttpServlet extends HttpServlet {\n        @Override\n        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n        }\n    }\n}\n"
  },
  {
    "path": "src/integTest/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright 2014 the original author or authors.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~   http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  ~\n  -->\n<configuration>\n  <include resource=\"org/springframework/boot/logging/logback/base.xml\"/>\n  <logger name=\"org.springframework.boot.context.embedded.netty\" level=\"DEBUG\"/>\n  <logger name=\"org.springframework.web\" level=\"INFO\"/>\n</configuration>\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/AbstractNettyRegistration.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport javax.servlet.FilterConfig;\nimport javax.servlet.Registration;\nimport javax.servlet.ServletConfig;\nimport javax.servlet.ServletContext;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.Map;\nimport java.util.Set;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * Abstract class for those classes implementing {@link javax.servlet.Registration} classes and\n * {@link ServletConfig}/{@link FilterConfig}.\n *\n * @author Danny Thomas\n */\nclass AbstractNettyRegistration implements Registration, Registration.Dynamic, ServletConfig, FilterConfig {\n    private final String name;\n    private final String className;\n    private final NettyEmbeddedContext context;\n    protected boolean asyncSupported;\n\n    protected AbstractNettyRegistration(String name, String className, NettyEmbeddedContext context) {\n        this.name = checkNotNull(name);\n        this.className = checkNotNull(className);\n        this.context = checkNotNull(context);\n    }\n\n    @Override\n    public void setAsyncSupported(boolean isAsyncSupported) {\n        asyncSupported = isAsyncSupported;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public String getClassName() {\n        return className;\n    }\n\n    @Override\n    public boolean setInitParameter(String name, String value) {\n        checkArgument(name != null, \"name may not be null\");\n        checkArgument(value != null, \"value may not be null\");\n        return false;\n    }\n\n    @Override\n    public String getFilterName() {\n        return name;\n    }\n\n    @Override\n    public String getServletName() {\n        return name;\n    }\n\n    @Override\n    public ServletContext getServletContext() {\n        return context;\n    }\n\n    protected NettyEmbeddedContext getNettyContext() {\n        return context;\n    }\n\n    @Override\n    public String getInitParameter(String name) {\n        return null;\n    }\n\n    @Override\n    public Enumeration<String> getInitParameterNames() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public Set<String> setInitParameters(Map<String, String> initParameters) {\n        return Collections.emptySet();\n    }\n\n    @Override\n    public Map<String, String> getInitParameters() {\n        return Collections.emptyMap();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/HttpContentInputStream.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport com.google.common.primitives.Ints;\nimport io.netty.buffer.ByteBuf;\nimport io.netty.channel.Channel;\nimport io.netty.handler.codec.http.HttpContent;\nimport io.netty.handler.codec.http.LastHttpContent;\n\nimport javax.servlet.ReadListener;\nimport javax.servlet.ServletInputStream;\nimport java.io.IOException;\nimport java.util.Queue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * A {@link javax.servlet.ServletInputStream} that allows reading from {@link Queue} of {@link HttpContent}, adapting\n * Netty HTTP codec POJOs into a stream readable by servlets.\n *\n * @author Danny Thomas\n */\nclass HttpContentInputStream extends ServletInputStream {\n    private final Channel channel;\n    private AtomicBoolean closed;\n    private final BlockingQueue<HttpContent> queue;\n    private HttpContent current;\n    private ReadListener readListener;\n\n    HttpContentInputStream(Channel channel) {\n        this.channel = checkNotNull(channel);\n        this.closed = new AtomicBoolean();\n        queue = new LinkedBlockingQueue<>();\n    }\n\n    public void addContent(HttpContent httpContent) {\n        checkNotClosed();\n        queue.offer(httpContent.retain());\n        // TODO limit the number of queued inputs, stop handler from reading from channel\n    }\n\n    @Override\n    public int readLine(byte[] b, int off, int len) throws IOException {\n        checkNotNull(b);\n        // TODO use ByteBuf native approach, i.e. bytesBefore, ByteBufProcessor\n        return super.readLine(b, off, len);\n    }\n\n    @Override\n    public boolean isFinished() {\n        checkNotClosed();\n        return isLastContent() && current.content().readableBytes() == 0;\n    }\n\n    private boolean isLastContent() {\n        return current instanceof LastHttpContent;\n    }\n\n    @Override\n    public boolean isReady() {\n        checkNotClosed();\n        return (current != null && current.content().readableBytes() > 0) || !queue.isEmpty();\n    }\n\n    @Override\n    public void setReadListener(ReadListener readListener) {\n        checkNotClosed();\n        checkNotNull(readListener);\n        this.readListener = readListener;\n    }\n\n    @Override\n    public long skip(long n) throws IOException {\n        checkNotClosed();\n        // TODO implement skip that doesn't read bytes\n        return readContent(Ints.checkedCast(n)).readableBytes();\n    }\n\n    @Override\n    public int available() throws IOException {\n        return null == current ? 0 : current.content().readableBytes();\n    }\n\n    @Override\n    public void close() throws IOException {\n        if (closed.compareAndSet(false, true)) {\n            // FIXME release the non-written HttpContents?\n            queue.clear();\n            current = null;\n        }\n    }\n\n    @Override\n    public int read(byte[] b, int off, int len) throws IOException {\n        checkNotNull(b);\n        if (0 == len) {\n            return 0;\n        }\n        poll();\n        if (isFinished()) {\n            return -1;\n        }\n        ByteBuf byteBuf = readContent(len);\n        int readableBytes = byteBuf.readableBytes();\n        byteBuf.readBytes(b, off, readableBytes);\n        return readableBytes - byteBuf.readableBytes();\n    }\n\n    @Override\n    public int read() throws IOException {\n        poll();\n        if (isFinished()) {\n            return -1;\n        }\n        return readContent(1).getByte(0);\n    }\n\n    private ByteBuf readContent(int length) throws IOException {\n        ByteBuf content = current.content();\n        if (length < content.readableBytes()) {\n            return content.readSlice(length);\n        } else {\n            return content;\n        }\n    }\n\n    private void poll() throws IOException {\n        checkNotClosed();\n        if (null == current || current.content().readableBytes() == 0) {\n            boolean blocking = null == readListener;\n            while (!isLastContent()) {\n                try {\n                    // FIXME add appropriate timeout value\n                    current = queue.poll(0, TimeUnit.NANOSECONDS);\n                } catch (InterruptedException ignored) {\n                }\n                if (current != null || !blocking) {\n                    break;\n                }\n                if (!channel.isActive()) {\n                    throw new IOException(\"Channel is not active\");\n                }\n            }\n        }\n    }\n\n    private void checkNotClosed() {\n        if (closed.get()) {\n            throw new IllegalStateException(\"Stream is closed\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/HttpResponseOutputStream.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.buffer.ByteBuf;\nimport io.netty.buffer.Unpooled;\nimport io.netty.channel.ChannelFuture;\nimport io.netty.channel.ChannelFutureListener;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpHeaders;\nimport io.netty.handler.codec.http.HttpResponse;\n\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.WriteListener;\nimport java.io.IOException;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.base.Preconditions.checkState;\n\n/**\n * A buffered {@link ServletOutputStream}, that writes Netty HTTP codec POJOs to the associated\n * {@link ChannelHandlerContext}.\n *\n * @author Danny Thomas\n */\nclass HttpResponseOutputStream extends ServletOutputStream {\n    private static final int DEFAULT_BUFFER_SIZE = 1024 * 8;\n\n    private final ChannelHandlerContext ctx;\n    private final NettyHttpServletResponse servletResponse;\n    private byte[] buf;\n    private int count;\n    private boolean closed;\n    private WriteListener writeListener;\n\n    HttpResponseOutputStream(ChannelHandlerContext ctx, NettyHttpServletResponse servletResponse) {\n        this.ctx = ctx;\n        this.servletResponse = servletResponse;\n        this.buf = new byte[DEFAULT_BUFFER_SIZE];\n    }\n\n    @Override\n    public boolean isReady() {\n        return true; // TODO implement\n    }\n\n    @Override\n    public void setWriteListener(WriteListener writeListener) {\n        checkNotNull(writeListener);\n        // TODO ISE when called more than once\n        // TODO ISE when associated request is not async\n    }\n\n    @Override\n    public void write(byte[] b, int off, int len) throws IOException {\n        if (len > count) {\n            flushBuffer();\n            ByteBuf content = ctx.alloc().buffer(len);\n            content.writeBytes(b, off, len);\n            writeContent(content, false);\n            return;\n        }\n        writeBufferIfNeeded(len);\n        System.arraycopy(b, off, buf, count, len);\n        count += len;\n    }\n\n    @Override\n    public void write(int b) throws IOException {\n        writeBufferIfNeeded(1);\n        buf[count++] = (byte) b;\n    }\n\n    private void writeBufferIfNeeded(int len) throws IOException {\n        if (len > buf.length - count) {\n            flushBuffer();\n        }\n    }\n\n    @Override\n    public void flush() throws IOException {\n        flushBuffer();\n    }\n\n    private void flushBuffer() {\n        flushBuffer(false);\n    }\n\n    private void flushBuffer(boolean lastContent) {\n        if (count > 0) {\n            ByteBuf content = ctx.alloc().buffer(count);\n            content.writeBytes(buf, 0, count);\n            count = 0;\n            writeContent(content, lastContent);\n        } else if (lastContent) {\n            writeContent(Unpooled.EMPTY_BUFFER, true);\n        }\n    }\n\n    private void writeContent(ByteBuf content, boolean lastContent) {\n        // TODO block if channel is not writable to avoid heap utilisation\n        if (!servletResponse.isCommitted()) {\n            writeResponse(lastContent);\n        }\n        if (content.readableBytes() > 0) {\n            assert content.refCnt() == 1;\n            ctx.write(content, ctx.voidPromise());\n        }\n        if (lastContent) {\n            HttpResponse nettyResponse = servletResponse.getNettyResponse();\n            ChannelFuture future = ctx.write(DefaultLastHttpContent.EMPTY_LAST_CONTENT);\n            if (!HttpHeaders.isKeepAlive(nettyResponse)) {\n                future.addListener(ChannelFutureListener.CLOSE);\n            }\n        }\n    }\n\n    private void writeResponse(boolean lastContent) {\n        HttpResponse response = servletResponse.getNettyResponse();\n        // TODO implement exceptions required by http://tools.ietf.org/html/rfc2616#section-4.4\n        if (!HttpHeaders.isContentLengthSet(response)) {\n            if (lastContent) {\n                HttpHeaders.setContentLength(response, count);\n            } else {\n                HttpHeaders.setTransferEncodingChunked(response);\n            }\n        }\n        ctx.write(response, ctx.voidPromise());\n    }\n\n    @Override\n    public void close() throws IOException {\n        if (closed) {\n            return;\n        }\n        closed = true;\n        try {\n            flushBuffer(true);\n            ctx.flush();\n        } finally {\n            buf = null;\n        }\n    }\n\n    void resetBuffer() {\n        assert !servletResponse.isCommitted();\n        count = 0;\n    }\n\n    int getBufferSize() {\n        return buf.length;\n    }\n\n    void setBufferSize(int size) {\n        assert !servletResponse.isCommitted();\n        checkState(count == 0, \"Response body content has been written\");\n        buf = new byte[size];\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyAsyncContext.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport com.google.common.collect.ImmutableList;\nimport io.netty.channel.ChannelHandlerContext;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Netty {@link AsyncContext}.\n *\n * @author Danny Thomas\n */\nclass NettyAsyncContext implements AsyncContext {\n    private ServletRequest servletRequest;\n    private final ChannelHandlerContext ctx;\n    private ServletResponse servletResponse;\n    private boolean asyncStarted;\n    private List<AsyncListener> listeners;\n\n    NettyAsyncContext(ServletRequest servletRequest, ChannelHandlerContext ctx) {\n        this.servletRequest = servletRequest;\n        this.ctx = ctx;\n        this.listeners = new ArrayList<>();\n    }\n\n    AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {\n        this.servletRequest = servletRequest;\n        this.servletResponse = servletResponse;\n        asyncStarted = true;\n        return this;\n    }\n\n    @Override\n    public ServletRequest getRequest() {\n        return servletRequest;\n    }\n\n    @Override\n    public ServletResponse getResponse() {\n        return servletResponse;\n    }\n\n    @Override\n    public boolean hasOriginalRequestAndResponse() {\n        return true;\n    }\n\n    @Override\n    public void dispatch() {\n        if (servletRequest instanceof HttpServletRequest) {\n            HttpServletRequest request = (HttpServletRequest) servletRequest;\n            String path = request.getServletPath();\n            String pathInfo = request.getPathInfo();\n            if (null != pathInfo) {\n                path += pathInfo;\n            }\n            dispatch(path);\n        }\n    }\n\n    @Override\n    public void dispatch(String path) {\n        dispatch(servletRequest.getServletContext(), path);\n    }\n\n    @Override\n    public void dispatch(ServletContext context, String path) {\n        final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;\n        httpRequest.setAttribute(ASYNC_CONTEXT_PATH, httpRequest.getContextPath());\n        httpRequest.setAttribute(ASYNC_PATH_INFO, httpRequest.getPathInfo());\n        httpRequest.setAttribute(ASYNC_QUERY_STRING, httpRequest.getQueryString());\n        httpRequest.setAttribute(ASYNC_REQUEST_URI, httpRequest.getRequestURI());\n        httpRequest.setAttribute(ASYNC_SERVLET_PATH, httpRequest.getServletPath());\n        final NettyRequestDispatcher dispatcher = (NettyRequestDispatcher) context.getRequestDispatcher(path);\n        ctx.executor().submit(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    dispatcher.dispatch(httpRequest, servletResponse);\n                    // TODO is this right?\n                    for (AsyncListener listener : ImmutableList.copyOf(listeners)) {\n                        listener.onComplete(new AsyncEvent(NettyAsyncContext.this));\n                    }\n                } catch (ServletException | IOException e) {\n                    // TODO notify listeners\n                    e.printStackTrace();\n                }\n            }\n        });\n    }\n\n    @Override\n    public void complete() {\n        try {\n            servletResponse.getOutputStream().close();\n        } catch (IOException e) {\n            // TODO notify listeners\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public void start(Runnable run) {\n        ctx.executor().submit(run, Object.class);\n    }\n\n    @Override\n    public void addListener(AsyncListener listener) {\n        listeners.add(listener);\n    }\n\n    @Override\n    public void addListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) {\n\n    }\n\n    @Override\n    public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException {\n        return null;\n    }\n\n    @Override\n    public void setTimeout(long timeout) {\n\n    }\n\n    @Override\n    public long getTimeout() {\n        return 0;\n    }\n\n    public boolean isAsyncStarted() {\n        return asyncStarted;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyEmbeddedContext.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport com.google.common.collect.ImmutableMap;\nimport io.netty.util.AsciiString;\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport javax.servlet.*;\nimport javax.servlet.descriptor.JspConfigDescriptor;\nimport java.io.InputStream;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.*;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.base.Preconditions.checkState;\n\n/**\n * Netty servlet bridge {@link ServletContext} implementation.\n */\nclass NettyEmbeddedContext implements ServletContext {\n    private final Log logger = LogFactory.getLog(NettyEmbeddedContext.class);\n\n    private final String contextPath;\n    private final ClassLoader classLoader;\n    private final Map<String, NettyServletRegistration> servlets = new HashMap<>();\n    private final Map<String, String> servletMappings = new HashMap<>();\n    private final Map<String, NettyFilterRegistration> filters = new HashMap<>();\n    private final AsciiString serverInfo;\n    private volatile boolean initialised;\n\n    NettyEmbeddedContext(String contextPath, ClassLoader classLoader, String serverInfo) {\n        this.contextPath = contextPath;\n        this.classLoader = classLoader;\n        this.serverInfo = new AsciiString(serverInfo);\n    }\n\n    public void setInitialised(boolean initialised) {\n        this.initialised = initialised;\n    }\n\n    public boolean isInitialised() {\n        return initialised;\n    }\n\n    public void checkNotInitialised() {\n        checkState(!isInitialised(), \"This method may not be called after the context has been initialised\");\n    }\n\n    public void addServletMapping(String urlPattern, String name) {\n        checkNotInitialised();\n        servletMappings.put(urlPattern, checkNotNull(name));\n    }\n\n    public void addFilterMapping(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String urlPattern) {\n        checkNotInitialised();\n        // TODO\n    }\n\n    @Override\n    public ServletContext getContext(String uripath) {\n        return null;\n    }\n\n    @Override\n    public String getContextPath() {\n        return contextPath;\n    }\n\n    @Override\n    public int getMajorVersion() {\n        return 0;\n    }\n\n    @Override\n    public int getMinorVersion() {\n        return 0;\n    }\n\n    @Override\n    public int getEffectiveMajorVersion() {\n        return 0;\n    }\n\n    @Override\n    public int getEffectiveMinorVersion() {\n        return 0;\n    }\n\n    @Override\n    public String getMimeType(String file) {\n        return null;\n    }\n\n    @Override\n    public Set<String> getResourcePaths(String path) {\n        return null;\n    }\n\n    @Override\n    public URL getResource(String path) throws MalformedURLException {\n        return null;\n    }\n\n    @Override\n    public InputStream getResourceAsStream(String path) {\n        return null;\n    }\n\n    @Override\n    public RequestDispatcher getRequestDispatcher(String path) {\n        // FIXME proper path matching\n        String servletName = servletMappings.get(path);\n        if (servletName == null) {\n            servletName = servletMappings.get(\"/\");\n        }\n        Servlet servlet = null;\n        try {\n            servlet = null == servletName ? null : servlets.get(servletName).getServlet();\n            if (servlet == null) {\n                return null;\n            }\n            // FIXME proper path matching\n            List<Filter> filters = new ArrayList<>();\n            for (NettyFilterRegistration registration : this.filters.values()) {\n                filters.add(registration.getFilter());\n            }\n            FilterChain filterChain = new SimpleFilterChain(servlet, filters);\n            return new NettyRequestDispatcher(this, filterChain);\n        } catch (ServletException e) {\n            // TODO log exception\n            return null;\n        }\n    }\n\n    @Override\n    public RequestDispatcher getNamedDispatcher(String name) {\n        return null;\n    }\n\n    @Override\n    public Servlet getServlet(String name) throws ServletException {\n        return servlets.get(name).getServlet();\n    }\n\n    @Override\n    public Enumeration<Servlet> getServlets() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public Enumeration<String> getServletNames() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public void log(String msg) {\n        logger.info(msg);\n    }\n\n    @Override\n    public void log(Exception exception, String msg) {\n        logger.error(msg, exception);\n    }\n\n    @Override\n    public void log(String message, Throwable throwable) {\n        logger.error(message, throwable);\n    }\n\n    @Override\n    public String getRealPath(String path) {\n        return null;\n    }\n\n    @Override\n    public String getServerInfo() {\n        return serverInfo.toString();\n    }\n\n    AsciiString getServerInfoAscii() {\n        return serverInfo;\n    }\n\n    @Override\n    public String getInitParameter(String name) {\n        return null;\n    }\n\n    @Override\n    public Enumeration<String> getInitParameterNames() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public boolean setInitParameter(String name, String value) {\n        return false;\n    }\n\n    @Override\n    public Object getAttribute(String name) {\n        return null;\n    }\n\n    @Override\n    public Enumeration<String> getAttributeNames() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public void setAttribute(String name, Object object) {\n\n    }\n\n    @Override\n    public void removeAttribute(String name) {\n\n    }\n\n    @Override\n    public String getServletContextName() {\n        return null;\n    }\n\n    @Override\n    public ServletRegistration.Dynamic addServlet(String servletName, String className) {\n        return addServlet(servletName, className, null);\n    }\n\n    @Override\n    public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {\n        return addServlet(servletName, servlet.getClass().getName(), servlet);\n    }\n\n    @Override\n    public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {\n        return addServlet(servletName, servletClass.getName());\n    }\n\n    private ServletRegistration.Dynamic addServlet(String servletName, String className, Servlet servlet) {\n        NettyServletRegistration servletRegistration = new NettyServletRegistration(this, servletName, className, servlet);\n        servlets.put(servletName, servletRegistration);\n        return servletRegistration;\n    }\n\n    @Override\n    public <T extends Servlet> T createServlet(Class<T> c) throws ServletException {\n        return null;\n    }\n\n    @Override\n    public ServletRegistration getServletRegistration(String servletName) {\n        return null;\n    }\n\n    @Override\n    public Map<String, ? extends ServletRegistration> getServletRegistrations() {\n        return null;\n    }\n\n    @Override\n    public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, String className) {\n        return addFilter(filterName, className, null);\n    }\n\n    @Override\n    public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {\n        return addFilter(filterName, filter.getClass().getName(), filter);\n    }\n\n    private javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, String className, Filter filter) {\n        NettyFilterRegistration filterRegistration = new NettyFilterRegistration(this, filterName, className, filter);\n        filters.put(filterName, filterRegistration);\n        return filterRegistration;\n    }\n\n\n    @Override\n    public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {\n        return addFilter(filterName, filterClass.getName());\n    }\n\n    @Override\n    public <T extends Filter> T createFilter(Class<T> c) throws ServletException {\n        return null;\n    }\n\n    @Override\n    public javax.servlet.FilterRegistration getFilterRegistration(String filterName) {\n        return filters.get(filterName);\n    }\n\n    @Override\n    public Map<String, ? extends javax.servlet.FilterRegistration> getFilterRegistrations() {\n        return ImmutableMap.copyOf(filters);\n    }\n\n    @Override\n    public SessionCookieConfig getSessionCookieConfig() {\n        return null;\n    }\n\n    @Override\n    public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) throws IllegalStateException, IllegalArgumentException {\n\n    }\n\n    @Override\n    public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {\n        return null;\n    }\n\n    @Override\n    public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {\n        return null;\n    }\n\n    @Override\n    public void addListener(String className) {\n\n    }\n\n    @Override\n    public <T extends EventListener> void addListener(T t) {\n\n    }\n\n    @Override\n    public void addListener(Class<? extends EventListener> listenerClass) {\n\n    }\n\n    @Override\n    public <T extends EventListener> T createListener(Class<T> c) throws ServletException {\n        return null;\n    }\n\n    @Override\n    public void declareRoles(String... roleNames) {\n\n    }\n\n    @Override\n    public String getVirtualServerName() {\n        return null;\n    }\n\n    @Override\n    public ClassLoader getClassLoader() {\n        return classLoader;\n    }\n\n    @Override\n    public JspConfigDescriptor getJspConfigDescriptor() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyEmbeddedServletContainer.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport com.google.common.base.StandardSystemProperty;\nimport io.netty.bootstrap.ServerBootstrap;\nimport io.netty.channel.ChannelFuture;\nimport io.netty.channel.ChannelOption;\nimport io.netty.channel.EventLoopGroup;\nimport io.netty.channel.epoll.EpollChannelOption;\nimport io.netty.channel.epoll.EpollEventLoopGroup;\nimport io.netty.channel.epoll.EpollServerSocketChannel;\nimport io.netty.channel.nio.NioEventLoopGroup;\nimport io.netty.channel.socket.nio.NioServerSocketChannel;\nimport io.netty.util.concurrent.DefaultEventExecutorGroup;\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.springframework.boot.context.embedded.EmbeddedServletContainer;\nimport org.springframework.boot.context.embedded.EmbeddedServletContainerException;\n\nimport java.net.InetSocketAddress;\n\n/**\n * An {@link EmbeddedServletContainer} used to control an embedded Netty instance, that bridges to\n * {@link javax.servlet.http.HttpServletRequest} and from {@link javax.servlet.http.HttpServletResponse}\n * to Netty HTTP codec {@link io.netty.handler.codec.http.HttpMessage}s.\n * <p>\n * This is a minimal Servlet 3.1 implementation to provide for the opinionated embedded servlet container model for\n * Spring Boot, supporting a single context, runtime {@link javax.servlet.Registration} only, and no default or JSP\n * servlets.\n * <p>\n * This class should be created using the {@link NettyEmbeddedServletContainerFactory}.\n *\n * @author Danny Thomas\n */\npublic class NettyEmbeddedServletContainer implements EmbeddedServletContainer {\n    private final Log logger = LogFactory.getLog(getClass());\n    private final InetSocketAddress address;\n    private final NettyEmbeddedContext context;\n\n    private EventLoopGroup bossGroup;\n    private EventLoopGroup workerGroup;\n    private DefaultEventExecutorGroup servletExecutor;\n\n    public NettyEmbeddedServletContainer(InetSocketAddress address, NettyEmbeddedContext context) {\n        this.address = address;\n        this.context = context;\n    }\n\n    @Override\n    public void start() throws EmbeddedServletContainerException {\n        ServerBootstrap b = new ServerBootstrap();\n        groups(b);\n        servletExecutor = new DefaultEventExecutorGroup(50);\n        b.childHandler(new NettyEmbeddedServletInitializer(servletExecutor, context));\n\n        // Don't yet need the complexity of lifecycle state, listeners etc, so tell the context it's initialised here\n        context.setInitialised(true);\n\n        ChannelFuture future = b.bind(address).awaitUninterruptibly();\n        //noinspection ThrowableResultOfMethodCallIgnored\n        Throwable cause = future.cause();\n        if (null != cause) {\n            throw new EmbeddedServletContainerException(\"Could not start Netty server\", cause);\n        }\n        logger.info(context.getServerInfo() + \" started on port: \" + getPort());\n    }\n\n    private void groups(ServerBootstrap b) {\n        if (StandardSystemProperty.OS_NAME.value().equals(\"Linux\")) {\n            bossGroup = new EpollEventLoopGroup(1);\n            workerGroup = new EpollEventLoopGroup();\n            b.channel(EpollServerSocketChannel.class)\n                    .group(bossGroup, workerGroup)\n                    .option(EpollChannelOption.TCP_CORK, true);\n        } else {\n            bossGroup = new NioEventLoopGroup(1);\n            workerGroup = new NioEventLoopGroup();\n            b.channel(NioServerSocketChannel.class)\n                    .group(bossGroup, workerGroup);\n        }\n        b.option(ChannelOption.TCP_NODELAY, true)\n                .option(ChannelOption.SO_REUSEADDR, true)\n                .option(ChannelOption.SO_BACKLOG, 100);\n        logger.info(\"Bootstrap configuration: \" + b.toString());\n    }\n\n    @Override\n    public void stop() throws EmbeddedServletContainerException {\n        try {\n            if (null != bossGroup) {\n                bossGroup.shutdownGracefully().await();\n            }\n            if (null != workerGroup) {\n                workerGroup.shutdownGracefully().await();\n            }\n            if (null != servletExecutor) {\n                servletExecutor.shutdownGracefully().await();\n            }\n        } catch (InterruptedException e) {\n            throw new EmbeddedServletContainerException(\"Container stop interrupted\", e);\n        }\n    }\n\n    @Override\n    public int getPort() {\n        return address.getPort();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyEmbeddedServletContainerAutoConfiguration.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.bootstrap.Bootstrap;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnClass;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;\nimport org.springframework.boot.autoconfigure.condition.SearchStrategy;\nimport org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration.EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar;\nimport org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.Import;\nimport org.springframework.core.Ordered;\nimport org.springframework.core.annotation.Order;\n\n/**\n * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration} for an embedded servlet containers.\n *\n * @author Danny Thomas\n */\n@Order(Ordered.HIGHEST_PRECEDENCE)\n@Configuration\n@ConditionalOnWebApplication\n@Import(EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar.class)\npublic class NettyEmbeddedServletContainerAutoConfiguration {\n    @Configuration\n    @ConditionalOnClass({Bootstrap.class})\n    @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)\n    public static class EmbeddedNetty {\n        @Bean\n        public NettyEmbeddedServletContainerFactory nettyEmbeddedServletContainerFactory() {\n            return new NettyEmbeddedServletContainerFactory();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyEmbeddedServletContainerFactory.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.bootstrap.Bootstrap;\nimport org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;\nimport org.springframework.boot.context.embedded.EmbeddedServletContainer;\nimport org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;\nimport org.springframework.boot.context.embedded.ServletContextInitializer;\nimport org.springframework.context.ResourceLoaderAware;\nimport org.springframework.core.io.ResourceLoader;\nimport org.springframework.util.ClassUtils;\n\nimport javax.servlet.ServletException;\nimport java.net.InetSocketAddress;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.Random;\n\n/**\n * An {@link EmbeddedServletContainerFactory} that can be used to create {@link NettyEmbeddedServletContainer}s.\n *\n * @author Danny Thomas\n */\npublic class NettyEmbeddedServletContainerFactory extends AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware {\n    public static final String SERVER_INFO = \"netty/servlet\";\n    private ResourceLoader resourceLoader;\n\n    @Override\n    public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {\n        ClassLoader parentClassLoader = resourceLoader != null ? resourceLoader.getClassLoader() : ClassUtils.getDefaultClassLoader();\n        Package nettyPackage = Bootstrap.class.getPackage();\n        String title = nettyPackage.getImplementationTitle();\n        String version = nettyPackage.getImplementationVersion();\n        logger.info(\"Running with \" + title + \" \" + version);\n        NettyEmbeddedContext context = new NettyEmbeddedContext(getContextPath(), new URLClassLoader(new URL[]{}, parentClassLoader), SERVER_INFO);\n        if (isRegisterDefaultServlet()) {\n            logger.warn(\"This container does not support a default servlet\");\n        }\n        if (isRegisterJspServlet()) {\n            logger.warn(\"This container does not support a JSP servlet\");\n        }\n        for (ServletContextInitializer initializer : initializers) {\n            try {\n                initializer.onStartup(context);\n            } catch (ServletException e) {\n                throw new RuntimeException(e);\n            }\n        }\n        int port = getPort() > 0 ? getPort() : new Random().nextInt(65535 - 1024) + 1024;\n        InetSocketAddress address = new InetSocketAddress(port);\n        logger.info(\"Server initialized with port: \" + port);\n        return new NettyEmbeddedServletContainer(address, context);\n    }\n\n    @Override\n    public void setResourceLoader(ResourceLoader resourceLoader) {\n        this.resourceLoader = resourceLoader;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyEmbeddedServletInitializer.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.channel.ChannelInitializer;\nimport io.netty.channel.ChannelPipeline;\nimport io.netty.channel.socket.SocketChannel;\nimport io.netty.handler.codec.http.HttpServerCodec;\nimport io.netty.util.concurrent.EventExecutorGroup;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * {@link ChannelInitializer} for {@link org.springframework.boot.context.embedded.netty.NettyEmbeddedServletContainer}.\n *\n * @author Danny Thomas\n */\nclass NettyEmbeddedServletInitializer extends ChannelInitializer<SocketChannel> {\n    private final EventExecutorGroup servletExecutor;\n    private final RequestDispatcherHandler requestDispatcherHandler;\n    private final NettyEmbeddedContext servletContext;\n\n    NettyEmbeddedServletInitializer(EventExecutorGroup servletExecutor, NettyEmbeddedContext servletContext) {\n        this.servletContext = servletContext;\n        this.servletExecutor = checkNotNull(servletExecutor);\n        requestDispatcherHandler = new RequestDispatcherHandler(servletContext);\n    }\n\n    @Override\n    protected void initChannel(SocketChannel ch) throws Exception {\n        ChannelPipeline p = ch.pipeline();\n        p.addLast(\"codec\", new HttpServerCodec(4096, 8192, 8192, false));\n        p.addLast(\"servletInput\", new ServletContentHandler(servletContext));\n        p.addLast(servletExecutor, \"filterChain\", requestDispatcherHandler);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyFilterRegistration.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport javax.servlet.DispatcherType;\nimport javax.servlet.Filter;\nimport javax.servlet.FilterRegistration;\nimport javax.servlet.ServletException;\nimport java.util.Collection;\nimport java.util.EnumSet;\n\n/**\n * A {@link org.springframework.boot.context.embedded.netty.NettyEmbeddedContext} {@link javax.servlet.FilterRegistration}.\n *\n * @author Danny Thomas\n */\nclass NettyFilterRegistration extends AbstractNettyRegistration implements FilterRegistration.Dynamic {\n    private volatile boolean initialised;\n    private Filter filter;\n\n    NettyFilterRegistration(NettyEmbeddedContext context, String filterName, String className, Filter filter) {\n        super(filterName, className, context);\n        this.filter = filter;\n    }\n\n    public Filter getFilter() throws ServletException {\n        if (!initialised) {\n            synchronized (this) {\n                if (!initialised) {\n                    if (null == filter) {\n                        try {\n                            filter = (Filter) Class.forName(getClassName()).newInstance();\n                        } catch (Exception e) {\n                            throw new ServletException(e);\n                        }\n                    }\n                    filter.init(this);\n                    initialised = true;\n                }\n            }\n        }\n        return filter;\n    }\n\n    @Override\n    public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... servletNames) {\n\n    }\n\n    @Override\n    public Collection<String> getServletNameMappings() {\n        return null;\n    }\n\n    @Override\n    public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns) {\n        NettyEmbeddedContext context = getNettyContext();\n        for (String urlPattern : urlPatterns) {\n            context.addFilterMapping(dispatcherTypes, isMatchAfter, urlPattern);\n        }\n    }\n\n    @Override\n    public Collection<String> getUrlPatternMappings() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyHttpServletRequest.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.handler.codec.http.HttpRequest;\n\nimport javax.servlet.*;\nimport javax.servlet.http.*;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.security.Principal;\nimport java.util.*;\n\n/**\n * {@link HttpServletRequest} wrapper for Netty's {@link HttpRequest}.\n *\n * @author Danny Thomas\n */\nclass NettyHttpServletRequest implements HttpServletRequest {\n    public static final String DISPATCHER_TYPE = NettyRequestDispatcher.class.getName() + \".DISPATCHER_TYPE\";\n\n    private final ChannelHandlerContext ctx;\n    private final NettyEmbeddedContext servletContext;\n    private final HttpRequest request;\n    private final ServletInputStream inputStream;\n    private final Map<String, Object> attributes;\n\n    private boolean asyncSupported = true;\n    private NettyAsyncContext asyncContext;\n    private HttpServletResponse servletResponse;\n\n    NettyHttpServletRequest(ChannelHandlerContext ctx, NettyEmbeddedContext servletContext, HttpRequest request, HttpServletResponse servletResponse, ServletInputStream inputStream) {\n        this.ctx = ctx;\n        this.servletContext = servletContext;\n        this.request = request;\n        this.servletResponse = servletResponse;\n        this.inputStream = inputStream;\n        this.attributes = new HashMap<>();\n    }\n\n    HttpRequest getNettyRequest() {\n        return request;\n    }\n\n    @Override\n    public String getAuthType() {\n        return null;\n    }\n\n    @Override\n    public Cookie[] getCookies() {\n        return new Cookie[0];\n    }\n\n    @Override\n    public long getDateHeader(String name) {\n        return 0;\n    }\n\n    @Override\n    public String getHeader(String name) {\n        return null;\n    }\n\n    @Override\n    public Enumeration<String> getHeaders(String name) {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public Enumeration<String> getHeaderNames() {\n        return Collections.emptyEnumeration();\n    }\n\n    @Override\n    public int getIntHeader(String name) {\n        return 0;\n    }\n\n    @Override\n    public String getMethod() {\n        return request.method().name();\n    }\n\n    @Override\n    public String getPathInfo() {\n        return null;\n    }\n\n    @Override\n    public String getPathTranslated() {\n        return null;\n    }\n\n    @Override\n    public String getContextPath() {\n        String requestURI = getRequestURI();\n        // FIXME implement properly\n        return \"/\".equals(requestURI) ? \"\" : requestURI;\n    }\n\n    @Override\n    public String getQueryString() {\n        return null;\n    }\n\n    @Override\n    public String getRemoteUser() {\n        return null;\n    }\n\n    @Override\n    public boolean isUserInRole(String role) {\n        return false;\n    }\n\n    @Override\n    public Principal getUserPrincipal() {\n        return null;\n    }\n\n    @Override\n    public String getRequestedSessionId() {\n        return null;\n    }\n\n    @Override\n    public String getRequestURI() {\n        return request.uri();\n    }\n\n    @Override\n    public StringBuffer getRequestURL() {\n        return null;\n    }\n\n    @Override\n    public String getServletPath() {\n        return getRequestURI();\n    }\n\n    @Override\n    public HttpSession getSession(boolean create) {\n        return null;\n    }\n\n    @Override\n    public HttpSession getSession() {\n        return null;\n    }\n\n    @Override\n    public String changeSessionId() {\n        return null;\n    }\n\n    @Override\n    public boolean isRequestedSessionIdValid() {\n        return false;\n    }\n\n    @Override\n    public boolean isRequestedSessionIdFromCookie() {\n        return false;\n    }\n\n    @Override\n    public boolean isRequestedSessionIdFromURL() {\n        return false;\n    }\n\n    @Override\n    public boolean isRequestedSessionIdFromUrl() {\n        return false;\n    }\n\n    @Override\n    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {\n        return false;\n    }\n\n    @Override\n    public void login(String username, String password) throws ServletException {\n\n    }\n\n    @Override\n    public void logout() throws ServletException {\n\n    }\n\n    @Override\n    public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {\n        return null;\n    }\n\n    @Override\n    public Part getPart(String name) throws IOException, IllegalStateException, ServletException {\n        return null;\n    }\n\n    @Override\n    public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {\n        return null;\n    }\n\n    @Override\n    public Object getAttribute(String name) {\n        synchronized (attributes) {\n            return attributes.get(name);\n        }\n    }\n\n    @Override\n    public Enumeration<String> getAttributeNames() {\n        synchronized (attributes) {\n            return Collections.enumeration(attributes.keySet());\n        }\n    }\n\n    @Override\n    public String getCharacterEncoding() {\n        return null;\n    }\n\n    @Override\n    public void setCharacterEncoding(String env) throws UnsupportedEncodingException {\n\n    }\n\n    @Override\n    public int getContentLength() {\n        return 0;\n    }\n\n    @Override\n    public long getContentLengthLong() {\n        return 0;\n    }\n\n    @Override\n    public String getContentType() {\n        return null;\n    }\n\n    @Override\n    public ServletInputStream getInputStream() throws IOException {\n        return inputStream;\n    }\n\n    @Override\n    public String getParameter(String name) {\n        return null;\n    }\n\n    @Override\n    public Enumeration<String> getParameterNames() {\n        return null;\n    }\n\n    @Override\n    public String[] getParameterValues(String name) {\n        return new String[0];\n    }\n\n    @Override\n    public Map<String, String[]> getParameterMap() {\n        return null;\n    }\n\n    @Override\n    public String getProtocol() {\n        return request.protocolVersion().protocolName();\n    }\n\n    @Override\n    public String getScheme() {\n        return null;\n    }\n\n    @Override\n    public String getServerName() {\n        return null;\n    }\n\n    @Override\n    public int getServerPort() {\n        return 0;\n    }\n\n    @Override\n    public BufferedReader getReader() throws IOException {\n        return null;\n    }\n\n    @Override\n    public String getRemoteAddr() {\n        return null;\n    }\n\n    @Override\n    public String getRemoteHost() {\n        return null;\n    }\n\n    @Override\n    public void setAttribute(String name, Object o) {\n        synchronized (attributes) {\n            attributes.put(name, o);\n        }\n    }\n\n    @Override\n    public void removeAttribute(String name) {\n        synchronized (attributes) {\n            attributes.remove(name);\n        }\n    }\n\n    @Override\n    public Locale getLocale() {\n        return null;\n    }\n\n    @Override\n    public Enumeration<Locale> getLocales() {\n        return null;\n    }\n\n    @Override\n    public boolean isSecure() {\n        return false;\n    }\n\n    @Override\n    public RequestDispatcher getRequestDispatcher(String path) {\n        return null;\n    }\n\n    @Override\n    public String getRealPath(String path) {\n        return null;\n    }\n\n    @Override\n    public int getRemotePort() {\n        return 0;\n    }\n\n    @Override\n    public String getLocalName() {\n        return null;\n    }\n\n    @Override\n    public String getLocalAddr() {\n        return null;\n    }\n\n    @Override\n    public int getLocalPort() {\n        return 0;\n    }\n\n    @Override\n    public ServletContext getServletContext() {\n        return servletContext;\n    }\n\n    @Override\n    public AsyncContext startAsync() {\n        return startAsync(this, null);\n    }\n\n    @Override\n    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {\n        return ((NettyAsyncContext) getAsyncContext()).startAsync(servletRequest, servletResponse);\n    }\n\n    @Override\n    public boolean isAsyncStarted() {\n        return null != asyncContext && asyncContext.isAsyncStarted();\n    }\n\n    void setAsyncSupported(boolean asyncSupported) {\n        this.asyncSupported = asyncSupported;\n    }\n\n    @Override\n    public boolean isAsyncSupported() {\n        return asyncSupported;\n    }\n\n    @Override\n    public AsyncContext getAsyncContext() {\n        if (null == asyncContext) {\n            asyncContext = new NettyAsyncContext(this, ctx);\n        }\n        return asyncContext;\n    }\n\n    @Override\n    public DispatcherType getDispatcherType() {\n        return attributes.containsKey(DISPATCHER_TYPE) ? (DispatcherType) attributes.get(DISPATCHER_TYPE) : DispatcherType.REQUEST;\n    }\n\n    public ServletResponse getServletResponse() {\n        return servletResponse;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyHttpServletResponse.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.base.Charsets;\nimport com.google.common.base.Optional;\nimport com.google.common.net.MediaType;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.handler.codec.http.HttpHeaders;\nimport io.netty.handler.codec.http.HttpResponse;\nimport io.netty.handler.codec.http.HttpResponseStatus;\nimport io.netty.util.concurrent.FastThreadLocal;\n\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.http.Cookie;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.nio.charset.Charset;\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.*;\n\nimport static com.google.common.base.Preconditions.checkState;\n\n/**\n * {@link HttpServletResponse} wrapper for Netty's {@link HttpResponse}.\n *\n * @author Danny Thomas\n */\nclass NettyHttpServletResponse implements HttpServletResponse {\n    private static final FastThreadLocal<DateFormat> FORMAT = new FastThreadLocal<DateFormat>() {\n        @Override\n        protected DateFormat initialValue() {\n            return new SimpleDateFormat(\"E, dd MMM yyyy HH:mm:ss z\");\n        }\n    };\n\n    private static final Locale DEFAULT_LOCALE = Locale.getDefault();\n    private static final String DEFAULT_CHARACTER_ENCODING = Charsets.ISO_8859_1.name();\n\n    private final NettyEmbeddedContext servletContext;\n    private HttpResponse response;\n    private HttpResponseOutputStream outputStream;\n    private boolean usingOutputStream;\n    private PrintWriter writer;\n    private boolean committed;\n    private List<Cookie> cookies;\n    private String contentType;\n    private String characterEncoding = DEFAULT_CHARACTER_ENCODING;\n    private Locale locale;\n\n    NettyHttpServletResponse(ChannelHandlerContext ctx, NettyEmbeddedContext servletContext, HttpResponse response) {\n        this.servletContext = servletContext;\n        this.response = response;\n        this.outputStream = new HttpResponseOutputStream(ctx, this);\n        cookies = new ArrayList<>();\n    }\n\n    /**\n     * Get a Netty {@link HttpResponse}, committing the {@link HttpServletResponse}.\n     */\n    public HttpResponse getNettyResponse() {\n        if (committed) {\n            return response;\n        }\n        committed = true;\n        HttpHeaders headers = response.headers();\n        if (null != contentType) {\n            String value = null == characterEncoding ? contentType : contentType + \"; charset=\" + characterEncoding;\n            headers.set(HttpHeaders.Names.CONTENT_TYPE, value);\n        }\n        CharSequence date = getFormattedDate();\n        headers.set(HttpHeaders.Names.DATE, date);\n        headers.set(HttpHeaders.Names.SERVER, servletContext.getServerInfoAscii());\n        // TODO cookies\n        return response;\n    }\n\n    @VisibleForTesting\n    CharSequence getFormattedDate() {\n        return HttpHeaders.newEntity(FORMAT.get().format(new Date()));\n    }\n\n    @Override\n    public void addCookie(Cookie cookie) {\n        cookies.add(cookie);\n    }\n\n    @Override\n    public boolean containsHeader(String name) {\n        return response.headers().contains(name);\n    }\n\n    @Override\n    public String encodeURL(String url) {\n        return null;\n    }\n\n    @Override\n    public String encodeRedirectURL(String url) {\n        return null;\n    }\n\n    @Override\n    public String encodeUrl(String url) {\n        return null;\n    }\n\n    @Override\n    public String encodeRedirectUrl(String url) {\n        return null;\n    }\n\n    @Override\n    public void sendError(int sc, String msg) throws IOException {\n        checkNotCommitted();\n        response.setStatus(new HttpResponseStatus(sc, msg));\n    }\n\n    @Override\n    public void sendError(int sc) throws IOException {\n        checkNotCommitted();\n        response.setStatus(HttpResponseStatus.valueOf(sc));\n    }\n\n    @Override\n    public void sendRedirect(String location) throws IOException {\n        checkNotCommitted();\n        // TODO implement\n    }\n\n    @Override\n    public void setDateHeader(String name, long date) {\n        response.headers().set(name, date);\n    }\n\n    @Override\n    public void addDateHeader(String name, long date) {\n        response.headers().add(name, date);\n    }\n\n    @Override\n    public void setHeader(String name, String value) {\n        if (setHeaderField(name, value)) {\n            return;\n        }\n        response.headers().set(name, value);\n    }\n\n    private boolean setHeaderField(String name, String value) {\n        // Handle headers that shouldn't be set directly, and are instance fields\n        char c = name.charAt(0);\n        if ('C' == c || 'c' == c) {\n            if (HttpHeaders.Names.CONTENT_TYPE.equalsIgnoreCase(name)) {\n                setContentType(value);\n                return true;\n            }\n            // TODO Content-Language?\n        }\n        return false;\n    }\n\n    @Override\n    public void addHeader(String name, String value) {\n        if (setHeaderField(name, value)) {\n            return;\n        }\n        response.headers().add(name, value);\n    }\n\n    @Override\n    public void setIntHeader(String name, int value) {\n        response.headers().set(name, value);\n    }\n\n    @Override\n    public void addIntHeader(String name, int value) {\n        response.headers().add(name, value);\n    }\n\n    @Override\n    public void setStatus(int sc) {\n        response.setStatus(HttpResponseStatus.valueOf(sc));\n    }\n\n    @Override\n    public void setStatus(int sc, String sm) {\n        response.setStatus(new HttpResponseStatus(sc, sm));\n    }\n\n    @Override\n    public int getStatus() {\n        return response.status().code();\n    }\n\n    @Override\n    public String getHeader(String name) {\n        return response.headers().get(name);\n    }\n\n    @Override\n    public Collection<String> getHeaders(String name) {\n        return response.headers().getAll(name);\n    }\n\n    @Override\n    public Collection<String> getHeaderNames() {\n        return response.headers().names();\n    }\n\n    @Override\n    public String getCharacterEncoding() {\n        return characterEncoding;\n    }\n\n    @Override\n    public String getContentType() {\n        return contentType;\n    }\n\n    @Override\n    public ServletOutputStream getOutputStream() throws IOException {\n        checkState(!hasWriter(), \"getWriter has already been called for this response\");\n        usingOutputStream = true;\n        return outputStream;\n    }\n\n    @Override\n    public PrintWriter getWriter() throws IOException {\n        checkState(!usingOutputStream, \"getOutputStream has already been called for this response\");\n        if (!hasWriter()) {\n            writer = new PrintWriter(outputStream);\n        }\n        return writer;\n    }\n\n    @Override\n    public void setCharacterEncoding(String charset) {\n        if (hasWriter()) {\n            return;\n        }\n        characterEncoding = charset;\n    }\n\n    @Override\n    public void setContentType(String type) {\n        if (isCommitted()) {\n            return;\n        }\n        if (hasWriter()) {\n            return;\n        }\n        if (null == type) {\n            contentType = null;\n            return;\n        }\n        MediaType mediaType = MediaType.parse(type);\n        Optional<Charset> charset = mediaType.charset();\n        if (charset.isPresent()) {\n            setCharacterEncoding(charset.get().name());\n        }\n        contentType = mediaType.type() + '/' + mediaType.subtype();\n    }\n\n    private boolean hasWriter() {\n        return null != writer;\n    }\n\n    @Override\n    public void setContentLength(int len) {\n        HttpHeaders.setContentLength(response, len);\n    }\n\n    @Override\n    public void setContentLengthLong(long len) {\n        HttpHeaders.setContentLength(response, len);\n    }\n\n    @Override\n    public void setBufferSize(int size) {\n        checkNotCommitted();\n        outputStream.setBufferSize(size);\n    }\n\n    @Override\n    public int getBufferSize() {\n        return outputStream.getBufferSize();\n    }\n\n    @Override\n    public void flushBuffer() throws IOException {\n        checkNotCommitted();\n        outputStream.flush();\n    }\n\n    @Override\n    public void resetBuffer() {\n        checkNotCommitted();\n        outputStream.resetBuffer();\n    }\n\n    @Override\n    public boolean isCommitted() {\n        return committed;\n    }\n\n    void checkNotCommitted() {\n        checkState(!committed, \"Cannot perform this operation after response has been committed\");\n    }\n\n    @Override\n    public void reset() {\n        resetBuffer();\n        usingOutputStream = false;\n        writer = null;\n    }\n\n    @Override\n    public void setLocale(Locale loc) {\n        locale = loc;\n    }\n\n    @Override\n    public Locale getLocale() {\n        return null == locale ? DEFAULT_LOCALE : locale;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyRequestDispatcher.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport javax.servlet.*;\nimport java.io.IOException;\n\n/**\n * @author Danny Thomas\n */\nclass NettyRequestDispatcher implements RequestDispatcher {\n    private final ServletContext context;\n    private final FilterChain filterChain;\n\n    NettyRequestDispatcher(ServletContext context, FilterChain filterChain) {\n        this.context = context;\n        this.filterChain = filterChain;\n    }\n\n    @Override\n    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {\n        request.setAttribute(NettyHttpServletRequest.DISPATCHER_TYPE, DispatcherType.FORWARD);\n        // TODO implement\n    }\n\n    @Override\n    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {\n        request.setAttribute(NettyHttpServletRequest.DISPATCHER_TYPE, DispatcherType.INCLUDE);\n        // TODO implement\n    }\n\n    void dispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException {\n        request.setAttribute(NettyHttpServletRequest.DISPATCHER_TYPE, DispatcherType.ASYNC);\n        filterChain.doFilter(request, response);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/NettyServletRegistration.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport javax.servlet.*;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Set;\n\n/**\n * A {@link org.springframework.boot.context.embedded.netty.NettyEmbeddedContext} {@link javax.servlet.ServletRegistration}.\n *\n * @author Danny Thomas\n */\nclass NettyServletRegistration extends AbstractNettyRegistration implements ServletRegistration.Dynamic {\n    private volatile boolean initialised;\n    private Servlet servlet;\n\n    NettyServletRegistration(NettyEmbeddedContext context, String servletName, String className, Servlet servlet) {\n        super(servletName, className, context);\n        this.servlet = servlet;\n    }\n\n    public Servlet getServlet() throws ServletException {\n        if (!initialised) {\n            synchronized (this) {\n                if (!initialised) {\n                    if (null == servlet) {\n                        try {\n                            servlet = (Servlet) Class.forName(getClassName()).newInstance();\n                        } catch (Exception e) {\n                            throw new ServletException(e);\n                        }\n                    }\n                    servlet.init(this);\n                    initialised = true;\n                }\n            }\n        }\n        return servlet;\n    }\n\n    @Override\n    public void setLoadOnStartup(int loadOnStartup) {\n\n    }\n\n    @Override\n    public Set<String> setServletSecurity(ServletSecurityElement constraint) {\n        return null;\n    }\n\n    @Override\n    public void setMultipartConfig(MultipartConfigElement multipartConfig) {\n\n    }\n\n    @Override\n    public void setRunAsRole(String roleName) {\n\n    }\n\n    @Override\n    public Set<String> addMapping(String... urlPatterns) {\n        // TODO check for conflicts\n\n        NettyEmbeddedContext context = getNettyContext();\n        for (String urlPattern : urlPatterns) {\n            context.addServletMapping(urlPattern, getName());\n        }\n        return Collections.emptySet();\n    }\n\n    @Override\n    public Collection<String> getMappings() {\n        return null;\n    }\n\n    @Override\n    public String getRunAsRole() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/RequestDispatcherHandler.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.channel.ChannelHandler;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.SimpleChannelInboundHandler;\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * A {@link io.netty.channel.ChannelInboundHandler} that bridges to and from {@link HttpServletRequest}s and\n * {@link HttpServletResponse}s from Netty HTTP codec objects.\n *\n * @author Danny Thomas\n */\n@ChannelHandler.Sharable\nclass RequestDispatcherHandler extends SimpleChannelInboundHandler<NettyHttpServletRequest> {\n    private final Log logger = LogFactory.getLog(getClass());\n    private final NettyEmbeddedContext context;\n\n    RequestDispatcherHandler(NettyEmbeddedContext context) {\n        this.context = checkNotNull(context);\n    }\n\n    @Override\n    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {\n        ctx.flush();\n    }\n\n    @Override\n    protected void channelRead0(ChannelHandlerContext ctx, NettyHttpServletRequest request) throws Exception {\n        HttpServletResponse servletResponse = (HttpServletResponse) request.getServletResponse();\n        try {\n            NettyRequestDispatcher dispatcher = (NettyRequestDispatcher) context.getRequestDispatcher(request.getRequestURI());\n            if (dispatcher == null) {\n                servletResponse.sendError(404);\n                return;\n            }\n            dispatcher.dispatch(request, servletResponse);\n        } finally {\n            if (!request.isAsyncStarted()) {\n                servletResponse.getOutputStream().close();\n            }\n        }\n    }\n\n    @Override\n    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {\n        logger.error(\"Unexpected exception caught during request\", cause);\n        ctx.close();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/ServletContentHandler.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelInboundHandlerAdapter;\nimport io.netty.handler.codec.http.*;\n\n/**\n * {@link io.netty.channel.ChannelInboundHandler} responsible for initial request handling, and getting received\n * {@link HttpContent} messages to the {@link HttpContentInputStream} for the request.\n */\nclass ServletContentHandler extends ChannelInboundHandlerAdapter {\n    private final NettyEmbeddedContext servletContext;\n    private HttpContentInputStream inputStream; // FIXME this feels wonky, need a better approach\n\n    ServletContentHandler(NettyEmbeddedContext servletContext) {\n        this.servletContext = servletContext;\n    }\n\n    @Override\n    public void channelActive(ChannelHandlerContext ctx) throws Exception {\n        inputStream = new HttpContentInputStream(ctx.channel());\n    }\n\n    @Override\n    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n        if (msg instanceof HttpRequest) {\n            HttpRequest request = (HttpRequest) msg;\n            HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false);\n            HttpHeaders.setKeepAlive(response, HttpHeaders.isKeepAlive(request));\n            NettyHttpServletResponse servletResponse = new NettyHttpServletResponse(ctx, servletContext, response);\n            NettyHttpServletRequest servletRequest = new NettyHttpServletRequest(ctx, servletContext, request, servletResponse, inputStream);\n            if (HttpHeaders.is100ContinueExpected(request)) {\n                ctx.write(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE), ctx.voidPromise());\n            }\n            ctx.fireChannelRead(servletRequest);\n        }\n        if (msg instanceof HttpContent) {\n            inputStream.addContent((HttpContent) msg);\n        }\n    }\n\n    @Override\n    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\n        inputStream.close();\n    }\n}"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/SimpleFilterChain.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty;\n\nimport javax.servlet.*;\nimport java.io.IOException;\nimport java.util.Iterator;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * A very simple {@link FilterChain} implementation.\n *\n * @author Danny Thomas\n */\nclass SimpleFilterChain implements FilterChain {\n    private final Iterator<Filter> filterIterator;\n    private final Servlet servlet;\n\n    SimpleFilterChain(Servlet servlet, Iterable<Filter> filters) throws ServletException {\n        this.filterIterator = checkNotNull(filters).iterator();\n        this.servlet = checkNotNull(servlet);\n    }\n\n    @Override\n    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {\n        if (filterIterator.hasNext()) {\n            Filter filter = filterIterator.next();\n            filter.doFilter(request, response, this);\n        } else {\n            servlet.service(request, response);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/springframework/boot/context/embedded/netty/package-info.java",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * Comment here.\n */\npackage org.springframework.boot.context.embedded.netty;"
  },
  {
    "path": "src/test/groovy/org/springframework/boot/context/embedded/netty/HttpContentInputStreamTest.groovy",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty\n\nimport com.google.common.base.Charsets\nimport io.netty.buffer.Unpooled\nimport io.netty.channel.Channel\nimport io.netty.handler.codec.http.DefaultHttpContent\nimport io.netty.handler.codec.http.LastHttpContent\nimport spock.lang.Specification\n\n/**\n * Tests for {@link HttpContentInputStream}.\n */\nclass HttpContentInputStreamTest extends Specification {\n    def channel\n    def stream\n\n    def setup() {\n        channel = Mock(Channel)\n        stream = new HttpContentInputStream(channel)\n    }\n\n    def 'a read with a an empty last content returns -1'() {\n        given:\n        stream.addContent(LastHttpContent.EMPTY_LAST_CONTENT)\n\n        expect:\n        stream.read() == -1\n    }\n\n    def 'a read with an empty last content, for a non-active channel, returns -1'() {\n        given:\n        stream.addContent(LastHttpContent.EMPTY_LAST_CONTENT)\n\n        expect:\n        stream.read() == -1\n    }\n\n    def 'an attempt to read with a non-active channel, throws IOException'() {\n        given:\n        channel.isActive() >> false\n\n        when:\n        stream.read()\n\n        then:\n        thrown(IOException)\n    }\n\n    def 'expected number of bytes and content is read for a single content read'() {\n        when:\n        stream.addContent(new DefaultHttpContent(Unpooled.copiedBuffer(\"My hovercraft is full of eels.\", Charsets.UTF_8)))\n\n        then:\n        def b = new byte[30]\n        stream.read(b, 0, 30) == 30\n        new String(b) == \"My hovercraft is full of eels.\"\n    }\n\n    def 'the expected number of bytes and content is read for partial read of two component contents'() {\n        when:\n        stream.addContent(new DefaultHttpContent(Unpooled.copiedBuffer(\"My hovercraft is full of eels.\", Charsets.UTF_8)))\n        stream.addContent(new DefaultHttpContent(Unpooled.copiedBuffer(\" I will not buy this record, it is scratched.\", Charsets.UTF_8)))\n\n        then:\n        def b = new byte[75]\n        stream.read(b, 0, 30) == 30\n        stream.read(b, 30, 45) == 45\n        new String(b) == \"My hovercraft is full of eels. I will not buy this record, it is scratched.\"\n    }\n\n    def 'zero length read returns 0'() {\n        expect:\n        stream.read(new byte[0], 0, 0) == 0\n    }\n\n    def 'stream is not finished'() {\n        expect:\n        !stream.isFinished()\n    }\n\n    def 'stream is not ready'() {\n        expect:\n        !stream.isReady()\n    }\n\n    def 'stream has no available bytes'() {\n        expect:\n        stream.available() == 0\n    }\n}\n"
  },
  {
    "path": "src/test/groovy/org/springframework/boot/context/embedded/netty/PackageSanityTest.groovy",
    "content": "/*\n * Copyright 2014 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.springframework.boot.context.embedded.netty\n\nimport com.google.common.base.Predicate\nimport com.google.common.testing.AbstractPackageSanityTests\nimport io.netty.buffer.ByteBuf\nimport io.netty.buffer.Unpooled\nimport org.junit.Ignore\n\nimport javax.annotation.Nullable\n\n/**\n * Sanity tests for {@link org.springframework.boot.context.embedded.netty}.\n */\n@Ignore\n// FIXME I've added a bunch of new classes that can't be instantiated automatically, that'll I'll need to add back here\nclass PackageSanityTest extends AbstractPackageSanityTests {\n    PackageSanityTest() {\n        setDefault(ByteBuf, Unpooled.buffer())\n        setDefault(NettyEmbeddedContext, new NettyEmbeddedContext(\"/\", Thread.currentThread().getContextClassLoader(), \"ServerInfo\"))\n        ignoreClasses(new Predicate<Class<?>>() {\n            @Override\n            boolean apply(@Nullable Class<?> input) {\n                input == AbstractNettyRegistration\n            }\n        })\n    }\n}\n"
  }
]