[
  {
    "path": ".gitignore",
    "content": "*.class\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n# Ignore everything in this directory\ntarget\n.classpath\n.settings\n.project\n*.iml\n*.iws\n*.ipr\n.idea\n\n# Ignore dependency-reduced-pom.xml file created by Apache Maven Shade Plugin, see https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html\ndependency-reduced-pom.xml\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 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\n"
  },
  {
    "path": "README.md",
    "content": "[Build status:](https://wso2.org/jenkins/job/products/job/msf4j/) ![Build Status](https://wso2.org/jenkins/job/products/job/msf4j/badge/icon)\n\n# WSO2 Microservices Framework for Java (MSF4J)\n\nWSO2 Microservices Framework for Java (MSF4J) is a lightweight high performance framework for developing\n& running microservices.\n\nWSO2 MSF4J is one of the highest performing lightweight Java microservices frameworks. The following graphs show the \nthroughput, memory consumption & latency characteristics of MSF4J against other microservices frameworks.\n \n![EchoThroughput](perf-benchmark/graphs/echotps.png) \n\nAn echo service which accepts a 1KB request & echoes it back directly and using a temp file was developed for the respective \nframeworks, and requests were sent for different concurrency values. The test was repeated for each concurrency value for each \nframework and the average throughput was calculated. \nTests were run out of the box without any tuning on 32 core 64GB server in JVM v1.8.0_60 with default configuration.\n\n![EchoMemory](perf-benchmark/graphs/echomem.png)\n\nMemory usage for each framework was observed after running the 1KB payload echo microservice on each framework & \nsending a number of requests at different concurrency levels to each service. \nThe graph above shows the averaged out values after several runs for each framework.\n \nLatency results was observed using the Apache bench provided percentile values. Results were plotted for \nvarious concurrency levels the simple echo test. \n  \n![MeanLatency](perf-benchmark/graphs/meanlatency.png)\n\nTests were run out of the box without any tuning on 32 core 64GB server in JVM v1.8.0_60 with default configuration.\n\nMore details about the performance test can found [here](perf-benchmark).\n\n## Hello world with MSF4J\n\nIt is really easy to define & deploy a Java microservice using WSO2 MSF4J. \nYou simply need to annotate your service and deploy it using a single line of code. \n\nLet's get started by writing a hello world MSF4J microservice. \n\nYou can use the [msf4j-microservice](archetypes) Maven [archetype](http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html)\n to create your first MSF4J project. \n Make sure you have JDK 1.8 and Maven 3.x installed, & run the following command.\n\n```\nmvn archetype:generate -DarchetypeGroupId=org.wso2.msf4j \\\n-DarchetypeArtifactId=msf4j-microservice -DarchetypeVersion=2.6.2 \\\n-DgroupId=org.example -DartifactId=Hello-Service -Dversion=0.1-SNAPSHOT \\\n-Dpackage=org.example.service -DserviceClass=HelloService\n```\n\nThis will generate a project structure for you to quickly get started.\nNext navigate to the Hello-Service directory. You will find a pom.xml file and also an src directory.\n\n#### pom.xml\nThis pom file inherits from the msf4j-service/pom.xml. It provides a way of setting things up quickly with minimum \namount of \nconfiguration. Click [here](poms/msf4j-service) for more information.\n\n```xml\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.6.2</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.example</groupId>\n    <artifactId>Hello-Service</artifactId>\n    <version>0.1-SNAPSHOT</version>\n    <name>WSO2 MSF4J Microservice</name>\n\n    <properties>\n        <microservice.mainClass>org.example.service.Application</microservice.mainClass>\n    </properties>\n\n</project>\n```\n\nYou don't need to change anything in this pom.xml file.\n\n#### HelloService.java\nChange the org.example.service.HelloService class as follows to echo back the name input parameter. \nYou can remove the auto generated code and replace it with the following code segment:\n\n```java\npackage org.example.service; \n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@Path(\"/hello\")\npublic class HelloService {\n\n    @GET\n    @Path(\"/{name}\")\n    public String hello(@PathParam(\"name\") String name) {\n        return \"Hello \" + name;\n    }\n\n}\n```\n\n#### Application.java\nThis is the one-liner to deploy your service using WSO2 MSF4J.\n```java\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new HelloService())\n                .start();\n    }\n}\n```\n\nYou can also pass in the port(s) as an argument to the MicroservicesRunner class constructor. When passing the port(s) \nas an argument, by default it binds to 0.0.0.0 host. Use \"msf4j.host\" environment variable to override the host value. \n\n\n### Build the Service\nRun the following Maven command. This will create the fat jar **Hello-Service-0.1-SNAPSHOT.jar** in the **target** directory.\n```\nmvn package\n```\nThis fat jar is a jar file that contains your microservice as well as all its dependencies.\n\n### Run the Service\nYou just have to run the following command to get your service up and running.\n```\njava -jar target/Hello-Service-*.jar\n```\n\n\n### Test the Service with cURL\nRun the following command or simply go to [http://localhost:8080/hello/wso2]\n(http://localhost:8080/hello/wso2) from your browser.\n```\ncurl http://localhost:8080/hello/wso2\n```\n\nYou should see a response that prints \"Hello wso2\"\n\n## Supported Annotations\n\nIn this section, we will look at the annotations used in MSF4J microservices. As you may have already noticed,\n we support a subset of the JAXRS annotations.\n\n### Class level annotations\n##### @Path\nRoot path for resource methods. All the paths specified in the resource methods will be sub paths of this.\n\n##### @Consumes\nDefault consume media type(s) for resource methods. The resource methods that do not specify @Consume annotation will\n inherit this consume media type(s).\n\n##### @Produces\nDefault produce media type(s) for resource methods. The resource methods that do not specify @Produce annotation will\ninherit this produce media type(s).\n\n\n### Method level annotations\n##### @Path\nEndpoint of the resource method relative to @Path of the container resource class.\n\n##### @Consumes\nMedia type(s) that the method can consume. This overrides the class level @Consumes media types.\n\n##### @Produces\nMedia type(s) that is produced by the method. This overrides the class level @Produces media types.\n\n##### @GET\nHTTP GET method. Specify that the resource method supports HTTP GET method.\n\n##### @PUT\nHTTP PUT method. Specify that the resource method supports HTTP PUT method.\n\n##### @POST\nHTTP POST method. Specify that the resource method supports HTTP POST method.\n\n##### @DELETE\nHTTP DELETE method. Specify that the resource method supports HTTP DELETE method.\n\n##### @HEAD\nHTTP HEAD method. Specify that the resource method supports HTTP HEAD method.\n\n##### @OPTIONS\nHTTP OPTIONS method. Specify that the resource method supports HTTP OPTIONS method.\n\n### Parameter level annotations\n##### @DefaultValue\nSpecify a default value for a resource method parameter. The value will be automatically converted to the \ncorresponding parameter's type.\n\n##### @Context\nInject additional objects to a resource method. Currently supports injection of the following objects.\n\n* org.wso2.msf4j.Request - \n    This object can be used to access properties of the HTTP request. The transport session (org.wso2.msf4j.Session) \n    can also be accessed via org.wso2.msf4j.Request#getSession(). \n    See the [Session-aware service](samples/http-session) sample.\n* org.wso2.msf4j.Response - \n    This object can be used to send HTTP responses. You can make responses more clean way by returning an instance of \n    javax.ws.rs.core.Response or a POJO. See the [StockQuote-Service]\n    (samples/stockquote/fatjar) sample.\n* org.wso2.msf4j.HttpStreamer - \n    This object can be used to stream a chunked request body and process it while the request is streaming. \n    See the [FileServer](samples/fileserver) sample.\n* org.wso2.msf4j.formparam.FormParamIterator - \n    This object can be used to stream a HTML form submission request body and process it while the request is streaming. \n    See the [FormParam](samples/formparam) sample.\n\n##### @PathParam\n/StockQuote/{symbol} to get value of symbol. The value will be automatically converted to the corresponding parameter\n type and assigned to that parameter.\n\n##### @QueryParam\n/Students?age=18 to get value of age. The value will be automatically converted to the corresponding parameter type \nand assigned to that parameter.\n\n##### @HeaderParam\nTo read HTTP request header values. The value will be automatically converted to the corresponding parameter type and\n assigned to that parameter.\n \n##### @CookieParam\nExtracts the value from the specified cookie, converts to the corresponding parameter type and assigns the value to \nthat parameter.  \n\n##### @FormParam\nTo support HTML form submission with application/x-www-form-urlencoded and multipart/form-data The value will be \nautomatically converted to the corresponding parameter type and assigned to that parameter\n\n##### @FormDataParam\nTo support complex form submission with multipart/form-data content type. E.g file uploads and beans. The values will be \nautomatically converted to the corresponding parameter type and assigned to that parameter\n\n### Lifecycle Callback Methods\nSupport following Java lifecycle callback method annotations. \n\n##### @PostConstruct\nInvoke by the container on newly constructed service instances after all dependency injection has completed and before transport starts. \n\n##### @PreDestroy\nInvoke by the container during server shutdown before the  container removes the service instance.\n\nFor a detailed example, check out the lifecycle sample [here](https://github.com/wso2/msf4j/tree/master/samples/lifecycle).\n \n## MSF4J Interceptors\n\nPlease do refer the following for complete instructions.\n\n* [General instructions](/samples/interceptor/README.md)\n* [MSF4J Interceptors - Stand alone mode instructions](/samples/interceptor/fatjar-interceptor-service/README.md)\n* [MSF4J Interceptors - Deployable Jar mode instructions ](/samples/interceptor/deployable-jar-interceptor-service/README.md)\n* [MSF4J Interceptors - OSGi mode instructions](/samples/interceptor/osgi-interceptor-service/README.md)\n* [MSF4J Interceptors with MSF4J Spring - Fat Jar mode](/samples/interceptor/spring-fatjar-interceptor-service/README.md)\n\n## Develop and configure MSF4J services using Spring framework\n\nSpring is a popular Java application development framework which supports concepts like Dependency Injection(DI) \nand Convention over Configuration.  Spring support for MSF4J provides following features. \n\n1. Develop MSF4J services as Spring beans \n2. Develop and configure MSF4J components such as Interceptors and ExceptionMappers using Spring. \n3. Use Annotation or XML based Spring configuration to configure internals of MSF4J framework such as ports, SSL etc. \n\nFollowing example illustrates how to use Spring annotations together with MSF4J annotations to build a RESTful service. The main advantage here is service developers can consume Spring features such as dependency injection , Spring AOP etc. in the Spring way.  \n\n```java\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n@Component\n@Path(\"/greeting\")\npublic class Hello {\n\n    @Autowired\n    private HelloService helloService;\n\n    @GET\n    public String message() {\n        return helloService.hello(\" World\");\n    }\n}\n```\n\nFor further details refer Spring [Helloworld sample](samples/spring-helloworld).\n\n\n\n## Annotations for Analytics\n\nIn this section, we will look at the annotations available for analytics purposes MSF4J microservices. There are annotations \nfor Metrics and HTTP Monitoring.\n\nYou will need to configure [analytics](analytics) when you want to publish Metrics and HTTP Monitoring events to \nWSO2 Data Analytics Server (DAS).\n\nThe Metrics data will be published to WSO2 DAS periodically. However the HTTP Monitoring events are published on each request.\n\nFor a detailed example, check out the [Metrics and HTTP Monitoring sample](samples/http-monitoring). \n\n### Metrics Annotations\n\nYou can use the Metrics annnotations in your MSF4J microservices to understand how your microservices work in production.\n\nThere are three metrics annotations supported. Those are @Counted, @Metered and @Timed.\n\nEach metric must have a unique name and the MSF4J will use the fully qualified method name as the metric name by default. \nYou can give a custom name by using the \"name\" parameter. This custom name will be appended to the fully qualified method name \nwith a dot character. You can set the \"absolute\" parameter to \"true\" if you want use only the given name as the metric name. \n\nFor example, see following table to understand how the final metric name is built by the Metrics runtime. Let's asssume that the \nannotation is added to the \"hello\" method of \"HelloService\" shown above.\n\n| Metrics Annotation                               | Metric Name                                         |\n| ------------------------------------------------ | --------------------------------------------------- |\n| @Counted                                         | org.example.service.HelloService.hello              |\n| @Counted(name = \"helloCounter\")                  | org.example.service.HelloService.hello.helloCounter |\n| @Counted(name = \"helloCounter\", absolute = true) | helloCounter                                        |\n\nThe Metrics annotations can be used at the Method level and Class level.\n\nYou can also configure a level in Metrics Annotations. For more information about Metric Levels, \nsee [WSO2 Carbon Metrics](https://github.com/wso2/carbon-metrics). In MSF4J, you can load the metrics level configuration \nvia the System Property named `metrics.level.conf`.\n\n##### @Counted\nCount the method invocations. There is a parameter named \"monotonic\" and it is set to false by default. This means that the\ncounter is decremented when the method returns. This is useful to count the current invocations of the annotated method.\n\nUse `@Counted(monotonic = true)` when you want the counter to increase monotonically. This is useful to count the total invocations \nof the annotated method\n\n##### @Metered\nMeasure the rate of method invocations. This also keeps a count of the total invocations of the annotated method.\n\n##### @Timed\nMaintain a histogram of durations of each method invocation. This also measures the rate of method invocations and keeps a count of the \ntotal invocations of the annotated method. \n\n### HTTP Monitoring Annotation\n\nYou can use the annotation provided for HTTP Monitoring when you want to monitor each HTTP request and see the summary \nin \"HTTP Monitoring Dashboard\".\n\n##### @HTTPMonitored\nMonitor each HTTP request. This annotation can be used at the Class level and the Method level.\n\n### HTTP Message Tracing\nMSF4J supports visual message tracing through user friendly dashboards in WSO2 DAS or Zipkin. MSF4J message tracing provides \na detailed insight to the complex microservices interactions in a system making monitoring, trouble shooting and optimization of \nmicroservices very easy. Please check [WSO2 DAS Tracing](samples/message-tracing/das) and [Zipkin Tracing](samples/message-tracing/zipkin) samples for more details.\n\n### Swagger Annotations\n[Swagger](http://swagger.io/getting-started/) is a standard, language-agnostic interface to REST APIs which allows both \nhumans and computers to discover and understand the capabilities of the service without access to source code, documentation, \nor through network traffic inspection. \n\nMSF4J supports all [Swagger annotations](https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X) out of the box.\n\nTo enable swagger support you need to add the following dependency to your project\n```xml\n<dependency>\n     <groupId>org.wso2.msf4j</groupId>\n     <artifactId>msf4j-swagger</artifactId>\n     <version>2.6.2</version>\n</dependency>\n```\nIn order to retrieve Swagger definitions of your microservice, go to <br/>http://&lt;host&gt;:&lt;port&gt;/swagger?path=&lt;service_base_path&gt;.\n\ne.g. [http://localhost:8080/swagger?path=/hello](http://localhost:8080/swagger?path=/hello)\n\nTo retrieve Swagger definitions of all microservices in your runtime, go to http://&lt;host&gt;:&lt;port&gt;/swagger.\n\ne.g. [http://localhost:8080/swagger](http://localhost:8080/swagger)\n\nNOTE: Even without any Swagger annotation, default Swagger definitions will be generated using the JAXRS annotation\nin your MSF4J microservice.\n\nThe [StockQuote sample](samples/stockquote/fatjar) demonstrates Swagger annotations in action.\n\n### ExceptionMapper \nMSF4J supports [JAXRS ExceptionMapper](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ExceptionMapper.html) \nwhich allows creation of custom responses when exceptions are thrown from MSF4J services. \n\nThe [StockQuote sample](samples/stockquote/fatjar) demonstrates ExceptionMapper in action.\n\nThe following code segment shows how ExceptionMappers are registered with the MSF4J runtime.\n\n```java\nnew MicroservicesRunner().addExceptionMapper(new SymbolNotFoundMapper(), new DuplicateSymbolMapper());\n```\n\n### Circuit Breaker\nNygard's circuit breaker pattern is supported in MSF4J using the Netflix Hystrix library. For more details see the\n[circuit breaker sample](samples/circuitbreaker)\n\n### Complete Feature List\n* Annotation based definition of microservices\n* High performance Netty based transport\n* WSO2 Developer Studio based tooling for microservices development starting from a Swagger API definition\n* Generate Swagger definition using [Swagger annotations](https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X)\n* Ability to develop and Configure MSF4J services using Spring framework\n* HTTP request & response streaming including support for javax.ws.rs.core.StreamingOutput.\n* [ExceptionMapper]((https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ExceptionMapper.html))\n* Support for metrics & visualization of metrics using WSO2 Data Analytics Server (DAS) dashboards\n* Message tracing with WSO2 DAS or Zipkin to get a detailed visual insight to the microservices interactions\n* Supports circuit breaker using Netflix Hystrix. \n* Support for securing microservices\n* Integration with rendering engines such as Mustache\n* Comprehensive samples demonstrating how to develop microservices based solutions\n"
  },
  {
    "path": "analytics/README.md",
    "content": "# WSO2 MSF4J - Analytics with WSO2 Data Analytics Server (DAS)\n\nThis directory contains the files related to publishing metrics to WSO2 Data Analytics Server (DAS)\n\nDownload WSO2 DAS\n------------------------------------------\n[Download](http://wso2.com/products/data-analytics-server/) WSO2 DAS and unpack it to some directory.\nThis will be the DAS_HOME directory.\n\nConfigure DAS\n------------------------------------------\nRun \"das-setup/setup.sh\" to setup DAS. Note that the DAS Home directory in the above step has to \nbe provided as an input to that script.\n\nThe setup script will also copy the already built MSF4J HTTP Monitoring Carbon App (CAPP) to DAS.\n\nStart DAS\n------------------------------------------\n\nFrom DAS_HOME, run, bin/wso2server.sh to start DAS and make sure that it starts properly.\n\nRun a sample that publishes data to DAS\n------------------------------------------\nRun the [HTTP Monitoring Sample](../samples/http-monitoring)\nincluded in the distribution. This sample will publish data to DAS.\n\nAccessing the dashboard\n------------------------------------------\n\nGo to [http://127.0.0.1:9763/monitoring/](http://127.0.0.1:9763/monitoring/). If everything works fine, you should\nsee the metrics & information related to your microservices on this dashboard. Please allow a few minutes for the\ndashboard to be updated because the dashboard update batch task runs every few minutes.\n\n\nFor Advanced Users\n------------------------------------------\nIf you are an advanced WSO2 DAS user, you can go to the DAS Management Console at\n[https://localhost:9443/](https://localhost:9443/) and login with username/password admin/admin.\nOnce you login, you can view and manually execute the *http_event_script*  in the console to immediately see\nthe results in the dashboard.\n\nThe sources for MSF4J HTTP Monitoring Carbon Application (CAPP) can be found inside \"msf4j_http_monitoring_capp_source\" \ndirectory. This CAPP is already built and copied to WSO2 DAS when you Configure DAS as mentioned above.\n"
  },
  {
    "path": "analytics/das-setup/setup.sh",
    "content": "#!/bin/bash\n# Copyright 2015 WSO2 Inc. (http://wso2.org)\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# A script for setting up DAS\n# ----------------------------------------------------------------------------\n\nset -e\n\nconfig_dir=$(dirname \"$0\")\n\ndas_dir=\"\"\nfunction help {\n    echo \"\"\n    echo \"Usage: \"\n    echo \"setup.sh -d <DAS_HOME>\"\n    echo \"\"\n    echo \"-d: WSO2 Data Analytics Server (DAS) home directory\"\n    echo \"\"\n}\n\ncheckcommand () {\n    command -v $1 >/dev/null 2>&1 || { echo >&2 \"Command $1 not found.\"; exit 1; }\n}\n\nwhile getopts \"d:\" opts\ndo\n  case $opts in\n    d)\n        das_dir=${OPTARG}\n        ;;\n    \\?)\n        help\n        exit 1\n        ;;\n  esac\ndone\n\nif [[ ! -d $das_dir ]]; then\n    echo \"Please specify the WSO2 DAS Home.\"\n    help\n    exit 1\nfi\n\ncheckcommand unzip\n\necho \"Copying Carbon Apps to DAS.\"\nmkdir -p $das_dir/repository/deployment/server/carbonapps\ncp $config_dir/capps/*.car $das_dir/repository/deployment/server/carbonapps\n\necho \"Setting up HTTP Monitoring Dashboard.\"\nif [[ ! -d $das_dir/repository/deployment/server/jaggeryapps/monitoring ]]; then\n    mkdir -p $das_dir/repository/deployment/server/jaggeryapps/monitoring\n    unzip -q $config_dir/httpmon-dashboard/monitoring.zip -d $das_dir/repository/deployment/server/jaggeryapps/monitoring\nfi\nunzip -q -o $config_dir/httpmon-dashboard/modules.zip -d $das_dir/modules/\n\necho \"Completed...\"\n"
  },
  {
    "path": "analytics/msf4j-analytics/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-analytics</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J Analytics</name>\n    <description>WSO2 MSF4J Analytics</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.jdbc.core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.das.core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.config</groupId>\n            <artifactId>org.wso2.carbon.config</artifactId>\n            <version>${carbon.config.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.wso2.carbon.config</groupId>\n                <artifactId>org.wso2.carbon.config.maven.plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <export.package>\n            org.wso2.msf4j.analytics.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            javax.annotation.*,\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            org.apache.commons.beanutils.*;version=\"${beanutils.version.range}\",\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.osgi.util.tracker; version=\"${osgi.service.tracker.import.version.range}\",\n            org.wso2.carbon.utils.*;version=\"${carbon.utils.package.import.version.range}\",\n            org.wso2.carbon.config.*;version=\"${carbon.config.package.import.version.range}\",\n            org.wso2.carbon.metrics.core.*;version=\"${carbon.metrics.version.range}\",\n            <!--org.wso2.carbon.databridge.*,-->\n            org.wso2.carbon.kernel.startupresolver.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.msf4j.*,\n            org.wso2.msf4j.util.*,\n            javax.ws.rs.*,\n        </import.package>\n        <carbon.component>\n            osgi.service;objectClass=\"org.wso2.carbon.kernel.startupresolver.CapabilityProvider\";capabilityName=\"org.wso2.msf4j.Interceptor\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/AnalyticUtils.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.config.ConfigProviderFactory;\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.msf4j.analytics.internal.DataHolder;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\n/**\n * Utils contains utility methods to use analytic purposes\n */\npublic class AnalyticUtils {\n\n    private static final Logger logger = LoggerFactory.getLogger(AnalyticUtils.class);\n    private static final String DEPLOYMENT_YAML_SYS_PROPERTY = \"msf4j.conf\";\n    private static final String DEPLOYMENT_YAML_FILE = \"deployment.yaml\";\n\n    /**\n     * Retrieve Configuration Provider Object to read analytic configurations\n     * @return configProvider object\n     */\n    public static ConfigProvider getConfigurationProvider() {\n        ConfigProvider configProvider = DataHolder.getInstance().getConfigProvider();\n        if (configProvider == null) {\n            if (DataHolder.getInstance().getBundleContext() != null) {\n                throw new RuntimeException(\n                        \"Failed to populate HTTPMonitoringConfig Configuration. Config Provider is Null.\");\n            }\n            //Standalone mode\n            String deploymentYamlPath = System.getProperty(DEPLOYMENT_YAML_SYS_PROPERTY);\n            if (deploymentYamlPath == null || deploymentYamlPath.isEmpty()) {\n                logger.info(\"System property '\" + DEPLOYMENT_YAML_SYS_PROPERTY +\n                        \"' is not set. Default deployment.yaml file will be used.\");\n                deploymentYamlPath = DEPLOYMENT_YAML_FILE;\n                try (InputStream configInputStream = AnalyticUtils.class.getClassLoader()\n                        .getResourceAsStream(DEPLOYMENT_YAML_FILE)) {\n                    if (configInputStream == null) {\n                        throw new RuntimeException(\"Couldn't find \" + deploymentYamlPath);\n                    }\n                    if (Files.notExists(Paths.get(deploymentYamlPath))) {\n                        Files.copy(configInputStream, Paths.get(deploymentYamlPath));\n                    }\n                } catch (IOException e) {\n                    throw new RuntimeException(\"Couldn't read configuration from file \" + deploymentYamlPath, e);\n                }\n            } else if (!Files.exists(Paths.get(deploymentYamlPath))) {\n                throw new RuntimeException(\"Couldn't find \" + deploymentYamlPath);\n            }\n\n            try {\n                configProvider = ConfigProviderFactory.getConfigProvider(Paths.get(deploymentYamlPath), null);\n                DataHolder.getInstance().setConfigProvider(configProvider);\n            } catch (ConfigurationException e) {\n                throw new RuntimeException(\"Error loading deployment.yaml Configuration\", e);\n            }\n        }\n        return configProvider;\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/HTTPMonitored.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Monitor HTTP Requests.\n */\n@Inherited\n@Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.TYPE, ElementType.METHOD })\npublic @interface HTTPMonitored {\n    \n    boolean tracing() default false;\n    \n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/HTTPMonitoringDataPublisher.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.databridge.agent.AgentHolder;\nimport org.wso2.carbon.databridge.agent.DataPublisher;\nimport org.wso2.carbon.databridge.agent.exception.DataEndpointAgentConfigurationException;\nimport org.wso2.carbon.databridge.agent.exception.DataEndpointAuthenticationException;\nimport org.wso2.carbon.databridge.agent.exception.DataEndpointConfigurationException;\nimport org.wso2.carbon.databridge.agent.exception.DataEndpointException;\nimport org.wso2.carbon.databridge.commons.Event;\nimport org.wso2.carbon.databridge.commons.exception.TransportException;\nimport org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.model.DasConfig;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport java.net.Inet4Address;\nimport java.net.InetAddress;\nimport java.net.NetworkInterface;\nimport java.net.SocketException;\nimport java.net.UnknownHostException;\nimport java.util.Enumeration;\nimport java.util.Map;\n\n/**\n * A utility class to initialize/destroy HTTP Monitoring Data Publisher for DAS.\n */\npublic final class HTTPMonitoringDataPublisher {\n\n    private static final Logger logger = LoggerFactory.getLogger(HTTPMonitoringDataPublisher.class);\n\n    private static final String HTTP_MONITORING_STREAM = \"org.wso2.msf4j.analytics.httpmonitoring\";\n    private static final String VERSION = \"1.0.0\";\n    private static final String HTTP_MONITORING_STREAM_ID;\n\n    private static final String SERVER_HOST_ADDRESS;\n    private static final String SERVER_HOSTNAME;\n\n    private static final String MICROSERVICE = \"Microservice\";\n\n    private DataPublisher dataPublisher;\n    private Map<String, String> arbitraryAttributes;\n\n    static {\n        HTTP_MONITORING_STREAM_ID = DataBridgeCommonsUtils.generateStreamId(HTTP_MONITORING_STREAM, VERSION);\n        try {\n            InetAddress localAddress = getLocalAddress();\n            SERVER_HOST_ADDRESS = localAddress.getHostAddress();\n            SERVER_HOSTNAME = localAddress.getHostName();\n        } catch (SocketException | UnknownHostException e) {\n            throw new IllegalStateException(\"Cannot determine server host address\", e);\n        }\n    }\n\n    public HTTPMonitoringDataPublisher(DasConfig dasConfig) {\n        init(dasConfig);\n        // Destroy data publisher at shutdown\n        Thread thread = new Thread(this::destroy);\n        Runtime.getRuntime().addShutdownHook(thread);\n    }\n\n    private static InetAddress getLocalAddress() throws SocketException, UnknownHostException {\n        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();\n        while (interfaces.hasMoreElements()) {\n            NetworkInterface iface = interfaces.nextElement();\n            Enumeration<InetAddress> addresses = iface.getInetAddresses();\n            if (iface.isUp()) {\n                while (addresses.hasMoreElements()) {\n                    InetAddress addr = addresses.nextElement();\n                    if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {\n                        return addr;\n                    }\n                }\n            }\n\n        }\n        return InetAddress.getLocalHost();\n    }\n\n    private void init(DasConfig dasConfig) {\n        if (logger.isInfoEnabled()) {\n            logger.info(\"Initializing HTTP Monitoring Data Publisher\");\n        }\n\n        String type = dasConfig.getType();\n        String receiverURL = dasConfig.getReceiverURL();\n        String authURL = dasConfig.getAuthURL();\n        String username = dasConfig.getUsername();\n        String password = dasConfig.getPassword();\n        String dataAgentConfigPath = dasConfig.getDataAgentConfigPath();\n\n        if (type == null) {\n            throw new IllegalArgumentException(\"Type cannot be null\");\n        }\n        if (receiverURL == null) {\n            throw new IllegalArgumentException(\"Data Receiver URL cannot be null\");\n        }\n        if (username == null) {\n            throw new IllegalArgumentException(\"Username cannot be null\");\n        }\n        if (password == null) {\n            throw new IllegalArgumentException(\"Password cannot be null\");\n        }\n        if (dataAgentConfigPath == null) {\n            throw new IllegalArgumentException(\"Data Agent Configuration Path cannot be null\");\n        }\n        AgentHolder.setConfigPath(dataAgentConfigPath);\n        arbitraryAttributes = SystemVariableUtil.getArbitraryAttributes();\n        try {\n            dataPublisher = new DataPublisher(type, receiverURL, authURL, username, password);\n        } catch (DataEndpointAgentConfigurationException | DataEndpointException | DataEndpointConfigurationException\n                | DataEndpointAuthenticationException | TransportException e) {\n            throw new IllegalStateException(\"Error when initializing the Data Publisher\", e);\n        }\n    }\n\n    private void destroy() {\n        if (dataPublisher != null) {\n            try {\n                dataPublisher.shutdownWithAgent();\n            } catch (DataEndpointException e) {\n                logger.error(\"Error shutting down the data publisher with agent\", e);\n            } finally {\n                dataPublisher = null;\n            }\n        }\n    }\n\n    public void publishEvent(HTTPMonitoringEvent httpMonitoringEvent) {\n        Object[] meta = new Object[4];\n        meta[0] = httpMonitoringEvent.getTimestamp();\n        meta[1] = SERVER_HOST_ADDRESS;\n        meta[2] = SERVER_HOSTNAME;\n        meta[3] = MICROSERVICE;\n        Object[] correlation = new Object[2];\n        correlation[0] = httpMonitoringEvent.getActivityId();\n        correlation[1] = httpMonitoringEvent.getParentRequest();\n        Object[] payload = new Object[11];\n        payload[0] = httpMonitoringEvent.getServiceClass();\n        payload[1] = httpMonitoringEvent.getServiceName();\n        payload[2] = httpMonitoringEvent.getServiceMethod();\n        payload[3] = httpMonitoringEvent.getRequestUri();\n        payload[4] = httpMonitoringEvent.getServiceContext();\n        payload[5] = httpMonitoringEvent.getHttpMethod();\n        payload[6] = httpMonitoringEvent.getContentType();\n        payload[7] = httpMonitoringEvent.getRequestSizeBytes();\n        payload[8] = httpMonitoringEvent.getReferrer();\n        payload[9] = httpMonitoringEvent.getResponseHttpStatusCode();\n        payload[10] = httpMonitoringEvent.getResponseTime();\n\n        Event event = new Event(HTTP_MONITORING_STREAM_ID, httpMonitoringEvent.getTimestamp(), meta, correlation,\n                payload, arbitraryAttributes);\n        dataPublisher.publish(event);\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/HTTPMonitoringEvent.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring;\n\n/**\n * Monitoring Event.\n */\npublic class HTTPMonitoringEvent {\n\n    private long timestamp;\n    private String serverName;\n    private String serverAddress;\n    private long startNanoTime;\n    private String serviceClass;\n    private String serviceName;\n    private String serviceContext;\n    private String serviceMethod;\n    private String requestUri;\n    private String httpMethod;\n    private String contentType;\n    private Integer responseHttpStatusCode;\n    private String referrer;\n    private long responseTime;\n    private long requestSizeBytes;\n    private String activityId;\n    private String parentRequest;\n\n    public long getTimestamp() {\n        return timestamp;\n    }\n\n    public void setTimestamp(long timestamp) {\n        this.timestamp = timestamp;\n    }\n\n    public String getServerName() {\n        return serverName;\n    }\n\n    public void setServerName(String serverName) {\n        this.serverName = serverName;\n    }\n\n    public String getServerAddress() {\n        return serverAddress;\n    }\n\n    public void setServerAddress(String serverAddress) {\n        this.serverAddress = serverAddress;\n    }\n\n    public long getStartNanoTime() {\n        return startNanoTime;\n    }\n\n    public void setStartNanoTime(long startNanoTime) {\n        this.startNanoTime = startNanoTime;\n    }\n\n    public String getServiceClass() {\n        return serviceClass;\n    }\n\n    public void setServiceClass(String serviceClass) {\n        this.serviceClass = serviceClass;\n    }\n\n    public String getServiceName() {\n        return serviceName;\n    }\n\n    public void setServiceName(String serviceName) {\n        this.serviceName = serviceName;\n    }\n\n    public String getServiceContext() {\n        return serviceContext;\n    }\n\n    public void setServiceContext(String serviceContext) {\n        this.serviceContext = serviceContext;\n    }\n\n    public String getServiceMethod() {\n        return serviceMethod;\n    }\n\n    public void setServiceMethod(String serviceMethod) {\n        this.serviceMethod = serviceMethod;\n    }\n\n    public String getRequestUri() {\n        return requestUri;\n    }\n\n    public void setRequestUri(String requestUri) {\n        this.requestUri = requestUri;\n    }\n\n    public String getHttpMethod() {\n        return httpMethod;\n    }\n\n    public void setHttpMethod(String httpMethod) {\n        this.httpMethod = httpMethod;\n    }\n\n    public String getContentType() {\n        return contentType;\n    }\n\n    public void setContentType(String contentType) {\n        this.contentType = contentType;\n    }\n\n    public Integer getResponseHttpStatusCode() {\n        return responseHttpStatusCode;\n    }\n\n    public void setResponseHttpStatusCode(Integer responseHttpStatusCode) {\n        this.responseHttpStatusCode = responseHttpStatusCode;\n    }\n\n    public String getReferrer() {\n        return referrer;\n    }\n\n    public void setReferrer(String referrer) {\n        this.referrer = referrer;\n    }\n\n    public long getResponseTime() {\n        return responseTime;\n    }\n\n    public void setResponseTime(long responseTime) {\n        this.responseTime = responseTime;\n    }\n\n    public long getRequestSizeBytes() {\n        return requestSizeBytes;\n    }\n\n    public void setRequestSizeBytes(long requestSizeBytes) {\n        this.requestSizeBytes = requestSizeBytes;\n    }\n\n    public String getActivityId() {\n        return activityId;\n    }\n\n    public void setActivityId(String activityId) {\n        this.activityId = activityId;\n    }\n\n    public String getParentRequest() {\n        return parentRequest;\n    }\n\n    public void setParentRequest(String parentRequest) {\n        this.parentRequest = parentRequest;\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/HTTPMonitoringInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.HTTPMonitoringConfigBuilder;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.model.HTTPMonitoringConfig;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.TimeUnit;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.HttpHeaders;\n\n/**\n * Monitor HTTP Requests for methods with {@link HTTPMonitored} annotations.\n */\npublic class HTTPMonitoringInterceptor implements Interceptor {\n\n    private static final Logger logger = LoggerFactory.getLogger(HTTPMonitoringInterceptor.class);\n\n    public static final String REFERER = \"Referer\";\n\n    private Map<Method, MethodInterceptor> map = new ConcurrentHashMap<>();\n\n    private final boolean enabled;\n\n    private final HTTPMonitoringDataPublisher httpMonitoringDataPublisher;\n\n    public HTTPMonitoringInterceptor() {\n        if (logger.isDebugEnabled()) {\n            logger.debug(\"Creating HTTP Monitoring Interceptor\");\n        }\n        HTTPMonitoringConfig httpMonitoringConfig = HTTPMonitoringConfigBuilder.build();\n        enabled = httpMonitoringConfig.isEnabled();\n        httpMonitoringDataPublisher = enabled ? new HTTPMonitoringDataPublisher(httpMonitoringConfig.getDas()) :\n                null;\n    }\n\n    /**\n     * Returns the final annotation that is application to the given method. For example,\n     * the {@link HTTPMonitored} annotation can be mentioned in class level, and also in\n     * the target method, but the method only have tracing enabled. Then we should get the\n     * setting as tracing is disabled for that specific method.\n     */\n    private HTTPMonitored extractFinalAnnotation(Method method) {\n        HTTPMonitored httpMon = method.getAnnotation(HTTPMonitored.class);\n        if (httpMon == null) {\n            httpMon = method.getDeclaringClass().getAnnotation(HTTPMonitored.class);\n        }\n        return httpMon;\n    }\n\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        if (!enabled) {\n            return true;\n        }\n        Method method = serviceMethodInfo.getMethod();\n        MethodInterceptor methodInterceptor = map.get(method);\n        if (methodInterceptor == null || !methodInterceptor.annotationScanned) {\n            HTTPMonitored httpMon = extractFinalAnnotation(method);\n            Interceptor interceptor = null;\n            if (httpMon != null) {\n                interceptor = new HTTPInterceptor(httpMon.tracing());\n            }\n\n            methodInterceptor = new MethodInterceptor(true, interceptor);\n            map.put(method, methodInterceptor);\n        }\n\n        return methodInterceptor.preCall(request, responder, serviceMethodInfo);\n    }\n\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        if (!enabled) {\n            return;\n        }\n        Method method = serviceMethodInfo.getMethod();\n        MethodInterceptor methodInterceptor = map.get(method);\n        if (methodInterceptor != null) {\n            methodInterceptor.postCall(request, status, serviceMethodInfo);\n        }\n    }\n\n    private static class MethodInterceptor implements Interceptor {\n\n        private final boolean annotationScanned;\n\n        private final Interceptor interceptor;\n\n        MethodInterceptor(boolean annotationScanned, Interceptor interceptor) {\n            this.annotationScanned = annotationScanned;\n            this.interceptor = interceptor;\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo)\n                throws Exception {\n            if (interceptor != null) {\n                return interceptor.preCall(request, responder, serviceMethodInfo);\n            }\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n            if (interceptor != null) {\n                interceptor.postCall(request, status, serviceMethodInfo);\n            }\n        }\n    }\n\n    private class HTTPInterceptor implements Interceptor {\n\n        private static final String DEFAULT_TRACE_ID = \"DEFAULT\";\n\n        private static final String DEFAULT_PARENT_REQUEST = \"DEFAULT\";\n\n        private static final String MONITORING_EVENT = \"MONITORING_EVENT\";\n\n        private static final String ACTIVITY_ID = \"activity-id\";\n\n        private static final String PARENT_REQUEST = \"parent-request\";\n\n        private String serviceClass;\n        private String serviceName;\n        private String serviceMethod;\n        private String servicePath;\n\n        private boolean tracing;\n\n        private HTTPInterceptor(boolean tracing) {\n            this.tracing = tracing;\n        }\n\n        boolean isTracing() {\n            return tracing;\n        }\n\n        private String generateTraceId() {\n            return UUID.randomUUID().toString();\n        }\n\n        private void handleTracing(Request request, HTTPMonitoringEvent httpMonitoringEvent) {\n            String traceId, parentRequest;\n            if (this.isTracing()) {\n                traceId = request.getHeader(ACTIVITY_ID);\n                if (traceId == null) {\n                    traceId = this.generateTraceId();\n                }\n                parentRequest = request.getHeader(PARENT_REQUEST);\n            } else {\n                traceId = DEFAULT_TRACE_ID;\n                parentRequest = DEFAULT_PARENT_REQUEST;\n            }\n            httpMonitoringEvent.setActivityId(traceId);\n            httpMonitoringEvent.setParentRequest(parentRequest);\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) {\n            HTTPMonitoringEvent httpMonitoringEvent = new HTTPMonitoringEvent();\n            httpMonitoringEvent.setTimestamp(System.currentTimeMillis());\n            httpMonitoringEvent.setStartNanoTime(System.nanoTime());\n            if (serviceClass == null) {\n                Method method = serviceMethodInfo.getMethod();\n                Class<?> serviceClass = method.getDeclaringClass();\n                this.serviceClass = serviceClass.getName();\n                serviceName = serviceClass.getSimpleName();\n                serviceMethod = method.getName();\n                if (serviceClass.isAnnotationPresent(Path.class)) {\n                    Path path = serviceClass.getAnnotation(Path.class);\n                    servicePath = path.value();\n                }\n            }\n            httpMonitoringEvent.setServiceClass(serviceClass);\n            httpMonitoringEvent.setServiceName(serviceName);\n            httpMonitoringEvent.setServiceMethod(serviceMethod);\n            httpMonitoringEvent.setRequestUri(request.getUri());\n            httpMonitoringEvent.setServiceContext(servicePath);\n\n            HttpHeaders httpHeaders = request.getHeaders();\n\n            httpMonitoringEvent.setHttpMethod(request.getHttpMethod());\n            httpMonitoringEvent.setContentType(httpHeaders.getHeaderString(HttpHeaders.CONTENT_TYPE));\n            String contentLength = httpHeaders.getHeaderString(HttpHeaders.CONTENT_LENGTH);\n            if (contentLength != null) {\n                httpMonitoringEvent.setRequestSizeBytes(Long.parseLong(contentLength));\n            }\n            httpMonitoringEvent.setReferrer(httpHeaders.getHeaderString(REFERER));\n\n            this.handleTracing(request, httpMonitoringEvent);\n\n            serviceMethodInfo.setAttribute(MONITORING_EVENT, httpMonitoringEvent);\n\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) {\n            HTTPMonitoringEvent httpMonitoringEvent =\n                    (HTTPMonitoringEvent) serviceMethodInfo.getAttribute(MONITORING_EVENT);\n            httpMonitoringEvent.setResponseTime(\n                    TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - httpMonitoringEvent.getStartNanoTime()));\n            httpMonitoringEvent.setResponseHttpStatusCode(status);\n            httpMonitoringDataPublisher.publishEvent(httpMonitoringEvent);\n        }\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/config/HTTPMonitoringConfigBuilder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring.config;\n\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.msf4j.analytics.AnalyticUtils;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.model.HTTPMonitoringConfig;\n\n\n/**\n * Build {@link HTTPMonitoringConfig} from the YAML file\n */\npublic final class HTTPMonitoringConfigBuilder {\n\n    public static HTTPMonitoringConfig build() {\n        HTTPMonitoringConfig configurationObject;\n        ConfigProvider configProvider = AnalyticUtils.getConfigurationProvider();\n\n        try {\n            configurationObject =\n                    configProvider.getConfigurationObject(HTTPMonitoringConfig.class);\n        } catch (ConfigurationException e) {\n            throw new RuntimeException(\n                    \"Error while loading \" + HTTPMonitoringConfig.class.getName() + \" from config provider\", e);\n        }\n\n        return configurationObject;\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/config/model/DasConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring.config.model;\n\nimport org.wso2.carbon.config.annotation.Configuration;\nimport org.wso2.carbon.config.annotation.Element;\nimport org.wso2.carbon.config.annotation.Ignore;\n\n/**\n * Configuration for connecting with Data Analytics Server (DAS)\n */\n@Configuration(description = \"DAS configuration\")\npublic class DasConfig {\n\n    @Element(description = \"The type used with Data Publisher\")\n    private String type = \"thrift\";\n\n    @Element(description = \"Data Receiver URL used by the Data Publisher\")\n    private String receiverURL = \"tcp://localhost:7611\";\n\n    @Ignore\n    private String authURL;\n\n    private String username = \"admin\";\n\n    private String password = \"admin\";\n\n    @Element(description = \"The path for Data Bridge Agent configuration\")\n    private String dataAgentConfigPath = \"data-agent-config.xml\";\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getReceiverURL() {\n        return receiverURL;\n    }\n\n    public void setReceiverURL(String receiverURL) {\n        this.receiverURL = receiverURL;\n    }\n\n    public String getAuthURL() {\n        return authURL;\n    }\n\n    public void setAuthURL(String authURL) {\n        this.authURL = authURL;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getPassword() {\n        return password;\n    }\n\n    public void setPassword(String password) {\n        this.password = password;\n    }\n\n    public String getDataAgentConfigPath() {\n        return dataAgentConfigPath;\n    }\n\n    public void setDataAgentConfigPath(String dataAgentConfigPath) {\n        this.dataAgentConfigPath = dataAgentConfigPath;\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/httpmonitoring/config/model/HTTPMonitoringConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.httpmonitoring.config.model;\n\nimport org.wso2.carbon.config.annotation.Configuration;\nimport org.wso2.carbon.config.annotation.Element;\n\n/**\n * Configuration for HTTP Monitoring\n */\n@Configuration(namespace = \"wso2.msf4j.analytics.configuration\", description = \"MSF4J Analytics configuration\")\npublic class HTTPMonitoringConfig {\n\n    @Element(description = \"Whether HTTP Monitoring is enables or not\")\n    private boolean enabled = false;\n\n    @Element(description = \"Configuration for DAS\")\n    private DasConfig das = new DasConfig();\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public DasConfig getDas() {\n        return das;\n    }\n\n    public void setDas(DasConfig das) {\n        this.das = das;\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/internal/AnalyticsSC.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.analytics.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Deactivate;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\n\n/**\n *\n * Bundle Activator for msf4j-analytics bundle.\n */\n@Component(\n        name = \"org.wso2.msf4j.analytics.httpmonitoringsc\",\n        immediate = true,\n        property = {\n                \"componentName=msf4j-analytics-sc\"\n        }\n)\npublic class AnalyticsSC {\n\n    @Reference(\n            name = \"carbon-config\",\n            service = ConfigProvider.class,\n            cardinality = ReferenceCardinality.MANDATORY,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"unregisterConfigProvider\"\n    )\n    protected void registerConfigProvider(ConfigProvider configProvider) {\n        DataHolder.getInstance().setConfigProvider(configProvider);\n    }\n\n    protected void unregisterConfigProvider(ConfigProvider configProvider) {\n        DataHolder.getInstance().setConfigProvider(null);\n    }\n\n    @Activate\n    protected void activate(BundleContext bundleContext) {\n        DataHolder.getInstance().setBundleContext(bundleContext);\n        bundleContext.registerService(Interceptor.class, new HTTPMonitoringInterceptor(), null);\n    }\n\n    @Deactivate\n    public void stop(BundleContext bundleContext) throws Exception {\n        DataHolder.getInstance().setBundleContext(null);\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/internal/DataHolder.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.analytics.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.wso2.carbon.config.provider.ConfigProvider;\n\n/**\n * Data holder for analytics bundle.\n */\npublic class DataHolder {\n    private static final DataHolder instance = new DataHolder();\n    private ConfigProvider configProvider;\n\n    public ConfigProvider getConfigProvider() {\n        return configProvider;\n    }\n\n    public void setConfigProvider(ConfigProvider configProvider) {\n        this.configProvider = configProvider;\n    }\n\n    public BundleContext getBundleContext() {\n        return bundleContext;\n    }\n\n    public void setBundleContext(BundleContext bundleContext) {\n        this.bundleContext = bundleContext;\n    }\n\n    private BundleContext bundleContext;\n\n    public static DataHolder getInstance() {\n        return instance;\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/internal/InterceptorCapabilityProvider.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\npackage org.wso2.msf4j.analytics.internal;\n\nimport org.osgi.service.component.annotations.Component;\nimport org.wso2.carbon.kernel.startupresolver.CapabilityProvider;\n\n/**\n * This class signals Startup Order Resolver module in kernel that this bundle provides\n * two services of type {@code Interceptor}\n */\n@Component(\n        name = \"org.wso2.msf4j.analytics.internal.InterceptorCapabilityProvider\",\n        immediate = true,\n        property = \"capabilityName=org.wso2.msf4j.Interceptor\"\n)\npublic class InterceptorCapabilityProvider implements CapabilityProvider {\n\n    /**\n     * Returns the count of {@code Interceptor} OSGi services registered by this bundle.\n     * <p>\n     * This bundle registers two Interceptors\n     * 1. {@code HTTPMonitoringInterceptor}\n     * 2. {@code MetricsInterceptor}\n     *\n     * But here we return count as one, due to a bug in the startup launcher in Kernel.\n     *\n     * @return count of {@code Interceptor} services registered by this bundle.\n     */\n    @Override\n    public int getCount() {\n        return 2;\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/metrics/Metrics.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.metrics;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.MetricManagementService;\nimport org.wso2.carbon.metrics.core.MetricService;\nimport org.wso2.msf4j.analytics.AnalyticUtils;\n\n/**\n * A utility class to keep Metric Services.\n */\npublic final class Metrics {\n\n    private static final Logger logger = LoggerFactory.getLogger(Metrics.class);\n\n    private volatile MetricService metricService;\n\n    private volatile MetricManagementService metricManagementService;\n\n    private Metrics() {\n    }\n\n    /**\n     * Initializes the Metrics instance\n     */\n    private static class MetricsHolder {\n        private static final Metrics INSTANCE = new Metrics();\n    }\n\n    /**\n     * This returns the Metrics singleton instance.\n     *\n     * @return The Metrics instance\n     */\n    public static Metrics getInstance() {\n        return MetricsHolder.INSTANCE;\n    }\n\n    /**\n     * Initialize metric services\n     */\n    private void initializeServices() {\n        if (logger.isInfoEnabled()) {\n            logger.info(\"Initializing Metrics Services\");\n        }\n        org.wso2.carbon.metrics.core.Metrics metrics =\n                new org.wso2.carbon.metrics.core.Metrics(AnalyticUtils.getConfigurationProvider());\n        // Activate metrics\n        metrics.activate();\n\n        metricService = metrics.getMetricService();\n        metricManagementService = metrics.getMetricManagementService();\n\n        // Deactivate Metrics at shutdown\n        Thread thread = new Thread(() -> metrics.deactivate());\n        Runtime.getRuntime().addShutdownHook(thread);\n    }\n\n    /**\n     * Returns the {@link MetricService}\n     *\n     * @return The {@link MetricService} instance\n     */\n    public MetricService getMetricService() {\n        if (metricService == null) {\n            synchronized (this) {\n                if (metricService == null) {\n                    initializeServices();\n                }\n            }\n        }\n        return metricService;\n    }\n\n    /**\n     * Set the {@link MetricService} service\n     *\n     * @param metricService The {@link MetricService} reference\n     */\n    void setMetricService(MetricService metricService) {\n        this.metricService = metricService;\n    }\n\n    /**\n     * Returns the {@link MetricManagementService}\n     *\n     * @return The {@link MetricManagementService} instance\n     */\n    public MetricManagementService getMetricManagementService() {\n        if (metricManagementService == null) {\n            synchronized (this) {\n                if (metricManagementService == null) {\n                    initializeServices();\n                }\n            }\n        }\n        return metricManagementService;\n    }\n\n    /**\n     * Set the {@link MetricManagementService} service\n     *\n     * @param metricManagementService The {@link MetricManagementService} reference\n     */\n    void setMetricManagementService(MetricManagementService metricManagementService) {\n        this.metricManagementService = metricManagementService;\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/metrics/MetricsComponent.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.metrics;\n\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Deactivate;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.MetricManagementService;\nimport org.wso2.carbon.metrics.core.MetricService;\n\n/**\n * Metrics OSGi Component to Initialize/Destroy Metrics.\n */\n@Component(name = \"org.wso2.msf4j.analytics.metrics.MetricsComponent\")\npublic class MetricsComponent {\n\n    private static final Logger logger = LoggerFactory.getLogger(MetricsComponent.class);\n\n    /**\n     * This is the activation method of MetricsComponent. This will be called when its references are\n     * satisfied.\n     */\n    @Activate\n    protected void activate() {\n        if (logger.isInfoEnabled()) {\n            logger.info(\"Metrics Component is activated\");\n        }\n    }\n\n    /**\n     * This is the deactivation method of MetricsComponent.\n     */\n    @Deactivate\n    protected void deactivate() {\n        if (logger.isInfoEnabled()) {\n            logger.info(\"Metrics Component is deactivated\");\n        }\n    }\n\n    /**\n     * This bind method will be called when {@link MetricService} is registered.\n     *\n     * @param metricService The {@link MetricService} instance registered as an OSGi service\n     */\n    @Reference(\n            name = \"carbon.metrics.service\",\n            service = MetricService.class,\n            cardinality = ReferenceCardinality.MANDATORY,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"unsetMetricService\"\n    )\n    protected void setMetricService(MetricService metricService) {\n        if (logger.isDebugEnabled()) {\n            logger.debug(\"Setting MetricService reference\");\n        }\n        Metrics.getInstance().setMetricService(metricService);\n    }\n\n    /**\n     * This is the unbind method which gets called at the un-registration of {@link MetricService}\n     *\n     * @param metricService The {@link MetricService} instance registered as an OSGi service\n     */\n    protected void unsetMetricService(MetricService metricService) {\n        Metrics.getInstance().setMetricService(null);\n    }\n\n    /**\n     * This bind method will be called when {@link MetricManagementService} is registered.\n     *\n     * @param metricManagementService The {@link MetricManagementService} instance registered as an OSGi service\n     */\n    @Reference(\n            name = \"carbon.metrics.management.service\",\n            service = MetricManagementService.class,\n            cardinality = ReferenceCardinality.MANDATORY,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"unsetMetricManagementService\"\n    )\n    protected void setMetricManagementService(MetricManagementService metricManagementService) {\n        if (logger.isDebugEnabled()) {\n            logger.debug(\"Setting MetricManagementService reference\");\n        }\n        Metrics.getInstance().setMetricManagementService(metricManagementService);\n    }\n\n    /**\n     * This is the unbind method which gets called at the un-registration of {@link MetricManagementService}\n     *\n     * @param metricManagementService The {@link MetricManagementService} instance registered as an OSGi service\n     */\n    protected void unsetMetricManagementService(MetricManagementService metricManagementService) {\n        Metrics.getInstance().setMetricManagementService(null);\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/metrics/MetricsInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.analytics.metrics;\n\nimport org.osgi.service.component.annotations.Component;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.Counter;\nimport org.wso2.carbon.metrics.core.Meter;\nimport org.wso2.carbon.metrics.core.MetricAnnotation;\nimport org.wso2.carbon.metrics.core.Timer;\nimport org.wso2.carbon.metrics.core.annotation.Counted;\nimport org.wso2.carbon.metrics.core.annotation.Metered;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\n/**\n * Collecting Metrics via annotations.\n */\n@Component(\n        name = \"org.wso2.msf4j.analytics.metrics.MetricsInterceptor\",\n        service = Interceptor.class\n)\npublic class MetricsInterceptor implements Interceptor {\n\n    private static final Logger logger = LoggerFactory.getLogger(MetricsInterceptor.class);\n\n    private Map<Method, MethodInterceptors> map = new ConcurrentHashMap<>();\n\n    public MetricsInterceptor() {\n        if (logger.isDebugEnabled()) {\n            logger.debug(\"Creating Metrics Interceptor\");\n        }\n    }\n\n    private Timed getTimedAnnotation(Method method) {\n        Timed annotation = method.getAnnotation(Timed.class);\n        if (annotation == null) {\n            annotation = method.getDeclaringClass().getAnnotation(Timed.class);\n        }\n        return annotation;\n    }\n\n    private Metered getMeteredAnnotation(Method method) {\n        Metered annotation = method.getAnnotation(Metered.class);\n        if (annotation == null) {\n            annotation = method.getDeclaringClass().getAnnotation(Metered.class);\n        }\n        return annotation;\n    }\n\n    private Counted getCountedAnnotation(Method method) {\n        Counted annotation = method.getAnnotation(Counted.class);\n        if (annotation == null) {\n            annotation = method.getDeclaringClass().getAnnotation(Counted.class);\n        }\n        return annotation;\n    }\n\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        Method method = serviceMethodInfo.getMethod();\n        MethodInterceptors methodInterceptors = map.get(method);\n        if (methodInterceptors == null || !methodInterceptors.annotationScanned) {\n            List<Interceptor> interceptors = new CopyOnWriteArrayList<>();\n            Timed timed = getTimedAnnotation(method);\n            if (timed != null) {\n                Timer timer = MetricAnnotation.timer(Metrics.getInstance().getMetricService(), timed, method);\n                Interceptor interceptor = new TimerInterceptor(timer);\n                interceptors.add(interceptor);\n            }\n            Metered metered = getMeteredAnnotation(method);\n            if (metered != null) {\n                Meter meter = MetricAnnotation.meter(Metrics.getInstance().getMetricService(), metered, method);\n                Interceptor interceptor = new MeterInterceptor(meter);\n                interceptors.add(interceptor);\n            }\n            Counted counted = getCountedAnnotation(method);\n            if (counted != null) {\n                Counter counter = MetricAnnotation.counter(Metrics.getInstance().getMetricService(), counted, method);\n                Interceptor interceptor = new CounterInterceptor(counter, counted.monotonic());\n                interceptors.add(interceptor);\n            }\n\n            methodInterceptors = new MethodInterceptors(true, interceptors);\n            map.put(method, methodInterceptors);\n        }\n\n        return methodInterceptors.preCall(request, responder, serviceMethodInfo);\n    }\n\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        Method method = serviceMethodInfo.getMethod();\n        MethodInterceptors methodInterceptors = map.get(method);\n        if (methodInterceptors != null) {\n            methodInterceptors.postCall(request, status, serviceMethodInfo);\n        }\n    }\n\n    private static class MethodInterceptors implements Interceptor {\n\n        private final boolean annotationScanned;\n\n        private Interceptor[] interceptors;\n\n        MethodInterceptors(boolean annotationScanned, List<Interceptor> interceptors) {\n            this.annotationScanned = annotationScanned;\n            if (!interceptors.isEmpty()) {\n                this.interceptors = interceptors.toArray(new Interceptor[interceptors.size()]);\n            }\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo)\n                throws Exception {\n            if (interceptors != null) {\n                for (Interceptor interceptor : interceptors) {\n                    interceptor.preCall(request, responder, serviceMethodInfo);\n                }\n            }\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n            if (interceptors != null) {\n                for (Interceptor interceptor : interceptors) {\n                    interceptor.postCall(request, status, serviceMethodInfo);\n                }\n            }\n        }\n    }\n\n    private static class TimerInterceptor implements Interceptor {\n\n        private final Timer timer;\n\n        private static final String TIMER_CONTEXT = \"TIMER_CONTEXT\";\n\n        private TimerInterceptor(Timer timer) {\n            this.timer = timer;\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) {\n            Timer.Context context = timer.start();\n            serviceMethodInfo.setAttribute(TIMER_CONTEXT, context);\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) {\n            Timer.Context context = (Timer.Context) serviceMethodInfo.getAttribute(TIMER_CONTEXT);\n            context.stop();\n        }\n    }\n\n    private static class MeterInterceptor implements Interceptor {\n\n        private final Meter meter;\n\n        private MeterInterceptor(Meter meter) {\n            this.meter = meter;\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) {\n            meter.mark();\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) {\n        }\n    }\n\n    private static class CounterInterceptor implements Interceptor {\n\n        private final Counter counter;\n        private final boolean monotonic;\n\n        private CounterInterceptor(Counter counter, boolean monotonic) {\n            this.counter = counter;\n            this.monotonic = monotonic;\n        }\n\n        @Override\n        public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) {\n            counter.inc();\n            return true;\n        }\n\n        @Override\n        public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) {\n            if (!monotonic) {\n                counter.dec();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/java/org/wso2/msf4j/analytics/tracing/MSF4JTracingInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.tracing;\n\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\nimport org.wso2.msf4j.analytics.common.tracing.TraceEvent;\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\nimport org.wso2.msf4j.analytics.common.tracing.TracingEventTracker;\nimport org.wso2.msf4j.analytics.common.tracing.TracingUtil;\n\nimport java.util.Date;\n\n/**\n * Interceptor for tracing server side request/response flows.\n */\n// TODO: Write tests and add the OSGi mode support\npublic class MSF4JTracingInterceptor implements Interceptor {\n\n    private static final String RESPONDER_ATTRIBUTE = \"responder-attribute\";\n    private static final String TRACE_EVENT_ATTRIBUTE = \"trace-event-attribute\";\n    private String instanceId;\n    private String instanceName;\n    private String dasUrl;\n\n    /**\n     * Constructor of the MSF4JTracingInterceptor.\n     *\n     * @param microServiceName Name of the Microservice\n     */\n    public MSF4JTracingInterceptor(String microServiceName) {\n        this(microServiceName, TracingConstants.DAS_RECEIVER_URL);\n    }\n\n    /**\n     * Constructor of the MSF4JTracingInterceptor.\n     *\n     * @param microServiceName Name of the Microservice\n     * @param dasUrl           URL of the receiver of DAS server\n     */\n    public MSF4JTracingInterceptor(String microServiceName, String dasUrl) {\n        this.instanceId = TracingUtil.generateUniqueId();\n        this.instanceName = microServiceName;\n        this.dasUrl = dasUrl;\n    }\n\n    /**\n     * Intercepts the server request flow and extract request information\n     * to be published to the DAS for tracing.\n     */\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        long time = new Date().getTime();\n        serviceMethodInfo.setAttribute(RESPONDER_ATTRIBUTE, responder);\n        String traceOriginId = request.getHeader(TracingConstants.TRACE_ORIGIN_ID_HEADER);\n        String serverTraceId;\n        if (traceOriginId == null) {\n            traceOriginId = TracingUtil.generateUniqueId();\n            serverTraceId = traceOriginId;\n        } else {\n            serverTraceId = TracingUtil.generateUniqueId();\n        }\n        String traceParentId = request.getHeader(TracingConstants.TRACE_ID_HEADER);\n        TraceEvent serverTraceEvent = new TraceEvent(\n                TracingConstants.SERVER_TRACE_START,\n                serverTraceId,\n                traceOriginId,\n                time\n        );\n        serverTraceEvent.setInstanceId(instanceId);\n        serverTraceEvent.setInstanceName(instanceName);\n        serverTraceEvent.setParentId(traceParentId);\n        serverTraceEvent.setHttpMethod(request.getHttpMethod());\n        serverTraceEvent.setUrl(request.getUri());\n        TracingEventTracker.setTraceEvent(serverTraceEvent);\n        serviceMethodInfo.setAttribute(TRACE_EVENT_ATTRIBUTE, serverTraceEvent);\n        TracingUtil.pushToDAS(serverTraceEvent, dasUrl);\n        return true;\n    }\n\n    /**\n     * Intercepts the server response flow and extract response information\n     * to be published to the DAS for tracing.\n     */\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        long time = new Date().getTime();\n        TraceEvent traceEvent = (TraceEvent) serviceMethodInfo.getAttribute(TRACE_EVENT_ATTRIBUTE);\n        if (traceEvent != null) {\n            TraceEvent endTraceEvent = new TraceEvent(\n                    TracingConstants.SERVER_TRACE_END,\n                    traceEvent.getTraceId(),\n                    traceEvent.getOriginId(),\n                    time\n            );\n            Response responder = (Response) serviceMethodInfo.getAttribute(RESPONDER_ATTRIBUTE);\n            endTraceEvent.setStatusCode(responder.getStatusCode());\n            TracingUtil.pushToDAS(endTraceEvent, dasUrl);\n        }\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/main/resources/http-monitoring.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\n# Enable HTTP Monitoring\nenabled: true\n\n# Data Analytics Server (DAS) configuration\ndas:\n  # Data Receiver URL used by the Data Publisher\n  receiverURL: tcp://localhost:7611\n\n  # Authentication URL for the Data Publisher\n  # authURL: ssl://localhost:7711\n\n  # The type used with Data Publisher\n  type: thrift\n\n  username: admin\n\n  password: admin\n\n  # The path for Data Bridge Agent configuration\n  dataAgentConfigPath: data-agent-config.xml\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/test/java/org/wso2/msf4j/analytics/HTTPMonitoringConfigTest.java",
    "content": "/*\n * Copyright 2016 WSO2 Inc. (http://wso2.org)\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 */\npackage org.wso2.msf4j.analytics;\n\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.HTTPMonitoringConfigBuilder;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.model.DasConfig;\nimport org.wso2.msf4j.analytics.httpmonitoring.config.model.HTTPMonitoringConfig;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\n\n/**\n * Test Cases for {@link HTTPMonitoringConfig}\n */\npublic class HTTPMonitoringConfigTest {\n\n    private static final String DEFAULT_CONFIG_PATH = \"deployment.yaml\";\n    private static HTTPMonitoringConfig httpMonitoringConfig;\n\n    @BeforeClass\n    private void load() {\n        httpMonitoringConfig = HTTPMonitoringConfigBuilder.build();\n    }\n\n    @AfterClass\n    private void clear() throws IOException {\n        Path configPath = Paths.get(DEFAULT_CONFIG_PATH);\n        if (Files.exists(configPath)) {\n            Files.delete(configPath);\n        }\n    }\n\n    @Test\n    public void testEnabled() {\n        Assert.assertFalse(httpMonitoringConfig.isEnabled());\n    }\n\n    @Test\n    public void testDasConfigLoad() {\n        DasConfig config = httpMonitoringConfig.getDas();\n        Assert.assertEquals(config.getReceiverURL(), \"tcp://localhost:7611\");\n        Assert.assertNull(config.getAuthURL());\n        Assert.assertEquals(config.getType(), \"thrift\");\n        Assert.assertEquals(config.getUsername(), \"admin\");\n        Assert.assertEquals(config.getPassword(), \"admin\");\n        Assert.assertEquals(config.getDataAgentConfigPath(), \"data-agent-config.xml\");\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics/src/test/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n  # MSF4J Analytics configuration\nwso2.msf4j.analytics.configuration:\n    # Whether HTTP Monitoring is enables or not\n  enabled: false\n    # DAS configuration\n  das:\n      # The type used with Data Publisher\n    type: thrift\n      # Data Receiver URL used by the Data Publisher\n    receiverURL: tcp://localhost:7611\n    username: admin\n    password: admin\n      # The path for Data Bridge Agent configuration\n    dataAgentConfigPath: data-agent-config.xml"
  },
  {
    "path": "analytics/msf4j-analytics-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-analytics-common</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J Analytics Common</name>\n    <description>WSO2 MSF4J Analytics Common</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <export.package>\n            org.wso2.msf4j.analytics.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.osgi.util.tracker; version=\"${osgi.service.tracker.import.version.range}\",\n            javax.ws.rs.*,\n        </import.package>\n        <carbon.component>\n            osgi.service;objectClass=\"org.wso2.carbon.kernel.startupresolver.CapabilityProvider\";capabilityName=\"org.wso2.msf4j.Interceptor\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "analytics/msf4j-analytics-common/src/main/java/org/wso2/msf4j/analytics/common/tracing/MSF4JClientTracingFilter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.common.tracing;\n\nimport java.io.IOException;\nimport java.util.Date;\nimport javax.ws.rs.client.ClientRequestContext;\nimport javax.ws.rs.client.ClientRequestFilter;\nimport javax.ws.rs.client.ClientResponseContext;\nimport javax.ws.rs.client.ClientResponseFilter;\n\n/**\n * Filter for tracing client side request/response flow.\n */\n// TODO: Write tests and add the OSGi mode support\npublic class MSF4JClientTracingFilter implements ClientRequestFilter, ClientResponseFilter {\n\n    private static final String TRACE_EVENT_ATTRIBUTE = \"trace-event-attribute\";\n    private TraceEvent parentEvent;\n    private String instanceId;\n    private String instanceName;\n    private String dasUrl;\n\n    /**\n     * Constructor of the MSF4JClientTracingFilter.\n     *\n     * @param clientName Name of the client\n     */\n    public MSF4JClientTracingFilter(String clientName) {\n        this(clientName, TracingConstants.DAS_RECEIVER_URL);\n    }\n\n    /**\n     * Constructor of the MSF4JClientTracingFilter.\n     *\n     * @param clientName Name of the client\n     * @param dasUrl     URL of the receiver of DAS server\n     */\n    public MSF4JClientTracingFilter(String clientName, String dasUrl) {\n        this(clientName, null, dasUrl);\n    }\n\n    /**\n     * Constructor of the MSF4JClientTracingFilter.\n     *\n     * @param clientName  Name of the client\n     * @param parentEvent TraceEvent of the caller\n     * @param dasUrl      URL of the receiver of DAS server\n     */\n    public MSF4JClientTracingFilter(String clientName, TraceEvent parentEvent, String dasUrl) {\n        this.instanceName = clientName;\n        this.instanceId = TracingUtil.generateUniqueId();\n        this.dasUrl = dasUrl;\n        if (parentEvent != null) {\n            this.parentEvent = parentEvent;\n        } else {\n            this.parentEvent = TracingEventTracker.getTraceEvent();\n        }\n    }\n\n    /**\n     * Intercepts the client request flow and extract request information\n     * to be published to the DAS for tracing.\n     */\n    @Override\n    public void filter(ClientRequestContext requestContext) throws IOException {\n        long time = new Date().getTime();\n        String clientTraceId;\n        String traceOriginId;\n        String traceParentId = null;\n        if (this.parentEvent == null) {\n            traceOriginId = TracingUtil.generateUniqueId();\n            clientTraceId = traceOriginId;\n        } else {\n            traceOriginId = parentEvent.getOriginId();\n            clientTraceId = TracingUtil.generateUniqueId();\n            traceParentId = parentEvent.getTraceId();\n        }\n        TraceEvent clientTraceEvent = new TraceEvent(\n                TracingConstants.CLIENT_TRACE_START,\n                clientTraceId,\n                traceOriginId,\n                time\n        );\n        clientTraceEvent.setInstanceId(instanceId);\n        clientTraceEvent.setInstanceName(instanceName);\n        clientTraceEvent.setParentId(traceParentId);\n        clientTraceEvent.setHttpMethod(requestContext.getMethod());\n        clientTraceEvent.setUrl(requestContext.getUri().toString());\n        requestContext.setProperty(TRACE_EVENT_ATTRIBUTE, clientTraceEvent);\n        requestContext.getHeaders().putSingle(TracingConstants.TRACE_ID_HEADER, clientTraceId);\n        requestContext.getHeaders().putSingle(TracingConstants.TRACE_ORIGIN_ID_HEADER, traceOriginId);\n        TracingUtil.pushToDAS(clientTraceEvent, dasUrl);\n    }\n\n    /**\n     * Intercepts the client response flow and extract response information\n     * to be published to the DAS server for tracing.\n     */\n    @Override\n    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {\n        long time = new Date().getTime();\n        TraceEvent traceEvent = (TraceEvent) requestContext.getProperty(TRACE_EVENT_ATTRIBUTE);\n        if (traceEvent != null) {\n            TraceEvent endTraceEvent = new TraceEvent(\n                    TracingConstants.CLIENT_TRACE_END,\n                    traceEvent.getTraceId(),\n                    traceEvent.getOriginId(),\n                    time\n            );\n            endTraceEvent.setStatusCode(responseContext.getStatus());\n            TracingUtil.pushToDAS(endTraceEvent, dasUrl);\n        }\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics-common/src/main/java/org/wso2/msf4j/analytics/common/tracing/TraceEvent.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.common.tracing;\n\n/**\n * Class to hold tracing start event data.\n */\npublic class TraceEvent {\n\n    private final String type;\n    private final String traceId;\n    private final String originId;\n    private final long time;\n    private int statusCode;\n    private String httpMethod;\n    private String instanceId;\n    private String instanceName;\n    private String parentId;\n    private String url;\n\n    public TraceEvent(String type, String traceId, String originId, long time) {\n        this.type = type;\n        this.traceId = traceId;\n        this.originId = originId;\n        this.time = time;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public String getTraceId() {\n        return traceId;\n    }\n\n    public String getOriginId() {\n        return originId;\n    }\n\n    public long getTime() {\n        return time;\n    }\n\n    public String getInstanceId() {\n        return instanceId;\n    }\n\n    public void setInstanceId(String instanceId) {\n        this.instanceId = instanceId;\n    }\n\n    public String getInstanceName() {\n        return instanceName;\n    }\n\n    public void setInstanceName(String instanceName) {\n        this.instanceName = instanceName;\n    }\n\n    public String getParentId() {\n        return parentId;\n    }\n\n    public void setParentId(String parentId) {\n        this.parentId = parentId;\n    }\n\n    public int getStatusCode() {\n        return statusCode;\n    }\n\n    public void setStatusCode(int statusCode) {\n        this.statusCode = statusCode;\n    }\n\n    public String getHttpMethod() {\n        return httpMethod;\n    }\n\n    public void setHttpMethod(String httpMethod) {\n        this.httpMethod = httpMethod;\n    }\n\n    public String getUrl() {\n        return url;\n    }\n\n    public void setUrl(String url) {\n        this.url = url;\n    }\n\n    @Override\n    public String toString() {\n        return \"TraceEvent{\" +\n                \"type='\" + type + '\\'' +\n                \", traceId='\" + traceId + '\\'' +\n                \", originId='\" + originId + '\\'' +\n                \", time=\" + time +\n                \", statusCode=\" + statusCode +\n                \", httpMethod='\" + httpMethod + '\\'' +\n                \", instanceId='\" + instanceId + '\\'' +\n                \", instanceName='\" + instanceName + '\\'' +\n                \", parentId='\" + parentId + '\\'' +\n                \", url='\" + url + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics-common/src/main/java/org/wso2/msf4j/analytics/common/tracing/TracingConstants.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.common.tracing;\n\n/**\n * Class to hold constants used in tracing.\n */\npublic class TracingConstants {\n\n    public static final String CLIENT_TRACE_START = \"CTS\";\n    public static final String CLIENT_TRACE_END = \"CTE\";\n    public static final String SERVER_TRACE_START = \"STS\";\n    public static final String SERVER_TRACE_END = \"STE\";\n    public static final String TRACE_ID_HEADER = \"X-msf4j-trace-id\";\n    public static final String TRACE_ORIGIN_ID_HEADER = \"X-msf4j-trace-origin-id\";\n    public static final String DAS_RECEIVER_URL = \"http://localhost:9763/endpoints/msf4jtracereceiver\";\n    public static final String DEFAULT_ZIPKIN_URL = \"http://0.0.0.0:9411\";\n\n    /**\n     * Tracing Types.\n     */\n    public enum TracingType {\n        DAS, ZIPKIN\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics-common/src/main/java/org/wso2/msf4j/analytics/common/tracing/TracingEventTracker.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.common.tracing;\n\n/**\n * Class for holding the thread local of tracing events.\n * This class help the Client interceptors to access the\n * request trace event of the containing service to keep\n * the correlation.\n */\npublic class TracingEventTracker {\n\n    private static final ThreadLocal<TraceEvent> traceEventThreadLocal = new ThreadLocal<>();\n\n    public static void setTraceEvent(TraceEvent traceEvent) {\n        traceEventThreadLocal.set(traceEvent);\n    }\n\n    public static TraceEvent getTraceEvent() {\n        return traceEventThreadLocal.get();\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j-analytics-common/src/main/java/org/wso2/msf4j/analytics/common/tracing/TracingUtil.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.common.tracing;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.Random;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport javax.ws.rs.client.ClientBuilder;\nimport javax.ws.rs.client.Entity;\nimport javax.ws.rs.core.Response;\n\n/**\n * Utility methods of for MSF4J tracing.\n */\npublic class TracingUtil {\n\n    private static final Logger log = LoggerFactory.getLogger(TracingUtil.class);\n    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();\n    private static final Random random = new Random();\n\n    /**\n     * Generate a random string unique identifier.\n     */\n    public static String generateUniqueId() {\n        // UUID.randomUUID().toString() is too slow\n        // TODO: Test whether the ID is unique enough\n        return System.currentTimeMillis() + \"\" + String.format(\"%08d\", random.nextInt(100000000));\n    }\n\n    /**\n     * Publish trace event to DAS in the background.\n     */\n    public static void pushToDAS(TraceEvent traceEvent, String dasUrl) {\n        Future<?> future = executorService.submit(() -> {\n            log.debug(\"Publishing trace event \" + traceEvent);\n            if (ClientBuilder.newClient().target(dasUrl)\n                    .request().post(Entity.json(traceEvent)).getStatus() != Response.Status.OK.getStatusCode()) {\n                log.error(\"Error while publishing trace event \" + traceEvent);\n            }\n        });\n        future.isDone(); // Added to avoid findbugs warning\n    }\n\n}\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project name=\"create-msf4j-http-monitoring-capp\" default=\"zip\" basedir=\".\">\n\n    <property name=\"target_dir\" value=\"target\" />\n    <property name=\"msf4j_http_monitoring_capp_dir\" value=\"msf4j_http_monitoring_capp\" />\n\n    <target name=\"zip\">\n        <zip destfile=\"${target_dir}/${msf4j_http_monitoring_capp_dir}.car\">\n            <zipfileset dir=\"${msf4j_http_monitoring_capp_dir}\" />\n        </zip>\n    </target>\n\n</project>\n\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/artifacts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<artifacts>\n    <artifact name=\"MSF4J_HTTP_Monitoring_CApp\" version=\"1.0.0\" type=\"carbon/application\">\n        <dependency artifact=\"http_event_receiver\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\" />\n        <dependency artifact=\"http_event_store\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\" />\n        <dependency artifact=\"http_event_stream\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\" />\n        <dependency artifact=\"spark_script\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\" />\n    </artifact>\n</artifacts>\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_receiver_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<artifact name=\"http_event_receiver\" version=\"1.0.0\" type=\"event/receiver\" serverRole=\"DataAnalyticsServer\">\n    <file>http_event_receiver.xml</file>\n</artifact>"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_receiver_1.0.0/http_event_receiver.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<eventReceiver name=\"http_event_receiver\" statistics=\"disable\" trace=\"disable\" xmlns=\"http://wso2.org/carbon/eventreceiver\">\n    <from eventAdapterType=\"wso2event\"/>\n    <mapping customMapping=\"disable\" type=\"wso2event\"/>\n    <to streamName=\"org.wso2.msf4j.analytics.httpmonitoring\" version=\"1.0.0\"/>\n</eventReceiver>"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_store_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<artifact name=\"http_event_store\" version=\"1.0.0\" type=\"analytics/eventstore\" serverRole=\"DataAnalyticsServer\">\n    <file>org_wso2_msf4j_analytics_httpmonitoring.xml</file>\n</artifact>"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_store_1.0.0/org_wso2_msf4j_analytics_httpmonitoring.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<EventStoreConfiguration>\n    <TableSchema>\n        <ColumnDefinition>\n            <Name>meta_timestamp</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>LONG</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>meta_server_address</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>meta_server_name</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>meta_application_type</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n\n        <ColumnDefinition>\n            <Name>correlation_activity_id</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>FACET</Type>\n        </ColumnDefinition>\n\n        <ColumnDefinition>\n            <Name>correlation_parent_request</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n\n        <ColumnDefinition>\n            <Name>service_class</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>service_name</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>service_method</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>request_uri</Name>\n            <EnableIndexing>false</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>service_context</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>http_method</Name>\n            <EnableIndexing>false</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>content_type</Name>\n            <EnableIndexing>false</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>request_content_length</Name>\n            <EnableIndexing>false</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>LONG</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>referrer</Name>\n            <EnableIndexing>false</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>STRING</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>http_status_code</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>INTEGER</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>response_time</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>LONG</Type>\n        </ColumnDefinition>\n        <ColumnDefinition>\n            <Name>group_by</Name>\n            <EnableIndexing>true</EnableIndexing>\n            <IsPrimaryKey>false</IsPrimaryKey>\n            <EnableScoreParam>false</EnableScoreParam>\n            <Type>FACET</Type>\n        </ColumnDefinition>\n    </TableSchema>\n    <Source>\n        <StreamId>org.wso2.msf4j.analytics.httpmonitoring:1.0.0</StreamId>\n    </Source>\n    <RecordStoreName>EVENT_STORE</RecordStoreName>\n</EventStoreConfiguration>\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_stream_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<artifact name=\"http_event_stream\" version=\"1.0.0\" type=\"event/stream\" serverRole=\"DataAnalyticsServer\">\n    <file>org.wso2.msf4j.analytics.httpmonitoring_1.0.0.json</file>\n</artifact>"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/http_event_stream_1.0.0/org.wso2.msf4j.analytics.httpmonitoring_1.0.0.json",
    "content": "{\n  \"name\": \"org.wso2.msf4j.analytics.httpmonitoring\",\n  \"version\": \"1.0.0\",\n  \"nickName\": \"msf4j_http_monitoring\",\n  \"description\": \"MSF4J HTTP Monitoring\",\n  \"metaData\": [\n    {\n      \"name\": \"timestamp\",\n      \"type\": \"LONG\"\n    },\n    {\n      \"name\": \"server_address\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"server_name\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"application_type\",\n      \"type\": \"STRING\"\n    }\n  ],\n  \"correlationData\": [\n    {\n      \"name\": \"activity_id\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"parent_request\",\n      \"type\": \"STRING\"\n    }\n  ],\n  \"payloadData\": [\n    {\n      \"name\": \"service_class\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"service_name\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"service_method\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"request_uri\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"service_context\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"http_method\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"content_type\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"request_content_length\",\n      \"type\": \"LONG\"\n    },\n    {\n      \"name\": \"referrer\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"http_status_code\",\n      \"type\": \"INT\"\n    },\n    {\n      \"name\": \"response_time\",\n      \"type\": \"LONG\"\n    }\n  ]\n}\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/spark_script_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<artifact name=\"spark_script\" version=\"1.0.0\" type=\"analytics/spark\" serverRole=\"DataAnalyticsServer\">\n    <file>http_event_script.xml</file>\n</artifact>\n"
  },
  {
    "path": "analytics/msf4j_http_monitoring_capp_source/msf4j_http_monitoring_capp/spark_script_1.0.0/http_event_script.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<Analytics>\n    <Name>http_event_script</Name>\n    <Script>\n\n        create temporary table ServiceRequestData USING CarbonAnalytics OPTIONS(tableName\n        \"ORG_WSO2_MSF4J_ANALYTICS_HTTPMONITORING\");\n\n        CREATE TEMPORARY TABLE MSS_REQUESTS_SUMMARY_PER_MINUTE USING CarbonAnalytics OPTIONS (tableName\n        \"MSS_REQUESTS_SUMMARY_PER_MINUTE\",\n        schema \"service_class string -i,\n        server_address string -i,\n        avg_request_count int,\n        avg_response_time int,\n        session_count int,\n        http_success_count int,\n        http_error_count int,\n        time long -i,\n        all_facet FACET -i,\n        time_facet FACET -i,\n        year_facet FACET -i,\n        month_facet FACET -i,\n        day_facet FACET -i,\n        hour_facet FACET -i,\n        service_class_facet FACET -i\",\n        primaryKeys \"service_class,server_address,time\"\n        );\n\n        insert into table MSS_REQUESTS_SUMMARY_PER_MINUTE select service_class,\n        meta_server_address as server_address,\n        count(request_uri) as avg_request_count,\n        avg(response_time) as avg_response_time,\n        0 as session_count,\n        sum(if(http_status_code&lt;400, 1, 0)) as http_success_count,\n        sum(if(http_status_code&gt;=400, 1, 0)) as http_error_count,\n        cast(first(meta_timestamp)/1000 as timestamp) as time,\n        facet1(1),\n        facet1(substring(cast(first(meta_timestamp)/1000 as timestamp),0,16)),\n        facet1(substring(cast(first(meta_timestamp)/1000 as timestamp),0,4)),\n        facet1(substring(cast(first(meta_timestamp)/1000 as timestamp),0,7)),\n        facet1(substring(cast(first(meta_timestamp)/1000 as timestamp),0,10)),\n        facet1(substring(cast(first(meta_timestamp)/1000 as timestamp),0,13)),\n        facet1(service_class)\n\t from ServiceRequestData group by meta_application_type, meta_server_address,\n        service_class, substring(cast(meta_timestamp/1000 as timestamp),0,16);\n\n        CREATE TEMPORARY TABLE MSS_NODES USING CarbonAnalytics OPTIONS (tableName \"MSS_NODES\",\n        schema \"server_address string -i\",\n        primaryKeys \"server_address\"\n        );\n\n        insert into table MSS_NODES select meta_server_address as server_address\n\t from ServiceRequestData group by meta_server_address;\n\n        CREATE TEMPORARY TABLE MSS_HTTP_STATUS USING CarbonAnalytics OPTIONS (tableName \"MSS_HTTP_STATUS\",\n        schema \"service_class string -i,\n        server_address string -i,\n        avg_request_count int,\n        http_status_code int,\n        time long -i,\n        all_facet FACET -i,\n        http_status_facet FACET -i\",\n        primaryKeys \"service_class,server_address,time\"\n        );\n\n        insert into table MSS_HTTP_STATUS select service_class,\n        meta_server_address as server_address,\n        count(request_uri) as avg_request_count,\n        http_status_code,\n        cast(first(meta_timestamp)/1000 as timestamp) as time,\n        facet1(1),\n        facet1(http_status_code)\n\t from ServiceRequestData group by meta_server_address, service_class, http_status_code,\n        substring(cast(meta_timestamp/1000 as timestamp),0,16);\n\n\n        CREATE TEMPORARY TABLE MSS_SERVICE_CONTEXT USING CarbonAnalytics OPTIONS (tableName \"MSS_SERVICE_CONTEXT\",\n        schema \"service_class string -i,\n        server_address string -i,\n        avg_request_count int,\n        service_context string,\n        time long -i,\n        all_facet FACET -i,\n        context_facet FACET -i\",\n        primaryKeys \"service_class,server_address,time\"\n        );\n\n        insert into table MSS_SERVICE_CONTEXT select service_class,\n        meta_server_address as server_address,\n        count(request_uri) as avg_request_count,\n        service_context,\n        cast(first(meta_timestamp)/1000 as timestamp) as time,\n        facet1(1),\n        facet1(service_context)\n\t from ServiceRequestData group by meta_server_address, service_class, service_context,\n        substring(cast(meta_timestamp/1000 as timestamp),0,16);\n\n\n    </Script>\n    <CronExpression>0 0/15 * 1/1 * ? *</CronExpression>\n</Analytics>\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Dashboard_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifact name=\"Dashboard\" version=\"1.0.0\" type=\"dashboards/dashboard\" serverRole=\"DataAnalyticsServer\">\n    <file>msf4j-message-tracing.json</file>\n</artifact>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Dashboard_1.0.0/msf4j-message-tracing.json",
    "content": "{\n  \"id\": \"msf4j-message-tracing\",\n  \"title\": \"MSF4J Message Tracing\",\n  \"description\": \"\",\n  \"permissions\": {\n    \"viewers\": [\n      \"Internal/everyone\"\n    ],\n    \"editors\": [\n      \"Internal/everyone\"\n    ]\n  },\n  \"pages\": [\n    {\n      \"id\": \"landing\",\n      \"title\": \"Welcome\",\n      \"layout\": {\n        \"content\": {\n          \"loggedIn\": {\n            \"blocks\": [\n              {\n                \"id\": \"a\",\n                \"col\": 1,\n                \"row\": 1,\n                \"size_x\": 12,\n                \"size_y\": 3,\n                \"banner\": false\n              }\n            ]\n          }\n        },\n        \"fluidLayout\": false\n      },\n      \"isanon\": false,\n      \"content\": {\n        \"default\": {\n          \"a\": [\n            {\n              \"id\": \"n6ql6vcjn4hs1mikmu5trzfr\",\n              \"content\": {\n                \"id\": \"msf4j-message-tracing\",\n                \"title\": \"MSF4J Message Tracing\",\n                \"type\": \"gadget\",\n                \"thumbnail\": \"store://gadget/msf4j-tracing/icon.png\",\n                \"data\": {\n                  \"url\": \"store://gadget/msf4j-tracing/index.xml\"\n                },\n                \"styles\": {\n                  \"title\": \"MSF4J Message Tracing\",\n                  \"borders\": true\n                },\n                \"options\": {\n                  \"timeBack\": {\n                    \"type\": \"STRING\",\n                    \"title\": \"Trace Last Minutes\",\n                    \"value\": \"1440\",\n                    \"options\": [],\n                    \"required\": false\n                  },\n                  \"dasHost\": {\n                    \"type\": \"STRING\",\n                    \"title\": \"DAS Host\",\n                    \"value\": \"https://localhost:9443\",\n                    \"options\": [],\n                    \"required\": false\n                  },\n                  \"username\": {\n                    \"type\": \"STRING\",\n                    \"title\": \"Username\",\n                    \"value\": \"admin\",\n                    \"options\": [],\n                    \"required\": false\n                  },\n                  \"password\": {\n                    \"type\": \"STRING\",\n                    \"title\": \"Password\",\n                    \"value\": \"admin\",\n                    \"options\": [],\n                    \"required\": false\n                  }\n                },\n                \"locale_titles\": {}\n              }\n            }\n          ]\n        },\n        \"anon\": {}\n      }\n    }\n  ],\n  \"identityServerUrl\": \"\",\n  \"accessTokenUrl\": \"\",\n  \"apiKey\": \"\",\n  \"apiSecret\": \"\",\n  \"banner\": {\n    \"globalBannerExists\": null,\n    \"customBannerExists\": null\n  },\n  \"landing\": \"landing\",\n  \"isanon\": false,\n  \"isUserCustom\": false\n}"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventreceiver_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifact name=\"Eventreceiver\" version=\"1.0.0\" type=\"event/receiver\" serverRole=\"DataAnalyticsServer\">\n    <file>msf4jtracereceiver.xml</file>\n</artifact>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventreceiver_1.0.0/msf4jtracereceiver.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<eventReceiver name=\"msf4jtracereceiver\" statistics=\"disable\"\n    trace=\"disable\" xmlns=\"http://wso2.org/carbon/eventreceiver\">\n    <from eventAdapterType=\"http\">\n        <property name=\"transports\">http</property>\n    </from>\n    <mapping customMapping=\"enable\" type=\"json\">\n        <property>\n            <from jsonPath=\"$.type\"/>\n            <to name=\"type\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.time\"/>\n            <to name=\"time\" type=\"long\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.statusCode\"/>\n            <to default=\"0\" name=\"statusCode\" type=\"int\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.httpMethod\"/>\n            <to default=\"\" name=\"httpMethod\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.instanceId\"/>\n            <to name=\"instanceId\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.instanceName\"/>\n            <to name=\"instanceName\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.parentId\"/>\n            <to default=\"\" name=\"parentId\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.traceId\"/>\n            <to name=\"traceId\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.originId\"/>\n            <to name=\"originId\" type=\"string\"/>\n        </property>\n        <property>\n            <from jsonPath=\"$.url\"/>\n            <to default=\"\" name=\"url\" type=\"string\"/>\n        </property>\n    </mapping>\n    <to streamName=\"msf4j-tracing\" version=\"1.0.0\"/>\n</eventReceiver>\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventstore_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifact name=\"Eventstore\" version=\"1.0.0\" type=\"analytics/eventstore\" serverRole=\"DataAnalyticsServer\">\n    <file>msf4j-tracing.xml</file>\n</artifact>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventstore_1.0.0/msf4j-tracing.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<EventStoreConfiguration><TableSchema><ColumnDefinition><Name>type</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>true</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>time</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>LONG</Type></ColumnDefinition><ColumnDefinition><Name>statusCode</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>INTEGER</Type></ColumnDefinition><ColumnDefinition><Name>httpMethod</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>instanceId</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>instanceName</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>parentId</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>traceId</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>true</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>originId</Name><EnableIndexing>true</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>url</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>meta_traceId</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>STRING</Type></ColumnDefinition><ColumnDefinition><Name>correlation_originId</Name><EnableIndexing>false</EnableIndexing><IsPrimaryKey>false</IsPrimaryKey><EnableScoreParam>false</EnableScoreParam><Type>INTEGER</Type></ColumnDefinition></TableSchema><Source><StreamId>msf4j-tracing:1.0.0</StreamId></Source><MergeSchema>false</MergeSchema><RecordStoreName>EVENT_STORE</RecordStoreName></EventStoreConfiguration>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventstream_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifact name=\"Eventstream\" version=\"1.0.0\" type=\"event/stream\" serverRole=\"DataAnalyticsServer\">\n    <file>msf4j-tracing_1.0.0.json</file>\n</artifact>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/Eventstream_1.0.0/msf4j-tracing_1.0.0.json",
    "content": "{\n  \"name\": \"msf4j-tracing\",\n  \"version\": \"1.0.0\",\n  \"nickName\": \"\",\n  \"description\": \"\",\n  \"payloadData\": [\n    {\n      \"name\": \"type\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"time\",\n      \"type\": \"LONG\"\n    },\n    {\n      \"name\": \"statusCode\",\n      \"type\": \"INT\"\n    },\n    {\n      \"name\": \"httpMethod\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"instanceId\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"instanceName\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"parentId\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"traceId\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"originId\",\n      \"type\": \"STRING\"\n    },\n    {\n      \"name\": \"url\",\n      \"type\": \"STRING\"\n    }\n  ]\n}"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/artifact.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifact name=\"GadgetMSF4JTracing\" version=\"1.0.0\" type=\"dashboards/gadget\" serverRole=\"DataAnalyticsServer\">\n    <file>msf4j-tracing</file>\n</artifact>"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/msf4j-tracing/css/main.css",
    "content": "body {\n    display: block;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    font-size: 14px;\n    overflow: hidden;\n}\n\n#refresh-traces {\n    padding: 5px 10px;\n    background-color: #005FB0;\n    color: #ffffff;\n    display: inline-block;\n    margin: 12px 32px;\n    cursor: pointer;\n}\n\n#refresh-traces .pressed {\n    background-color: #ffffff;\n}\n\n#trace-groups {\n    position: relative;\n    display: block;\n    width: 100%;\n    height: 100%;\n    overflow-y: auto;\n}\n\n.trace-group {\n    padding: 12px;\n    cursor: default;\n    border-bottom: 1px solid #dddddd;\n}\n\n.trace-group .inst-name {\n    display: inline-block;\n    margin-left: 20px;\n    max-width: 120px;\n}\n\n.trace-group .endpoint {\n    display: inline-block;\n    margin-left: 20px;\n}\n\n.trace-group .method {\n    font-weight: bold;\n    display: inline-block;\n    margin-left: 20px;\n}\n\n.trace-group .url {\n    margin-left: 20px;\n    display: inline-block;\n}\n\n.trace-group .time {\n    display: inline-block;\n    margin-left: 20px;\n    min-width: 145px;\n}\n\n.trace-bar, .trace-bar * {\n    position: relative;\n}\n\n.trace-bar .bar-row {\n    border-bottom: 1px solid #dddddd;\n}\n\n.trace-bar .left-pane {\n    position: absolute;\n    float: left;\n    left: 0;\n    top: 0;\n    width: 200px;\n    line-height: 20px;\n    padding: 10px 0;\n    cursor: pointer;\n}\n\n.trace-bar .arrow {\n    display: inline-block;\n    width: 0;\n    height: 0;\n    border-left: 5px solid transparent;\n    border-right: 5px solid transparent;\n    border-top: 5px solid #000;\n}\n\n.trace-bar .arrow-down {\n    display: inline-block;\n    width: 0;\n    height: 0;\n    border-top: 5px solid transparent;\n    border-bottom: 5px solid transparent;\n    border-left: 5px solid #000;\n}\n\n.trace-bar .arrow-hide {\n    margin-left: 5px;\n    display: inline-block;\n}\n\n.trace-bar .right-pane {\n    margin-left: 200px;\n    border-left: 1px solid #dddddd;\n    padding: 14px 0;\n}\n\n.trace-bar .bar-wrapper {\n    padding: 0 5px;\n}\n\n.trace-bar .bar {\n    position: relative;\n    background-color: #005FB0;\n    top: 0;\n    height: 12px;\n    cursor: pointer;\n    border-radius: 2px;\n}\n\n.trace-bar .child-container {\n}\n\n#trace-tree-view {\n    position: absolute;\n    display: block;\n    height: 100%;\n    width: 100%;\n    left: 0;\n    top: 0;\n    z-index: 100;\n    background-color: #ffffff;\n    padding-top: 40px;\n    overflow-y: auto;\n}\n\n.bar-info {\n    z-index: 100;\n    margin: 5px auto;\n    width: 600px;\n    position: relative;\n}\n\n.bar-info .row {\n    display: block;\n    position: relative;\n}\n\n.bar-info .row.emp {\n    font-weight: bold;\n}\n\n.bar-info .row.gap {\n    margin-top: 15px;\n}\n\n.bar-info .left-ipane {\n    position: relative;\n    display: block;\n    left: 0;\n    width: 50%;\n    text-align: right;\n}\n\n.bar-info .left-ipane .wrapper.emp, .bar-info .right-ipane .wrapper.emp {\n    padding: 8px;\n}\n\n.bar-info .left-ipane .wrapper, .bar-info .right-ipane .wrapper {\n    padding: 8px;\n}\n\n.bar-info .right-ipane {\n    position: absolute;\n    display: block;\n    left: 50%;\n    width: 50%;\n    top: 0;\n    text-align: left;\n}\n\n.bar-info .close {\n    z-index: 100;\n}\n\n#trace-tree-view .container {\n    border-top: 1px solid #dddddd;\n}\n\n.bar-info .cell {\n    display: inline-block;\n}\n\n#trace-tree-view .close, .bar-info .close {\n    cursor: pointer;\n    position: absolute;\n    display: block;\n    left: 0;\n    top: 0;\n    margin-left: 10px;\n    font-size: 18px;\n}\n\n#trace-tree-view .close .arrow {\n    display: inline-block;\n    width: 0;\n    height: 0;\n    border-right: 10px solid #666;\n    border-top: 8px solid transparent;\n    border-bottom: 8px solid transparent;\n    margin-right: 5px;\n    margin-bottom: -2px;\n}\n\n#trace-tree-view .time-line-pane {\n    margin-left: 200px;\n}\n\n#trace-tree-view .time-line-wrapper {\n    position: relative;\n    display: block;\n}\n\n#time-line {\n    width: 100%;\n    height: 20px;\n}\n\n#time-line .unit {\n    border-left: 1px solid #dddddd;\n    color: #666666;\n    min-height: 4px;\n    font-size: 10px;\n    padding-top: 3px;\n    padding-left: 3px;\n    display: inline-block;\n    position: absolute;\n}"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/msf4j-tracing/gadget.json",
    "content": "{\n    \"id\": \"msf4j-message-tracing\",\n    \"title\": \"MSF4J Message Tracing\",\n    \"type\": \"gadget\",\n    \"thumbnail\": \"store://gadget/msf4j-tracing/icon.png\",\n    \"data\": {\n        \"url\": \"store://gadget/msf4j-tracing/index.xml\"\n    }\n}\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/msf4j-tracing/index.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Module>\n    <ModulePrefs title=\"MSF4J Message Tracing\" height=\"700\" description=\"MSF4J Tracing\">\n        <Require feature=\"dynamic-height\"/>\n        <Require feature=\"setprefs\"/>\n    </ModulePrefs>\n    <UserPref name=\"timeBack\" display_name=\"Trace Last Minutes\" default_value=\"1440\"/>\n    <UserPref name=\"dasHost\" display_name=\"DAS Host\" default_value=\"https://localhost:9443\"/>\n    <UserPref name=\"username\" display_name=\"Username\" default_value=\"admin\"/>\n    <UserPref name=\"password\" display_name=\"Password\" default_value=\"admin\"/>\n    <Content type=\"html\">\n        <![CDATA[\n        <head>\n            <link type=\"text/css\" rel=\"stylesheet\" href=\"css/main.css\" media=\"all\">\n            <script language=\"javascript\" type=\"text/javascript\" src=\"js/libs/jquery-3.1.0.min.js\"></script>\n            <script language=\"javascript\" type=\"text/javascript\" src=\"js/libs/jquery.base64.js\"></script>\n            <script language=\"javascript\" type=\"text/javascript\" src=\"js/libs/mustache.min.js\"></script>\n            <script language=\"javascript\" type=\"text/javascript\" src=\"js/main.js\"></script>\n        <head>\n        <body>\n            <div>\n                <div>\n                    <div id=\"refresh-traces\">Refresh Traces</div>\n                </div>\n                <div id=\"trace-groups\"></div>\n            </div>\n            <div id=\"trace-tree-view\">\n                <div class=\"close\"><div class=\"arrow\"></div>Back</div>\n                <div>\n                    <div class=\"container\"></div>\n                    <div class=\"time-line-pane\">\n                        <div class=\"time-line-wrapper\">\n                            <div id=\"time-line\"></div>\n                        <div>\n                    </div>\n                </div>\n            </div>\n            <script id=\"bar-info\" type=\"x-tmpl-mustache\">\n                <div class=\"bar-info\">\n                    <!-- <div class=\"close\">Close</div>-->\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Client HTTP Method</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{chttpMethod}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Client Request Path</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{clientPath}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Microservice HTTP Method</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{shttpMethod}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Microservice Path</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{serverPath}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Client Response Status</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{cStatusCode}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row emp\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">Server Response Status</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper emp\">\n                                <div class=\"cell\">{{sStatusCode}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row gap\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Client Request Start</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{clientStartTime}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Server Request Receive</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{serverStartTime}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Server Response Sent</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{serverEndTime}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Client Response Receive</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{clientEndTime}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row gap\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Client Instance Name</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{clientInstName}}</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row\">\n                        <div class=\"left-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">Server Instance Name</div>\n                            </div>\n                        </div>\n                        <div class=\"right-ipane\">\n                            <div class=\"wrapper\">\n                                <div class=\"cell\">{{serverInstName}}</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </script>\n            <script id=\"trace-group\" type=\"x-tmpl-mustache\">\n                <div class=\"trace-group\">\n                    <div class=\"inst-name\">{{origin.instanceName}}</div>\n                    <div class=\"time\">{{origin.timeStr}}</div>\n                    <div class=\"endpoint\">\n                        <span class=\"method\">{{origin.httpMethod}}</span>\n                        <span class=\"url\">{{origin.url}}</span>\n                    </div>\n                </div>\n            </script>\n            <script id=\"trace-bar\" type=\"x-tmpl-mustache\">\n                <div class=\"trace-bar\">\n                    <div class=\"bar-row\">\n                        <div class=\"left-pane\">\n                            <div class=\"arrow\"></div>\n                            <span class=\"label\">Service-01</span>\n                        </div>\n                        <div class=\"right-pane\">\n                            <div class=\"bar-wrapper\">\n                                <div class=\"bar\"></div>\n                                <div class=\"bar-info-container\"></div>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"child-container\"></div>\n                </div>\n            </script>\n        </body>\n        ]]>\n    </Content>\n</Module>\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/msf4j-tracing/js/libs/jquery.base64.js",
    "content": "/*!\n * jquery.base64.js 0.1 - https://github.com/yckart/jquery.base64.js\n * Makes Base64 en & -decoding simpler as it is.\n *\n * Based upon: https://gist.github.com/Yaffle/1284012\n *\n * Copyright (c) 2012 Yannick Albert (http://yckart.com)\n * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).\n * 2013/02/10\n **/\n;(function($) {\n\n    var b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",\n        a256 = '',\n        r64 = [256],\n        r256 = [256],\n        i = 0;\n\n    var UTF8 = {\n\n        /**\n         * Encode multi-byte Unicode string into utf-8 multiple single-byte characters\n         * (BMP / basic multilingual plane only)\n         *\n         * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars\n         *\n         * @param {String} strUni Unicode string to be encoded as UTF-8\n         * @returns {String} encoded string\n         */\n        encode: function(strUni) {\n            // use regular expressions & String.replace callback function for better efficiency\n            // than procedural approaches\n            var strUtf = strUni.replace(/[\\u0080-\\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz\n            function(c) {\n                var cc = c.charCodeAt(0);\n                return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);\n            })\n            .replace(/[\\u0800-\\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz\n            function(c) {\n                var cc = c.charCodeAt(0);\n                return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3F, 0x80 | cc & 0x3f);\n            });\n            return strUtf;\n        },\n\n        /**\n         * Decode utf-8 encoded string back into multi-byte Unicode characters\n         *\n         * @param {String} strUtf UTF-8 string to be decoded back to Unicode\n         * @returns {String} decoded string\n         */\n        decode: function(strUtf) {\n            // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!\n            var strUni = strUtf.replace(/[\\u00e0-\\u00ef][\\u0080-\\u00bf][\\u0080-\\u00bf]/g, // 3-byte chars\n            function(c) { // (note parentheses for precence)\n                var cc = ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f);\n                return String.fromCharCode(cc);\n            })\n            .replace(/[\\u00c0-\\u00df][\\u0080-\\u00bf]/g, // 2-byte chars\n            function(c) { // (note parentheses for precence)\n                var cc = (c.charCodeAt(0) & 0x1f) << 6 | c.charCodeAt(1) & 0x3f;\n                return String.fromCharCode(cc);\n            });\n            return strUni;\n        }\n    };\n\n    while(i < 256) {\n        var c = String.fromCharCode(i);\n        a256 += c;\n        r256[i] = i;\n        r64[i] = b64.indexOf(c);\n        ++i;\n    }\n\n    function code(s, discard, alpha, beta, w1, w2) {\n        s = String(s);\n        var buffer = 0,\n            i = 0,\n            length = s.length,\n            result = '',\n            bitsInBuffer = 0;\n\n        while(i < length) {\n            var c = s.charCodeAt(i);\n            c = c < 256 ? alpha[c] : -1;\n\n            buffer = (buffer << w1) + c;\n            bitsInBuffer += w1;\n\n            while(bitsInBuffer >= w2) {\n                bitsInBuffer -= w2;\n                var tmp = buffer >> bitsInBuffer;\n                result += beta.charAt(tmp);\n                buffer ^= tmp << bitsInBuffer;\n            }\n            ++i;\n        }\n        if(!discard && bitsInBuffer > 0) result += beta.charAt(buffer << (w2 - bitsInBuffer));\n        return result;\n    }\n\n    var Plugin = $.base64 = function(dir, input, encode) {\n            return input ? Plugin[dir](input, encode) : dir ? null : this;\n        };\n\n    Plugin.btoa = Plugin.encode = function(plain, utf8encode) {\n        plain = Plugin.raw === false || Plugin.utf8encode || utf8encode ? UTF8.encode(plain) : plain;\n        plain = code(plain, false, r256, b64, 8, 6);\n        return plain + '===='.slice((plain.length % 4) || 4);\n    };\n\n    Plugin.atob = Plugin.decode = function(coded, utf8decode) {\n        coded = String(coded).split('=');\n        var i = coded.length;\n        do {--i;\n            coded[i] = code(coded[i], true, r64, a256, 6, 8);\n        } while (i > 0);\n        coded = coded.join('');\n        return Plugin.raw === false || Plugin.utf8decode || utf8decode ? UTF8.decode(coded) : coded;\n    };\n}(jQuery));"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/GadgetMSF4JTracing_1.0.0/msf4j-tracing/js/main.js",
    "content": "gadgets.util.registerOnLoadHandler(function () {\n    gadgets.window.adjustHeight();\n});\n\n$(document).ready(function () {\n    var prefs = new _IG_Prefs();\n\n    var traceGroupsElm = $('#trace-groups');\n\n    var traceTreeVwElm = $(\"#trace-tree-view\");\n    var traceTreeVw = initTraceTreeView(\n        traceTreeVwElm,\n        traceTreeVwElm.find(\".container\").first(),\n        traceTreeVwElm.find(\".close\").first()\n    );\n\n    (function () {\n        var refreshTracesElm = $(\"#refresh-traces\");\n        var isLoading = false;\n\n        load();\n\n        function load() {\n            if (isLoading == false) {\n                isLoading = true;\n                loadAndRenderTraceGroups(prefs, traceGroupsElm, traceTreeVw, function () {\n                    isLoading = false;\n                });\n            }\n        }\n\n        refreshTracesElm.click(function () {\n            load();\n        });\n    })();\n});\n\nfunction loadAndRenderTraceGroups(prefs, traceGroupsElm, traceTreeVw, callback) {\n\n    var analyticsPath = \"/analytics/tables/MSF4J-TRACING\";\n\n    var timeBack = prefs.getInt(\"timeBack\");\n    var dasHost = prefs.getString(\"dasHost\");\n    var username = prefs.getString(\"username\");\n    var password = prefs.getString(\"password\");\n\n    loadTraces((function (dasHost, analyticsPath, timeBack) {\n        return dasHost + analyticsPath +\n            ((dasHost.substr(dasHost.length - 1) == \"/\") ? \"\" : \"/\") +\n            ((new Date()).getTime() - timeBack * 60 * 1000);\n    })(dasHost, analyticsPath, timeBack), timeBack, username, password, function (data) {\n        var traceGroups = groupTraceEvents(data);\n        renderTraceGroups(traceGroups, traceGroupsElm, traceTreeVw);\n        callback();\n    }, function (jqXHR) {\n        callback();\n        var errorData = $.parseJSON(jqXHR.responseText);\n        if (errorData) {\n            alert(errorData.message);\n        } else {\n            alert(\"Failed to load traces\");\n        }\n    });\n\n}\n\nfunction initBarInfoView(rootElm, traceData, closeCallBack) {\n\n    var close = null;\n\n    function buildBarInfoVwModel(traceData) {\n        var vwModel = {\n            chttpMethod: \"-\",\n            shttpMethod: \"-\",\n            clientPath: \"-\",\n            serverPath: \"-\",\n            cStatusCode: \"-\",\n            sStatusCode: \"-\",\n            clientStartTime: \"-\",\n            serverStartTime: \"-\",\n            serverEndTime: \"-\",\n            clientEndTime: \"-\",\n            serverInstName: \"-\",\n            clientInstName: \"-\",\n            serverInstId: \"-\",\n            clientInstId: \"-\"\n        };\n        if (traceData.type == \"CTS\") {\n            vwModel.chttpMethod = traceData.httpMethod || \"-\";\n            vwModel.clientPath = traceData.url || \"-\";\n            vwModel.clientStartTime = traceData.timeStr || \"-\";\n            vwModel.clientEndTime = (traceData.end) ? traceData.end.timeStr || \"-\" : \"-\";\n            vwModel.clientInstName = traceData.clientName || \"-\";\n            vwModel.clientInstId = traceData.instanceId || \"-\";\n            vwModel.cStatusCode = (traceData.end) ? traceData.end.statusCode : \"-\";\n            if (traceData.service) {\n                vwModel.shttpMethod = traceData.service.httpMethod || \"-\";\n                vwModel.serverPath = traceData.service.url || \"-\";\n                vwModel.serverStartTime = traceData.service.timeStr || \"-\";\n                vwModel.serverEndTime = (traceData.service.end) ? traceData.service.end.timeStr || \"-\" : \"-\";\n                vwModel.serverInstName = traceData.instanceName || \"-\";\n                vwModel.serverInstId = traceData.service.instanceId || \"-\";\n                vwModel.sStatusCode = (traceData.service.end) ? traceData.service.end.statusCode : \"-\";\n            }\n        } else if (traceData.type == \"STS\") {\n            vwModel.shttpMethod = traceData.httpMethod || \"-\";\n            vwModel.serverPath = traceData.url || \"-\";\n            vwModel.serverStartTime = traceData.timeStr || \"-\";\n            vwModel.serverEndTime = (traceData.end) ? traceData.end.timeStr || \"-\" : \"-\";\n            vwModel.serverInstName = traceData.instanceName || \"-\";\n            vwModel.serverInstId = traceData.instanceId || \"-\";\n            vwModel.sStatusCode = (traceData.end) ? traceData.end.statusCode : \"-\";\n        }\n        return vwModel;\n    }\n\n    function show(traceData) {\n        var barInfoElm = $(\n            Mustache.render(\n                $('#bar-info').html(),\n                buildBarInfoVwModel(traceData)\n            )\n        );\n\n        close = function () {\n            barInfoElm.remove();\n            if (closeCallBack) {\n                closeCallBack();\n            }\n        };\n\n        // var closeBtnElm = barInfoElm.find(\".close\").first();\n        // closeBtnElm.click(close);\n\n        rootElm.append(barInfoElm);\n    }\n\n    return {\n        show: show,\n        close: function () {\n            if (close) {\n                close();\n            }\n        }\n    };\n}\n\nfunction initTraceTreeView(viewElm, containerElm, closeBtnElm) {\n\n    hide();\n\n    closeBtnElm.click(function () {\n        hide();\n    });\n\n    function clean() {\n        containerElm.empty();\n    }\n\n    function hide() {\n        clean();\n        viewElm.hide();\n    }\n\n    function renderTimeLine(start, end) {\n        var timeLineElm = $(\"#time-line\");\n        var timeGaps = [\n            {\n                gap: 1,\n                unit: \"ms\",\n                unitMs: 1\n            },\n            {\n                gap: 5,\n                unit: \"ms\",\n                unitMs: 1\n            },\n            {\n                gap: 10,\n                unit: \"ms\",\n                unitMs: 1\n            },\n            {\n                gap: 100,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 200,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 500,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 1000,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 1000 * 5,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 1000 * 10,\n                unit: \"s\",\n                unitMs: 1000\n            },\n            {\n                gap: 1000 * 60,\n                unit: \"s\",\n                unitMs: 1000 * 60\n            },\n            {\n                gap: 1000 * 60 * 5,\n                unit: \"m\",\n                unitMs: 1000 * 60\n            },\n            {\n                gap: 1000 * 60 * 10,\n                unit: \"m\",\n                unitMs: 1000 * 60\n            },\n            {\n                gap: 1000 * 60 * 60,\n                unit: \"h\",\n                unitMs: 1000 * 60 * 60\n            }\n        ];\n        var timeDiff = end - start;\n\n        function render() {\n            var spaceDiff = timeLineElm.width();\n            var minGapWidth = 40;\n            var timeGap = (function () {\n                var timeGapsLen = timeGaps.length;\n                for (var i = 0; i < timeGapsLen; i++) {\n                    var timeGap = timeGaps[i];\n                    var gapCount = (timeDiff / timeGap.gap);\n                    var gapWidth = spaceDiff / gapCount;\n                    if (gapWidth >= minGapWidth) {\n                        return timeGap;\n                    }\n                }\n                return timeGaps[timeGapsLen - 1];\n            })();\n            var gapCount = (timeDiff / timeGap.gap);\n            var unitGap = timeGap.gap / timeGap.unitMs;\n            for (var i = 0; i < gapCount; i++) {\n                var left = (i * timeGap.gap) * 100 / timeDiff;\n                var unitElm = $(document.createElement(\"div\"));\n                unitElm.attr(\"class\", \"unit\");\n                unitElm.css(\"left\", left + \"%\");\n                unitElm.html((i * unitGap).toFixed(3) + timeGap.unit);\n                timeLineElm.append(unitElm);\n            }\n        }\n\n        timeLineElm.empty();\n        render();\n        timeLineElm.resize(function () {\n            timeLineElm.empty();\n            render();\n        });\n    }\n\n    function show(traceTree) {\n        viewElm.show();\n        renderTraceTree(traceTree, buildOriginTraceBarVw(traceTree, traceTree.timeRange, 0));\n        renderTimeLine(traceTree.timeRange.start, traceTree.timeRange.end);\n    }\n\n    function buildOriginTraceBarVw(traceTree, timeRange, callDepth) {\n        var originTraceBarVw = buildTraceBarView(traceTree, timeRange, callDepth);\n        containerElm.append(originTraceBarVw.traceBarElm);\n        return originTraceBarVw;\n    }\n\n    function renderTraceTree(traceTree, parentTraceBarVw) {\n        var children = traceTree.children;\n        var childrenLen = children.length;\n        for (var i = 0; i < childrenLen; i++) {\n            var child = children[i];\n            var childTraceBarVw = buildTraceBarView(\n                child,\n                parentTraceBarVw.timeRange,\n                // Do not indent the service call of a client\n                (child.type == \"STS\") ? parentTraceBarVw.callDepth : parentTraceBarVw.callDepth + 1\n            );\n            parentTraceBarVw.addChildTraceBar(childTraceBarVw);\n            renderTraceTree(child, childTraceBarVw);\n        }\n    }\n\n    return {\n        show: function (traceTree) {\n            show(traceTree);\n        }\n    };\n}\n\nfunction buildTraceBarView(traceData, timeRange, callDepth) {\n    var traceBarElm = $(\n        Mustache.render(\n            $('#trace-bar').html()\n        )\n    );\n    var childContainerElm = traceBarElm.find(\".child-container\").first();\n    var leftPaneElm = traceBarElm.find(\".left-pane\").first();\n    var arrowElm = traceBarElm.find(\".arrow\").first();\n    var labelElm = traceBarElm.find(\".label\").first();\n    var barElm = traceBarElm.find(\".bar\").first();\n    var barInfoContElm = traceBarElm.find(\".bar-info-container\").first();\n    var childTraceBarVws = [];\n    var collapseChildren = null;\n\n    setName(traceData.instanceName);\n    setTimeRange(\n        traceData.time,\n        // If end time is not available, draw the bar to touch right end\n        (traceData.end) ? traceData.end.time : timeRange.end,\n        timeRange.start,\n        timeRange.end\n    );\n    setCallDepth(callDepth);\n\n\n    (function () {\n        var inforBarVw = null;\n        barElm.click(function () {\n            if (!inforBarVw) {\n                inforBarVw = initBarInfoView(barInfoContElm, traceData);\n                inforBarVw.show(traceData);\n            } else {\n                inforBarVw.close();\n                inforBarVw = null;\n            }\n        });\n    })();\n\n    (function (childTraceBarVws) {\n        var isHidden = false;\n\n        collapseChildren = function () {\n            if (traceData.children.length > 0) {\n                childContainerElm.hide();\n                labelElm.css(\"font-weight\", \"bold\");\n                arrowElm.attr(\"class\", \"arrow-down\");\n                var childTraceBarVwsLen = childTraceBarVws.length;\n                for (var i = 0; i < childTraceBarVwsLen; i++) {\n                    childTraceBarVw = childTraceBarVws[i];\n                    childTraceBarVw.collapseChildren();\n                }\n                isHidden = true;\n            }\n        };\n\n        if (traceData.children.length > 0) {\n            leftPaneElm.click(function () {\n                if (isHidden) {\n                    childContainerElm.show();\n                    labelElm.css(\"font-weight\", \"normal\");\n                    arrowElm.attr(\"class\", \"arrow\");\n                    isHidden = false;\n                } else {\n                    collapseChildren();\n                }\n            });\n        } else {\n            arrowElm.attr(\"class\", \"arrow-hide\");\n        }\n    })(childTraceBarVws);\n\n    function setTimeRange(startTime, endTime, rootStart, rootEnd) {\n        var left = 100 * (startTime - rootStart) / (rootEnd - rootStart);\n        var width = 100 * (endTime - startTime) / (rootEnd - rootStart);\n        barElm.css({\n            left: left + \"%\",\n            width: width + \"%\",\n            \"background-color\": (function shadeBlend(p, c0, c1) {\n                var n = p < 0 ? p * -1 : p, u = Math.round, w = parseInt;\n                if (c0.length > 7) {\n                    var f = c0.split(\",\"), t = (c1 ? c1 : p < 0 ? \"rgb(0,0,0)\" : \"rgb(255,255,255)\").split(\",\"), R = w(f[0].slice(4)), G = w(f[1]), B = w(f[2]);\n                    return \"rgb(\" + (u((w(t[0].slice(4)) - R) * n) + R) + \",\" + (u((w(t[1]) - G) * n) + G) + \",\" + (u((w(t[2]) - B) * n) + B) + \")\"\n                } else {\n                    var f = w(c0.slice(1), 16), t = w((c1 ? c1 : p < 0 ? \"#000000\" : \"#FFFFFF\").slice(1), 16), R1 = f >> 16, G1 = f >> 8 & 0x00FF, B1 = f & 0x0000FF;\n                    return \"#\" + (0x1000000 + (u(((t >> 16) - R1) * n) + R1) * 0x10000 + (u(((t >> 8 & 0x00FF) - G1) * n) + G1) * 0x100 + (u(((t & 0x0000FF) - B1) * n) + B1)).toString(16).slice(1)\n                }\n            })((function () {\n                var p = callDepth * 0.1;\n                return (p > 0.4) ? 0.4 : p;\n            })(callDepth), \"#005FB0\")\n        });\n    }\n\n    function setName(name) {\n        labelElm.html(name);\n    }\n\n    function addChildTraceBar(traceBarVw) {\n        childTraceBarVws.push(traceBarVw);\n        childContainerElm.append(traceBarVw.traceBarElm);\n    }\n\n    function setCallDepth(callDepth) {\n        leftPaneElm.css(\"margin-left\", callDepth * 15);\n    }\n\n    return {\n        traceBarElm: traceBarElm,\n        collapseChildren: collapseChildren,\n        timeRange: timeRange,\n        callDepth: callDepth,\n        addChildTraceBar: function (traceBarVw) {\n            addChildTraceBar(traceBarVw);\n        }\n    };\n}\n\nfunction loadTraces(url, timeBack, username, password, callback, errorCallback) {\n    $.ajax({\n        type: \"GET\",\n        beforeSend: function (request) {\n            if (!window.btoa) {\n                window.btoa = $.base64.btoa;\n            }\n            request.setRequestHeader(\"Authorization\", \"Basic \" + btoa(username + \":\" + password));\n        },\n        url: url,\n        data: \"json\",\n        processData: false,\n        success: callback,\n        error: errorCallback\n    });\n}\n\nfunction renderTraceGroups(traceGroups, rootElm, traceTreeVw) {\n    rootElm.empty();\n    itrValidTraceGroups(traceGroups, function (traceGroup) {\n        var traceGroupElm = $(\n            Mustache.render(\n                $('#trace-group').html(),\n                traceGroup\n            )\n        );\n        traceGroupElm.click(function () {\n            traceTreeVw.show(traceGroup.getTraceTree());\n        });\n        rootElm.prepend(traceGroupElm);\n    });\n}\n\nfunction groupTraceEvents(data) {\n    var traceGroups = {};\n    var dataLen = data.length;\n    for (var i = 0; i < dataLen; i++) {\n        var event = data[i].values;\n        if (!event || !event.originId) {\n            // Ignore the event if it is null or does not contain the original event ID\n            // Or the original event Id is invalid\n            continue;\n        }\n        var eventDate = new Date(event.time);\n        event.timeStr = eventDate.toTimeString()\n            .replace(\" GMT\", \":\" + (\"00\" + eventDate.getMilliseconds()).slice(-3) + \" GMT\");\n        var traceGroup = traceGroups[event.originId];\n        if (!traceGroup) {\n            traceGroups[event.originId] = traceGroup = {\n                isBuilt: false,\n                timeRange: {\n                    // The time range that the trace spans\n                    // Required for drawing gantt bars to scale\n                    start: Number.MAX_VALUE,\n                    end: 0,\n                    addStart: function (startTime) {\n                        if (this.start > startTime) {\n                            this.start = startTime;\n                        }\n                    },\n                    addEnd: function (endTime) {\n                        if (this.end < endTime) {\n                            this.end = endTime;\n                        }\n                    }\n                },\n                origin: null,\n                events: {\n                    start: {},\n                    end: {}\n                },\n                addEvent: function (event) {\n                    if (event.type == \"STS\" || event.type == \"CTS\") {\n                        if (event.traceId == event.originId) {\n                            // If this condition is met this is the first event of the trace\n                            if (validateOriginEvent(event)) {\n                                this.origin = event;\n                                this.timeRange.addStart(event.time);\n                            }\n                        } else {\n                            var children = this.events.start[event.parentId];\n                            if (!children) {\n                                this.events.start[event.parentId] = children = [];\n                            }\n                            children.push(event);\n                            this.timeRange.addStart(event.time);\n                        }\n                    } else {\n                        this.events.end[event.traceId] = event;\n                        this.timeRange.addEnd(event.time);\n                    }\n                },\n                getTraceTree: function () {\n                    if (this.isBuilt) {\n                        return this.origin;\n                    } else {\n                        var startEvents = this.events.start;\n                        var endEvents = this.events.end;\n                        var origin = this.origin;\n                        origin.timeRange = this.timeRange;\n                        var parents = [];\n                        parents.push(origin);\n                        while (Object.keys(startEvents).length > 0 || parents.length > 0) {\n                            var parent = parents.shift();\n                            parent.end = endEvents[parent.traceId];\n                            parent.children = startEvents[parent.traceId] || [];\n                            delete startEvents[parent.traceId];\n                            var childrenLen = parent.children.length;\n                            if (parent.type == \"CTS\") {\n                                // Parent STS can have many children that are initiated multiple client calls\n                                // Parent CTS will have only one child which is the service call (Merge it to CTS itself)\n                                // In all iterations except the initial* iteration Parent will be CTS\n                                if (childrenLen == 1) {\n                                    // The only child of CTS is a STS\n                                    // Add children of STS to CTS\n                                    var childSTS = parent.children[0];\n                                    childSTS.end = endEvents[childSTS.traceId];\n                                    parent.service = childSTS;\n                                    parent.clientName = parent.instanceName;\n                                    parent.instanceName = childSTS.instanceName;\n                                    parent.children = startEvents[childSTS.traceId] || [];\n                                    delete startEvents[childSTS.traceId];\n                                }\n                            }\n                            parent.children.sort(function (a, b) {\n                                return a.time - b.time;\n                            });\n                            childrenLen = parent.children.length;\n                            for (var i = 0; i < childrenLen; i++) {\n                                var childCTS = parent.children[i];\n                                childCTS.end = endEvents[childCTS.traceId];\n                                parents.push(childCTS);\n                            }\n                        }\n                        this.isBuilt = true;\n                        this.events = null;\n                        console.log(\"TraceTree:\");\n                        console.log(origin);\n                        if (origin.timeRange.end == 0) {\n                            // This condition will satisfy if no end events are available\n                            origin.timeRange.end = (new Date()).getTime();\n                        }\n                        return origin;\n                    }\n                }\n            };\n        }\n        traceGroup.addEvent(event);\n    }\n    console.log(\"Trace groups:\");\n    console.log(traceGroups);\n    return traceGroups;\n}\n\nfunction itrValidTraceGroups(traceGroups, callback) {\n    for (var key in traceGroups) {\n        if (!traceGroups.hasOwnProperty(key)) {\n            continue;\n        }\n        var traceGroup = traceGroups[key];\n        if (traceGroup.origin && validateOriginEvent(traceGroup.origin)) {\n            callback(traceGroup);\n        }\n    }\n}\n\nfunction validateOriginEvent(event) {\n    return event.instanceName && event.time && event.traceId && event.url && event.httpMethod && !event.parentId;\n}\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/capp-content/artifacts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<artifacts>\n    <artifact name=\"org.wso2.msf4j.wso2das-msf4j-tracing\" version=\"1.0.0\" type=\"carbon/application\">\n        <dependency artifact=\"Eventstream\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\"/>\n        <dependency artifact=\"Eventstore\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\"/>\n        <dependency artifact=\"Eventreceiver\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\"/>\n        <!-- Gadgets -->\n        <dependency artifact=\"GadgetMSF4JTracing\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\"/>\n        <!-- Dashboard Definition -->\n        <dependency artifact=\"Dashboard\" version=\"1.0.0\" include=\"true\" serverRole=\"DataAnalyticsServer\"/>\n    </artifact>\n</artifacts>\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>wso2das-msf4j-tracing</artifactId>\n\n    <name>WSO2 DAS MSF4J message tracing C-App</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <configuration>\n                    <descriptors>\n                        <descriptor>zip.xml</descriptor>\n                    </descriptors>\n                    <appendAssemblyId>false</appendAssemblyId>\n                    <finalName>${project.artifactId}-${project.version}</finalName>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>make-assembly</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>single</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-antrun-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <configuration>\n                            <target>\n                                <copy file=\"${project.build.directory}/${project.artifactId}-${project.version}.zip\" tofile=\"${project.build.directory}/${project.artifactId}-${project.version}.car\" />\n                            </target>\n                        </configuration>\n                        <goals>\n                            <goal>run</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-jar-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <id>default-jar</id>\n                        <phase>none</phase>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "analytics/wso2das-tracing-capp/zip.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<assembly xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n          xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0\n          http://maven.apache.org/xsd/assembly-1.1.0.xsd\">\n    <id>bin</id>\n    <baseDirectory>/</baseDirectory>\n    <formats>\n        <format>zip</format>\n    </formats>\n    <includeBaseDirectory>false</includeBaseDirectory>\n    <fileSets>\n        <fileSet>\n            <directory>capp-content/</directory>\n            <outputDirectory>/</outputDirectory>\n        </fileSet>\n    </fileSets>\n</assembly>"
  },
  {
    "path": "analytics/zipkin-tracing/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>zipkin-tracing</artifactId>\n    <!-- TODO: Make this an OSGi bundle to support MSF4J OSGi mode -->\n    <packaging>jar</packaging>\n\n    <name>Zipkin Tracing Module</name>\n    <description>This module provides Zipkin tracing support for MSF4J server-less mode.</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.zipkin.brave</groupId>\n            <artifactId>brave-spancollector-http</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.zipkin.brave</groupId>\n            <artifactId>brave-http</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n</project>\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/main/java/org/wso2/msf4j/analytics/zipkintracing/MSF4JZipkinTracingInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.Brave;\nimport com.github.kristofa.brave.EmptySpanCollectorMetricsHandler;\nimport com.github.kristofa.brave.ServerRequestInterceptor;\nimport com.github.kristofa.brave.ServerResponseInterceptor;\nimport com.github.kristofa.brave.http.DefaultSpanNameProvider;\nimport com.github.kristofa.brave.http.HttpResponse;\nimport com.github.kristofa.brave.http.HttpServerRequest;\nimport com.github.kristofa.brave.http.HttpServerRequestAdapter;\nimport com.github.kristofa.brave.http.HttpServerResponseAdapter;\nimport com.github.kristofa.brave.http.HttpSpanCollector;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\n\n/**\n * Interceptor for tracing server side request/response flows to Zipkin.\n */\npublic class MSF4JZipkinTracingInterceptor implements Interceptor {\n\n    private final ServerRequestInterceptor reqInterceptor;\n    private final ServerResponseInterceptor respInterceptor;\n    private static final String RESPONDER_ATTRIBUTE = \"responder-attribute\";\n\n    /**\n     * Constructor of the MSF4JTracingInterceptor.\n     *\n     * @param microServiceName Name of the Microservice\n     */\n    public MSF4JZipkinTracingInterceptor(String microServiceName) {\n        this(microServiceName, TracingConstants.DEFAULT_ZIPKIN_URL);\n    }\n\n    /**\n     * Constructor of the MSF4JTracingInterceptor.\n     *\n     * @param microServiceName Name of the Microservice\n     * @param zipkinUrl        Base URL of the Zipkin server\n     */\n    public MSF4JZipkinTracingInterceptor(String microServiceName, String zipkinUrl) {\n        Brave.Builder builder = new Brave.Builder(microServiceName);\n        builder.spanCollector(HttpSpanCollector.create(zipkinUrl, new EmptySpanCollectorMetricsHandler()));\n        Brave brave = builder.build();\n        reqInterceptor = brave.serverRequestInterceptor();\n        respInterceptor = brave.serverResponseInterceptor();\n    }\n\n    /**\n     * Intercepts the server request flow and extract request information\n     * to be published to the Zipkin server for tracing.\n     */\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        serviceMethodInfo.setAttribute(RESPONDER_ATTRIBUTE, responder);\n        HttpServerRequest req = new TraceableHttpServerRequest(request);\n        HttpServerRequestAdapter reqAdapter = new HttpServerRequestAdapter(req, new DefaultSpanNameProvider());\n        reqInterceptor.handle(reqAdapter);\n        return true;\n    }\n\n    /**\n     * Intercepts the server response flow and extract response information\n     * to be published to the Zipkin server for tracing.\n     */\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        HttpResponse httpResponse = new TraceableHttpServerResponse((Response) serviceMethodInfo\n                .getAttribute(RESPONDER_ATTRIBUTE));\n        HttpServerResponseAdapter adapter = new HttpServerResponseAdapter(httpResponse);\n        respInterceptor.handle(adapter);\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/main/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpClientRequest.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpClientRequest;\nimport feign.Request;\n\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * Adaptor class for client side request object tracing\n */\npublic class TraceableHttpClientRequest implements HttpClientRequest {\n\n    private final Request request;\n\n    public TraceableHttpClientRequest(Request request) {\n        this.request = request;\n    }\n\n    @Override\n    public void addHeader(String header, String value) {\n        Collection<String> existingValues = request.headers().get(header);\n        if (existingValues == null) {\n            existingValues = new ArrayList<>();\n        }\n        existingValues.add(value);\n        request.headers().put(header, existingValues);\n    }\n\n    @Override\n    public URI getUri() {\n        return URI.create(request.url());\n    }\n\n    @Override\n    public String getHttpMethod() {\n        return request.method();\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/main/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpClientResponse.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpResponse;\nimport feign.Response;\n\n/**\n * Adaptor class for client side response object tracing\n */\npublic class TraceableHttpClientResponse implements HttpResponse {\n\n    private final Response response;\n\n    public TraceableHttpClientResponse(Response response) {\n        this.response = response;\n    }\n\n    @Override\n    public int getHttpStatusCode() {\n        return response.status();\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/main/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpServerRequest.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpServerRequest;\nimport org.wso2.msf4j.Request;\n\nimport java.net.URI;\n\n/**\n * Adaptor class for server side request object tracing\n */\npublic class TraceableHttpServerRequest implements HttpServerRequest {\n\n    private final Request req;\n\n    TraceableHttpServerRequest(Request req) {\n        this.req = req;\n    }\n\n    @Override\n    public String getHttpHeaderValue(String headerName) {\n        return req.getHeader(headerName);\n    }\n\n    @Override\n    public URI getUri() {\n        return URI.create(req.getUri());\n    }\n\n    @Override\n    public String getHttpMethod() {\n        return req.getHttpMethod();\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/main/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpServerResponse.java",
    "content": "/*\n*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n*  software distributed under the License is distributed on an\n*  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n*  KIND, either express or implied.  See the License for the\n*  specific language governing permissions and limitations\n*  under the License.\n*/\n\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpResponse;\nimport org.wso2.msf4j.Response;\n\n/**\n * Adaptor class for server side response object tracing\n */\npublic class TraceableHttpServerResponse implements HttpResponse {\n\n    private Response response;\n\n    TraceableHttpServerResponse(Response response) {\n        this.response = response;\n    }\n\n    @Override\n    public int getHttpStatusCode() {\n        return response.getStatusCode();\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/test/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpClientRequestTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpClientRequest;\nimport feign.Request;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.net.MalformedURLException;\nimport java.net.URI;\nimport java.nio.charset.Charset;\nimport java.util.HashMap;\nimport javax.ws.rs.HttpMethod;\n\n/**\n * Class for testing TraceableHttpClient.\n */\npublic class TraceableHttpClientRequestTest extends Assert {\n\n    private Request request;\n    private HttpClientRequest httpRequest;\n\n    @BeforeClass\n    public void setUp() throws MalformedURLException {\n        request = Request.create(HttpMethod.GET, URI.create(\"msf4j\").toString(), new HashMap<>(), null,\n                                 Charset.defaultCharset());\n        httpRequest = new TraceableHttpClientRequest(request);\n    }\n\n    @Test\n    public void testAddHeader() {\n        httpRequest.addHeader(\"testK\", \"testV\");\n        assertTrue(request.headers().get(\"testK\").contains(\"testV\"));\n    }\n\n    @Test\n    public void testGetUri() {\n        assertEquals(httpRequest.getUri(), URI.create(\"msf4j\"));\n    }\n\n    @Test\n    public void testGetHttpMethod() {\n        assertEquals(httpRequest.getHttpMethod(), HttpMethod.GET);\n    }\n\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/test/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpClientResponseTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpResponse;\nimport feign.Response;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.util.HashMap;\n\n/**\n * Class for testing TraceableHttpClientResponse.\n */\npublic class TraceableHttpClientResponseTest extends Assert {\n\n    private Response response;\n    private HttpResponse httpResponse;\n\n    @BeforeClass\n    public void setUp() throws IOException {\n        response = Response.builder().status(200).headers(new HashMap<>()).build();\n        httpResponse = new TraceableHttpClientResponse(response);\n    }\n\n    @Test\n    public void testGetStatusCode() {\n        assertEquals(httpResponse.getHttpStatusCode(), response.status());\n    }\n\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/test/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpServerRequestTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpServerRequest;\nimport io.netty.handler.codec.http.DefaultHttpRequest;\nimport io.netty.handler.codec.http.HttpVersion;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.Request;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport javax.ws.rs.HttpMethod;\n\n/**\n * Class for testing TraceableHttpServerRequest.\n */\npublic class TraceableHttpServerRequestTest extends Assert {\n\n    private Request request;\n    private HttpServerRequest httpServerRequest;\n\n    @BeforeClass\n    public void setUp() throws IOException {\n        HttpCarbonMessage httpCarbonMessage = new HttpCarbonMessage(\n                new DefaultHttpRequest(HttpVersion.HTTP_1_1, io.netty.handler.codec.http.HttpMethod.GET, \"msf4j\"));\n        httpCarbonMessage.setHeader(\"testK\", \"testV\");\n        httpCarbonMessage.setHttpMethod(HttpMethod.GET);\n        request = new Request(httpCarbonMessage);\n        request.setProperty(\"TO\", \"msf4j\");\n        httpServerRequest = new TraceableHttpServerRequest(request);\n    }\n\n    @Test\n    public void testGetHeader() {\n        assertEquals(httpServerRequest.getHttpHeaderValue(\"testK\"), \"testV\");\n    }\n\n    @Test\n    public void testGetUrl() {\n        assertEquals(httpServerRequest.getUri(), URI.create(\"msf4j\"));\n    }\n\n    @Test\n    public void testGetHttpMethod() {\n        assertEquals(httpServerRequest.getHttpMethod(), HttpMethod.GET);\n    }\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/test/java/org/wso2/msf4j/analytics/zipkintracing/TraceableHttpServerResponseTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.analytics.zipkintracing;\n\nimport com.github.kristofa.brave.http.HttpResponse;\nimport io.netty.handler.codec.http.DefaultHttpResponse;\nimport io.netty.handler.codec.http.HttpResponseStatus;\nimport io.netty.handler.codec.http.HttpVersion;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.Response;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.io.IOException;\n\n/**\n * Class for testing TraceableHttpServerResponse.\n */\npublic class TraceableHttpServerResponseTest extends Assert {\n\n    private Response response;\n    private HttpResponse httpResponse;\n\n    @BeforeClass\n    public void setUp() throws IOException {\n        HttpCarbonMessage httpCarbonMessage =\n                new HttpCarbonMessage(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));\n        response = new Response(httpCarbonMessage);\n        response.setStatus(200);\n        httpResponse = new TraceableHttpServerResponse(response);\n    }\n\n    @Test\n    public void testGetStatusCode() {\n        assertEquals(httpResponse.getHttpStatusCode(), response.getStatusCode());\n    }\n\n}\n"
  },
  {
    "path": "analytics/zipkin-tracing/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\nhttp://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"MSF4J-Zipkin-Tracing-Test-Suite\">\n\n    <test name=\"Traceable-Request-Response-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.analytics.zipkintracing.TraceableHttpClientRequestTest\"/>\n            <class name=\"org.wso2.msf4j.analytics.zipkintracing.TraceableHttpClientResponseTest\"/>\n            <class name=\"org.wso2.msf4j.analytics.zipkintracing.TraceableHttpServerRequestTest\"/>\n            <class name=\"org.wso2.msf4j.analytics.zipkintracing.TraceableHttpServerResponseTest\"/>\n        </classes>\n    </test>\n\n</suite>"
  },
  {
    "path": "archetypes/README.md",
    "content": "#Creating a Microservice using the msf4j-microservice Maven archetype\n\nA Microservice based on WSO2 Microservices Framework for Java (MSF4J) can be created with single command \nusing this Maven archetype.\n\nHere is an example;\n\n```\nmvn archetype:generate -DarchetypeGroupId=org.wso2.msf4j -DarchetypeArtifactId=msf4j-microservice \n-DarchetypeVersion=2.6.2 -DgroupId=org.example -DartifactId=myservice -Dversion=1.0.0-SNAPSHOT \n-Dpackage=org.example.service\n\n```\n\nThe above command will create an MSF4J microservice project structure for you similar to the one shown below;\n\n```\nmyservice\n├── pom.xml\n└── src\n    └── main\n        └── java\n            └── org\n                └── example\n                    └── service\n                        ├── Application.java\n                        └── MyService.java\n```\n\n##Properties\n\nThe following table lists down the properties specific to the msf4j-microservice Maven archetype;\n\n\n| Property            | Description                     | Mandatory/Optional |\n| ------------------- | ------------------------------- | ------------------ |\n| archetypeGroupId    | The groupId of the archetype    | Mandatory          |\n| archetypeArtifactId | The artifactId of the archetype | Mandatory          |\n| archetypeVersion    | The version of the archetype    | Optional           |\n\n\nThe table below lists down the properties which are specific to the project you create.\n\n| Property        | Description                          | Default value               |\n| --------------- | ------------------------------------ | --------------------------- |\n| groupId         | The groupId of the project           | org.example                 |\n| artifactId      | The artifactId of the project        | msf4j-service               |\n| version         | The version of the project           | 1.0.0-SNAPSHOT              |\n| package         | The package hierarchy of the project | org.example.service         |\n| serviceClass    | The names of the microservice class  | org.example.service         |\n\nFor more information about Maven archetypes, see [http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html](http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html)\n"
  },
  {
    "path": "archetypes/msf4j-microservice/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>msf4j-microservice</artifactId>\n    <packaging>maven-archetype</packaging>\n    <name>WSO2 MSF4J - Microservice Archetype</name>\n    <description>This an archetype for WSO2 MSF4J microservice</description>\n\n    <build>\n        <resources>\n            <resource>\n                <directory>${project.basedir}/src/main/resources</directory>\n                <filtering>true</filtering>\n                <includes>\n                    <include>**/*</include>\n                </includes>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-resources-plugin</artifactId>\n                <configuration>\n                    <delimiters>\n                        <delimiter>^*^</delimiter>\n                    </delimiters>\n                    <useDefaultDelimiters>false</useDefaultDelimiters>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "archetypes/msf4j-microservice/src/main/resources/META-INF/maven/archetype-metadata.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<archetype-descriptor\n        xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0\n        http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd\"\n        name=\"msf4j-microservice\"\n        xmlns=\"http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0\"\n        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <fileSets>\n        <fileSet filtered=\"true\" packaged=\"true\" encoding=\"UTF-8\">\n            <directory>src/main/java</directory>\n            <includes>\n                <include>**/*.java</include>\n            </includes>\n        </fileSet>\n    </fileSets>\n\n    <requiredProperties>\n        <requiredProperty key=\"groupId\">\n            <defaultValue>org.example</defaultValue>\n        </requiredProperty>\n        <requiredProperty key=\"artifactId\">\n            <defaultValue>msf4j-service</defaultValue>\n        </requiredProperty>\n        <requiredProperty key=\"version\">\n            <defaultValue>1.0.0-SNAPSHOT</defaultValue>\n        </requiredProperty>\n        <requiredProperty key=\"package\">\n            <defaultValue>org.example.service</defaultValue>\n        </requiredProperty>\n        <requiredProperty key=\"serviceClass\">\n            <defaultValue>MyService</defaultValue>\n        </requiredProperty>\n    </requiredProperties>\n</archetype-descriptor>\n"
  },
  {
    "path": "archetypes/msf4j-microservice/src/main/resources/archetype-resources/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>^project.version^</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>${groupId}</groupId>\n    <artifactId>${artifactId}</artifactId>\n    <version>${version}</version>\n    <name>WSO2 MSF4J Microservice</name>\n\n\n    <dependencies>\n    <!-- Uncomment the following if you want to enable metrics & monitoring -->\n    <!--\n    <dependency>\n       <groupId>org.wso2.msf4j</groupId>\n       <artifactId>msf4j-analytics</artifactId>\n    </dependency>\n    -->\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>${package}.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "archetypes/msf4j-microservice/src/main/resources/archetype-resources/src/main/java/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage ${package};\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n *\n * @since ${version}\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new ${serviceClass}())\n                .start();\n    }\n}\n"
  },
  {
    "path": "archetypes/msf4j-microservice/src/main/resources/archetype-resources/src/main/java/__serviceClass__.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage ${package};\n\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.Path;\n\n/**\n * This is the Microservice resource class.\n * See <a href=\"https://github.com/wso2/msf4j#getting-started\">https://github.com/wso2/msf4j#getting-started</a>\n * for the usage of annotations.\n *\n * @since ${version}\n */\n@Path(\"/service\")\npublic class ${serviceClass} {\n\n    @GET\n    @Path(\"/\")\n    public String get() {\n        // TODO: Implementation for HTTP GET request\n        System.out.println(\"GET invoked\");\n        return \"Hello from WSO2 MSF4J\";\n    }\n\n    @POST\n    @Path(\"/\")\n    public void post() {\n        // TODO: Implementation for HTTP POST request\n        System.out.println(\"POST invoked\");\n    }\n\n    @PUT\n    @Path(\"/\")\n    public void put() {\n        // TODO: Implementation for HTTP PUT request\n        System.out.println(\"PUT invoked\");\n    }\n\n    @DELETE\n    @Path(\"/\")\n    public void delete() {\n        // TODO: Implementation for HTTP DELETE request\n        System.out.println(\"DELETE invoked\");\n    }\n}\n"
  },
  {
    "path": "client/README.md",
    "content": "# MSF4J Client\n\nMSF4J client which allow making HTTP calls to other microservices as well as external APIs."
  },
  {
    "path": "client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-client</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J client</name>\n    <description>WSO2 MSF4J client</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.wso2.msf4j</groupId>\n                    <artifactId>msf4j-core</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>\n                    <artifactId>httpclient</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-jackson</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.core</groupId>\n                    <artifactId>jackson-databind</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-hystrix</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpclient-osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpcore-osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-databind</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-annotations</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.zipkin.brave</groupId>\n            <artifactId>brave-spancollector-http</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.zipkin.brave</groupId>\n            <artifactId>brave-http</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>zipkin-tracing</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.utils</groupId>\n            <artifactId>org.wso2.carbon.utils</artifactId>\n        </dependency>\n\n        <!-- Test Dependencies-->\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <private.package>org.wso2.msf4j.internal.*</private.package>\n        <export.package>\n            !org.wso2.msf4j.client.internal.*,\n            org.wso2.msf4j.client.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            feign.*;version=\"${feign.version}\",\n            feign.gson.*;version=\"${feign.version}\",\n            com.google.gson.*;version=\"${gson.version.range}\",\n            com.google.common.*;version=\"${guava.version.range}\",\n            javax.annotation.*,\n            javax.ws.rs.*,\n            javax.xml.bind;resolution:=optional,\n            javax.xml.bind.annotation;resolution:=optional,\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.osgi.util.tracker; version=\"${osgi.service.tracker.import.version.range}\",\n            com.github.kristofa.brave.*;resolution:=optional,\n            org.wso2.msf4j.analytics.*;version=\"${msf4j.version}\";resolution:=optional,\n            org.slf4j.*;version=\"${slf4j.version.range}\";resolution:=optional,\n        </import.package>\n    </properties>\n</project>\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/ApacheHttpClient.java",
    "content": "/*\n *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client;\n\nimport feign.Client;\nimport feign.Request;\nimport feign.Response;\nimport feign.Util;\nimport org.apache.http.Header;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.NameValuePair;\nimport org.apache.http.StatusLine;\nimport org.apache.http.client.CookieStore;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.client.methods.HttpUriRequest;\nimport org.apache.http.client.methods.RequestBuilder;\nimport org.apache.http.client.protocol.HttpClientContext;\nimport org.apache.http.client.utils.URIBuilder;\nimport org.apache.http.client.utils.URLEncodedUtils;\nimport org.apache.http.entity.ByteArrayEntity;\nimport org.apache.http.entity.ContentType;\nimport org.apache.http.entity.StringEntity;\nimport org.apache.http.impl.client.BasicCookieStore;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.http.protocol.BasicHttpContext;\nimport org.apache.http.protocol.HttpContext;\nimport org.apache.http.util.EntityUtils;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.io.UnsupportedEncodingException;\nimport java.net.MalformedURLException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static feign.Util.UTF_8;\n\n/**\n * This module directs Feign's http requests to Apache's\n * <a href=\"https://hc.apache.org/httpcomponents-client-ga/\">HttpClient</a>. Ex.\n * <pre>\n * GitHub github = Feign.builder().client(new ApacheHttpClient()).target(GitHub.class,\n * \"https://api.github.com\");\n *\n * Based on Square, Inc's Retrofit ApacheClient implementation\n */\npublic final class ApacheHttpClient implements Client {\n    private static final String ACCEPT_HEADER_NAME = \"Accept\";\n    private final ThreadLocal<HttpContext> httpContextThreadLocal = new ThreadLocal<>();\n    private final HttpClient client;\n\n    public ApacheHttpClient() {\n        this(HttpClientBuilder.create().build());\n    }\n\n    public ApacheHttpClient(HttpClient client) {\n        this.client = client;\n    }\n\n    @Override\n    public Response execute(Request request, Request.Options options) throws IOException {\n        HttpUriRequest httpUriRequest;\n        HttpContext httpContext = httpContextThreadLocal.get();\n        if (httpContext == null) {\n            CookieStore cookieStore = new BasicCookieStore();\n            httpContext = new BasicHttpContext();\n            httpContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);\n            httpContextThreadLocal.set(httpContext);\n        }\n\n        try {\n            httpUriRequest = toHttpUriRequest(request, options);\n        } catch (URISyntaxException e) {\n            throw new IOException(\"URL '\" + request.url() + \"' couldn't be parsed into a URI\", e);\n        }\n        HttpResponse httpResponse = client.execute(httpUriRequest, httpContext);\n        return toFeignResponse(httpResponse).toBuilder().request(request).build();\n    }\n\n    HttpUriRequest toHttpUriRequest(Request request, Request.Options options) throws\n            UnsupportedEncodingException, MalformedURLException, URISyntaxException {\n        RequestBuilder requestBuilder = RequestBuilder.create(request.method());\n\n        //per request timeouts\n        RequestConfig requestConfig = RequestConfig\n                .custom()\n                .setConnectTimeout(options.connectTimeoutMillis())\n                .setSocketTimeout(options.readTimeoutMillis())\n                .build();\n        requestBuilder.setConfig(requestConfig);\n\n        URI uri = new URIBuilder(request.url()).build();\n\n        requestBuilder.setUri(uri.getScheme() + \"://\" + uri.getAuthority() + uri.getRawPath());\n\n        //request query params\n        List<NameValuePair> queryParams = URLEncodedUtils.parse(uri, requestBuilder.getCharset().name\n                ());\n        for (NameValuePair queryParam : queryParams) {\n            requestBuilder.addParameter(queryParam);\n        }\n\n        //request headers\n        boolean hasAcceptHeader = false;\n        for (Map.Entry<String, Collection<String>> headerEntry : request.headers().entrySet()) {\n            String headerName = headerEntry.getKey();\n            if (headerName.equalsIgnoreCase(ACCEPT_HEADER_NAME)) {\n                hasAcceptHeader = true;\n            }\n\n            if (headerName.equalsIgnoreCase(Util.CONTENT_LENGTH)) {\n                // The 'Content-Length' header is always set by the Apache client and it\n                // doesn't like us to set it as well.\n                continue;\n            }\n\n            for (String headerValue : headerEntry.getValue()) {\n                requestBuilder.addHeader(headerName, headerValue);\n            }\n        }\n        //some servers choke on the default accept string, so we'll set it to anything\n        if (!hasAcceptHeader) {\n            requestBuilder.addHeader(ACCEPT_HEADER_NAME, \"*/*\");\n        }\n\n        //request body\n        if (request.body() != null) {\n            HttpEntity entity = null;\n            if (request.charset() != null) {\n                ContentType contentType = getContentType(request);\n                String content = new String(request.body(), request.charset());\n                entity = new StringEntity(content, contentType);\n            } else {\n                entity = new ByteArrayEntity(request.body());\n            }\n\n            requestBuilder.setEntity(entity);\n        }\n\n        return requestBuilder.build();\n    }\n\n    private ContentType getContentType(Request request) {\n        ContentType contentType = ContentType.DEFAULT_TEXT;\n        for (Map.Entry<String, Collection<String>> entry : request.headers().entrySet()) {\n            if (entry.getKey().equalsIgnoreCase(\"Content-Type\")) {\n                Collection values = entry.getValue();\n                if (values != null && !values.isEmpty()) {\n                    contentType = ContentType.create(entry.getValue().iterator().next(), request.charset());\n                    break;\n                }\n            }\n        }\n        return contentType;\n    }\n\n    Response toFeignResponse(HttpResponse httpResponse) throws IOException {\n        StatusLine statusLine = httpResponse.getStatusLine();\n        int statusCode = statusLine.getStatusCode();\n\n        String reason = statusLine.getReasonPhrase();\n\n        Map<String, Collection<String>> headers = new HashMap<String, Collection<String>>();\n        for (Header header : httpResponse.getAllHeaders()) {\n            String name = header.getName();\n            String value = header.getValue();\n\n            Collection<String> headerValues = headers.get(name);\n            if (headerValues == null) {\n                headerValues = new ArrayList<String>();\n                headers.put(name, headerValues);\n            }\n            headerValues.add(value);\n        }\n\n        return Response.builder()\n                .status(statusCode)\n                .reason(reason)\n                .headers(headers)\n                .body(toFeignBody(httpResponse))\n                .build();\n    }\n\n    Response.Body toFeignBody(HttpResponse httpResponse) throws IOException {\n        final HttpEntity entity = httpResponse.getEntity();\n        if (entity == null) {\n            return null;\n        }\n        return new HttpEntityResponseBody(entity);\n    }\n\n    /**\n     * Implements {@link feign.Response.Body} which represents HTTP response body\n     */\n    private static class HttpEntityResponseBody implements Response.Body {\n        final HttpEntity entity;\n\n        HttpEntityResponseBody(HttpEntity entity) {\n            this.entity = entity;\n        }\n\n        @Override\n        public Integer length() {\n            return entity.getContentLength() >= 0 && entity.getContentLength() <= Integer.MAX_VALUE ?\n                    (int) entity.getContentLength() : null;\n        }\n\n        @Override\n        public boolean isRepeatable() {\n            return entity.isRepeatable();\n        }\n\n        @Override\n        public InputStream asInputStream() throws IOException {\n            return entity.getContent();\n        }\n\n        @Override\n        public Reader asReader() throws IOException {\n            return new InputStreamReader(asInputStream(), UTF_8);\n        }\n\n        @Override\n        public void close() throws IOException {\n            EntityUtils.consume(entity);\n        }\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/FeginZipkinTracingClient.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client;\n\nimport com.github.kristofa.brave.Brave;\nimport com.github.kristofa.brave.ClientRequestAdapter;\nimport com.github.kristofa.brave.ClientRequestInterceptor;\nimport com.github.kristofa.brave.ClientResponseAdapter;\nimport com.github.kristofa.brave.ClientResponseInterceptor;\nimport com.github.kristofa.brave.EmptySpanCollectorMetricsHandler;\nimport com.github.kristofa.brave.http.DefaultSpanNameProvider;\nimport com.github.kristofa.brave.http.HttpClientRequest;\nimport com.github.kristofa.brave.http.HttpClientRequestAdapter;\nimport com.github.kristofa.brave.http.HttpClientResponseAdapter;\nimport com.github.kristofa.brave.http.HttpResponse;\nimport com.github.kristofa.brave.http.HttpSpanCollector;\nimport feign.Client;\nimport feign.Request;\nimport feign.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\nimport org.wso2.msf4j.analytics.zipkintracing.TraceableHttpClientRequest;\nimport org.wso2.msf4j.analytics.zipkintracing.TraceableHttpClientResponse;\n\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *  Client for Zipkin Tracing.\n */\npublic class FeginZipkinTracingClient implements Client {\n    private static final Logger log = LoggerFactory.getLogger(FeignTracingClient.class);\n    private final Client clientDelegate;\n    private final ClientRequestInterceptor requestInterceptor;\n    private final ClientResponseInterceptor responseInterceptor;\n\n    /**\n     * Constructor of FeignTracingClient.\n     */\n    public FeginZipkinTracingClient(Client client, String instanceName) {\n        this(client, instanceName, TracingConstants.DEFAULT_ZIPKIN_URL);\n    }\n\n    /**\n     * Constructor of FeginZipkinTracingClient.\n     *\n     * @param client\n     * @param instanceName\n     * @param zipkinUrl URL of the receiver of DAS server.\n     */\n    public FeginZipkinTracingClient(Client client, String instanceName, String zipkinUrl) {\n        this.clientDelegate = client;\n        Brave.Builder builder = new Brave.Builder(instanceName);\n        builder.spanCollector(HttpSpanCollector.create(zipkinUrl, new EmptySpanCollectorMetricsHandler()));\n        Brave brave = builder.build();\n        requestInterceptor = brave.clientRequestInterceptor();\n        responseInterceptor = brave.clientResponseInterceptor();\n    }\n\n    @Override\n    public Response execute(Request request, Request.Options options) throws IOException {\n        Map<String, Collection<String>> traceHeaders = new HashMap<>();\n        traceHeaders.putAll(request.headers());\n        Request wrappedRequest =\n                Request.create(request.method(), request.url(), traceHeaders, request.body(), request.charset());\n        HttpClientRequest httpClientRequest = new TraceableHttpClientRequest(wrappedRequest);\n        ClientRequestAdapter adapter = new HttpClientRequestAdapter(httpClientRequest, new DefaultSpanNameProvider());\n        requestInterceptor.handle(adapter);\n\n        Response response = clientDelegate.execute(wrappedRequest, options);\n\n        HttpResponse httpResponse = new TraceableHttpClientResponse(response);\n        ClientResponseAdapter responseAdapter = new HttpClientResponseAdapter(httpResponse);\n        responseInterceptor.handle(responseAdapter);\n        return response;\n    }\n}\n\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/FeignClientWrapper.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client;\n\nimport feign.Client;\nimport feign.Request;\nimport feign.Response;\n\nimport java.io.IOException;\n\n/**\n * Wrapper for #Feign.Client\n */\npublic class FeignClientWrapper implements Client {\n\n    private final Client clientDelegate;\n\n    public FeignClientWrapper(Client client) {\n        this.clientDelegate = client;\n    }\n\n    @Override\n    public Response execute(Request request, Request.Options options) throws IOException {\n        return clientDelegate.execute(request, options);\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/FeignTracingClient.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client;\n\nimport feign.Client;\nimport feign.Request;\nimport feign.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.analytics.common.tracing.TraceEvent;\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\nimport org.wso2.msf4j.analytics.common.tracing.TracingEventTracker;\nimport org.wso2.msf4j.analytics.common.tracing.TracingUtil;\n\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Supports tracing capabilities with WSO2DAS\n */\nclass FeignTracingClient implements Client {\n    private static final Logger log = LoggerFactory.getLogger(FeignTracingClient.class);\n    private final String instanceId;\n    private final String instanceName;\n    private final String dasUrl;\n    private final Client clientDelegate;\n\n    /**\n     * Constructor of FeignTracingClient.\n     */\n    public FeignTracingClient(Client client, String instanceName) {\n        this(client, instanceName, TracingConstants.DAS_RECEIVER_URL);\n    }\n\n    /**\n     * Constructor of FeignTracingClient with custom SSL configuration\n     *\n     * @param dasReceiverUrl URL of the receiver of DAS server\n     */\n    public FeignTracingClient(Client client, String instanceName, String dasReceiverUrl) {\n        this.instanceName = instanceName;\n        this.dasUrl = dasReceiverUrl;\n        this.instanceId = TracingUtil.generateUniqueId();\n        this.clientDelegate = client;\n    }\n\n    @Override\n    public Response execute(Request request, Request.Options options) throws IOException {\n        TraceEvent clientStartTraceEvent = generateClientStartTraceEvent(request);\n        Request traceableRequest = tracePreRequest(request, clientStartTraceEvent);\n        Response response = clientDelegate.execute(traceableRequest, options);\n        tracePostRequest(response, clientStartTraceEvent);\n        return response;\n    }\n\n    private TraceEvent generateClientStartTraceEvent(Request request) {\n        long time = new Date().getTime();\n        String clientTraceId;\n        String traceOriginId;\n        String traceParentId = null;\n        TraceEvent parentEvent = TracingEventTracker.getTraceEvent();\n        if (parentEvent == null) {\n            traceOriginId = TracingUtil.generateUniqueId();\n            clientTraceId = traceOriginId;\n        } else {\n            traceOriginId = parentEvent.getOriginId();\n            clientTraceId = TracingUtil.generateUniqueId();\n            traceParentId = parentEvent.getTraceId();\n        }\n        TraceEvent clientStartTraceEvent = new TraceEvent(\n                TracingConstants.CLIENT_TRACE_START,\n                clientTraceId,\n                traceOriginId,\n                time\n        );\n        clientStartTraceEvent.setInstanceId(instanceId);\n        clientStartTraceEvent.setInstanceName(instanceName);\n        clientStartTraceEvent.setParentId(traceParentId);\n        clientStartTraceEvent.setHttpMethod(request.method());\n        clientStartTraceEvent.setUrl(request.url());\n        if (log.isDebugEnabled()) {\n            log.debug(\"clientStartTraceEvent: \" + ModelUtils.toString(clientStartTraceEvent));\n        }\n        return clientStartTraceEvent;\n    }\n\n    private Request tracePreRequest(Request request, TraceEvent traceEvent) {\n        // set tracing headers to HTTP request\n        Map<String, Collection<String>> traceHeaders = new HashMap<>();\n        traceHeaders.putAll(request.headers());\n        traceHeaders.put(TracingConstants.TRACE_ID_HEADER, Collections.singletonList(traceEvent.getTraceId()));\n        traceHeaders.put(TracingConstants.TRACE_ORIGIN_ID_HEADER, Collections.singletonList(traceEvent.getOriginId()));\n\n        // publish event to DAS\n        TracingUtil.pushToDAS(traceEvent, dasUrl);\n        return Request.create(request.method(), request.url(), traceHeaders, request.body(), request.charset());\n    }\n\n    /**\n     * Publish client request information to DAS after response is received\n     */\n    private void tracePostRequest(Response response, TraceEvent traceEvent) {\n        long time = new Date().getTime();\n        if (traceEvent != null) {\n            TraceEvent clientEndTraceEvent = new TraceEvent(\n                    TracingConstants.CLIENT_TRACE_END,\n                    traceEvent.getTraceId(),\n                    traceEvent.getOriginId(),\n                    time\n            );\n            clientEndTraceEvent.setStatusCode(response.status());\n            if (log.isDebugEnabled()) {\n                log.debug(\"ClientEndTraceEvent: \" + ModelUtils.toString(clientEndTraceEvent));\n            }\n            TracingUtil.pushToDAS(clientEndTraceEvent, dasUrl);\n        }\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/MSF4JClient.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client;\n\nimport feign.Client;\nimport feign.Feign;\nimport feign.RequestInterceptor;\nimport feign.codec.Decoder;\nimport feign.codec.Encoder;\nimport feign.codec.ErrorDecoder;\nimport feign.gson.GsonDecoder;\nimport feign.gson.GsonEncoder;\nimport feign.hystrix.FallbackFactory;\nimport feign.hystrix.HystrixFeign;\nimport org.apache.http.impl.client.CloseableHttpClient;\nimport org.apache.http.impl.client.HttpClients;\nimport org.apache.http.impl.conn.PoolingHttpClientConnectionManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.utils.StringUtils;\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\nimport org.wso2.msf4j.client.codec.DefaultErrorDecoder;\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.SSLContext;\n\n/**\n * MSF4J client.\n *\n * @param <T> REST service API interface\n */\npublic class MSF4JClient<T> {\n    private static final Logger log = LoggerFactory.getLogger(MSF4JClient.class);\n    private final T api;\n\n    public MSF4JClient(T api) {\n        this.api = api;\n    }\n\n    public T api() {\n        return api;\n    }\n\n    /**\n     * MSF4J client builder\n     *\n     * @param <T> API interface\n     */\n    public static class Builder<T> {\n\n        private final List<RequestInterceptor> requestInterceptors = new ArrayList<RequestInterceptor>();\n        private final Map<String, Class<? extends RestServiceException>> errorCodeExceptionMap = new HashMap<>();\n        private FallbackFactory<? extends T> fallbackFactory;\n        private boolean enableCircuitBreaker;\n        private boolean enableTracing;\n        private String instanceName;\n        private String analyticsEndpoint;\n        private String serviceEndpoint;\n        private SSLContext sslContext;\n        private HostnameVerifier hostnameVerifier;\n        private boolean decode404;\n        private Class<T> apiClass;\n        private ErrorDecoder errorDecoder = new DefaultErrorDecoder(errorCodeExceptionMap);\n        private Encoder encoder = new GsonEncoder(ModelUtils.GSON);\n        private Decoder decoder = new GsonDecoder(ModelUtils.GSON);\n        private TracingConstants.TracingType tracingType = TracingConstants.TracingType.DAS;\n\n        public Feign.Builder newFeignClientBuilder() {\n            return Feign.builder()\n                    .encoder(encoder)\n                    .decoder(decoder);\n        }\n\n        public HystrixFeign.Builder newHystrixFeignClientBuilder() {\n            return HystrixFeign.builder()\n                    .encoder(encoder)\n                    .decoder(decoder);\n        }\n\n        /**\n         * Adds a single request interceptor to the builder.\n         */\n        public MSF4JClient.Builder<T> requestInterceptor(RequestInterceptor requestInterceptor) {\n            this.requestInterceptors.add(requestInterceptor);\n            return this;\n        }\n\n        /**\n         * Sets the full set of request interceptors for the builder, overwriting any previous\n         * interceptors.\n         */\n        public MSF4JClient.Builder<T> requestInterceptors(Iterable<RequestInterceptor> requestInterceptors) {\n            this.requestInterceptors.clear();\n            for (RequestInterceptor requestInterceptor : requestInterceptors) {\n                this.requestInterceptors.add(requestInterceptor);\n            }\n            return this;\n        }\n\n        /**\n         * Sets the fallback factory for HystrixFeign client which supports circuit breaker\n         */\n        public MSF4JClient.Builder<T> fallbackFactory(FallbackFactory<? extends T> fallbackFactory) {\n            this.fallbackFactory = fallbackFactory;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> enableCircuitBreaker() {\n            this.enableCircuitBreaker = true;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> enableTracing() {\n            this.enableTracing = true;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> instanceName(String instanceName) {\n            this.instanceName = instanceName;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> analyticsEndpoint(String analyticsEndpoint) {\n            this.analyticsEndpoint = analyticsEndpoint;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> serviceEndpoint(String serviceEndpoint) {\n            this.serviceEndpoint = serviceEndpoint;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> apiClass(Class<T> apiClass) {\n            this.apiClass = apiClass;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> decode404(boolean decode404) {\n            this.decode404 = decode404;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> encoder(Encoder encoder) {\n            this.encoder = encoder;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> decoder(Decoder decoder) {\n            this.decoder = decoder;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> tracingType(TracingConstants.TracingType tracingType) {\n            this.tracingType = tracingType;\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> addErrorResponseMapper(RestErrorResponseMapper... responseMappers) {\n            Arrays.stream(responseMappers).forEach(rm -> {\n                Arrays.stream(rm.getClass().getMethods()).\n                        filter(method -> !StringUtils.isNullOrEmptyAfterTrim(rm.getExceptionKey())).\n                        findAny().\n                        ifPresent(method -> {\n                            if (errorCodeExceptionMap.containsKey(rm.getExceptionKey())) {\n                                log.warn(\"RestErrorResponseMapper has already been added for the given exception key \" +\n                                        \"'{}'\", rm.getExceptionKey());\n                            }\n                            errorCodeExceptionMap.put(rm.getExceptionKey(), rm.getExceptionClass());\n                        });\n            });\n            return this;\n        }\n\n        public MSF4JClient.Builder<T> errorDecoder(ErrorDecoder errorDecoder) {\n            this.errorDecoder = errorDecoder;\n            return this;\n        }\n\n        public HostnameVerifier getHostnameVerifier() {\n            return hostnameVerifier;\n        }\n\n        public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {\n            this.hostnameVerifier = hostnameVerifier;\n        }\n\n        public SSLContext getSslContext() {\n            return sslContext;\n        }\n\n        public void setSslContext(SSLContext sslContext) {\n            this.sslContext = sslContext;\n        }\n\n        public MSF4JClient<T> build() {\n            MSF4JClient<T> msf4JClient;\n            Client client;\n\n            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();\n            cm.setMaxTotal(200);\n            cm.setDefaultMaxPerRoute(20);\n\n            CloseableHttpClient apacheHttpClient = HttpClients.custom()\n                                                              .setSSLContext(sslContext)\n                                                              .setSSLHostnameVerifier(hostnameVerifier)\n                                                              .setConnectionManager(cm)\n                                                              .build();\n\n            if (enableTracing) {\n                if (tracingType == TracingConstants.TracingType.ZIPKIN) {\n                    client = new FeignClientWrapper(\n                            new FeginZipkinTracingClient(new ApacheHttpClient(apacheHttpClient), instanceName,\n                                                         analyticsEndpoint));\n                } else {\n                    client = new FeignClientWrapper(\n                            new FeignTracingClient(new ApacheHttpClient(apacheHttpClient), instanceName,\n                                                   analyticsEndpoint));\n                }\n            } else {\n                client = new FeignClientWrapper(new ApacheHttpClient(apacheHttpClient));\n            }\n\n            if (enableCircuitBreaker) {\n                HystrixFeign.Builder builder = newHystrixFeignClientBuilder();\n                builder.client(client);\n                builder.requestInterceptors(requestInterceptors);\n                builder.errorDecoder(errorDecoder);\n                if (decode404) {\n                    builder.decode404();\n                }\n                msf4JClient = new MSF4JClient<T>(builder.target(apiClass, serviceEndpoint, fallbackFactory));\n            } else {\n                Feign.Builder builder = newFeignClientBuilder();\n                builder.client(client);\n                builder.requestInterceptors(requestInterceptors);\n                builder.errorDecoder(errorDecoder);\n                if (decode404) {\n                    builder.decode404();\n                }\n                msf4JClient = new MSF4JClient<T>(builder.target(apiClass, serviceEndpoint));\n            }\n            return msf4JClient;\n        }\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/ModelUtils.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\n\n/**\n * Converts Object to gson\n */\npublic class ModelUtils {\n    public static final Gson GSON = new GsonBuilder().setPrettyPrinting()\n            .disableHtmlEscaping().create();\n\n    public static String toString(Object o) {\n        return GSON.toJson(o);\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/codec/DefaultErrorDecoder.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.codec;\n\nimport feign.Response;\nimport feign.codec.Decoder;\nimport feign.codec.ErrorDecoder;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\nimport java.io.IOException;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Feign error decoder which translates REST service error response to Java exception class\n * which inherits {@link RestServiceException}\n */\npublic class DefaultErrorDecoder implements ErrorDecoder {\n    private static final Logger log = LoggerFactory.getLogger(DefaultErrorDecoder.class);\n    private final Map<String, Class<? extends RestServiceException>> errorResponseMappers;\n    private Decoder decoder = new MSF4JJacksonDecoder();\n    private ErrorDecoder fallbackErrorDecoder = new ErrorDecoder.Default();\n\n    public DefaultErrorDecoder(Map<String, Class<? extends RestServiceException>> errorResponseMappers) {\n        this.errorResponseMappers = errorResponseMappers;\n    }\n\n    @Override\n    public Exception decode(String methodKey, Response response) {\n        try {\n            DefaultRestErrorResponse apiErrorResponse = (DefaultRestErrorResponse) decoder.decode(response,\n                    DefaultRestErrorResponse.class);\n            if (apiErrorResponse != null && errorResponseMappers.containsKey(apiErrorResponse.getErrorCode())) {\n                return getExceptionSupplierFromExceptionClass(\n                        errorResponseMappers.get(apiErrorResponse.getErrorCode()), apiErrorResponse.getMessage());\n            }\n        } catch (IOException e) {\n            log.error(\"Error decoding error response\", e);\n        } catch (Exception e) {\n            log.error(\"Error instantiating the exception mapped for the REST service error response '{}'\",\n                    response, e);\n        }\n        return fallbackErrorDecoder.decode(methodKey, response);\n    }\n\n    private RestServiceException getExceptionSupplierFromExceptionClass(Class<? extends RestServiceException> clazz,\n                                                                        String message)\n            throws IllegalAccessException, InvocationTargetException, InstantiationException {\n        List<Object> supportedArguments = Collections.singletonList(message);\n        for (Constructor<?> constructor : clazz.getConstructors()) {\n            Class<?>[] parameters = constructor.getParameterTypes();\n            List<Object> arguments = new ArrayList<>();\n            for (Class<?> parameter : parameters) {\n                supportedArguments\n                        .stream()\n                        .filter(argumentInstance -> parameter.isAssignableFrom(argumentInstance.getClass()))\n                        .findFirst()\n                        .ifPresent(arguments::add);\n            }\n            if (arguments.size() == parameters.length) {\n                return (RestServiceException) constructor.newInstance(arguments.toArray(new Object[0]));\n            }\n        }\n        log.warn(\"Could not instantiate the exception '{}'\", clazz.getName());\n        return null;\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/codec/DefaultRestErrorResponse.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.codec;\n\nimport org.wso2.msf4j.client.ModelUtils;\n\n/**\n * Represents a REST service error response. A service response is considered an error response when response HTTP\n * status code is not within 2xx range.\n */\npublic class DefaultRestErrorResponse {\n    private String errorCode;\n    private String message;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public DefaultRestErrorResponse() {\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n\n    public String getErrorCode() {\n        return errorCode;\n    }\n\n    public void setErrorCode(String errorCode) {\n        this.errorCode = errorCode;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/codec/MSF4JDecoder.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.codec;\n\nimport feign.FeignException;\nimport feign.Response;\nimport feign.codec.Decoder;\nimport feign.codec.StringDecoder;\nimport feign.gson.GsonDecoder;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.Collection;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Decoder for fegin client.\n */\npublic class MSF4JDecoder implements Decoder {\n\n    private GsonDecoder gsonDecoder = new GsonDecoder();\n    private StringDecoder stringDecoder = new StringDecoder();\n    private static final String CONTENT_TYPE = \"Content-Type\";\n\n    @Override\n    public Object decode(Response response, Type type) throws IOException, FeignException {\n        Collection<String> contentTypeHeaders = response.headers().get(CONTENT_TYPE);\n        String responseContentType =\n                contentTypeHeaders != null ? contentTypeHeaders.iterator().next() : MediaType.TEXT_PLAIN;\n\n        if (responseContentType.equals(MediaType.APPLICATION_JSON)) {\n            return gsonDecoder.decode(response, type);\n        } else if (responseContentType.equals(MediaType.TEXT_PLAIN) || responseContentType.equals(MediaType.WILDCARD)) {\n            return stringDecoder.decode(response, type);\n        }\n        throw new RuntimeException(\"Unsupported Content Type \" + responseContentType);\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/codec/MSF4JJacksonDecoder.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.codec;\n\nimport com.fasterxml.jackson.databind.DeserializationFeature;\nimport com.fasterxml.jackson.databind.Module;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.RuntimeJsonMappingException;\nimport feign.FeignException;\nimport feign.Response;\nimport feign.jackson.JacksonDecoder;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.Reader;\nimport java.lang.reflect.Type;\nimport java.util.Collections;\n\n/**\n * Decoder class for decoding error response which also handles error responses with 404 HTTP status code\n */\npublic class MSF4JJacksonDecoder extends JacksonDecoder {\n\n    private final ObjectMapper mapper;\n\n    public MSF4JJacksonDecoder() {\n        this(Collections.<Module>emptyList());\n    }\n\n    public MSF4JJacksonDecoder(Iterable<Module> modules) {\n        this(new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)\n                .registerModules(modules));\n    }\n\n    public MSF4JJacksonDecoder(ObjectMapper mapper) {\n        this.mapper = mapper;\n    }\n\n    @Override\n    public Object decode(Response response, Type type) throws IOException, FeignException {\n        if (response.body() == null) {\n            return null;\n        }\n        Reader reader = response.body().asReader();\n        if (!reader.markSupported()) {\n            reader = new BufferedReader(reader, 1);\n        }\n        try {\n            // Read the first byte to see if we have any data\n            reader.mark(1);\n            if (reader.read() == -1) {\n                return null; // Eagerly returning null avoids \"No content to map due to end-of-input\"\n            }\n            reader.reset();\n            return mapper.readValue(reader, mapper.constructType(type));\n        } catch (RuntimeJsonMappingException e) {\n            Throwable cause = e.getCause();\n            if (cause != null && cause instanceof IOException) {\n                throw IOException.class.cast(cause);\n            }\n            throw e;\n        }\n    }\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/codec/RestErrorResponseMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.codec;\n\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\n/**\n * Interface for returning the key of type {@link String} from REST service error response to instantiate the\n * corresponding interface\n *\n * @param <T> A Class representing the {@link Exception} which extends {@link RestServiceException} to be thrown for\n *           the given key\n */\npublic abstract class RestErrorResponseMapper<T extends RestServiceException> {\n    public abstract String getExceptionKey();\n\n    public abstract Class<T> getExceptionClass();\n}\n"
  },
  {
    "path": "client/src/main/java/org/wso2/msf4j/client/exception/RestServiceException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.client.exception;\n\n/**\n * Base exception class for REST service error responses\n */\npublic class RestServiceException extends Exception {\n\n    // Always throw the exception HTTP REST service error response\n    public RestServiceException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/ClientTest.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test;\n\nimport com.fasterxml.jackson.annotation.JsonTypeInfo;\nimport com.google.gson.Gson;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.IOUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\nimport org.wso2.msf4j.client.exception.RestServiceException;\nimport org.wso2.msf4j.client.test.client.exception.InvoiceNotFoundResponseMapper;\nimport org.wso2.msf4j.client.test.client.exception.InvoiceNotFoundRestServiceException;\nimport org.wso2.msf4j.client.test.exception.CustomerNotFoundMapper;\nimport org.wso2.msf4j.client.test.exception.InvoiceNotFoundMapper;\nimport org.wso2.msf4j.client.test.service.CustomerService;\nimport org.wso2.msf4j.client.test.service.InvoiceService;\nimport org.wso2.msf4j.client.test.service.ReportService;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport javax.ws.rs.HttpMethod;\n\npublic class ClientTest {\n    private static final String HEADER_VAL_CLOSE = \"CLOSE\";\n    private static final String HOSTNAME = \"localhost\";\n    private static final int PORT = 8090;\n    private MicroservicesRunner microservicesRunner1;\n    private MicroservicesRunner microservicesRunner2;\n    private MicroservicesRunner microservicesRunner3;\n    private URI baseURI;\n\n    public static void main(String[] args) {\n        MicroservicesRunner microservicesRunner2 = new MicroservicesRunner(8089);\n        microservicesRunner2.addExceptionMapper(new InvoiceNotFoundMapper())\n                            .deploy(new InvoiceService()).start();\n        MicroservicesRunner microservicesRunner1 = new MicroservicesRunner(8088);\n        microservicesRunner1.addExceptionMapper(new CustomerNotFoundMapper())\n                            .deploy(new CustomerService()).start();\n\n\n        MicroservicesRunner microservicesRunner3 = new MicroservicesRunner(PORT);\n        microservicesRunner3.addExceptionMapper(new CustomerNotFoundMapper(), new InvoiceNotFoundMapper())\n                            .deploy(new ReportService()).start();\n    }\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"http://%s:%d\", HOSTNAME, PORT));\n        microservicesRunner1 = new MicroservicesRunner(8088);\n        microservicesRunner1.addExceptionMapper(new CustomerNotFoundMapper())\n                            .deploy(new CustomerService()).start();\n\n        microservicesRunner2 = new MicroservicesRunner(8089);\n        microservicesRunner2.addExceptionMapper(new InvoiceNotFoundMapper())\n                            .deploy(new InvoiceService()).start();\n\n        microservicesRunner3 = new MicroservicesRunner(PORT);\n        microservicesRunner3.addExceptionMapper(new CustomerNotFoundMapper(), new InvoiceNotFoundMapper())\n                            .deploy(new ReportService()).start();\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner1.stop();\n        microservicesRunner2.stop();\n        microservicesRunner3.stop();\n    }\n\n    @Test\n    public void testClient() throws Exception {\n        HttpURLConnection urlConn = request(\"/report/invoice/I001\", HttpMethod.GET, false);\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        Assert.assertEquals(response,\n                            \"{\\\"id\\\":\\\"I001\\\",\\\"customer\\\":{\\\"id\\\":\\\"C001\\\",\\\"firstName\\\":\\\"WSO2\\\",\\\"lastName\\\":\" +\n                            \"\\\"Inc\\\",\\\"address\\\":\\\"Colombo\\\"},\\\"amount\\\":250.15}\");\n\n        urlConn = request(\"/report/invoice/I002\", HttpMethod.GET, false);\n        int responseCode = urlConn.getResponseCode();\n        Assert.assertEquals(responseCode, 404);\n        inputStream = urlConn.getErrorStream();\n        response = StreamUtil.asString(inputStream);\n        Gson gson = new Gson();\n        InvoiceNotFoundResponseMapper invoiceNotFoundResponseMapper =\n                gson.fromJson(response, InvoiceNotFoundResponseMapper.class);\n        IOUtils.closeQuietly(inputStream);\n        Assert.assertEquals(invoiceNotFoundResponseMapper.getExceptionKey(), \"30002\");\n        Assert.assertEquals(invoiceNotFoundResponseMapper.getExceptionClass(),\n                            InvoiceNotFoundRestServiceException.class);\n        urlConn.disconnect();\n    }\n\n    protected HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/ModelUtils.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\n\n/**\n * Converts Object to gson\n */\npublic class ModelUtils {\n    public static final Gson GSON = new GsonBuilder().setPrettyPrinting()\n            .disableHtmlEscaping().create();\n\n    public static String toString(Object o) {\n        return GSON.toJson(o);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/api/CustomerServiceAPI.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.client.test.client.api;\n\nimport feign.Param;\nimport feign.RequestLine;\nimport org.wso2.msf4j.client.exception.RestServiceException;\nimport org.wso2.msf4j.client.test.client.exception.CustomerNotFoundRestServiceException;\nimport org.wso2.msf4j.client.test.model.Customer;\n\npublic interface CustomerServiceAPI {\n    // Customer service\n    @RequestLine(\"GET /customer/{id}\")\n    Customer getCustomer(@Param(\"id\") String id) throws CustomerNotFoundRestServiceException, RestServiceException;\n}"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/api/InvoiceServiceAPI.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport feign.Param;\nimport feign.RequestLine;\nimport org.wso2.msf4j.client.test.client.exception.InvoiceNotFoundRestServiceException;\nimport org.wso2.msf4j.client.test.model.Invoice;\n\npublic interface InvoiceServiceAPI {\n    // Invoice service\n    @RequestLine(\"GET /invoice/{id}\")\n    Invoice getInvoice(@Param(\"id\") String id) throws InvoiceNotFoundRestServiceException;\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/exception/CustomerNotFoundResponseMapper.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.client.exception;\n\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\n\n/**\n * RestErrorResponseMapper which maps REST service response error to CustomerNotFoundRestServiceException\n */\npublic class CustomerNotFoundResponseMapper extends RestErrorResponseMapper<CustomerNotFoundRestServiceException> {\n\n    public static final String ERROR_CODE = \"30001\";\n\n    @Override\n    public String getExceptionKey() {\n        return ERROR_CODE;\n    }\n\n    @Override\n    public Class<CustomerNotFoundRestServiceException> getExceptionClass() {\n        return CustomerNotFoundRestServiceException.class;\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/exception/CustomerNotFoundRestServiceException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.client.exception;\n\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\npublic class CustomerNotFoundRestServiceException extends RestServiceException {\n\n    public CustomerNotFoundRestServiceException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/exception/InvoiceNotFoundResponseMapper.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.client.exception;\n\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\n\n/**\n * RestErrorResponseMapper which maps REST service response error to CustomerNotFoundRestServiceException\n */\npublic class InvoiceNotFoundResponseMapper extends RestErrorResponseMapper<InvoiceNotFoundRestServiceException> {\n    public static final String ERROR_CODE = \"30002\";\n\n    @Override\n    public String getExceptionKey() {\n        return ERROR_CODE;\n    }\n\n    @Override\n    public Class<InvoiceNotFoundRestServiceException> getExceptionClass() {\n        return InvoiceNotFoundRestServiceException.class;\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/client/exception/InvoiceNotFoundRestServiceException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.client.exception;\n\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\npublic class InvoiceNotFoundRestServiceException extends RestServiceException {\n\n    public InvoiceNotFoundRestServiceException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/CustomerNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\n/**\n * Thrown when a Customer record is not found.\n */\npublic class CustomerNotFoundException extends EntityNotFoundException {\n    public CustomerNotFoundException() {\n        super();\n    }\n\n    public CustomerNotFoundException(String message) {\n        super(message);\n    }\n\n    public CustomerNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public CustomerNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected CustomerNotFoundException(String message, Throwable cause,\n                                        boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/CustomerNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\nimport org.wso2.msf4j.client.test.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handles CustomerNotFoundException.\n */\npublic class CustomerNotFoundMapper implements ExceptionMapper<CustomerNotFoundException> {\n\n    private static final String ERROR_CODE = \"30001\";\n\n    public Response toResponse(CustomerNotFoundException ex) {\n        return Response.status(404)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/EntityNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\n/**\n * EntityNotFoundException.\n */\npublic class EntityNotFoundException extends Exception {\n    public EntityNotFoundException() {\n        super();\n    }\n\n    public EntityNotFoundException(String message) {\n        super(message);\n    }\n\n    public EntityNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public EntityNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected EntityNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/EntityNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * EntityNotFoundMapper.\n */\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/GenericServerErrorException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.exception;\n\n/**\n * Thrown when a generic exception occurs while handling a micro service request\n */\npublic class GenericServerErrorException extends Exception {\n    public GenericServerErrorException() {\n        super();\n    }\n\n    public GenericServerErrorException(String message) {\n        super(message);\n    }\n\n    public GenericServerErrorException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public GenericServerErrorException(Throwable cause) {\n        super(cause);\n    }\n\n    protected GenericServerErrorException(String message, Throwable cause,\n                                          boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/GenericServerErrorMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\nimport org.wso2.msf4j.client.test.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handled GenericServerErrorException.\n */\npublic class GenericServerErrorMapper implements ExceptionMapper<GenericServerErrorException> {\n\n    private static final String ERROR_CODE = \"10000\";\n\n    @Override\n    public Response toResponse(GenericServerErrorException ex) {\n        return Response.status(500)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/InvoiceNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\n/**\n * Thrown when a Invoice record is not found.\n */\npublic class InvoiceNotFoundException extends EntityNotFoundException {\n    public InvoiceNotFoundException() {\n        super();\n    }\n\n    public InvoiceNotFoundException(String message) {\n        super(message);\n    }\n\n    public InvoiceNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public InvoiceNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected InvoiceNotFoundException(String message, Throwable cause,\n                                       boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/exception/InvoiceNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.client.test.exception;\n\nimport org.wso2.msf4j.client.test.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handles InvoiceNotFoundException.\n */\npublic class InvoiceNotFoundMapper implements ExceptionMapper<InvoiceNotFoundException> {\n\n    private static final String ERROR_CODE = \"30002\";\n\n    public Response toResponse(InvoiceNotFoundException ex) {\n        return Response.status(404)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/model/Customer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.client.test.model;\n\nimport org.wso2.msf4j.client.test.ModelUtils;\n\n/**\n * Represents a Customer item\n */\n@SuppressWarnings(\"unused\")\npublic class Customer {\n\n    private String id;\n    private String firstName;\n    private String lastName;\n    private String address;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public Customer() {\n    }\n\n    public Customer(String id, String firstName, String lastName, String address) {\n        this.id = id;\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.address = address;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getAddress() {\n        return address;\n    }\n\n    public void setAddress(String address) {\n        this.address = address;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/model/Invoice.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.client.test.model;\n\n\nimport org.wso2.msf4j.client.test.ModelUtils;\n\nimport java.util.Date;\n\n/**\n * Represents an Invoice item\n */\n@SuppressWarnings(\"unused\")\npublic class Invoice {\n\n    private String id;\n    private String customerId;\n    private double amount;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public Invoice() {\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public Invoice(String id, String customerId, double amount) {\n        this.id = id;\n        this.customerId = customerId;\n        this.amount = amount;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getCustomerId() {\n        return customerId;\n    }\n\n    public void setCustomerId(String customerId) {\n        this.customerId = customerId;\n    }\n\n    public double getAmount() {\n        return amount;\n    }\n\n    public void setAmount(double amount) {\n        this.amount = amount;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/model/InvoiceReport.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.client.test.model;\n\nimport org.wso2.msf4j.client.test.ModelUtils;\n\nimport java.util.Date;\n\n/**\n * Represents an Invoice Report item.\n */\n@SuppressWarnings(\"unused\")\npublic class InvoiceReport {\n\n    private String id;\n    private Customer customer;\n    private double amount;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public InvoiceReport() {\n    }\n\n    public InvoiceReport(Invoice invoice, Customer customer) {\n        this.id = invoice.getId();\n        this.customer = customer;\n        this.amount = invoice.getAmount();\n    }\n\n    public InvoiceReport(String id, Customer customer, double amount, Date date) {\n        this.id = id;\n        this.customer = customer;\n        this.amount = amount;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public Customer getCustomer() {\n        return customer;\n    }\n\n    public void setCustomer(Customer customer) {\n        this.customer = customer;\n    }\n\n    public double getAmount() {\n        return amount;\n    }\n\n    public void setAmount(double amount) {\n        this.amount = amount;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/model/ServiceErrorResponse.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.client.test.model;\n\nimport org.wso2.msf4j.client.test.ModelUtils;\n\n/**\n * Represents error response body to be sent back to the client\n */\npublic class ServiceErrorResponse {\n    private String errorCode;\n    private String message;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public ServiceErrorResponse() {\n    }\n\n    public ServiceErrorResponse(String errorCode, String message) {\n        this.errorCode = errorCode;\n        this.message = message;\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n\n    public String getErrorCode() {\n        return errorCode;\n    }\n\n    public void setErrorCode(String errorCode) {\n        this.errorCode = errorCode;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/service/CustomerService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.client.test.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.client.test.model.Customer;\nimport org.wso2.msf4j.client.test.exception.CustomerNotFoundException;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * CustomerService resource class.\n */\n@Path(\"/customer\")\npublic class CustomerService {\n\n    private static final Logger log = LoggerFactory.getLogger(CustomerService.class);\n    private Map<String, Customer> customerMap = new HashMap<>();\n\n    public CustomerService() {\n        customerMap.put(\"C001\", new Customer(\"C001\", \"WSO2\", \"Inc\", \"Colombo\"));\n    }\n\n    /**\n     * Retrieves a customer record for a given customer ID.\n     * http://localhost:8080/customer/C001\n     *\n     * @param id Customer ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/{id}\")\n    @Produces({\"application/json\"})\n    public Response getCustomer(@PathParam(\"id\") String id) throws CustomerNotFoundException {\n        Customer customer = customerMap.get(id);\n        if (customer == null) {\n            log.info(\"Request for non-existing customer: \" + id);\n            throw new CustomerNotFoundException(\"Customer ID \" + id + \" not found\");\n        }\n        return Response.status(Response.Status.OK).entity(customer).build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/service/InvoiceService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.client.test.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.client.test.exception.InvoiceNotFoundException;\nimport org.wso2.msf4j.client.test.model.Invoice;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * CustomerService resource class.\n */\n@Path(\"/invoice\")\npublic class InvoiceService {\n\n    private static final Logger log = LoggerFactory.getLogger(InvoiceService.class);\n    private Map<String, Invoice> invoiceMap = new HashMap<>();\n\n    public InvoiceService() {\n        invoiceMap.put(\"I001\", new Invoice(\"I001\", \"C001\", 250.15));\n    }\n\n    /**\n     * Retrieves an invoice record for a given invoice ID.\n     * http://localhost:8080/invoice/I001\n     *\n     * @param id Invoice ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/{id}\")\n    @Produces({\"application/json\"})\n    public Response getCustomer(@PathParam(\"id\") String id) throws InvoiceNotFoundException {\n        Invoice invoice = invoiceMap.get(id);\n        if (invoice == null) {\n            log.info(\"Request for non-existing invoice: \" + id);\n            throw new InvoiceNotFoundException(\"Invoice ID \" + id + \" not found\");\n        }\n        return Response.status(Response.Status.OK).entity(invoice).build();\n    }\n}\n"
  },
  {
    "path": "client/test/java/org/wso2/msf4j/client/test/service/ReportService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.client.test.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.client.MSF4JClient;\nimport org.wso2.msf4j.client.test.client.api.CustomerServiceAPI;\nimport org.wso2.msf4j.client.test.client.api.InvoiceServiceAPI;\nimport org.wso2.msf4j.client.test.client.exception.CustomerNotFoundRestServiceException;\nimport org.wso2.msf4j.client.test.client.exception.InvoiceNotFoundRestServiceException;\nimport org.wso2.msf4j.client.test.exception.InvoiceNotFoundException;\nimport org.wso2.msf4j.client.test.model.Customer;\nimport org.wso2.msf4j.client.test.client.exception.CustomerNotFoundResponseMapper;\nimport org.wso2.msf4j.client.test.client.exception.InvoiceNotFoundResponseMapper;\nimport org.wso2.msf4j.client.test.exception.CustomerNotFoundException;\nimport org.wso2.msf4j.client.test.exception.GenericServerErrorException;\nimport org.wso2.msf4j.client.test.model.Invoice;\nimport org.wso2.msf4j.client.test.model.InvoiceReport;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * ReportService resource class.\n */\n@Path(\"/report\")\npublic class ReportService {\n\n    private static final Logger log = LoggerFactory.getLogger(ReportService.class);\n    private static final String CUSTOMER_SERVICE_URL = \"http://localhost:8088\";\n    private static final String INVOICE_SERVICE_URL = \"http://localhost:8089\";\n    private final MSF4JClient<CustomerServiceAPI> customerServiceClient;\n    private final MSF4JClient<InvoiceServiceAPI> invoiceServiceClient;\n\n    public ReportService() {\n        customerServiceClient = new MSF4JClient.Builder<CustomerServiceAPI>()\n                .apiClass(CustomerServiceAPI.class)\n                .instanceName(\"CustomerServiceClient\")\n                .serviceEndpoint(CUSTOMER_SERVICE_URL)\n                .addErrorResponseMapper(new CustomerNotFoundResponseMapper())\n                .build();\n\n        invoiceServiceClient = new MSF4JClient.Builder<InvoiceServiceAPI>()\n                .apiClass(InvoiceServiceAPI.class)\n                .instanceName(\"InvoiceServiceClient\")\n                .serviceEndpoint(INVOICE_SERVICE_URL)\n               // .addErrorResponseMapper(new InvoiceNotFoundResponseMapper())\n                .build();\n    }\n\n    /**\n     * Retrieves the invoice report for a given invoice ID.\n     * http://localhost:8080/report/invoice/I001\n     *\n     * @param id Invoice ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/invoice/{id}\")\n    @Produces({\"application/json\"})\n    public Response getInvoiceReport(@PathParam(\"id\") String id) throws InvoiceNotFoundException,\n                                                                        CustomerNotFoundException, GenericServerErrorException {\n        InvoiceReport invoiceReport;\n        Invoice invoice;\n        try {\n            invoice = invoiceServiceClient.api().getInvoice(id);\n            if (log.isDebugEnabled()) {\n                log.info(\"Invoice retrieved: \" + invoice);\n            }\n        } catch (InvoiceNotFoundRestServiceException e) {\n            throw new InvoiceNotFoundException(e);\n        } catch (Exception e) {\n            log.error(\"Generic exception encountered\", e);\n            throw new GenericServerErrorException(\"Server Error: Something went wrong!\");\n        }\n\n        try {\n            String customerId = invoice.getCustomerId();\n            Customer customer = customerServiceClient.api().getCustomer(customerId);\n            if (log.isDebugEnabled()) {\n                log.debug(\"Customer retrieved: \" + customer);\n            }\n            invoiceReport = new InvoiceReport(invoice, customer);\n        } catch (CustomerNotFoundRestServiceException e) {\n            throw new CustomerNotFoundException(e);\n        } catch (Exception e) {\n            log.error(\"Generic exception encountered\", e);\n            throw new GenericServerErrorException(\"Server Error: Something went wrong!\");\n        }\n\n        return Response.status(Response.Status.OK).entity(invoiceReport).build();\n    }\n}\n"
  },
  {
    "path": "client/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"MSF4J_Client_Test-Suite\">\n    <test name=\"client-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.client.test.ClientTest\"/>\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "core/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "core/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-core</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J core</name>\n    <description>WSO2 MSF4J core</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.carbon.messaging</groupId>\n            <artifactId>org.wso2.carbon.messaging</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>wso2carbon-kernel</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.server.feature</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.osgi.feature</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.transport.http</groupId>\n            <artifactId>org.wso2.transport.http.netty</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.wso2.carbon.messaging</groupId>\n                    <artifactId>org.wso2.carbon.messaging</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.orbit.org.yaml</groupId>\n                    <artifactId>snakeyaml</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi.services</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>jaxrs-delegates</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-log4j12</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.findbugs</groupId>\n            <artifactId>jsr305</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicemix.bundles</groupId>\n            <artifactId>org.apache.servicemix.bundles.commons-beanutils</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.yaml</groupId>\n            <artifactId>snakeyaml</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.config</groupId>\n            <artifactId>org.wso2.carbon.config</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.annotation</groupId>\n            <artifactId>javax.annotation-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>commons-io.wso2</groupId>\n            <artifactId>commons-io</artifactId>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-core</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpmime</artifactId>\n            <version>4.5.1</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.maven.shared</groupId>\n            <artifactId>maven-invoker</artifactId>\n            <version>2.2</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>javax.websocket</groupId>\n            <artifactId>javax.websocket-api</artifactId>\n            <version>${javax.websocket.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                    <systemPropertyVariables>\n                        <maven.home>${maven.home}</maven.home>\n                        <project.filepath>${project.basedir}</project.filepath>\n                    </systemPropertyVariables>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-jar-plugin</artifactId>\n                <version>2.6</version>\n                <executions>\n                    <execution>\n                        <goals>\n                            <goal>test-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.wso2.carbon.config</groupId>\n                <artifactId>org.wso2.carbon.config.maven.plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <bundle.activator>org.wso2.msf4j.internal.MicroservicesServerActivator</bundle.activator>\n        <private.package>org.wso2.msf4j.internal.*</private.package>\n        <export.package>\n            !org.wso2.msf4j.internal.*,\n            !org.wso2.msf4j.delegates.*,\n            org.wso2.msf4j.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            org.wso2.msf4j.delegates.*;version=\"${msf4j.version.range}\",\n            org.apache.commons.io.*;version=\"${commons-io.version.range}\",\n            com.google.gson.*;version=\"${gson.version.range}\",\n            javax.annotation.*,\n            javax.ws.rs.*,\n            javax.websocket.*;version=\"${javax.websocket.version}\",\n            javax.xml.bind;resolution:=optional,\n            javax.xml.bind.annotation;resolution:=optional,\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            org.apache.commons.beanutils.*;version=\"${beanutils.version.range}\",\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.osgi.util.tracker; version=\"${osgi.service.tracker.import.version.range}\",\n            org.wso2.carbon.kernel.startupresolver.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.kernel.config.model.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.config.*;version=\"${carbon.config.package.import.version.range}\",\n            org.wso2.transport.*;version=\"${org.wso2.transport.http.version.range}\",\n            io.netty.*;version=\"${netty.version.range}\",\n            org.yaml.snakeyaml.*;version=\"${org.snakeyaml.version}\"\n        </import.package>\n        <carbon.component>\n            startup.listener;componentName=\"wso2-microservices-server\";requiredService=\"org.wso2.msf4j.Microservice,org.wso2.msf4j.Interceptor,\n            org.wso2.msf4j.interceptor.OSGiInterceptorConfig,org.wso2.carbon.config.provider.ConfigProvider\",\n            startup.listener;componentName=\"wso2-websocket-server\";requiredService=\"org.wso2.msf4j.WebSocketEndpoint\",\n            osgi.service;objectClass=\"org.wso2.msf4j.internal.MicroservicesServerSC\",\n            osgi.service;objectClass=\"org.wso2.msf4j.internal.websocket.WebSocketServerSC\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/AbstractSessionManager.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport org.wso2.msf4j.internal.session.SessionIdGenerator;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Abstract SessionManager implementation which leave the sessions persistence related method to be implemented.\n */\npublic abstract class AbstractSessionManager implements SessionManager {\n    private boolean isStopped;\n\n    /**\n     * The default maximum inactive interval, in minutes, for Sessions created by\n     * this Manager.\n     */\n    private static final int DEFAULT_MAX_INACTIVE_INTERVAL = 15;  // In minutes\n\n    /**\n     * Max number of sessions that can be active at a given time.\n     */\n    private static final int DEFAULT_MAX_ACTIVE_SESSIONS = 100_000;\n\n    /**\n     * The session id length of Sessions created by this Manager.\n     */\n    private static final int SESSION_ID_LENGTH = 16;\n\n    private Map<String, Session> sessions = new ConcurrentHashMap<>();\n    private SessionIdGenerator sessionIdGenerator = new SessionIdGenerator();\n\n    private ScheduledExecutorService sessionExpiryChecker;\n\n    public final void init() {\n        sessionIdGenerator.setSessionIdLength(SESSION_ID_LENGTH);\n        loadSessions(sessions);\n\n        // Session expiry scheduled task\n        sessionExpiryChecker = Executors.newScheduledThreadPool(1);\n        sessionExpiryChecker.scheduleAtFixedRate(() ->\n                        sessions.values().parallelStream()\n                                .filter(session ->\n                                        (System.currentTimeMillis() - session.getLastAccessedTime() >=\n                                                (long) session.getMaxInactiveInterval() * 60 * 1000))\n                                .forEach(Session::invalidate),\n                30, 30, TimeUnit.SECONDS);\n    }\n\n    public final Session getSession(String sessionId) {\n        checkValidity();\n        Session session = sessions.get(sessionId);\n        if (session == null) {\n            session = readSession(sessionId);\n        }\n        if (session != null) {\n            sessions.put(session.getId(), session);\n            session.setNew(false);\n        }\n        return session;\n    }\n\n    public final Session createSession() {\n        checkValidity();\n        if (sessions.size() >= DEFAULT_MAX_ACTIVE_SESSIONS) {\n            throw new IllegalStateException(\"Too many active sessions\");\n        }\n        Session session = new Session(sessionIdGenerator.generateSessionId(\"\"), DEFAULT_MAX_INACTIVE_INTERVAL);\n        session.setManager(this);\n        sessions.put(session.getId(), session);\n        saveSession(session);\n        return session;\n    }\n\n    public final void invalidateSession(Session session) {\n        checkValidity();\n        sessions.remove(session.getId());\n        deleteSession(session);\n    }\n\n    @Override\n    public final int getDefaultMaxInactiveInterval() {\n        return DEFAULT_MAX_INACTIVE_INTERVAL;\n    }\n\n    @Override\n    public final int getDefaultMaxActiveSessions() {\n        return DEFAULT_MAX_ACTIVE_SESSIONS;\n    }\n\n    @Override\n    public final int getSessionIdLength() {\n        return SESSION_ID_LENGTH;\n    }\n\n    @Override\n    public final void stop() {\n        sessionExpiryChecker.shutdown();\n        isStopped = true;\n    }\n\n    protected final void checkValidity() {\n        if (isStopped) {\n            throw new IllegalStateException(\"This SessionManager has been stopped\");\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/DefaultSessionManager.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport java.util.Map;\n\n/**\n * Default SessionManager to manage MSF4J transport sessions.\n */\npublic class DefaultSessionManager extends AbstractSessionManager {\n\n    @Override\n    public void loadSessions(Map<String, Session> sessions) {\n        checkValidity();\n        // Nothing to do because this is an in-memory implementation\n    }\n\n    @Override\n    public void saveSession(Session session) {\n        checkValidity();\n        // Nothing to do because this is an in-memory implementation\n    }\n\n    @Override\n    public Session readSession(String sessionId) {\n        checkValidity();\n        // Nothing to do because this is an in-memory implementation\n        return null;\n    }\n\n    @Override\n    public void deleteSession(Session session) {\n        checkValidity();\n        // Nothing to do because this is an in-memory implementation\n    }\n\n    @Override\n    public void updateSession(Session session) {\n        checkValidity();\n        // Nothing to do because this is an in-memory implementation\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/HttpStreamHandler.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport java.nio.ByteBuffer;\n\n/**\n * HttpHandler would extend this abstract class and implement methods to stream the body directly.\n * chunk method would receive the http-chunks of the body and finished would be called\n * on receipt of the last chunk.\n */\npublic interface HttpStreamHandler {\n\n    /**\n     * Initialize the stream handler.\n     *\n     * @param response response object that should be used to send response\n     */\n    void init(Response response);\n\n    /**\n     * Http request content will be streamed directly to this method.\n     *\n     * @param content content of chunks\n     * @throws  Exception if error occurs while invoking streaming handlers\n     */\n    void chunk(ByteBuffer content) throws Exception;\n\n    /**\n     * This method will be called when all chunks\n     * have been completely streamed.\n     *\n     * @throws Exception if error occurs while stopping streaming handlers\n     */\n    void end() throws Exception;\n\n    /**\n     * When there is exception on netty while streaming, it will be propagated to handler\n     * so the handler can do the cleanup.\n     *\n     * @param cause Cause of the Exception\n     */\n    void error(Throwable cause);\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/HttpStreamer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n/**\n * This class can be injected to a resource method\n * inorder to consume requests as streams.\n */\npublic class HttpStreamer {\n\n    private HttpStreamHandler httpStreamHandler;\n\n    /**\n     * Register a streaming callback to handle body chunks.\n     *\n     * @param httpStreamHandler handler object\n     */\n    public void callback(HttpStreamHandler httpStreamHandler) {\n        this.httpStreamHandler = httpStreamHandler;\n    }\n\n    public HttpStreamHandler getHttpStreamHandler() {\n        return httpStreamHandler;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/Interceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\nimport org.wso2.msf4j.internal.MSF4JConstants;\n\nimport java.lang.reflect.Method;\n\n/**\n * Interface that needs to be implemented to intercept handler method calls.\n *\n * @deprecated\n */\npublic interface Interceptor extends RequestInterceptor, ResponseInterceptor {\n\n    /**\n     * preCall is run before a handler method call is made. If any of the preCalls throw exception or return false then\n     * no other subsequent preCalls will be called and the request processing will be terminated,\n     * also no postCall interceptors will be called.\n     *\n     * @param request           HttpRequest being processed.\n     * @param responder         HttpResponder to send response.\n     * @param serviceMethodInfo Info on handler method that will be called.\n     * @return true if the request processing can continue, otherwise the hook should send response and return false to\n     * stop further processing.\n     * @throws Exception if error occurs while executing the preCall\n     * @deprecated\n     */\n    boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception;\n\n    /**\n     * postCall is run after a handler method call is made. If any of the postCalls throw and exception then the\n     * remaining postCalls will still be called. If the handler method was not called then postCall interceptors will\n     * not be called.\n     *\n     * @param request           HttpRequest being processed.\n     * @param status            Http status returned to the client.\n     * @param serviceMethodInfo Info on handler method that was called.\n     * @throws Exception if error occurs while executing the postCall\n     * @deprecated\n     */\n    void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception;\n\n    @Override\n    default boolean interceptRequest(Request request, Response response) throws Exception {\n        Method method = (Method) request.getProperty(MSF4JConstants.METHOD_PROPERTY_NAME);\n        ServiceMethodInfo serviceMethodInfo = new ServiceMethodInfo(method.getName(), method, request);\n        request.getProperties().forEach(serviceMethodInfo::setAttribute);\n        return preCall(request, response, serviceMethodInfo);\n    }\n\n    @Override\n    default boolean interceptResponse(Request request, Response response) throws Exception {\n        Method method = (Method) request.getProperty(MSF4JConstants.METHOD_PROPERTY_NAME);\n        ServiceMethodInfo serviceMethodInfo = new ServiceMethodInfo(method.getName(), method, request);\n        request.getProperties().forEach(serviceMethodInfo::setAttribute);\n        postCall(request, response.getStatusCode(), serviceMethodInfo);\n        return true;\n    }\n\n    /**\n     * As of according to the deprecated interceptors, the post call is void and there was no control given to the user\n     * to control the interceptor flow in the post call. True is returned to depict the same behaviour to ensure\n     * proper backward compatibility.\n     *\n     * @param request  MSF4J request.\n     * @param response MSF4J Response.\n     * @return should interception flow proceed?\n     */\n    @Override\n    default boolean onResponseInterceptionError(Request request, Response response, Exception e) {\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/Microservice.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n/**\n * Interface that needs to be implemented for handling HTTP methods.\n */\npublic interface Microservice {\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/MicroservicesRegistry.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * Interface that needs to be implemented for handle the registry.\n */\npublic interface MicroservicesRegistry {\n\n    /**\n     * Get the service object with given base path.\n     *\n     * @param path base path of the service\n     * @return service obj for the given base path or Optional null if no service found for given path.\n     */\n    Optional<Map.Entry<String, Object>> getServiceWithBasePath(String path);\n\n    /**\n     * Get all the available service.\n     *\n     * @return Set of all the available services\n     */\n    Set<Object> getHttpServices();\n\n    /**\n     * Register service instances.\n     *\n     * @param service instances\n     */\n    void addService(Object... service);\n\n    /**\n     * Register a service instance to given basepath. This will discard the class level Path annotation.\n     *\n     * @param basePath path string which services need to be registered.\n     * @param service instance.\n     */\n    void addService(String basePath, Object service);\n\n    /**\n     * Remove the given service instance.\n     *\n     * @param service instance to be remove.\n     */\n    void removeService(Object service);\n\n    /**\n     * Register SessionManager.\n     *\n     * @param sessionManager SessionManager instance.\n     */\n    void setSessionManager(SessionManager sessionManager);\n\n    /**\n     * Register request interceptors.\n     *\n     * @param requestInterceptor interceptor instances.\n     */\n    void addGlobalRequestInterceptor(RequestInterceptor... requestInterceptor);\n\n    /**\n     * Remove msf4j request interceptor.\n     *\n     * @param requestInterceptor MSF4J interceptor instance.\n     */\n    void removeGlobalRequestInterceptor(RequestInterceptor requestInterceptor);\n\n    /**\n     * Register response interceptors.\n     *\n     * @param responseInterceptors interceptor instances.\n     */\n    void addGlobalResponseInterceptor(ResponseInterceptor... responseInterceptors);\n\n    /**\n     * Remove msf4j response interceptor.\n     *\n     * @param responseInterceptor MSF4J interceptor instance.\n     */\n    void removeGlobalResponseInterceptor(ResponseInterceptor responseInterceptor);\n\n    /**\n     * Add msf4j global request and response interceptor.\n     *\n     * @param interceptor instance.\n     */\n    @Deprecated\n    void addInterceptor(Interceptor... interceptor);\n\n    /**\n     * Remove msf4j global request and response interceptor.\n     *\n     * @param interceptor instance.\n     */\n    @Deprecated\n    void removeInterceptor(Interceptor interceptor);\n\n    /**\n     * Register exception mappers.\n     *\n     * @param mapper ExceptionMapper instances.\n     */\n    void addExceptionMapper(ExceptionMapper... mapper);\n\n    /**\n     * Remove exception mapper.\n     *\n     * @param em ExceptionMapper instance.\n     */\n    void removeExceptionMapper(ExceptionMapper em);\n\n    /**\n     * Invoke post construct life cycle state for all the service.\n     */\n    void initServices();\n\n    /**\n     * Invoke post construct life cycle state for given service.\n     *\n     * @param httpService service instance\n     */\n    void initService(Object httpService);\n\n    /**\n     * Invoke predestroy life cycle state for all the service.\n     */\n    void preDestroyServices();\n\n    /**\n     * Invoke predestroy life cycle state for given service.\n     *\n     * @param httpService service instance\n     */\n    void preDestroyService(Object httpService);\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/MicroservicesRunner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.config.ConfigProviderFactory;\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\nimport org.wso2.msf4j.internal.DataHolder;\nimport org.wso2.msf4j.internal.HttpConnectorPortBindingListener;\nimport org.wso2.msf4j.internal.MSF4JConstants;\nimport org.wso2.msf4j.internal.MSF4JHttpConnectorListener;\nimport org.wso2.msf4j.internal.MSF4JWSConnectorListener;\nimport org.wso2.msf4j.internal.MicroservicesRegistryImpl;\nimport org.wso2.msf4j.internal.websocket.EndpointsRegistryImpl;\nimport org.wso2.msf4j.util.Utils;\nimport org.wso2.transport.http.netty.contract.Constants;\nimport org.wso2.transport.http.netty.contract.HttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.contract.ServerConnector;\nimport org.wso2.transport.http.netty.contract.ServerConnectorFuture;\nimport org.wso2.transport.http.netty.contract.config.ListenerConfiguration;\nimport org.wso2.transport.http.netty.contract.config.ServerBootstrapConfiguration;\nimport org.wso2.transport.http.netty.contract.config.TransportsConfiguration;\nimport org.wso2.transport.http.netty.contractimpl.DefaultHttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.contractimpl.common.Util;\nimport org.wso2.transport.http.netty.message.HttpConnectorUtil;\n\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.ws.rs.ext.ExceptionMapper;\n\nimport static org.wso2.msf4j.internal.MSF4JConstants.STREAMLINED_TRANSPORT_NAMESPACE;\n\n/**\n * This runner initializes the microservices runtime, deploys the microservices and service interceptors,\n * and starts the relevant transports.\n */\npublic class MicroservicesRunner {\n\n    private static final Logger log = LoggerFactory.getLogger(MicroservicesRunner.class);\n    /**\n     * Default host used when using microservice runner starts with {@link #MicroservicesRunner(int...)}.\n     */\n    private static final String DEFAULT_HOST = \"0.0.0.0\";\n    /**\n     * The environment variable which overrides the {@link #DEFAULT_HOST}.\n     */\n    private static final String MSF4J_HOST = \"msf4j.host\";\n    /**\n     * The environment variable which have netty transport configuration file path.\n     */\n    private static final String TRANSPORTS_NETTY_CONF = \"transports.netty.conf\";\n    protected List<ServerConnector> serverConnectors = new ArrayList<>();\n    private EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n    private MicroservicesRegistryImpl msRegistry = new MicroservicesRegistryImpl();\n    private long startTime = System.currentTimeMillis();\n    private boolean isStarted;\n\n    /**\n     * Creates a MicroservicesRunner instance which will be used for deploying microservices. Allows specifying\n     * ports on which the microservices in this MicroservicesRunner are deployed.\n     *\n     * @param ports The port on which the microservices are exposed\n     */\n    public MicroservicesRunner(int... ports) {\n        configureTransport(ports);\n    }\n\n    /**\n     * Default constructor which will take care of initializing Netty transports in the file pointed to by the\n     * System property <code>transports.netty.conf</code>.\n     * <p>\n     * If that System property is not specified, it will start a single Netty transport on port 8080.\n     * <p>\n     * {@link #MicroservicesRunner(int...)}\n     */\n    public MicroservicesRunner() {\n        configureTransport();\n    }\n\n    /**\n     * Creates a MicroservicesRunner instance which will be used for deploying microservices. Allows specifying\n     * transport configuration on which the microservices in this MicroservicesRunner are deployed.\n     *\n     * @param transportsConfiguration The transport configuration on which the microservices are exposed\n     */\n    public MicroservicesRunner(TransportsConfiguration transportsConfiguration) {\n        configureTransport(transportsConfiguration);\n    }\n\n    /**\n     * Deploy a microservice.\n     *\n     * @param microservice The microservice which is to be deployed\n     * @return this MicroservicesRunner object\n     */\n    public MicroservicesRunner deploy(Object... microservice) {\n        checkState();\n        msRegistry.addService(microservice);\n        return this;\n    }\n\n    /**\n     * Deploy a microservice with dynamic path.\n     *\n     * @param microservice The microservice which is to be deployed\n     * @param basePath     The context path for the service\n     * @return this MicroservicesRunner object\n     */\n    public MicroservicesRunner deploy(String basePath, Object microservice) {\n        msRegistry.addService(basePath, microservice);\n        return this;\n    }\n\n    /**\n     * Add WebSocket endpoint to the MicroserviceRunner\n     *\n     * @param webSocketEndpoint webSocketEndpoint endpoint which is to be added.\n     * @return this MicroservicesRunner object.\n     */\n    public MicroservicesRunner deployWebSocketEndpoint(Object webSocketEndpoint) {\n        endpointsRegistry.addEndpoint(webSocketEndpoint);\n        return this;\n    }\n\n    /**\n     * Register a custom {@link SessionManager}.\n     *\n     * @param sessionManager The SessionManager instance to be registered.\n     * @return this MicroservicesRunner object\n     */\n    public MicroservicesRunner setSessionManager(SessionManager sessionManager) {\n        msRegistry.setSessionManager(sessionManager);\n        return this;\n    }\n\n    /**\n     * Register request interceptors.\n     *\n     * @param requestInterceptor interceptor instances\n     */\n    public MicroservicesRunner addGlobalRequestInterceptor(RequestInterceptor... requestInterceptor) {\n        msRegistry.addGlobalRequestInterceptor(requestInterceptor);\n        return this;\n    }\n\n    /**\n     * Register response interceptors.\n     *\n     * @param responseInterceptor interceptor instances\n     */\n    public MicroservicesRunner addGlobalResponseInterceptor(ResponseInterceptor... responseInterceptor) {\n        msRegistry.addGlobalResponseInterceptor(responseInterceptor);\n        return this;\n    }\n\n    /**\n     * Add an interceptor which will get called before &amp; after the deployed microservices are invoked.\n     * Multiple interceptors can be added\n     *\n     * @param interceptor interceptor The interceptor to be added.\n     * @return this MicroservicesRunner object\n     * @deprecated\n     */\n    public MicroservicesRunner addInterceptor(Interceptor... interceptor) {\n        msRegistry.addGlobalRequestInterceptor(interceptor);\n        msRegistry.addGlobalResponseInterceptor(interceptor);\n        return this;\n    }\n\n    /**\n     * Add javax.ws.rs.ext.ExceptionMapper objects.\n     *\n     * @param exceptionMapper The ExceptionMapper to be added\n     * @return this MicroservicesRunner object\n     */\n    public MicroservicesRunner addExceptionMapper(ExceptionMapper... exceptionMapper) {\n        checkState();\n        msRegistry.addExceptionMapper(exceptionMapper);\n        return this;\n    }\n\n    /**\n     * Method to configure transports.\n     *\n     * @param ports The port on which the microservices are exposed\n     */\n    protected void configureTransport(int... ports) {\n        HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory();\n        ServerBootstrapConfiguration bootstrapConfiguration = new ServerBootstrapConfiguration(new HashMap<>());\n        for (int port : ports) {\n            ListenerConfiguration listenerConfiguration = new ListenerConfiguration(\"netty-\" + port, System\n                    .getProperty(MSF4J_HOST, DEFAULT_HOST), port);\n\n            DataHolder.getInstance().getMicroservicesRegistries()\n                    .put(Util.createServerConnectorID(listenerConfiguration.getHost(),\n                            listenerConfiguration.getPort()), msRegistry);\n            ServerConnector serverConnector =\n                    connectorFactory.createServerConnector(bootstrapConfiguration, listenerConfiguration);\n            serverConnectors.add(serverConnector);\n        }\n    }\n\n    /**\n     * Method to configure transports.\n     */\n    protected void configureTransport() {\n        String transportYaml = System.getProperty(TRANSPORTS_NETTY_CONF);\n        if (transportYaml == null || transportYaml.isEmpty()) {\n            HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory();\n            ServerBootstrapConfiguration bootstrapConfiguration = new ServerBootstrapConfiguration(new HashMap<>());\n            ListenerConfiguration listenerConfiguration = new ListenerConfiguration();\n            ServerConnector serverConnector =\n                    connectorFactory.createServerConnector(bootstrapConfiguration, listenerConfiguration);\n            DataHolder.getInstance().getMicroservicesRegistries()\n                    .put(Util.createServerConnectorID(listenerConfiguration.getHost(),\n                            listenerConfiguration.getPort()), msRegistry);\n            serverConnectors.add(serverConnector);\n        } else {\n            try {\n                ConfigProvider configProvider = ConfigProviderFactory.getConfigProvider(Paths.get(transportYaml), null);\n                TransportsConfiguration transportsConfiguration;\n                Object transportConf = configProvider.getConfigurationObject(STREAMLINED_TRANSPORT_NAMESPACE);\n                if (transportConf != null) {\n                    transportsConfiguration = Utils.resolveTransportsNSConfiguration(transportConf);\n                } else {\n                    transportsConfiguration = configProvider.getConfigurationObject\n                            (MSF4JConstants.WSO2_TRANSPORT_HTTP_CONFIG_NAMESPACE, TransportsConfiguration.class);\n                }\n\n                Map<String, Object> transportProperties = HttpConnectorUtil\n                        .getTransportProperties(transportsConfiguration);\n                int bossGroup = transportProperties.get(Constants.SERVER_BOOTSTRAP_BOSS_GROUP_SIZE) != null ? (Integer)\n                        transportProperties.get(Constants.SERVER_BOOTSTRAP_BOSS_GROUP_SIZE) : Runtime.getRuntime()\n                        .availableProcessors();\n                int workerGroup = transportProperties.get(Constants.SERVER_BOOTSTRAP_WORKER_GROUP_SIZE) != null ?\n                        (Integer) transportProperties.get(Constants.SERVER_BOOTSTRAP_WORKER_GROUP_SIZE) :\n                        Runtime.getRuntime().availableProcessors() * 2;\n                HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory(bossGroup, workerGroup,\n                        workerGroup);\n                ServerBootstrapConfiguration serverBootstrapConfiguration = HttpConnectorUtil\n                        .getServerBootstrapConfiguration(transportsConfiguration.getTransportProperties());\n\n                for (ListenerConfiguration listenerConfiguration :\n                        transportsConfiguration.getListenerConfigurations()) {\n                    ServerConnector serverConnector =\n                            connectorFactory.createServerConnector(serverBootstrapConfiguration, listenerConfiguration);\n                    DataHolder.getInstance().getMicroservicesRegistries()\n                            .put(Util.createServerConnectorID(listenerConfiguration.getHost(),\n                                    listenerConfiguration.getPort()), msRegistry);\n                    serverConnectors.add(serverConnector);\n                }\n            } catch (ConfigurationException e) {\n                throw new RuntimeException(\"Error loading yaml Configuration\", e);\n            }\n        }\n    }\n\n    /**\n     * Method to configure transports with external transport configuration\n     *\n     * @param transportsConfiguration the external transports configuration\n     */\n    protected void configureTransport(TransportsConfiguration transportsConfiguration) {\n        if (transportsConfiguration != null) {\n            Map<String, Object> transportProperties = HttpConnectorUtil.getTransportProperties(transportsConfiguration);\n            int bossGroup = transportProperties.get(Constants.SERVER_BOOTSTRAP_BOSS_GROUP_SIZE) != null ? (Integer)\n                    transportProperties.get(Constants.SERVER_BOOTSTRAP_BOSS_GROUP_SIZE) : Runtime.getRuntime()\n                    .availableProcessors();\n            int workerGroup = transportProperties.get(Constants.SERVER_BOOTSTRAP_WORKER_GROUP_SIZE) != null ? (Integer)\n                    transportProperties.get(Constants.SERVER_BOOTSTRAP_WORKER_GROUP_SIZE) : Runtime.getRuntime()\n                    .availableProcessors() * 2;\n            HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory(bossGroup, workerGroup,\n                    workerGroup);\n            ServerBootstrapConfiguration serverBootstrapConfiguration =\n                    HttpConnectorUtil.getServerBootstrapConfiguration(transportsConfiguration.getTransportProperties());\n            for (ListenerConfiguration listenerConfiguration : transportsConfiguration.getListenerConfigurations()) {\n                ServerConnector serverConnector =\n                        connectorFactory.createServerConnector(serverBootstrapConfiguration, listenerConfiguration);\n                DataHolder.getInstance().getMicroservicesRegistries()\n                        .put(Util.createServerConnectorID(listenerConfiguration.getHost(),\n                                listenerConfiguration.getPort()), msRegistry);\n                serverConnectors.add(serverConnector);\n            }\n        } else {\n            configureTransport();\n        }\n    }\n\n    private void checkState() {\n        if (isStarted) {\n            throw new IllegalStateException(\"Microservices runner already started\");\n        }\n    }\n\n    /**\n     * Start this Microservices runner. This will startup all the HTTP transports.\n     */\n    public void start() {\n        msRegistry.getSessionManager().init();\n        handleServiceLifecycleMethods();\n        MSF4JHttpConnectorListener msf4JHttpConnectorListener = new MSF4JHttpConnectorListener();\n        MSF4JWSConnectorListener msf4JWSConnectorListener = new MSF4JWSConnectorListener();\n        serverConnectors.forEach(serverConnector -> {\n            ServerConnectorFuture serverConnectorFuture = serverConnector.start();\n            serverConnectorFuture.setHttpConnectorListener(msf4JHttpConnectorListener);\n            serverConnectorFuture.setWebSocketConnectorListener(msf4JWSConnectorListener);\n            serverConnectorFuture.setPortBindingEventListener(new HttpConnectorPortBindingListener());\n            isStarted = true;\n            log.info(\"Microservices server started in \" + (System.currentTimeMillis() - startTime) + \"ms\");\n        });\n    }\n\n    /**\n     * Stop this Microservices runner. This will stop all the HTTP Transports.\n     */\n    public void stop() {\n        serverConnectors.forEach(ServerConnector::stop);\n        log.info(\"Microservices server stopped\");\n    }\n\n    /**\n     * Get the MicroservicesRegistry instance of this runner.\n     *\n     * @return MicroservicesRegistry instance of this runner\n     */\n    public MicroservicesRegistryImpl getMsRegistry() {\n        return msRegistry;\n    }\n\n    protected void handleServiceLifecycleMethods() {\n        msRegistry.initServices();\n        Runtime.getRuntime().addShutdownHook(new Thread() {\n            public void run() {\n                msRegistry.preDestroyServices();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/MicroservicesServer.java",
    "content": "/*\n *  Copyright (c) 2017 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport org.wso2.transport.http.netty.contract.config.ListenerConfiguration;\n\nimport java.util.Map;\n\n/**\n * Interface to handle server details of Microservices server. transport details etc.\n * <p>\n * This interface handles server details of microservices server in OSGi environment.\n *\n * @since 4.5.0\n */\npublic interface MicroservicesServer {\n\n    /**\n     * Provide Listener Configuration details with server connector id used in microservices server.\n     *\n     * @return ListenerConfigurationMap\n     */\n    Map<String, ListenerConfiguration> getListenerConfigurations();\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/PersistentSessionManager.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.nio.file.Paths;\nimport java.util.Arrays;\nimport java.util.Map;\n\n/**\n * This session manager persists sessions in the local file system.\n */\npublic class PersistentSessionManager extends AbstractSessionManager {\n    private static final Logger log = LoggerFactory.getLogger(PersistentSessionManager.class);\n    private static final String SESSION_DIR = \".sessions\";\n\n    public PersistentSessionManager() {\n        File dir = new File(SESSION_DIR);\n        if (!dir.exists() && !dir.mkdirs()) {\n            throw new IllegalStateException(\"Cannot create .tmp directory\");\n        }\n    }\n\n    @Override\n    public void loadSessions(Map<String, Session> sessions) {\n        File dir = new File(SESSION_DIR);\n        if (!dir.exists()) {\n            return;\n        }\n        String path = Paths.get(SESSION_DIR).toString();\n\n        Arrays.stream(new File(path).listFiles()).parallel().forEach(file -> {\n            Session session = readSession(file.getName());\n\n            // Delete expired session files\n            if (System.currentTimeMillis() - session.getLastAccessedTime() >=\n                    (long) session.getMaxInactiveInterval() * 60 * 1000 && !file.delete()) {\n                log.warn(\"Couldn't delete expired session file \" + file.getAbsolutePath());\n            } else {\n                sessions.put(session.getId(), session);\n            }\n        });\n    }\n\n    @Override\n    public Session readSession(String sessionId) {\n        String path = Paths.get(SESSION_DIR, sessionId).toString();\n        if (!new File(path).exists()) {\n            return null;\n        }\n        try (FileInputStream fis = new FileInputStream(path);\n             ObjectInputStream ois = new ObjectInputStream(fis);) {\n\n            Session session = (Session) ois.readObject();\n            session.setManager(this);\n            return session;\n        } catch (IOException | ClassNotFoundException e) {\n            throw new RuntimeException(\"Cannot read session \" + sessionId, e);\n        }\n    }\n\n    @Override\n    public void saveSession(Session session) {\n        try (FileOutputStream fout = new FileOutputStream(Paths.get(SESSION_DIR, session.getId()).toString());\n             ObjectOutputStream oos = new ObjectOutputStream(fout)) {\n            oos.writeObject(session);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Cannot save session \" + session.getId(), e);\n        }\n    }\n\n    @Override\n    public void deleteSession(Session session) {\n        String pathname = Paths.get(SESSION_DIR, session.getId()).toString();\n        if (!new File(pathname).delete()) {\n            throw new IllegalStateException(\"File \" + pathname + \" deletion failed\");\n        }\n    }\n\n    @Override\n    public void updateSession(Session session) {\n        saveSession(session);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/Request.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport io.netty.buffer.ByteBuf;\nimport org.wso2.msf4j.internal.HttpHeadersImpl;\nimport org.wso2.msf4j.internal.MSF4JConstants;\nimport org.wso2.transport.http.netty.contract.Constants;\nimport org.wso2.transport.http.netty.contract.HttpResponseFuture;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\nimport org.wso2.transport.http.netty.message.HttpMessageDataStreamer;\n\nimport java.io.InputStream;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport javax.ws.rs.core.HttpHeaders;\n\n/**\n * Class that represents an HTTP request in MSF4J level.\n */\npublic class Request {\n\n    private final HttpCarbonMessage httpCarbonMessage;\n    private List<String> acceptTypes = null;\n    private String contentType = null;\n    private SessionManager sessionManager;\n    private Session session;\n\n    public Request(HttpCarbonMessage httpCarbonMessage) {\n        this.httpCarbonMessage = httpCarbonMessage;\n        // find accept types\n        String acceptHeaderStr = httpCarbonMessage.getHeader(javax.ws.rs.core.HttpHeaders.ACCEPT);\n        acceptTypes = (acceptHeaderStr != null) ?\n                Arrays.stream(acceptHeaderStr.split(\"\\\\s*,\\\\s*\"))\n                        .map(mediaType -> mediaType.split(\"\\\\s*;\\\\s*\")[0])\n                        .collect(Collectors.toList()) :\n                null;\n        //find content type\n        String contentTypeHeaderStr = httpCarbonMessage.getHeader(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE);\n        //Trim specified charset since UTF-8 is assumed\n        contentType = (contentTypeHeaderStr != null) ? contentTypeHeaderStr.split(\"\\\\s*;\\\\s*\")[0] : null;\n    }\n\n    public void setSessionManager(SessionManager sessionManager) {\n        this.sessionManager = sessionManager;\n    }\n\n    /**\n     * @return true if the request does not have body content\n     */\n    public boolean isEmpty() {\n        return httpCarbonMessage.isEmpty();\n    }\n\n    /**\n     * @return next available message body chunk\n     */\n    @Deprecated\n    public ByteBuf getMessageBody() {\n        return httpCarbonMessage.getMessageBody();\n    }\n\n    /**\n     * @return map of headers of the HTTP request\n     */\n    public HttpHeaders getHeaders() {\n        return new HttpHeadersImpl(httpCarbonMessage.getHeaders());\n    }\n\n    /**\n     * Get an HTTP header of the HTTP request.\n     *\n     * @param key name of the header\n     * @return value of the header\n     */\n    public String getHeader(String key) {\n        return httpCarbonMessage.getHeader(key);\n    }\n\n    /**\n     * Set a property in the underlining Carbon Message.\n     *\n     * @param key property key\n     * @return value of the property key\n     */\n    public Object getProperty(String key) {\n        return httpCarbonMessage.getProperty(key);\n    }\n\n    /**\n     * @return property map of the underlining CarbonMessage\n     */\n    public Map<String, Object> getProperties() {\n        return httpCarbonMessage.getProperties();\n    }\n\n    /**\n     * Set a property in the underlining Carbon Message.\n     *\n     * @param key   property key\n     * @param value property value\n     */\n    public void setProperty(String key, Object value) {\n        httpCarbonMessage.setProperty(key, value);\n    }\n\n    /**\n     * Remove a property from the underlining CarbonMessage object.\n     *\n     * @param key property key\n     */\n    public void removeProperty(String key) {\n        httpCarbonMessage.removeProperty(key);\n    }\n\n    /**\n     * @return URL of the request.\n     */\n    public String getUri() {\n        return (String) httpCarbonMessage.getProperty(Constants.TO);\n    }\n\n    /**\n     * @return HTTP method of the request.\n     */\n    public String getHttpMethod() {\n        return httpCarbonMessage.getHttpMethod();\n    }\n\n    /**\n     * @return accept type of the request.\n     */\n    public List<String> getAcceptTypes() {\n        return acceptTypes;\n    }\n\n    /**\n     * @return request body content type.\n     */\n    public String getContentType() {\n        return contentType;\n    }\n\n    /**\n     * Returns the current session associated with this request, or if the request does not have a session,\n     * creates one.\n     *\n     * @return Session\n     */\n    public Session getSession() {\n        if (sessionManager == null) {\n            throw new IllegalStateException(\"SessionManager has not been set\");\n        }\n        if (session != null) {\n            return session.setAccessed();\n        }\n        String cookieHeader = getHeader(\"Cookie\");\n        if (cookieHeader != null) {\n            session = Arrays.stream(cookieHeader.split(\";\")).map(String::trim)\n                    .filter(cookie -> cookie.startsWith(MSF4JConstants.SESSION_ID))\n                    .findFirst()\n                    .map(jsession -> sessionManager.getSession(jsession.substring(MSF4JConstants.SESSION_ID.length())))\n                    .orElseGet(sessionManager::createSession);\n            return session.setAccessed();\n        }\n        return session = sessionManager.createSession();\n    }\n\n    /**\n     * Returns the current HttpSession associated with this request or, if there is no current session and create is\n     * true, returns a new session.\n     *\n     * @param create Create a new session or not\n     * @return Session\n     */\n    public Session getSession(boolean create) {\n        if (sessionManager == null) {\n            throw new IllegalStateException(\"SessionManager has not been set\");\n        }\n        if (session != null) {\n            return session.setAccessed();\n        }\n        String cookieHeader = getHeader(\"Cookie\");\n        if (cookieHeader != null) {\n            session = Arrays.stream(cookieHeader.split(\";\")).map(String::trim)\n                    .filter(cookie -> cookie.startsWith(MSF4JConstants.SESSION_ID))\n                    .findFirst()\n                    .map(jsession -> sessionManager.getSession(jsession.substring(MSF4JConstants.SESSION_ID.length())))\n                    .orElseGet(() -> {\n                        if (create) {\n                            return sessionManager.createSession();\n                        }\n                        return null;\n                    });\n            return session.setAccessed();\n        } else if (create) {\n            return session = sessionManager.createSession();\n        }\n        return null;\n    }\n\n    Session getSessionInternal() {\n        return session;\n    }\n\n    /**\n     * Get underlying HttpCarbonMessage.\n     *\n     * @return HttpCarbonMessage instance of the Request\n     */\n    HttpCarbonMessage getHttpCarbonMessage() {\n        return httpCarbonMessage;\n    }\n\n    /**\n     * Method use to send the response to the caller.\n     *\n     * @param carbonMessage Response message\n     * @return true if no errors found, else otherwise\n     * @throws ServerConnectorException server connector exception.\n     */\n    public boolean respond(HttpCarbonMessage carbonMessage) throws ServerConnectorException {\n        HttpResponseFuture statusFuture = httpCarbonMessage.respond(carbonMessage);\n        return statusFuture.getStatus().getCause() == null;\n    }\n\n    /**\n     * Returns InputStream of the ByteBuffers in message content.\n     *\n     * @return InputStream of the ByteBuffers\n     */\n    public InputStream getMessageContentStream() {\n        return new HttpMessageDataStreamer(httpCarbonMessage).getInputStream();\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/Response.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport io.netty.buffer.ByteBuf;\nimport io.netty.buffer.Unpooled;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport org.wso2.msf4j.delegates.CookieHeaderProvider;\nimport org.wso2.msf4j.internal.HttpHeadersImpl;\nimport org.wso2.msf4j.internal.MSF4JConstants;\nimport org.wso2.msf4j.internal.entitywriter.EntityWriter;\nimport org.wso2.msf4j.internal.entitywriter.EntityWriterRegistry;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport javax.ws.rs.core.HttpHeaders;\nimport javax.ws.rs.core.MultivaluedMap;\nimport javax.ws.rs.core.NewCookie;\n\n/**\n * Class that represents an HTTP response in MSF4J level.\n */\npublic class Response {\n\n    private static final String COMMA_SEPARATOR = \", \";\n    private static final int NULL_STATUS_CODE = -1;\n    public static final int NO_CHUNK = 0;\n    public static final int DEFAULT_CHUNK_SIZE = -1;\n\n    private final HttpCarbonMessage httpCarbonMessage;\n    private int statusCode = NULL_STATUS_CODE;\n    private String mediaType = null;\n    private Object entity;\n    private int chunkSize = NO_CHUNK;\n    private Request request;\n    private javax.ws.rs.core.Response jaxrsResponse;\n\n    public Response(HttpCarbonMessage responder) {\n        this.httpCarbonMessage = responder;\n    }\n\n    public Response(Request request) {\n        this(request.getHttpCarbonMessage().cloneCarbonMessageWithOutData());\n        this.httpCarbonMessage.getHeaders().clear();\n        this.request = request;\n    }\n\n    /**\n     * @return returns true if the message body is empty\n     */\n    public boolean isEmpty() {\n        return httpCarbonMessage.isEmpty();\n    }\n\n    /**\n     * @return next available message body chunk\n     */\n    @Deprecated\n    public ByteBuf getMessageBody() {\n        return httpCarbonMessage.getMessageBody();\n    }\n\n    /**\n     * @return map of headers in the response object\n     */\n    public HttpHeaders getHeaders() {\n        return new HttpHeadersImpl(httpCarbonMessage.getHeaders());\n    }\n\n    /**\n     * Get a header of the response.\n     *\n     * @param key header neame\n     * @return value of the header\n     */\n    public String getHeader(String key) {\n        return httpCarbonMessage.getHeader(key);\n    }\n\n    /**\n     * Set a header in the response.\n     *\n     * @param key   header name\n     * @param value value of the header\n     * @return Response object\n     */\n    public Response setHeader(String key, String value) {\n        httpCarbonMessage.setHeader(key, value);\n        return this;\n    }\n\n    /**\n     * Add a set of headers to the response as a map.\n     *\n     * @param headerMap headers to be added to the response\n     */\n    public void setHeaders(Map<String, String> headerMap) {\n        headerMap.forEach(httpCarbonMessage::setHeader);\n    }\n\n    /**\n     * Get a property of the CarbonMessage.\n     *\n     * @param key Property key\n     * @return property value\n     */\n    public Object getProperty(String key) {\n        return httpCarbonMessage.getProperty(key);\n    }\n\n    /**\n     * @return map of properties in the CarbonMessage\n     */\n    public Map<String, Object> getProperties() {\n        return httpCarbonMessage.getProperties();\n    }\n\n    /**\n     * Set a property in the underlining CarbonMessage object.\n     *\n     * @param key   property key\n     * @param value property value\n     */\n    public void setProperty(String key, Object value) {\n        httpCarbonMessage.setProperty(key, value);\n    }\n\n    /**\n     * @param key remove the header with this name\n     */\n    public void removeHeader(String key) {\n        httpCarbonMessage.removeHeader(key);\n    }\n\n    /**\n     * Remove a property from the underlining CarbonMessage object.\n     *\n     * @param key property key\n     */\n    public void removeProperty(String key) {\n        httpCarbonMessage.removeProperty(key);\n    }\n\n    /**\n     * @return the underlining CarbonMessage object\n     */\n    HttpCarbonMessage getHttpCarbonMessage() {\n        return httpCarbonMessage;\n    }\n\n    /**\n     * Set the status code of the HTTP response.\n     *\n     * @param statusCode HTTP status code\n     * @return Response object\n     */\n    public Response setStatus(int statusCode) {\n        this.statusCode = statusCode;\n        return this;\n    }\n\n    /**\n     * Get the status code of the HTTP response.\n     *\n     * @return status code value\n     */\n    public int getStatusCode() {\n        if (statusCode != NULL_STATUS_CODE) {\n            return statusCode;\n        } else if (entity != null) {\n            return javax.ws.rs.core.Response.Status.OK.getStatusCode();\n        } else {\n            return javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode();\n        }\n    }\n\n    /**\n     * Set HTTP media type of the response.\n     *\n     * @param mediaType HTTP media type string\n     * @return Response object\n     */\n    public Response setMediaType(String mediaType) {\n        this.mediaType = mediaType;\n        return this;\n    }\n\n    /**\n     * Set http body for the HTTP response.\n     *\n     * @param entity object that should be set as the response body\n     * @return Response object\n     */\n    public Response setEntity(Object entity) {\n        if (!httpCarbonMessage.isEmpty()) {\n            throw new IllegalStateException(\"CarbonMessage should not contain a message body\");\n        }\n        if (entity instanceof javax.ws.rs.core.Response) {\n            javax.ws.rs.core.Response response = (javax.ws.rs.core.Response) entity;\n            this.jaxrsResponse = response;\n            this.entity = response.getEntity();\n\n            //TODO: if you remove these lines, the tests fail.\n            /*MultivaluedMap<String, String> multivaluedMap = response.getStringHeaders();\n            if (multivaluedMap != null) {\n                multivaluedMap.forEach((key, strings) -> setHeader(key, String.join(COMMA_SEPARATOR, strings)));\n            }*/\n            setStatus(response.getStatus());\n            if (response.getMediaType() != null) {\n                setMediaType(response.getMediaType().toString());\n            }\n        } else {\n            this.entity = entity;\n        }\n        return this;\n    }\n\n    /**\n     * Specify the chunk size to send the response.\n     *\n     * @param chunkSize if 0 response will be sent without chunking\n     *                  if -1 a default chunk size will be applied\n     */\n    public void setChunkSize(int chunkSize) {\n        this.chunkSize = chunkSize;\n    }\n\n    /**\n     * Send the HTTP response using the content in this object.\n     */\n    public void send() {\n        httpCarbonMessage.setHttpStatusCode(getStatusCode());\n\n        List<String> cookiesHeaderValue = new ArrayList<>();\n\n        if (jaxrsResponse != null) {\n            MultivaluedMap<String, String> multivaluedMap = jaxrsResponse.getStringHeaders();\n            if (multivaluedMap != null) {\n                multivaluedMap.forEach((key, strings) -> setHeader(key, String.join(COMMA_SEPARATOR, strings)));\n            }\n\n            // String - cookie name\n            Map<String, NewCookie> cookies = jaxrsResponse.getCookies();\n            CookieHeaderProvider cookieProvider = new CookieHeaderProvider();\n            cookies.forEach((name, cookie) -> {\n                cookiesHeaderValue.add(cookieProvider.toString(cookie));\n            });\n        }\n\n\n        //Set-Cookie: session\n        Session session = request.getSessionInternal();\n        if (session != null && session.isValid() && session.isNew()) {\n            cookiesHeaderValue.add(MSF4JConstants.SESSION_ID + session.getId());\n        }\n        for (String cookie : cookiesHeaderValue) {\n            httpCarbonMessage.getHeaders().add(\"Set-Cookie\", cookie);\n        }\n        processEntity();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private void processEntity() {\n        if (entity != null) {\n            EntityWriter entityWriter = EntityWriterRegistry.getEntityWriter(entity.getClass());\n            entityWriter.writeData(httpCarbonMessage, entity, mediaType, chunkSize, request.getHttpCarbonMessage());\n        } else {\n            ByteBuffer byteBuffer = ByteBuffer.allocate(0);\n            httpCarbonMessage.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(byteBuffer)));\n            try {\n                request.getHttpCarbonMessage().respond(httpCarbonMessage);\n            } catch (ServerConnectorException e) {\n                throw new RuntimeException(\"Error while sending the response.\", e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/ServiceMethodInfo.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n\nimport java.lang.reflect.Method;\n\n/**\n * Contains information about service method details.\n * @deprecated\n */\npublic class ServiceMethodInfo {\n\n    private final String methodName;\n    private final Method method;\n    private final Request request;\n\n    public ServiceMethodInfo(String methodName, Method method, Request request) {\n        this.methodName = methodName;\n        this.method = method;\n        this.request = request;\n    }\n\n    public String getMethodName() {\n        return methodName;\n    }\n\n    public Method getMethod() {\n        return method;\n    }\n\n    /**\n     * Returns the value of the named attribute as an Object, or null if no attribute of the given name exists.\n     *\n     * @param name a {@link String} specifying the name of the attribute\n     * @return an {@link Object} containing the value of the attribute, or null if the attribute does not exist\n     */\n    public Object getAttribute(String name) {\n        return request.getProperty(name);\n    }\n\n    /**\n     * Stores an attribute in this request.\n     *\n     * @param name a {@link String} specifying the name of the attribute\n     * @param obj  the {@link Object} to be stored\n     */\n    public void setAttribute(String name, Object obj) {\n        request.setProperty(name, obj);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/Session.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport java.io.Serializable;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * Represents a transport session.\n */\npublic class Session implements Serializable {\n\n    private static final long serialVersionUID = -3945729418329160933L;\n    private transient SessionManager sessionManager;\n\n    private String id;\n    private long creationTime;\n    private long lastAccessedTime;\n    private int maxInactiveInterval;\n    private boolean isValid = true;\n    private boolean isNew = true;\n    private Map<String, Object> attributes = new ConcurrentHashMap<>();\n\n    public Session() {\n    }\n\n    public Session(String id, int maxInactiveInterval) {\n        this.id = id;\n        this.maxInactiveInterval = maxInactiveInterval;\n        creationTime = System.currentTimeMillis();\n        lastAccessedTime = creationTime;\n    }\n\n    long getCreationTime() {\n        return creationTime;\n    }\n\n    String getId() {\n        return id;\n    }\n\n    void setMaxInactiveInterval(int interval) {\n        this.maxInactiveInterval = interval;\n    }\n\n    int getMaxInactiveInterval() {\n        return maxInactiveInterval;\n    }\n\n    public Object getAttribute(String name) {\n        checkValidity();\n        return attributes.get(name);\n    }\n\n    public Set<String> getAttributeNames() {\n        checkValidity();\n        return attributes.keySet();\n    }\n\n    public void setAttribute(String name, Object value) {\n        checkValidity();\n        attributes.put(name, value);\n        sessionManager.updateSession(this);\n    }\n\n    public void removeAttribute(String name) {\n        checkValidity();\n        sessionManager.updateSession(this);\n        attributes.remove(name);\n    }\n\n    private void checkValidity() {\n        if (!isValid) {\n            throw new IllegalStateException(\"Session is invalid\");\n        }\n    }\n\n    public void invalidate() {\n        sessionManager.invalidateSession(this);\n        attributes.clear();\n        isValid = false;\n    }\n\n    boolean isValid() {\n        return isValid;\n    }\n\n    boolean isNew() {\n        return isNew;\n    }\n\n    boolean getIsNew() {\n        return isNew;\n    }\n\n    public void setNew(boolean isNew) {\n        this.isNew = isNew;\n    }\n\n    Session setAccessed() {\n        checkValidity();\n        lastAccessedTime = System.currentTimeMillis();\n        return this;\n    }\n\n    long getLastAccessedTime() {\n        return lastAccessedTime;\n    }\n\n    public void setManager(SessionManager sessionManager) {\n        this.sessionManager = sessionManager;\n    }\n}\n\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/SessionManager.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j;\n\nimport java.util.Map;\n\n/**\n * Manage transport sessions.\n */\npublic interface SessionManager {\n\n    /**\n     * Initialize the SessionManager.\n     */\n    void init();\n\n    /**\n     * Retrieve a session with ID.\n     *\n     * @param sessionId ID of the session\n     * @return Session with id <code>sessionId</code> if it exists, and null otherwise.\n     */\n    Session getSession(String sessionId);\n\n    /**\n     * Create a new session.\n     *\n     * @return the newly created session\n     */\n    Session createSession();\n\n    /**\n     * Invalidate a session.\n     *\n     * @param session The session to be invalidated.\n     */\n    void invalidateSession(Session session);\n\n    /**\n     * The maximum time in minutes a session could be inactive before it is expired.\n     *\n     * @return max inactive interval\n     */\n    int getDefaultMaxInactiveInterval();\n\n    /**\n     * The maximum number of active sessions that can exist.\n     *\n     * @return max active sessions\n     */\n    int getDefaultMaxActiveSessions();\n\n    /**\n     * @return Length of the session ID in bytes.\n     */\n    int getSessionIdLength();\n\n    /**\n     * Load sessions from a persistent storage, for example, into memory.\n     *\n     * @param sessions The map into which the sessions are to be loaded.\n     */\n    void loadSessions(Map<String, Session> sessions);\n\n    /**\n     * Read a session from a persistent storage, for example, into memory.\n     *\n     * @param sessionId ID of the session to be loaded or read.\n     * @return The Session object.\n     */\n    Session readSession(String sessionId);\n\n    /**\n     * Persist a new session.\n     *\n     * @param session the new session to be persisted.\n     */\n    void saveSession(Session session);\n\n    /**\n     * Delete a session which has been persisted.\n     *\n     * @param session Session to be deleted\n     */\n    void deleteSession(Session session);\n\n\n    /**\n     * Update a session in persistent storage.\n     *\n     * @param session Session to to be updated\n     */\n    void updateSession(Session session);\n\n    /**\n     * Stop this SessionManager.\n     */\n    void stop();\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/SwaggerService.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n/**\n * Interface need to implement for Swagger service.\n */\npublic interface SwaggerService {\n\n    void init(MicroservicesRegistry serviceRegistry);\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/beanconversion/BeanConversionException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.beanconversion;\n\n/**\n * Exception that is thrown when a bean conversion is failed.\n */\npublic class BeanConversionException extends RuntimeException {\n\n    public BeanConversionException(String msg) {\n        super(msg);\n    }\n\n    public BeanConversionException(String msg, Exception cause) {\n        super(msg, cause);\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/beanconversion/MediaTypeConverter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.beanconversion;\n\nimport java.io.InputStream;\nimport java.lang.reflect.Type;\nimport java.nio.ByteBuffer;\n\n/**\n * Interface of media type conversion classes.\n */\npublic abstract class MediaTypeConverter {\n\n    protected static final String UTF_8_CHARSET = \"UTF-8\";\n\n    /**\n     * Convert an object to a specific media type.\n     *\n     * @param object object that needs to be converted to a media content\n     * @return converted media content\n     */\n    public ByteBuffer convertToMedia(Object object) {\n        if (object == null) {\n            throw new BeanConversionException(\"Object cannot be null\");\n        }\n        return toMedia(object);\n    }\n\n    /**\n     * Create an object from a specific content.\n     *\n     * @param content    content that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return created object\n     * @throws BeanConversionException throws if object creation is failed\n     */\n    public Object convertToObject(ByteBuffer content, Type targetType) throws BeanConversionException {\n        if (content == null || targetType == null) {\n            throw new BeanConversionException(\"Content or target type cannot be null\");\n        }\n        return toObject(content, targetType);\n    }\n\n    /**\n     * Create an object from input stream..\n     *\n     * @param inputStream  stream that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return created object\n     * @throws BeanConversionException throws if object creation is failed\n     */\n    public Object convertToObject(InputStream inputStream, Type targetType) throws BeanConversionException {\n        if (inputStream == null || targetType == null) {\n            throw new BeanConversionException(\"Content or target type cannot be null\");\n        }\n        return toObject(inputStream, targetType);\n    }\n\n    /**\n     * Return an array of supported media types.\n     *\n     * @return String array of media types\n     */\n    public abstract String[] getSupportedMediaTypes();\n\n    /**\n     * Convert an object to a specific media type.\n     *\n     * @param object object that needs to be converted to a media content\n     * @return converted media content\n     * @throws BeanConversionException throws if conversion is failed\n     */\n    protected abstract ByteBuffer toMedia(Object object) throws BeanConversionException;\n\n    /**\n     * Create an object from a specific content.\n     *\n     * @param content    content that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return created object\n     * @throws BeanConversionException throws if object creation is failed\n     */\n    protected abstract Object toObject(ByteBuffer content, Type targetType) throws BeanConversionException;\n\n    /**\n     * Create an object from input stream.\n     *\n     * @param inputStream input stream that needs to be converted to an object\n     * @param targetType target object type\n     * @return created object\n     * @throws BeanConversionException throws if object creation is failed\n     */\n    protected abstract Object toObject(InputStream inputStream, Type targetType) throws BeanConversionException;\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/config/MSF4JConfig.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.config;\n\nimport org.wso2.carbon.config.annotation.Configuration;\nimport org.wso2.carbon.config.annotation.Element;\n\n/**\n * Configuration class MSF4J.\n */\n@Configuration(namespace = \"wso2.msf4j.configuration\", description = \"MSF4J configuration\")\npublic class MSF4JConfig {\n\n    @Element(description = \"No of worker pool threads to handle MSF4J requests\")\n    private int threadCount = 100;\n\n    @Element(description = \"MSF4J thread pool name \")\n    private String threadPoolName = \"msf4j.executor.workerpool\";\n\n    public int getThreadCount() {\n        return threadCount;\n    }\n\n    public void setThreadCount(int threadCount) {\n        this.threadCount = threadCount;\n    }\n\n    public String getThreadPoolName() {\n        return threadPoolName;\n    }\n\n    public void setThreadPoolName(String threadPoolName) {\n        this.threadPoolName = threadPoolName;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/exception/InterceptorException.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.exception;\n\n/**\n * Exception that is thrown when an interceptor fails.\n */\npublic class InterceptorException extends Exception {\n\n    public InterceptorException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/exception/OSGiDeclarativeServiceException.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.exception;\n\n/**\n * Runtime exception when MicroServices Service Component fails to add or remove OSGi Declarative Services\n */\npublic class OSGiDeclarativeServiceException extends RuntimeException {\n\n    public OSGiDeclarativeServiceException(String message) {\n        super(message);\n    }\n\n    public OSGiDeclarativeServiceException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/FileInfo.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\n/**\n * <p>\n * This class contains basic file information which can be used with\n * FormDataParam(\"file\") InputStream.\n * </p>\n */\npublic class FileInfo {\n    private String fileName;\n    private String contentType;\n\n    public String getFileName() {\n        return fileName;\n    }\n\n    public void setFileName(String fileName) {\n        this.fileName = fileName;\n    }\n\n    public String getContentType() {\n        return contentType;\n    }\n\n    public void setContentType(String contentType) {\n        this.contentType = contentType;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/FormDataParam.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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.wso2.msf4j.formparam;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This {@link java.lang.annotation.Annotation} provide supports for multipart/form-data with MSF4J.\n *\n */\n@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\npublic @interface FormDataParam {\n\n    /**\n     * Defines the control name of a \"multipart/form-data\" body part whose\n     * content will be used to initialize the value of the annotated method\n     * argument.\n     *\n     * @return name of a \"multipart/form-data\" body part\n     */\n    String value();\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/FormItem.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.util.Closeable;\nimport org.wso2.msf4j.formparam.util.FormItemHeader;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * <p> This provides access to a file or form item that was\n * received within a <code>multipart/form-data</code> POST request.\n * The items contents are retrieved by calling {@link #openStream()}.</p>\n * <p>Instances of this class are created by accessing the\n * iterator, returned by\n * {@link FormParamIterator}.</p>\n * <p><em>Note</em>: There is an interaction between the iterator and\n * its associated instances of {@link FormItem}: By invoking\n * @see java.util.Iterator#hasNext() on the iterator, you discard all data,\n * which hasn't been read so far from the previous data.</p>\n *\n */\npublic class FormItem {\n\n    /**\n     * The file items content type.\n     */\n    private final String contentType;\n\n    /**\n     * The file items field name.\n     */\n    private final String fieldName;\n\n    /**\n     * The file items file name.\n     */\n    private final String name;\n\n    /**\n     * Whether the file item is a form field.\n     */\n    private final boolean formField;\n\n    /**\n     * The file items input stream.\n     */\n    private final InputStream stream;\n\n    /**\n     * The headers, if any.\n     */\n    private FormItemHeader headers;\n\n    /**\n     * Creates a new instance.\n     *\n     * @param pName          The items file name, or null.\n     * @param pFieldName     The items field name.\n     * @param pContentType   The items content type, or null.\n     * @param pFormField     Whether the item is a form field.\n     * @param pContentLength The items content length, if known, or -1\n     * @throws IOException Creating the file item failed.\n     */\n    FormItem(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength,\n             MultipartStream multi) {\n        name = pName;\n        fieldName = pFieldName;\n        contentType = pContentType;\n        formField = pFormField;\n        stream = multi.newInputStream();\n    }\n\n    /**\n     * Returns the items content type, or null.\n     *\n     * @return Content type, if known, or null.\n     */\n    public String getContentType() {\n        return contentType;\n    }\n\n    /**\n     * Returns the items field name.\n     *\n     * @return Field name.\n     */\n    public String getFieldName() {\n        return fieldName;\n    }\n\n    /**\n     * Returns the items file name.\n     *\n     * @return File name, if known, or null.\n     */\n    public String getName() {\n        return StreamUtil.checkFileName(name);\n    }\n\n    /**\n     * Returns, whether this is a form field.\n     *\n     * @return True, if the item is a form field,\n     * otherwise false.\n     */\n    public boolean isFormField() {\n        return formField;\n    }\n\n    /**\n     * Returns an input stream, which may be used to\n     * read the items contents.\n     *\n     * @return Opened input stream.\n     * @throws IOException An I/O error occurred.\n     */\n    public InputStream openStream() throws IOException {\n        if (((Closeable) stream).isClosed()) {\n            throw new ItemSkippedException();\n        }\n        return stream;\n    }\n\n    /**\n     * Closes the file item.\n     *\n     */\n    public void close() {\n        try {\n            stream.close();\n        } catch (IOException e) {\n            throw new FormUploadException(\"Error while closing the stream\", e);\n        }\n    }\n\n    /**\n     * Returns the file item headers.\n     *\n     * @return The items header object\n     */\n    public FormItemHeader getHeaders() {\n        return headers;\n    }\n\n    /**\n     * Sets the file item headers.\n     *\n     * @param pHeaders The items header object\n     */\n    void setHeaders(FormItemHeader pHeaders) {\n        headers = pHeaders;\n    }\n\n    static class ItemSkippedException extends RuntimeException {\n\n        /**\n         * The exceptions serial version UID, which is being used\n         * when serializing an exception instance.\n         */\n        private static final long serialVersionUID = -7280778431581963740L;\n\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/FormParamIterator.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\nimport org.apache.commons.io.IOUtils;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.exception.InvalidContentTypeException;\nimport org.wso2.msf4j.formparam.util.FormItemHeader;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.UnsupportedEncodingException;\nimport java.nio.charset.Charset;\nimport java.util.Iterator;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\n\nimport static java.lang.String.format;\n\n/**\n *\n */\npublic class FormParamIterator implements Iterator {\n\n    /**\n     * HTTP content type header name.\n     */\n    private static final String CONTENT_TYPE = \"Content-type\";\n\n    /**\n     * HTTP content disposition header name.\n     */\n    private static final String CONTENT_DISPOSITION = \"Content-disposition\";\n\n    /**\n     * HTTP content length header name.\n     */\n    private static final String CONTENT_LENGTH = \"Content-length\";\n\n    /**\n     * Content-disposition value for form data.\n     */\n    private static final String FORM_DATA = \"form-data\";\n\n    /**\n     * Content-disposition value for file attachment.\n     */\n    private static final String ATTACHMENT = \"attachment\";\n\n    /**\n     * Part of HTTP content type header.\n     */\n    private static final String MULTIPART = \"multipart/\";\n\n    /**\n     * HTTP content type header for multipart forms.\n     */\n    private static final String MULTIPART_FORM_DATA = \"multipart/form-data\";\n\n    /**\n     * HTTP content type header for multiple uploads.\n     */\n    private static final String MULTIPART_MIXED = \"multipart/mixed\";\n\n    /**\n     * The multi part stream to process.\n     */\n    private final MultipartStream multi;\n\n    /**\n     * The boundary, which separates the various parts.\n     */\n    private final byte[] boundary;\n\n    /**\n     * The item, which we currently process.\n     */\n    private FormItem currentItem;\n\n    /**\n     * The current items field name.\n     */\n    private String currentFieldName;\n\n    /**\n     * Whether we are currently skipping the preamble.\n     */\n    private boolean skipPreamble;\n\n    /**\n     * Whether the current item may still be read.\n     */\n    private boolean itemValid;\n\n    /**\n     * Whether we have seen the end of the file.\n     */\n    private boolean eof;\n\n    // ----------------------------------------------------------- Data members\n\n    /**\n     * Processes an <a href=\"http://www.ietf.org/rfc/rfc1867.txt\">RFC 1867</a>\n     * compliant <code>multipart/form-data</code> stream.\n     *\n     * @param request The context for the request to be parsed.\n     * @throws FormUploadException if there are problems reading/parsing\n     *                             the request or storing files.\n     * @throws IOException         An I/O error occurred. This may be a network\n     *                             error while communicating with the client or a problem while\n     *                             storing the uploaded content.\n     */\n    public FormParamIterator(Request request) throws FormUploadException, IOException {\n        this(new RequestContext(request));\n    }\n\n    // ------------------------------------------------------ Protected methods\n\n    /**\n     * Retrieves the boundary from the <code>Content-type</code> header.\n     *\n     * @param contentType The value of the content type header from which to\n     *                    extract the boundary value.\n     * @return The boundary, as a byte array.\n     */\n    private byte[] getBoundary(String contentType) {\n        ParameterParser parser = new ParameterParser();\n        parser.setLowerCaseNames(true);\n        // Parameter parser can handle null input\n        Map<String, String> params = parser.parse(contentType, new char[] { ';', ',' });\n        String boundaryStr = params.get(\"boundary\");\n\n        if (boundaryStr == null) {\n            return new byte[] {};\n        }\n        byte[] boundary;\n        try {\n            boundary = boundaryStr.getBytes(\"ISO-8859-1\");\n        } catch (UnsupportedEncodingException e) {\n            boundary = boundaryStr.getBytes(Charset.defaultCharset()); // Intentionally falls back to default charset\n        }\n        return boundary;\n    }\n\n    /**\n     * Retrieves the file name from the <code>Content-disposition</code>\n     * header.\n     *\n     * @param headers The HTTP headers object.\n     * @return The file name for the current <code>encapsulation</code>.\n     */\n    private String getFileName(FormItemHeader headers) {\n        return getFileName(headers.getHeader(CONTENT_DISPOSITION));\n    }\n\n    /**\n     * Returns the given content-disposition headers file name.\n     *\n     * @param pContentDisposition The content-disposition headers value.\n     * @return The file name\n     */\n    private String getFileName(String pContentDisposition) {\n        String fileName = null;\n        if (pContentDisposition != null) {\n            String cdl = pContentDisposition.toLowerCase(Locale.ENGLISH);\n            if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) {\n                ParameterParser parser = new ParameterParser();\n                parser.setLowerCaseNames(true);\n                // Parameter parser can handle null input\n                Map<String, String> params = parser.parse(pContentDisposition, ';');\n                if (params.containsKey(\"filename\")) {\n                    fileName = params.get(\"filename\");\n                    if (fileName != null) {\n                        fileName = fileName.trim();\n                    } else {\n                        // Even if there is no value, the parameter is present,\n                        // so we return an empty file name rather than no file\n                        // name.\n                        fileName = \"\";\n                    }\n                }\n            }\n        }\n        return fileName;\n    }\n\n    /**\n     * Retrieves the field name from the <code>Content-disposition</code>\n     * header.\n     *\n     * @param headers A <code>Map</code> containing the HTTP request headers.\n     * @return The field name for the current <code>encapsulation</code>.\n     */\n    private String getFieldName(FormItemHeader headers) {\n        return getFieldName(headers.getHeader(CONTENT_DISPOSITION));\n    }\n\n    /**\n     * Returns the field name, which is given by the content-disposition\n     * header.\n     *\n     * @param pContentDisposition The content-dispositions header value.\n     * @return The field jake\n     */\n    private String getFieldName(String pContentDisposition) {\n        String fieldName = null;\n        if (pContentDisposition != null && pContentDisposition.toLowerCase(Locale.ENGLISH).startsWith(FORM_DATA)) {\n            ParameterParser parser = new ParameterParser();\n            parser.setLowerCaseNames(true);\n            // Parameter parser can handle null input\n            Map<String, String> params = parser.parse(pContentDisposition, ';');\n            fieldName = params.get(\"name\");\n            if (fieldName != null) {\n                fieldName = fieldName.trim();\n            }\n        }\n        return fieldName;\n    }\n\n    /**\n     * <p> Parses the <code>header-part</code> and returns as key/value\n     * pairs.\n     * <p>\n     * <p> If there are multiple headers of the same names, the name\n     * will map to a comma-separated list containing the values.\n     *\n     * @param headerPart The <code>header-part</code> of the current\n     *                   <code>encapsulation</code>.\n     * @return A <code>Map</code> containing the parsed HTTP request headers.\n     */\n    private FormItemHeader getParsedHeaders(String headerPart) {\n        final int len = headerPart.length();\n        FormItemHeader headers = newFileItemHeaders();\n        int start = 0;\n        for (;;) {\n            int end = parseEndOfLine(headerPart, start);\n            if (start == end) {\n                break;\n            }\n            StringBuilder header = new StringBuilder(headerPart.substring(start, end));\n            start = end + 2;\n            while (start < len) {\n                int nonWs = start;\n                while (nonWs < len) {\n                    char c = headerPart.charAt(nonWs);\n                    if (c != ' ' && c != '\\t') {\n                        break;\n                    }\n                    ++nonWs;\n                }\n                if (nonWs == start) {\n                    break;\n                }\n                // Continuation line found\n                end = parseEndOfLine(headerPart, nonWs);\n                header.append(\" \").append(headerPart.substring(nonWs, end));\n                start = end + 2;\n            }\n            parseHeaderLine(headers, header.toString());\n        }\n        return headers;\n    }\n\n    /**\n     * Creates a new instance of {@link FormItemHeader}.\n     *\n     * @return The new instance.\n     */\n    private FormItemHeader newFileItemHeaders() {\n        return new FormItemHeader();\n    }\n\n    /**\n     * Skips bytes until the end of the current line.\n     *\n     * @param headerPart The headers, which are being parsed.\n     * @param end        Index of the last byte, which has yet been\n     *                   processed.\n     * @return Index of the \\r\\n sequence, which indicates\n     * end of line.\n     */\n    private int parseEndOfLine(String headerPart, int end) {\n        int index = end;\n        for (;;) {\n            int offset = headerPart.indexOf('\\r', index);\n            if (offset == -1 || offset + 1 >= headerPart.length()) {\n                throw new IllegalStateException(\"Expected headers to be terminated by an empty line.\");\n            }\n            if (headerPart.charAt(offset + 1) == '\\n') {\n                return offset;\n            }\n            index = offset + 1;\n        }\n    }\n\n    /**\n     * Reads the next header line.\n     *\n     * @param headers String with all headers.\n     * @param header  Map where to store the current header.\n     */\n    private void parseHeaderLine(FormItemHeader headers, String header) {\n        final int colonOffset = header.indexOf(':');\n        if (colonOffset == -1) {\n            // This header line is malformed, skip it.\n            return;\n        }\n        String headerName = header.substring(0, colonOffset).trim();\n        String headerValue = header.substring(header.indexOf(':') + 1).trim();\n        headers.addHeader(headerName, headerValue);\n    }\n\n    /**\n     * Creates a new instance.\n     *\n     * @param ctx The request context.\n     * @throws FormUploadException An error occurred while\n     *                             parsing the request.\n     * @throws IOException         An I/O error occurred.\n     */\n    private FormParamIterator(RequestContext ctx) throws FormUploadException, IOException {\n        if (ctx == null) {\n            throw new NullPointerException(\"ctx parameter\");\n        }\n\n        String contentType = ctx.getContentType();\n        if ((null == contentType) || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {\n            throw new InvalidContentTypeException(\n                    format(\"the request doesn't contain a %s or %s stream, content type header is %s\",\n                           MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType));\n        }\n\n        InputStream input = ctx.getInputStream();\n\n        String charEncoding = ctx.getCharacterEncoding();\n\n        boundary = getBoundary(contentType);\n        if (boundary.length == 0) {\n            IOUtils.closeQuietly(input); // avoid possible resource leak\n            throw new FormUploadException(\"the request was rejected because no multipart boundary was found\");\n        }\n\n        try {\n            multi = new MultipartStream(input, boundary);\n        } catch (IllegalArgumentException iae) {\n            IOUtils.closeQuietly(input); // avoid possible resource leak\n            throw new InvalidContentTypeException(\n                    format(\"The boundary specified in the %s header is too long\", CONTENT_TYPE), iae);\n        }\n        multi.setHeaderEncoding(charEncoding);\n\n        skipPreamble = true;\n        findNextItem();\n    }\n\n    /**\n     * Called for finding the next item, if any.\n     *\n     * @return True, if an next item was found, otherwise false.\n     * @throws IOException An I/O error occurred.\n     */\n    private boolean findNextItem() {\n        if (eof) {\n            return false;\n        }\n        if (currentItem != null) {\n            currentItem.close();\n            currentItem = null;\n        }\n        for (;;) {\n            boolean nextPart;\n            if (skipPreamble) {\n                nextPart = multi.skipPreamble();\n            } else {\n                nextPart = multi.readBoundary();\n            }\n            if (!nextPart) {\n                if (currentFieldName == null) {\n                    // Outer multipart terminated -> No more data\n                    eof = true;\n                    return false;\n                }\n                // Inner multipart terminated -> Return to parsing the outer\n                multi.setBoundary(boundary);\n                currentFieldName = null;\n                continue;\n            }\n            FormItemHeader headers = getParsedHeaders(multi.readHeaders());\n            if (currentFieldName == null) {\n                // We're parsing the outer multipart\n                String fieldName = getFieldName(headers);\n                if (fieldName != null) {\n                    String subContentType = headers.getHeader(CONTENT_TYPE);\n                    if (subContentType != null &&\n                        subContentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART_MIXED)) {\n                        currentFieldName = fieldName;\n                        // Multiple files associated with this field name\n                        byte[] subBoundary = getBoundary(subContentType);\n                        multi.setBoundary(subBoundary);\n                        skipPreamble = true;\n                        continue;\n                    }\n                    String fileName = getFileName(headers);\n                    currentItem = new FormItem(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null,\n                                               getContentLength(headers), multi);\n                    currentItem.setHeaders(headers);\n                    itemValid = true;\n                    return true;\n                }\n            } else {\n                String fileName = getFileName(headers);\n                if (fileName != null) {\n                    currentItem = new FormItem(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false,\n                                               getContentLength(headers), multi);\n                    currentItem.setHeaders(headers);\n                    itemValid = true;\n                    return true;\n                }\n            }\n            multi.discardBodyData();\n        }\n    }\n\n    private long getContentLength(FormItemHeader pHeaders) {\n        try {\n            return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH));\n        } catch (Exception e) {\n            return -1;\n        }\n    }\n\n    /**\n     * Returns, whether another instance of {@link FormItem}\n     * is available.\n     *\n     * @return True, if one or more additional file items\n     * are available, otherwise false.\n     */\n    public boolean hasNext() {\n        if (eof) {\n            return false;\n        }\n        return itemValid || findNextItem();\n    }\n\n    /**\n     * Returns the next available {@link FormItem}.\n     *\n     * @return FileItemStream instance, which provides\n     * access to the next file item.\n     */\n    public FormItem next() {\n        if (eof || (!itemValid && !hasNext())) {\n            throw new NoSuchElementException();\n        }\n        itemValid = false;\n        return currentItem;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/MultipartStream.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.util.Closeable;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.UnsupportedEncodingException;\nimport java.nio.charset.Charset;\n\nimport static java.lang.String.format;\n\n/**\n * <p> Low level API for processing file uploads. </p>\n *\n * <p> This class can be used to process data streams conforming to MIME\n * 'multipart' format as defined in\n * <a href=\"http://www.ietf.org/rfc/rfc1867.txt\">RFC 1867</a>. Arbitrarily\n * large amounts of data in the stream can be processed under constant\n * memory usage.\n *\n * <p> The format of the stream is defined in the following way:<br>\n * </p>\n * <code>\n * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br>\n * encapsulation := delimiter body CRLF<br>\n * delimiter := \"--\" boundary CRLF<br>\n * close-delimiter := \"--\" boundary \"--\"<br>\n * preamble := &lt;ignore&gt;<br>\n * epilogue := &lt;ignore&gt;<br>\n * body := header-part CRLF body-part<br>\n * header-part := 1*header CRLF<br>\n * header := header-name \":\" header-value<br>\n * header-name := &lt;printable ascii characters except \":\"&gt;<br>\n * header-value := &lt;any ascii characters except CR &amp; LF&gt;<br>\n * body-data := &lt;arbitrary data&gt;<br>\n * </code>\n *\n * <p>Note that body-data can contain another mulipart entity.  There\n * is limited support for single pass processing of such nested\n * streams.  The nested stream is <strong>required</strong> to have a\n * boundary token of the same length as the parent stream (see {@link\n * #setBoundary(byte[])}).\n * </p>\n *\n * <p>Here is an example of usage of this class.<br>\n * </p>\n * <pre>\n *   try {\n *     MultipartStream multipartStream = new MultipartStream(input, boundary);\n *     boolean nextPart = multipartStream.skipPreamble();\n *     OutputStream output;\n *     while(nextPart) {\n *       String header = multipartStream.readHeaders();\n *       // process headers\n *       // create some output stream\n *       multipartStream.readBodyData(output);\n *       nextPart = multipartStream.readBoundary();\n *     }\n *   } catch(MultipartStream.MalformedStreamException e) {\n *     // the stream failed to follow required syntax\n *   } catch(IOException e) {\n *     // a read or write error occurred\n *   }\n * </pre>\n *\n */\npublic class MultipartStream {\n\n    // ----------------------------------------------------- Manifest constants\n\n    /**\n     * The Carriage Return ASCII character value.\n     */\n    private static final byte CR = 0x0D;\n\n    /**\n     * The Line Feed ASCII character value.\n     */\n    private static final byte LF = 0x0A;\n\n    /**\n     * The dash (-) ASCII character value.\n     */\n    private static final byte DASH = 0x2D;\n\n    /**\n     * The maximum length of <code>header-part</code> that will be\n     * processed (10 kilobytes = 10240 bytes.).\n     */\n    private static final int HEADER_PART_SIZE_MAX = 10240;\n\n    /**\n     * The default length of the buffer used for processing a request.\n     */\n    private static final int DEFAULT_BUFSIZE = 4096;\n\n    /**\n     * A byte sequence that marks the end of <code>header-part</code>\n     * (<code>CRLFCRLF</code>).\n     */\n    private static final byte[] HEADER_SEPARATOR = { CR, LF, CR, LF };\n\n    /**\n     * A byte sequence that that follows a delimiter that will be\n     * followed by an encapsulation (<code>CRLF</code>).\n     */\n    private static final byte[] FIELD_SEPARATOR = { CR, LF };\n\n    /**\n     * A byte sequence that that follows a delimiter of the last\n     * encapsulation in the stream (<code>--</code>).\n     */\n    private static final byte[] STREAM_TERMINATOR = { DASH, DASH };\n\n    /**\n     * A byte sequence that precedes a boundary (<code>CRLF--</code>).\n     */\n    private static final byte[] BOUNDARY_PREFIX = { CR, LF, DASH, DASH };\n\n    // ----------------------------------------------------------- Data members\n\n    /**\n     * The input stream from which data is read.\n     */\n    private final InputStream input;\n\n    /**\n     * The length of the boundary token plus the leading <code>CRLF--</code>.\n     */\n    private int boundaryLength;\n\n    /**\n     * The amount of data, in bytes, that must be kept in the buffer in order\n     * to detect delimiters reliably.\n     */\n    private final int keepRegion;\n\n    /**\n     * The byte sequence that partitions the stream.\n     */\n    private final byte[] boundary;\n\n    /**\n     * The length of the buffer used for processing the request.\n     */\n    private final int bufSize;\n\n    /**\n     * The buffer used for processing the request.\n     */\n    private final byte[] buffer;\n\n    /**\n     * The index of first valid character in the buffer.\n     * <br>\n     * 0 <= head < bufSize\n     */\n    private int head;\n\n    /**\n     * The index of last valid character in the buffer + 1.\n     * <br>\n     * 0 <= tail <= bufSize\n     */\n    private int tail;\n\n    /**\n     * The content encoding to use when reading headers.\n     */\n    private String headerEncoding;\n\n    private static final Logger log = LoggerFactory.getLogger(MultipartStream.class);\n\n    // ----------------------------------------------------------- Constructors\n\n    /**\n     * <p> Constructs a <code>MultipartStream</code> with a custom size buffer.\n     * </p>\n     * <p> Note that the buffer must be at least big enough to contain the\n     * boundary string, plus 4 characters for CR/LF and double dash, plus at\n     * least one byte of data.  Too small a buffer size setting will degrade\n     * performance.\n     * </p>\n     * @param input    The <code>InputStream</code> to serve as a data source.\n     * @param boundary The token used for dividing the stream into\n     *                 <code>encapsulations</code>.\n     * @param bufSize  The size of the buffer to be used, in bytes.\n     */\n    public MultipartStream(InputStream input, byte[] boundary, int bufSize) {\n\n        if (boundary == null) {\n            throw new IllegalArgumentException(\"boundary may not be null\");\n        }\n        // We prepend CR/LF to the boundary to chop trailing CR/LF from\n        // body-data tokens.\n        this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length;\n        if (bufSize < this.boundaryLength + 1) {\n            throw new IllegalArgumentException(\"The buffer size specified for the MultipartStream is too small\");\n        }\n\n        this.input = input;\n        this.bufSize = Math.max(bufSize, boundaryLength * 2);\n        this.buffer = new byte[this.bufSize];\n\n        this.boundary = new byte[this.boundaryLength];\n        this.keepRegion = this.boundary.length;\n\n        System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, BOUNDARY_PREFIX.length);\n        System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length);\n\n        head = 0;\n        tail = 0;\n    }\n\n    /**\n     * <p> Constructs a <code>MultipartStream</code> with a default size buffer.</p>\n     *\n     * @param input    The <code>InputStream</code> to serve as a data source.\n     * @param boundary The token used for dividing the stream into\n     *                 <code>encapsulations</code>.\n     * @see #MultipartStream(InputStream, byte[], int)\n     */\n    MultipartStream(InputStream input, byte[] boundary) {\n        this(input, boundary, DEFAULT_BUFSIZE);\n    }\n\n    // --------------------------------------------------------- Public methods\n\n    /**\n     * Retrieves the character encoding used when reading the headers of an\n     * individual part. When not specified, or <code>null</code>, the platform\n     * default encoding is used.\n     *\n     * @return The encoding used to read part headers.\n     */\n    public String getHeaderEncoding() {\n        return headerEncoding;\n    }\n\n    /**\n     * Specifies the character encoding to be used when reading the headers of\n     * individual parts. When not specified, or <code>null</code>, the platform\n     * default encoding is used.\n     *\n     * @param encoding The encoding used to read part headers.\n     */\n    public void setHeaderEncoding(String encoding) {\n        headerEncoding = encoding;\n    }\n\n    /**\n     * Reads a byte from the <code>buffer</code>, and refills it as\n     * necessary.\n     *\n     * @return The next byte from the input stream.\n     * @throws IOException if there is no more data available.\n     */\n    public byte readByte() throws IOException {\n        // Buffer depleted ?\n        if (head == tail) {\n            head = 0;\n            // Refill.\n            tail = input.read(buffer, head, bufSize);\n            if (tail == -1) {\n                // No more data available.\n                throw new IOException(\"No more data is available\");\n            }\n        }\n        return buffer[head++];\n    }\n\n    /**\n     * Skips a <code>boundary</code> token, and checks whether more\n     * <code>encapsulations</code> are contained in the stream.\n     *\n     * @return <code>true</code> if there are more encapsulations in\n     * this stream; <code>false</code> otherwise.\n     */\n    public boolean readBoundary() {\n        byte[] marker = new byte[2];\n        boolean nextChunk;\n\n        head += boundaryLength;\n        try {\n            marker[0] = readByte();\n            if (marker[0] == LF) {\n                // Work around IE5 Mac bug with input type=image.\n                // Because the boundary delimiter, not including the trailing\n                // CRLF, must not appear within any file (RFC 2046, section\n                // 5.1.1), we know the missing CR is due to a buggy browser\n                // rather than a file containing something similar to a\n                // boundary.\n                return true;\n            }\n\n            marker[1] = readByte();\n            if (arrayequals(marker, STREAM_TERMINATOR, 2)) {\n                nextChunk = false;\n            } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) {\n                nextChunk = true;\n            } else {\n                throw new MalformedStreamException(\"Unexpected characters follow a boundary\");\n            }\n        } catch (IOException e) {\n            throw new MalformedStreamException(\"Stream ended unexpectedly\");\n        }\n        return nextChunk;\n    }\n\n    /**\n     * <p>Changes the boundary token used for partitioning the stream.\n     * </p>\n     * <p>This method allows single pass processing of nested multipart\n     * streams.\n     * </p>\n     * <p>The boundary token of the nested stream is <code>required</code>\n     * to be of the same length as the boundary token in parent stream.\n     * </p>\n     * <p>Restoring the parent stream boundary token after processing of a\n     * nested stream is left to the application.\n     * </p>\n     * @param boundary The boundary to be used for parsing of the nested\n     *                 stream.\n     */\n    public void setBoundary(byte[] boundary) {\n        if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) {\n            throw new IllegalBoundaryException(\"The length of a boundary token can not be changed\");\n        }\n        System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, boundary.length);\n    }\n\n    /**\n     * <p>Reads the <code>header-part</code> of the current\n     * <code>encapsulation</code>.\n     * </p>\n     * <p>Headers are returned verbatim to the input stream, including the\n     * trailing <code>CRLF</code> marker. Parsing is left to the\n     * application.\n     * </p>\n     *\n     * @return The <code>header-part</code> of the current encapsulation.\n     */\n    public String readHeaders() {\n        int i = 0;\n        byte b;\n        // to support multi-byte characters\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        int size = 0;\n        while (i < HEADER_SEPARATOR.length) {\n            try {\n                b = readByte();\n            } catch (IOException e) {\n                throw new MalformedStreamException(\"Stream ended unexpectedly\");\n            }\n            if (++size > HEADER_PART_SIZE_MAX) {\n                throw new MalformedStreamException(\n                        format(\"Header section has more than %s bytes (maybe it is not properly terminated)\",\n                               Integer.valueOf(HEADER_PART_SIZE_MAX)));\n            }\n            if (b == HEADER_SEPARATOR[i]) {\n                i++;\n            } else {\n                i = 0;\n            }\n            baos.write(b);\n        }\n\n        String headers = null;\n        if (headerEncoding != null) {\n            try {\n                headers = baos.toString(headerEncoding);\n            } catch (UnsupportedEncodingException e) {\n                // Fall back to platform default if specified encoding is not\n                // supported.\n                if (!headerEncoding.equals(Charset.defaultCharset().displayName())) {\n                    try {\n                        headers = baos.toString(Charset.defaultCharset().displayName());\n                    } catch (UnsupportedEncodingException e1) {\n                        throw new FormUploadException(\"Provided encoding doesn't support\", e);\n                    }\n                }\n            }\n        } else {\n            try {\n                headers = baos.toString(Charset.defaultCharset().displayName());\n            } catch (UnsupportedEncodingException e) {\n                throw new FormUploadException(\"Provided encoding doesn't support\", e);\n            }\n        }\n\n        return headers;\n    }\n\n    /**\n     * <p>Reads <code>body-data</code> from the current\n     * <code>encapsulation</code> and writes its contents into the\n     * output <code>Stream</code>.\n     * </p>\n     * <p>Arbitrary large amounts of data can be processed by this\n     * method using a constant size buffer. (see {@link\n     * #MultipartStream(InputStream, byte[], int) constructor}).\n     * </p>\n     * @param output The <code>Stream</code> to write data into. May\n     *               be null, in which case this method is equivalent\n     *               to {@link #discardBodyData()}.\n     * @return the amount of data written.\n     */\n    public int readBodyData(OutputStream output) {\n        return (int) StreamUtil.copy(newInputStream(), output, false); // N.B. Streams.copy closes the input stream\n    }\n\n    /**\n     * Creates a new {@link ItemInputStream}.\n     *\n     * @return A new instance of {@link ItemInputStream}.\n     */\n    ItemInputStream newInputStream() {\n        return new ItemInputStream();\n    }\n\n    /**\n     * <p> Reads <code>body-data</code> from the current\n     * <code>encapsulation</code> and discards it.\n     * </p>\n     * <p>Use this method to skip encapsulations you don't need or don't\n     * understand.</p>\n     *\n     * @return The amount of data discarded.\n     */\n    public int discardBodyData() {\n        return readBodyData(null);\n    }\n\n    /**\n     * Finds the beginning of the first <code>encapsulation</code>.\n     *\n     * @return <code>true</code> if an <code>encapsulation</code> was found in\n     * the stream.\n     */\n    public boolean skipPreamble() {\n        // First delimiter may be not preceeded with a CRLF.\n        System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);\n        boundaryLength = boundary.length - 2;\n        try {\n            // Discard all data up to the delimiter.\n            discardBodyData();\n\n            // Read boundary - if succeeded, the stream contains an\n            // encapsulation.\n            return readBoundary();\n        } catch (MalformedStreamException e) {\n            return false;\n        } finally {\n            // Restore delimiter.\n            System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2);\n            boundaryLength = boundary.length;\n            boundary[0] = CR;\n            boundary[1] = LF;\n        }\n    }\n\n    /**\n     * Compares <code>count</code> first bytes in the arrays\n     * <code>a</code> and <code>b</code>.\n     *\n     * @param a     The first array to compare.\n     * @param b     The second array to compare.\n     * @param count How many bytes should be compared.\n     * @return <code>true</code> if <code>count</code> first bytes in arrays\n     * <code>a</code> and <code>b</code> are equal.\n     */\n    public static boolean arrayequals(byte[] a, byte[] b, int count) {\n        for (int i = 0; i < count; i++) {\n            if (a[i] != b[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Searches for a byte of specified value in the <code>buffer</code>,\n     * starting at the specified <code>position</code>.\n     *\n     * @param value The value to find.\n     * @param pos   The starting position for searching.\n     * @return The position of byte found, counting from beginning of the\n     * <code>buffer</code>, or <code>-1</code> if not found.\n     */\n    protected int findByte(byte value, int pos) {\n        for (int i = pos; i < tail; i++) {\n            if (buffer[i] == value) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * Searches for the <code>boundary</code> in the <code>buffer</code>\n     * region delimited by <code>head</code> and <code>tail</code>.\n     *\n     * @return The position of the boundary found, counting from the\n     * beginning of the <code>buffer</code>, or <code>-1</code> if\n     * not found.\n     */\n    protected int findSeparator() {\n        int first;\n        int match = 0;\n        int maxpos = tail - boundaryLength;\n        for (first = head; first <= maxpos && match != boundaryLength; first++) {\n            first = findByte(boundary[0], first);\n            if (first == -1 || first > maxpos) {\n                return -1;\n            }\n            for (match = 1; match < boundaryLength; match++) {\n                if (buffer[first + match] != boundary[match]) {\n                    break;\n                }\n            }\n        }\n        if (match == boundaryLength) {\n            return first - 1;\n        }\n        return -1;\n    }\n\n    /**\n     * Thrown to indicate that the input stream fails to follow the\n     * required syntax.\n     */\n    public static class MalformedStreamException extends RuntimeException {\n\n        /**\n         * The UID to use when serializing this instance.\n         */\n        private static final long serialVersionUID = 6466926458059796677L;\n\n        /**\n         * Constructs a <code>MalformedStreamException</code> with no\n         * detail message.\n         */\n        public MalformedStreamException() {\n            super();\n        }\n\n        /**\n         * Constructs an <code>MalformedStreamException</code> with\n         * the specified detail message.\n         *\n         * @param message The detail message.\n         */\n        public MalformedStreamException(String message) {\n            super(message);\n        }\n\n    }\n\n    /**\n     * Thrown upon attempt of setting an invalid boundary token.\n     */\n    public static class IllegalBoundaryException extends RuntimeException {\n\n        /**\n         * The UID to use when serializing this instance.\n         */\n        private static final long serialVersionUID = -161533165102632918L;\n\n        /**\n         * Constructs an <code>IllegalBoundaryException</code> with\n         * the specified detail message.\n         *\n         * @param message The detail message.\n         */\n        public IllegalBoundaryException(String message) {\n            super(message);\n        }\n\n    }\n\n    /**\n     * An {@link InputStream} for reading an items contents.\n     */\n    public class ItemInputStream extends InputStream implements Closeable {\n\n        /**\n         * The number of bytes, which have been read so far.\n         */\n        private long total;\n\n        /**\n         * The number of bytes, which must be hold, because\n         * they might be a part of the boundary.\n         */\n        private int pad;\n\n        /**\n         * The current offset in the buffer.\n         */\n        private int pos;\n\n        /**\n         * Whether the stream is already closed.\n         */\n        private boolean closed;\n\n        /**\n         * Creates a new instance.\n         */\n        ItemInputStream() {\n            findSeparator();\n        }\n\n        /**\n         * Called for finding the separator.\n         */\n        private void findSeparator() {\n            pos = MultipartStream.this.findSeparator();\n            if (pos == -1) {\n                if (tail - head > keepRegion) {\n                    pad = keepRegion;\n                } else {\n                    pad = tail - head;\n                }\n            }\n        }\n\n        /**\n         * Returns the number of bytes, which have been read\n         * by the stream.\n         *\n         * @return Number of bytes, which have been read so far.\n         */\n        public long getBytesRead() {\n            return total;\n        }\n\n        /**\n         * Returns the number of bytes, which are currently\n         * available, without blocking.\n         *\n         * @return Number of bytes in the buffer.\n         */\n        @Override\n        public int available() {\n            if (pos == -1) {\n                return tail - head - pad;\n            }\n            return pos - head;\n        }\n\n        /**\n         * Offset when converting negative bytes to integers.\n         */\n        private static final int BYTE_POSITIVE_OFFSET = 256;\n\n        /**\n         * Returns the next byte in the stream.\n         *\n         * @return The next byte in the stream, as a non-negative\n         * integer, or -1 for EOF.\n         * @throws IOException An I/O error occurred.\n         */\n        @Override\n        public int read() throws IOException {\n            if (closed) {\n                throw new FormItem.ItemSkippedException();\n            }\n            if (available() == 0 && makeAvailable() == 0) {\n                return -1;\n            }\n            ++total;\n            int b = buffer[head++];\n            if (b >= 0) {\n                return b;\n            }\n            return b + BYTE_POSITIVE_OFFSET;\n        }\n\n        /**\n         * Reads bytes into the given buffer.\n         *\n         * @param b   The destination buffer, where to write to.\n         * @param off Offset of the first byte in the buffer.\n         * @param len Maximum number of bytes to read.\n         * @return Number of bytes, which have been actually read,\n         * or -1 for EOF.\n         * @throws IOException An I/O error occurred.\n         */\n        @Override\n        public int read(byte[] b, int off, int len) throws IOException {\n            if (closed) {\n                throw new FormItem.ItemSkippedException();\n            }\n            if (len == 0) {\n                return 0;\n            }\n            int res = available();\n            if (res == 0) {\n                res = makeAvailable();\n                if (res == 0) {\n                    return -1;\n                }\n            }\n            res = Math.min(res, len);\n            System.arraycopy(buffer, head, b, off, res);\n            head += res;\n            total += res;\n            return res;\n        }\n\n        /**\n         * Closes the input stream.\n         *\n         * @throws IOException An I/O error occurred.\n         */\n        @Override\n        public void close() throws IOException {\n            close(false);\n        }\n\n        /**\n         * Closes the input stream.\n         *\n         * @param pCloseUnderlying Whether to close the underlying stream\n         *                         (hard close)\n         * @throws IOException An I/O error occurred.\n         */\n        public void close(boolean pCloseUnderlying) throws IOException {\n            if (closed) {\n                return;\n            }\n            if (pCloseUnderlying) {\n                closed = true;\n                input.close();\n            } else {\n                for (;;) {\n                    int av = available();\n                    if (av == 0) {\n                        av = makeAvailable();\n                        if (av == 0) {\n                            break;\n                        }\n                    }\n                    long skip = skip(av);\n                    if (skip != av) {\n                        if (log.isDebugEnabled()) {\n                            log.debug(skip + \" bytes been skipped.\");\n                        }\n                    }\n                }\n            }\n            closed = true;\n        }\n\n        /**\n         * Skips the given number of bytes.\n         *\n         * @param bytes Number of bytes to skip.\n         * @return The number of bytes, which have actually been\n         * skipped.\n         */\n        @Override\n        public long skip(long bytes) {\n            if (closed) {\n                throw new FormItem.ItemSkippedException();\n            }\n            int av = available();\n            if (av == 0) {\n                av = makeAvailable();\n                if (av == 0) {\n                    return 0;\n                }\n            }\n            long res = Math.min(av, bytes);\n            head += res;\n            return res;\n        }\n\n        /**\n         * Attempts to read more data.\n         *\n         * @return Number of available bytes\n         */\n        private int makeAvailable() {\n            if (pos != -1) {\n                return 0;\n            }\n\n            // Move the data to the beginning of the buffer.\n            total += tail - head - pad;\n            System.arraycopy(buffer, tail - pad, buffer, 0, pad);\n\n            // Refill buffer with new data.\n            head = 0;\n            tail = pad;\n\n            for (;;) {\n                int bytesRead = 0;\n                try {\n                    bytesRead = input.read(buffer, tail, bufSize - tail);\n                } catch (IOException e) {\n                    throw new RuntimeException(\"Error while reading multipart stream\");\n                }\n                if (bytesRead == -1) {\n                    // The last pad amount is left in the buffer.\n                    // Boundary can't be in there so signal an error\n                    // condition.\n                    final String msg = \"Stream ended unexpectedly\";\n                    throw new MalformedStreamException(msg);\n                }\n                tail += bytesRead;\n\n                findSeparator();\n                int av = available();\n\n                if (av > 0 || pos != -1) {\n                    return av;\n                }\n            }\n        }\n\n        /**\n         * Returns, whether the stream is closed.\n         *\n         * @return True, if the stream is closed, otherwise false.\n         */\n        public boolean isClosed() {\n            return closed;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/ParameterParser.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\nimport org.wso2.msf4j.formparam.util.mime.MimeUtility;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\n/**\n * A simple parser intended to parse sequences of name/value pairs.\n * <p>\n * Parameter values are expected to be enclosed in quotes if they\n * contain unsafe characters, such as '=' characters or separators.\n * Parameter values are optional and can be omitted.\n *\n * <p>\n * <code>param1 = value; param2 = \"anything goes; really\"; param3</code>\n * </p>\n *\n */\npublic class ParameterParser {\n\n    /**\n     * String to be parsed.\n     */\n    private char[] chars =  null;\n\n    /**\n     * Current position in the string.\n     */\n    private int pos = 0;\n\n    /**\n     * Maximum position in the string.\n     */\n    private int len = 0;\n\n    /**\n     * Start of a token.\n     */\n    private int i1 = 0;\n\n    /**\n     * End of a token.\n     */\n    private int i2 = 0;\n\n    /**\n     * Whether names stored in the map should be converted to lower case.\n     */\n    private boolean lowerCaseNames = false;\n\n    /**\n     * Default ParameterParser constructor.\n     */\n    public ParameterParser() {\n        super();\n    }\n\n    /**\n     * Are there any characters left to parse?\n     *\n     * @return {@code true} if there are unparsed characters,\n     * {@code false} otherwise.\n     */\n    private boolean hasChar() {\n        return this.pos < this.len;\n    }\n\n    /**\n     * A helper method to process the parsed token. This method removes\n     * leading and trailing blanks as well as enclosing quotation marks,\n     * when necessary.\n     *\n     * @param quoted {@code true} if quotation marks are expected,\n     *               {@code false} otherwise.\n     * @return the token\n     */\n    private String getToken(boolean quoted) {\n        // Trim leading white spaces\n        while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) {\n            i1++;\n        }\n        // Trim trailing white spaces\n        while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) {\n            i2--;\n        }\n        // Strip away quotation marks if necessary\n        if (quoted && ((i2 - i1) >= 2) && (chars[i1] == '\"') && (chars[i2 - 1] == '\"')) {\n            i1++;\n            i2--;\n        }\n        String result = null;\n        if (i2 > i1) {\n            result = new String(chars, i1, i2 - i1);\n        }\n        return result;\n    }\n\n    /**\n     * Tests if the given character is present in the array of characters.\n     *\n     * @param ch      the character to test for presense in the array of characters\n     * @param charray the array of characters to test against\n     * @return {@code true} if the character is present in the array of\n     * characters, {@code false} otherwise.\n     */\n    private boolean isOneOf(char ch, final char[] charray) {\n        boolean result = false;\n        for (char element : charray) {\n            if (ch == element) {\n                result = true;\n                break;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Parses out a token until any of the given terminators\n     * is encountered.\n     *\n     * @param terminators the array of terminating characters. Any of these\n     *                    characters when encountered signify the end of the token\n     * @return the token\n     */\n    private String parseToken(final char[] terminators) {\n        char ch;\n        i1 = pos;\n        i2 = pos;\n        while (hasChar()) {\n            ch = chars[pos];\n            if (isOneOf(ch, terminators)) {\n                break;\n            }\n            i2++;\n            pos++;\n        }\n        return getToken(false);\n    }\n\n    /**\n     * Parses out a token until any of the given terminators\n     * is encountered outside the quotation marks.\n     *\n     * @param terminators the array of terminating characters. Any of these\n     *                    characters when encountered outside the quotation marks signify the end\n     *                    of the token\n     * @return the token\n     */\n    private String parseQuotedToken(final char[] terminators) {\n        char ch;\n        i1 = pos;\n        i2 = pos;\n        boolean quoted = false;\n        boolean charEscaped = false;\n        while (hasChar()) {\n            ch = chars[pos];\n            if (!quoted && isOneOf(ch, terminators)) {\n                break;\n            }\n            if (!charEscaped && ch == '\"') {\n                quoted = !quoted;\n            }\n            charEscaped = (!charEscaped && ch == '\\\\');\n            i2++;\n            pos++;\n\n        }\n        return getToken(true);\n    }\n\n    /**\n     * Returns {@code true} if parameter names are to be converted to lower\n     * case when name/value pairs are parsed.\n     *\n     * @return {@code true} if parameter names are to be\n     * converted to lower case when name/value pairs are parsed.\n     * Otherwise returns {@code false}\n     */\n    public boolean isLowerCaseNames() {\n        return this.lowerCaseNames;\n    }\n\n    /**\n     * Sets the flag if parameter names are to be converted to lower case when\n     * name/value pairs are parsed.\n     *\n     * @param b {@code true} if parameter names are to be\n     *          converted to lower case when name/value pairs are parsed.\n     *          {@code false} otherwise.\n     */\n    public void setLowerCaseNames(boolean b) {\n        this.lowerCaseNames = b;\n    }\n\n    /**\n     * Extracts a map of name/value pairs from the given string. Names are\n     * expected to be unique. Multiple separators may be specified and\n     * the earliest found in the input string is used.\n     *\n     * @param str        the string that contains a sequence of name/value pairs\n     * @param separators the name/value pairs separators\n     * @return a map of name/value pairs\n     */\n    public Map<String, String> parse(final String str, char[] separators) {\n        if (separators == null || separators.length == 0) {\n            return new HashMap<>();\n        }\n        char separator = separators[0];\n        if (str != null) {\n            int idx = str.length();\n            for (char separator2 : separators) {\n                int tmp = str.indexOf(separator2);\n                if (tmp != -1 && tmp < idx) {\n                    idx = tmp;\n                    separator = separator2;\n                }\n            }\n        }\n        return parse(str, separator);\n    }\n\n    /**\n     * Extracts a map of name/value pairs from the given string. Names are\n     * expected to be unique.\n     *\n     * @param str       the string that contains a sequence of name/value pairs\n     * @param separator the name/value pairs separator\n     * @return a map of name/value pairs\n     */\n    public Map<String, String> parse(final String str, char separator) {\n        if (str == null) {\n            return new HashMap<>();\n        }\n        return parse(str.toCharArray(), separator);\n    }\n\n    /**\n     * Extracts a map of name/value pairs from the given array of\n     * characters. Names are expected to be unique.\n     *\n     * @param charArray the array of characters that contains a sequence of\n     *                  name/value pairs\n     * @param separator the name/value pairs separator\n     * @return a map of name/value pairs\n     */\n    public Map<String, String> parse(final char[] charArray, char separator) {\n        if (charArray == null) {\n            return new HashMap<>();\n        }\n        return parse(charArray, 0, charArray.length, separator);\n    }\n\n    /**\n     * Extracts a map of name/value pairs from the given array of\n     * characters. Names are expected to be unique.\n     *\n     * @param charArray - the array of characters that contains a sequence of name/value pairs\n     * @param offset    - the initial offset.\n     * @param length    - the length.\n     * @param separator the name/value pairs separator\n     * @return a map of name/value pairs\n     */\n    public Map<String, String> parse(final char[] charArray, int offset, int length, char separator) {\n        if (charArray == null) {\n            return new HashMap<>();\n        }\n        HashMap<String, String> params = new HashMap<>();\n        this.chars = Arrays.copyOf(charArray, charArray.length);\n        this.pos = offset;\n        this.len = length;\n\n        String paramName;\n        String paramValue;\n        while (hasChar()) {\n            paramName = parseToken(new char[] { '=', separator });\n            paramValue = null;\n            if (hasChar() && (charArray[pos] == '=')) {\n                pos++; // skip '='\n                paramValue = parseQuotedToken(new char[] { separator });\n\n                if (paramValue != null) {\n                    try {\n                        paramValue = MimeUtility.decodeText(paramValue);\n                    } catch (UnsupportedEncodingException e) {\n                        // let's keep the original value in this case\n                    }\n                }\n            }\n            if (hasChar() && (charArray[pos] == separator)) {\n                pos++; // skip separator\n            }\n            if ((paramName != null) && (paramName.length() > 0)) {\n                if (this.lowerCaseNames) {\n                    paramName = paramName.toLowerCase(Locale.ENGLISH);\n                }\n\n                params.put(paramName, paramValue);\n            }\n        }\n        return params;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/RequestContext.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam;\n\nimport org.wso2.msf4j.Request;\n\nimport java.io.InputStream;\nimport java.nio.charset.Charset;\n\n/**\n * Request information needed for file uploads.\n */\npublic class RequestContext {\n\n    private Request request;\n\n    public RequestContext(Request request) {\n        this.request = request;\n    }\n\n    /**\n     * Get request's character encoding.\n     *\n     * @return character encoding of the request\n     */\n    public String getCharacterEncoding() {\n        return Charset.defaultCharset().name();\n    }\n\n    /**\n     * Get the request's content type.\n     *\n     * @return String request's content type\n     */\n    public String getContentType() {\n        return this.request.getHeader(\"Content-Type\");\n    }\n\n    /**\n     * Get the request's inputstream.\n     *\n     * @return InputStream request's inputstream\n     */\n    public InputStream getInputStream() {\n        return request.getMessageContentStream();\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/exception/FormUploadException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.exception;\n\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\n\n/**\n * Exception for errors encountered while processing the request.\n *\n */\npublic class FormUploadException extends RuntimeException {\n\n    /**\n     * Serial version UID, being used, if the exception\n     * is serialized.\n     */\n    private static final long serialVersionUID = 8881893724388807504L;\n\n    /**\n     * The exceptions cause. We overwrite the cause of\n     * the super class, which isn't available in Java 1.3.\n     */\n    private final Throwable cause;\n\n    /**\n     * Constructs a new <code>FileUploadException</code> without message.\n     */\n    public FormUploadException() {\n        this(null, null);\n    }\n\n    /**\n     * Constructs a new <code>FileUploadException</code> with specified detail\n     * message.\n     *\n     * @param msg the error message.\n     */\n    public FormUploadException(final String msg) {\n        this(msg, null);\n    }\n\n    /**\n     * Creates a new <code>FileUploadException</code> with the given\n     * detail message and cause.\n     *\n     * @param msg The exceptions detail message.\n     * @param cause The exceptions cause.\n     */\n    public FormUploadException(String msg, Throwable cause) {\n        super(msg);\n        this.cause = cause;\n    }\n\n    /**\n     * Prints this throwable and its backtrace to the specified print stream.\n     *\n     * @param stream <code>PrintStream</code> to use for output\n     */\n    @Override\n    public void printStackTrace(PrintStream stream) {\n        super.printStackTrace(stream);\n        if (cause != null) {\n            stream.println(\"Caused by:\");\n            cause.printStackTrace(stream);\n        }\n    }\n\n    /**\n     * Prints this throwable and its backtrace to the specified\n     * print writer.\n     *\n     * @param writer <code>PrintWriter</code> to use for output\n     */\n    @Override\n    public void printStackTrace(PrintWriter writer) {\n        super.printStackTrace(writer);\n        if (cause != null) {\n            writer.println(\"Caused by:\");\n            cause.printStackTrace(writer);\n        }\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public Throwable getCause() {\n        return cause;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/exception/InvalidContentTypeException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.exception;\n\n/**\n * Thrown to indicate that the request is not a multipart request.\n */\npublic class InvalidContentTypeException extends FormUploadException {\n\n    /**\n     * The exceptions UID, for serializing an instance.\n     */\n    private static final long serialVersionUID = -9073026332015646668L;\n\n    /**\n     * Constructs an <code>InvalidContentTypeException</code> with\n     * the specified detail message.\n     *\n     * @param message The detail message.\n     */\n    public InvalidContentTypeException(String message) {\n        super(message);\n    }\n\n    /**\n     * Constructs an <code>InvalidContentTypeException</code> with\n     * the specified detail message and cause.\n     *\n     * @param msg   The detail message.\n     * @param cause the original cause\n     */\n    public InvalidContentTypeException(String msg, Throwable cause) {\n        super(msg, cause);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/exception/InvalidFileNameException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.exception;\n\n/**\n * This exception is thrown in case of an invalid file name.\n * A file name is invalid, if it contains a NUL character.\n * Attackers might use this to circumvent security checks:\n * For example, a malicious user might upload a file with the name\n * \"foo.exe\\0.png\". This file name might pass security checks (i.e.\n * checks for the extension \".png\"), while, depending on the underlying\n * C library, it might create a file named \"foo.exe\", as the NUL\n * character is the string terminator in C.\n *\n */\npublic class InvalidFileNameException extends RuntimeException {\n\n    /**\n     * Serial version UID, being used, if the exception\n     * is serialized.\n     */\n    private static final long serialVersionUID = 7922042602454350470L;\n\n    /**\n     * The file name causing the exception.\n     */\n    private final String name;\n\n    /**\n     * Creates a new instance.\n     *\n     * @param pName The file name causing the exception.\n     * @param pMessage A human readable error message.\n     */\n    public InvalidFileNameException(String pName, String pMessage) {\n        super(pMessage);\n        name = pName;\n    }\n\n    /**\n     * Returns the invalid file name.\n     *\n     * @return the invalid file name.\n     */\n    public String getName() {\n        return name;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/Closeable.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util;\n\nimport java.io.IOException;\n\n/**\n * Interface of an object, which may be closed.\n *\n */\npublic interface Closeable {\n\n    /**\n     * Closes the object.\n     *\n     * @throws IOException An I/O error occurred.\n     */\n    void close() throws IOException;\n\n    /**\n     * Returns, whether the object is already closed.\n     *\n     * @return True, if the object is closed, otherwise false.\n     * @throws IOException An I/O error occurred.\n     */\n    boolean isClosed() throws IOException;\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/FormItemHeader.java",
    "content": "\n/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\n\n/**\n * <p> This class provides support for accessing the headers for a file or form\n * item that was received within a <code>multipart/form-data</code> POST\n * request.</p>\n */\npublic class FormItemHeader implements Serializable {\n\n    /**\n     * Serial version UID, being used, if serialized.\n     */\n    private static final long serialVersionUID = -4455695752627032559L;\n\n    /**\n     * Map of <code>String</code> keys to a <code>List</code> of\n     * <code>String</code> instances.\n     */\n    private final Map<String, List<String>> headerNameToValueListMap = new LinkedHashMap<>();\n\n    /**\n     * {@inheritDoc}\n     */\n    public String getHeader(String name) {\n        String nameLower = name.toLowerCase(Locale.ENGLISH);\n        List<String> headerValueList = headerNameToValueListMap.get(nameLower);\n        if (null == headerValueList) {\n            return null;\n        }\n        return headerValueList.get(0);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public Iterator<String> getHeaderNames() {\n        return headerNameToValueListMap.keySet().iterator();\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public Iterator<String> getHeaders(String name) {\n        String nameLower = name.toLowerCase(Locale.ENGLISH);\n        List<String> headerValueList = headerNameToValueListMap.get(nameLower);\n        if (null == headerValueList) {\n            headerValueList = Collections.emptyList();\n        }\n        return headerValueList.iterator();\n    }\n\n    /**\n     * Method to add header values to this instance.\n     *\n     * @param name name of this header\n     * @param value value of this header\n     */\n    public synchronized void addHeader(String name, String value) {\n        String nameLower = name.toLowerCase(Locale.ENGLISH);\n        List<String> headerValueList = headerNameToValueListMap.get(nameLower);\n        if (null == headerValueList) {\n            headerValueList = new ArrayList<>();\n            headerNameToValueListMap.put(nameLower, headerValueList);\n        }\n        headerValueList.add(value);\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/StreamUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util;\n\nimport org.apache.commons.io.IOUtils;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.exception.InvalidFileNameException;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.charset.Charset;\n\n/**\n * Utility class for working with streams.\n */\npublic final class StreamUtil {\n\n    /**\n     * Private constructor, to prevent instantiation.\n     * This class has only static methods.\n     */\n    private StreamUtil() {\n        // Does nothing\n    }\n\n    /**\n     * Default buffer size for use in\n     * {@link #copy(InputStream, OutputStream, boolean)}.\n     */\n    private static final int DEFAULT_BUFFER_SIZE = 8192;\n\n    /**\n     * Copies the contents of the given {@link InputStream}\n     * to the given {@link OutputStream}. Shortcut for\n     * <pre>\n     *   copy(pInputStream, pOutputStream, new byte[8192]);\n     * </pre>\n     *\n     * @param inputStream       The input stream, which is being read.\n     *                          It is guaranteed, that {@link InputStream#close()} is called\n     *                          on the stream.\n     * @param outputStream      The output stream, to which data should\n     *                          be written. May be null, in which case the input streams\n     *                          contents are simply discarded.\n     * @param closeOutputStream True guarantees, that {@link OutputStream#close()}\n     *                          is called on the stream. False indicates, that only\n     *                          {@link OutputStream#flush()} should be called finally.\n     * @return Number of bytes, which have been copied.\n     */\n    public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream) {\n        return copy(inputStream, outputStream, closeOutputStream, new byte[DEFAULT_BUFFER_SIZE]);\n    }\n\n    /**\n     * Copies the contents of the given {@link InputStream}\n     * to the given {@link OutputStream}.\n     *\n     * @param inputStream       The input stream, which is being read.\n     *                          It is guaranteed, that {@link InputStream#close()} is called\n     *                          on the stream.\n     * @param outputStream      The output stream, to which data should\n     *                          be written. May be null, in which case the input streams\n     *                          contents are simply discarded.\n     * @param closeOutputStream True guarantees, that {@link OutputStream#close()}\n     *                          is called on the stream. False indicates, that only\n     *                          {@link OutputStream#flush()} should be called finally.\n     * @param buffer            Temporary buffer, which is to be used for\n     *                          copying data.\n     * @return Number of bytes, which have been copied.\n     */\n    public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream,\n                            byte[] buffer) {\n        OutputStream out = outputStream;\n        InputStream in = inputStream;\n        try {\n            long total = 0;\n            for (;;) {\n                int res = in.read(buffer);\n                if (res == -1) {\n                    break;\n                }\n                if (res > 0) {\n                    total += res;\n                    if (out != null) {\n                        out.write(buffer, 0, res);\n                    }\n                }\n            }\n            if (out != null) {\n                if (!closeOutputStream) {\n                    out.flush();\n                }\n            }\n            return total;\n        } catch (IOException e) {\n            throw new FormUploadException(\"Error while copying streams\", e);\n        } finally {\n            IOUtils.closeQuietly(in);\n            if (closeOutputStream) {\n                IOUtils.closeQuietly(out);\n            }\n        }\n    }\n\n    /**\n     * This convenience method allows to read a\n     * {@link org.wso2.msf4j.formparam.FormItem}'s\n     * content into a string. The platform's default character encoding\n     * is used for converting bytes into characters.\n     *\n     * @param inputStream The input stream to read.\n     * @return The streams contents, as a string.\n     * @throws IOException An I/O error occurred.\n     * @see #asString(InputStream, String)\n     */\n    public static String asString(InputStream inputStream) throws IOException {\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        copy(inputStream, baos, true);\n        return baos.toString(Charset.defaultCharset().name());\n    }\n\n    /**\n     * This convenience method allows to read a\n     * {@link org.wso2.msf4j.formparam.FormItem}'s\n     * content into a string, using the given character encoding.\n     *\n     * @param inputStream The input stream to read.\n     * @param encoding    The character encoding, typically \"UTF-8\".\n     * @return The streams contents, as a string.\n     * @throws IOException An I/O error occurred.\n     * @see #asString(InputStream)\n     */\n    public static String asString(InputStream inputStream, String encoding) throws IOException {\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        copy(inputStream, baos, true);\n        return baos.toString(encoding);\n    }\n\n    /**\n     * Checks, whether the given file name is valid in the sense,\n     * that it doesn't contain any NUL characters. If the file name\n     * is valid, it will be returned without any modifications. Otherwise,\n     * an {@link InvalidFileNameException} is raised.\n     *\n     * @param fileName The file name to check\n     * @return Unmodified file name, if valid.\n     */\n    public static String checkFileName(String fileName) {\n        if (fileName != null && fileName.indexOf('\\u0000') != -1) {\n            // pFileName.replace(\"\\u0000\", \"\\\\0\")\n            final StringBuilder sb = new StringBuilder();\n            for (int i = 0; i < fileName.length(); i++) {\n                char c = fileName.charAt(i);\n                switch (c) {\n                    case 0:\n                        sb.append(\"\\\\0\");\n                        break;\n                    default:\n                        sb.append(c);\n                        break;\n                }\n            }\n            throw new InvalidFileNameException(fileName, \"Invalid file name: \" + sb);\n        }\n        return fileName;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/mime/Base64Decoder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util.mime;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\n/**\n * Simple Bas64 decoder.\n */\nfinal class Base64Decoder {\n\n    /**\n     * Decoding table value for invalid bytes.\n     */\n    private static final int INVALID_BYTE = -1; // must be outside range 0-63\n\n    /**\n     * Decoding table value for padding bytes, so can detect PAD afer conversion.\n     */\n    private static final int PAD_BYTE = -2; // must be outside range 0-63\n\n    /**\n     * Mask to treat byte as unsigned integer.\n     */\n    private static final int MASK_BYTE_UNSIGNED = 0xFF;\n\n    /**\n     * Number of bytes per encoded chunk - 4 6bit bytes produce 3 8bit bytes on output.\n     */\n    private static final int INPUT_BYTES_PER_CHUNK = 4;\n\n    /**\n     * Set up the encoding table.\n     */\n    private static final byte[] ENCODING_TABLE =\n            { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H',\n              (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',\n              (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X',\n              (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',\n              (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',\n              (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v',\n              (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',\n              (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' };\n\n    /**\n     * The padding byte.\n     */\n    private static final byte PADDING = (byte) '=';\n\n    /**\n     * Set up the decoding table; this is indexed by a byte converted to an unsigned int,\n     * so must be at least as large as the number of different byte values,\n     * positive and negative and zero.\n     */\n    private static final byte[] DECODING_TABLE = new byte[Byte.MAX_VALUE - Byte.MIN_VALUE + 1];\n\n    static {\n        // Initialise as all invalid characters\n        for (int i = 0; i < DECODING_TABLE.length; i++) {\n            DECODING_TABLE[i] = INVALID_BYTE;\n        }\n        // set up valid characters\n        for (int i = 0; i < ENCODING_TABLE.length; i++) {\n            DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i;\n        }\n        // Allow pad byte to be easily detected after conversion\n        DECODING_TABLE[PADDING] = PAD_BYTE;\n    }\n\n    /**\n     * Hidden constructor, this class must not be instantiated.\n     */\n    private Base64Decoder() {\n        // do nothing\n    }\n\n    /**\n     * Decode the base 64 encoded byte data writing it to the given output stream,\n     * whitespace characters will be ignored.\n     *\n     * @param data the buffer containing the Base64-encoded data\n     * @param out  the output stream to hold the decoded bytes\n     * @return the number of bytes produced.\n     * @throws IOException thrown when the padding is incorrect or the input is truncated.\n     */\n    public static int decode(byte[] data, OutputStream out) throws IOException {\n        int outLen = 0;\n        byte[] cache = new byte[INPUT_BYTES_PER_CHUNK];\n        int cachedBytes = 0;\n\n        for (byte b : data) {\n            final byte d = DECODING_TABLE[MASK_BYTE_UNSIGNED & b];\n            if (d == INVALID_BYTE) {\n                continue; // Ignore invalid bytes\n            }\n            cache[cachedBytes++] = d;\n            if (cachedBytes == INPUT_BYTES_PER_CHUNK) {\n                // CHECKSTYLE IGNORE MagicNumber FOR NEXT 4 LINES\n                final byte b1 = cache[0];\n                final byte b2 = cache[1];\n                final byte b3 = cache[2];\n                final byte b4 = cache[3];\n                if (b1 == PAD_BYTE || b2 == PAD_BYTE) {\n                    throw new IOException(\"Invalid Base64 input: incorrect padding, first two bytes cannot be padding\");\n                }\n                // Convert 4 6-bit bytes to 3 8-bit bytes\n                // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE\n                out.write((b1 << 2) | (b2 >> 4)); // 6 bits of b1 plus 2 bits of b2\n                outLen++;\n                if (b3 != PAD_BYTE) {\n                    // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE\n                    out.write((b2 << 4) | (b3 >> 2)); // 4 bits of b2 plus 4 bits of b3\n                    outLen++;\n                    if (b4 != PAD_BYTE) {\n                        // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE\n                        out.write((b3 << 6) | b4);        // 2 bits of b3 plus 6 bits of b4\n                        outLen++;\n                    }\n                } else if (b4 != PAD_BYTE) { // if byte 3 is pad, byte 4 must be pad too\n                    throw new // line wrap to avoid 120 char limit\n                            IOException(\n                            \"Invalid Base64 input: incorrect padding, 4th byte must be padding if 3rd byte is\");\n                }\n                cachedBytes = 0;\n            }\n        }\n        // Check for anything left over\n        if (cachedBytes != 0) {\n            throw new IOException(\"Invalid Base64 input: truncated\");\n        }\n        return outLen;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/mime/MimeUtility.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util.mime;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\n/**\n * Utility class to decode MIME texts.\n *\n */\npublic final class MimeUtility {\n\n    /**\n     * The {@code US-ASCII} charset identifier constant.\n     */\n    private static final String US_ASCII_CHARSET = \"US-ASCII\";\n\n    /**\n     * The marker to indicate text is encoded with BASE64 algorithm.\n     */\n    private static final String BASE64_ENCODING_MARKER = \"B\";\n\n    /**\n     * The marker to indicate text is encoded with QuotedPrintable algorithm.\n     */\n    private static final String QUOTEDPRINTABLE_ENCODING_MARKER = \"Q\";\n\n    /**\n     * If the text contains any encoded tokens, those tokens will be marked with \"=?\".\n     */\n    private static final String ENCODED_TOKEN_MARKER = \"=?\";\n\n    /**\n     * If the text contains any encoded tokens, those tokens will terminate with \"=?\".\n     */\n    private static final String ENCODED_TOKEN_FINISHER = \"?=\";\n\n    /**\n     * The linear whitespace chars sequence.\n     */\n    private static final String LINEAR_WHITESPACE = \" \\t\\r\\n\";\n\n    /**\n     * Mappings between MIME and Java charset.\n     */\n    private static final Map<String, String> MIME2JAVA = new HashMap<>();\n\n    static {\n        MIME2JAVA.put(\"iso-2022-cn\", \"ISO2022CN\");\n        MIME2JAVA.put(\"iso-2022-kr\", \"ISO2022KR\");\n        MIME2JAVA.put(\"utf-8\", \"UTF8\");\n        MIME2JAVA.put(\"utf8\", \"UTF8\");\n        MIME2JAVA.put(\"ja_jp.iso2022-7\", \"ISO2022JP\");\n        MIME2JAVA.put(\"ja_jp.eucjp\", \"EUCJIS\");\n        MIME2JAVA.put(\"euc-kr\", \"KSC5601\");\n        MIME2JAVA.put(\"euckr\", \"KSC5601\");\n        MIME2JAVA.put(\"us-ascii\", \"ISO-8859-1\");\n        MIME2JAVA.put(\"x-us-ascii\", \"ISO-8859-1\");\n    }\n\n    /**\n     * Hidden constructor, this class must not be instantiated.\n     */\n    private MimeUtility() {\n        // do nothing\n    }\n\n    /**\n     * Decode a string of text obtained from a mail header into\n     * its proper form.  The text generally will consist of a\n     * string of tokens, some of which may be encoded using\n     * base64 encoding.\n     *\n     * @param text   The text to decode.\n     *\n     * @return The decoded text string.\n     * @throws UnsupportedEncodingException if the detected encoding in the input text is not supported.\n     */\n    public static String decodeText(String text) throws UnsupportedEncodingException {\n        // if the text contains any encoded tokens, those tokens will be marked with \"=?\".  If the\n        // source string doesn't contain that sequent, no decoding is required.\n        if (!text.contains(ENCODED_TOKEN_MARKER)) {\n            return text;\n        }\n\n        int offset = 0;\n        int endOffset = text.length();\n\n        int startWhiteSpace = -1;\n        int endWhiteSpace = -1;\n\n        StringBuilder decodedText = new StringBuilder(text.length());\n\n        boolean previousTokenEncoded = false;\n\n        while (offset < endOffset) {\n            char ch = text.charAt(offset);\n\n            // is this a whitespace character?\n            if (LINEAR_WHITESPACE.indexOf(ch) != -1) { // whitespace found\n                startWhiteSpace = offset;\n                while (offset < endOffset) {\n                    // step over the white space characters.\n                    ch = text.charAt(offset);\n                    if (LINEAR_WHITESPACE.indexOf(ch) != -1) { // whitespace found\n                        offset++;\n                    } else {\n                        // record the location of the first non lwsp and drop down to process the\n                        // token characters.\n                        endWhiteSpace = offset;\n                        break;\n                    }\n                }\n            } else {\n                // we have a word token.  We need to scan over the word and then try to parse it.\n                int wordStart = offset;\n\n                while (offset < endOffset) {\n                    // step over the non white space characters.\n                    ch = text.charAt(offset);\n                    if (LINEAR_WHITESPACE.indexOf(ch) == -1) { // not white space\n                        offset++;\n                    } else {\n                        break;\n                    }\n\n                    //NB:  Trailing whitespace on these header strings will just be discarded.\n                }\n                // pull out the word token.\n                String word = text.substring(wordStart, offset);\n                // is the token encoded?  decode the word\n                if (word.startsWith(ENCODED_TOKEN_MARKER)) {\n                    try {\n                        // if this gives a parsing failure, treat it like a non-encoded word.\n                        String decodedWord = decodeWord(word);\n\n                        // are any whitespace characters significant?  Append 'em if we've got 'em.\n                        if (!previousTokenEncoded && startWhiteSpace != -1) {\n                            decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));\n                            startWhiteSpace = -1;\n                        }\n                        // this is definitely a decoded token.\n                        previousTokenEncoded = true;\n                        // and add this to the text.\n                        decodedText.append(decodedWord);\n                        // we continue parsing from here...we allow parsing errors to fall through\n                        // and get handled as normal text.\n                        continue;\n\n                    } catch (ParseException e) {\n                        // just ignore it, skip to next word\n                    }\n                }\n                // this is a normal token, so it doesn't matter what the previous token was.  Add the white space\n                // if we have it.\n                if (startWhiteSpace != -1) {\n                    decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));\n                    startWhiteSpace = -1;\n                }\n                // this is not a decoded token.\n                previousTokenEncoded = false;\n                decodedText.append(word);\n            }\n        }\n\n        return decodedText.toString();\n    }\n\n    /**\n     * Parse a string using the RFC 2047 rules for an \"encoded-word\"\n     * type.  This encoding has the syntax:\n     *\n     * encoded-word = \"=?\" charset \"?\" encoding \"?\" encoded-text \"?=\"\n     *\n     * @param word   The possibly encoded word value.\n     *\n     * @return The decoded word.\n     * @throws ParseException\n     * @throws UnsupportedEncodingException\n     */\n    private static String decodeWord(String word) throws ParseException, UnsupportedEncodingException {\n        // encoded words start with the characters \"=?\".  If this not an encoded word, we throw a\n        // ParseException for the caller.\n\n        if (!word.startsWith(ENCODED_TOKEN_MARKER)) {\n            throw new ParseException(\"Invalid RFC 2047 encoded-word: \" + word);\n        }\n\n        int charsetPos = word.indexOf('?', 2);\n        if (charsetPos == -1) {\n            throw new ParseException(\"Missing charset in RFC 2047 encoded-word: \" + word);\n        }\n\n        // pull out the character set information (this is the MIME name at this point).\n        String charset = word.substring(2, charsetPos).toLowerCase(Locale.getDefault());\n\n        // now pull out the encoding token the same way.\n        int encodingPos = word.indexOf('?', charsetPos + 1);\n        if (encodingPos == -1) {\n            throw new ParseException(\"Missing encoding in RFC 2047 encoded-word: \" + word);\n        }\n\n        String encoding = word.substring(charsetPos + 1, encodingPos);\n\n        // and finally the encoded text.\n        int encodedTextPos = word.indexOf(ENCODED_TOKEN_FINISHER, encodingPos + 1);\n        if (encodedTextPos == -1) {\n            throw new ParseException(\"Missing encoded text in RFC 2047 encoded-word: \" + word);\n        }\n\n        String encodedText = word.substring(encodingPos + 1, encodedTextPos);\n\n        // seems a bit silly to encode a null string, but easy to deal with.\n        if (encodedText.length() == 0) {\n            return \"\";\n        }\n\n        try {\n            // the decoder writes directly to an output stream.\n            ByteArrayOutputStream out = new ByteArrayOutputStream(encodedText.length());\n\n            byte[] encodedData = encodedText.getBytes(US_ASCII_CHARSET);\n\n            // Base64 encoded?\n            if (BASE64_ENCODING_MARKER.equals(encoding)) {\n                Base64Decoder.decode(encodedData, out);\n            } else if (QUOTEDPRINTABLE_ENCODING_MARKER.equals(encoding)) { // maybe quoted printable.\n                QuotedPrintableDecoder.decode(encodedData, out);\n            } else {\n                throw new UnsupportedEncodingException(\"Unknown RFC 2047 encoding: \" + encoding);\n            }\n            // get the decoded byte data and convert into a string.\n            byte[] decodedData = out.toByteArray();\n            return new String(decodedData, javaCharset(charset));\n        } catch (IOException e) {\n            throw new UnsupportedEncodingException(\"Invalid RFC 2047 encoding\");\n        }\n    }\n\n    /**\n     * Translate a MIME standard character set name into the Java\n     * equivalent.\n     *\n     * @param charset The MIME standard name.\n     *\n     * @return The Java equivalent for this name.\n     */\n    private static String javaCharset(String charset) {\n        // nothing in, nothing out.\n        if (charset == null) {\n            return null;\n        }\n\n        String mappedCharset = MIME2JAVA.get(charset.toLowerCase(Locale.ENGLISH));\n        // if there is no mapping, then the original name is used.  Many of the MIME character set\n        // names map directly back into Java.  The reverse isn't necessarily true.\n        if (mappedCharset == null) {\n            return charset;\n        }\n        return mappedCharset;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/mime/ParseException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util.mime;\n\n/**\n * Exception that will be thrown if any issues occur\n * when parsing the multipart/form-data request.\n *\n */\nfinal class ParseException extends Exception {\n\n    /**\n     * The UID to use when serializing this instance.\n     */\n    private static final long serialVersionUID = 5355281266579392077L;\n\n    /**\n     * Constructs a new exception with the specified detail message.\n     *\n     * @param message the detail message.\n     */\n    public ParseException(String message) {\n        super(message);\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/mime/QuotedPrintableDecoder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.formparam.util.mime;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\n/**\n * Simple decoder for quoted values.\n */\nfinal class QuotedPrintableDecoder {\n\n    /**\n     * The shift value required to create the upper nibble\n     * from the first of 2 byte values converted from ascii hex.\n     */\n    private static final int UPPER_NIBBLE_SHIFT = Byte.SIZE / 2;\n\n    /**\n     * Hidden constructor, this class must not be instantiated.\n     */\n    private QuotedPrintableDecoder() {\n        // do nothing\n    }\n\n    /**\n     * Decode the encoded byte data writing it to the given output stream.\n     *\n     * @param data   The array of byte data to decode.\n     * @param out    The output stream used to return the decoded data.\n     *\n     * @return the number of bytes produced.\n     * @exception IOException\n     */\n    public static int decode(byte[] data, OutputStream out) throws IOException {\n        int off = 0;\n        int length = data.length;\n        int endOffset = off + length;\n        int bytesWritten = 0;\n\n        while (off < endOffset) {\n            byte ch = data[off++];\n\n            // space characters were translated to '_' on encode, so we need to translate them back.\n            if (ch == '_') {\n                out.write(' ');\n            } else if (ch == '=') {\n                // we found an encoded character.  Reduce the 3 char sequence to one.\n                // but first, make sure we have two characters to work with.\n                if (off + 1 >= endOffset) {\n                    throw new IOException(\"Invalid quoted printable encoding; truncated escape sequence\");\n                }\n\n                byte b1 = data[off++];\n                byte b2 = data[off++];\n\n                // we've found an encoded carriage return.  The next char needs to be a newline\n                if (b1 == '\\r') {\n                    if (b2 != '\\n') {\n                        throw new IOException(\"Invalid quoted printable encoding; CR must be followed by LF\");\n                    }\n                    // this was a soft linebreak inserted by the encoding.  We just toss this away\n                    // on decode.\n                } else {\n                    // this is a hex pair we need to convert back to a single byte.\n                    int c1 = hexToBinary(b1);\n                    int c2 = hexToBinary(b2);\n                    out.write((c1 << UPPER_NIBBLE_SHIFT) | c2);\n                    // 3 bytes in, one byte out\n                    bytesWritten++;\n                }\n            } else {\n                // simple character, just write it out.\n                out.write(ch);\n                bytesWritten++;\n            }\n        }\n\n        return bytesWritten;\n    }\n\n    /**\n     * Convert a hex digit to the binary value it represents.\n     *\n     * @param b the ascii hex byte to convert (0-0, A-F, a-f)\n     * @return the int value of the hex byte, 0-15\n     * @throws IOException if the byte is not a valid hex digit.\n     */\n    private static int hexToBinary(final byte b) throws IOException {\n        // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE\n        final int i = Character.digit((char) b, 16);\n        if (i == -1) {\n            throw new IOException(\"Invalid quoted printable encoding: not a valid hex digit: \" + b);\n        }\n        return i;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/mime/package-info.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 * MIME decoder implementation, imported and retailed from\n * <a href=\"http://svn.apache.org/repos/asf/geronimo/specs/tags/geronimo-javamail_1.4_spec-1.4/\">Apache Geronimo</a>.\n */\npackage org.wso2.msf4j.formparam.util.mime;\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/formparam/util/package-info.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 * This package contains various IO related utility classes\n * or methods, which are basically reusable and not necessarily\n * restricted to the scope of a file upload.\n */\npackage org.wso2.msf4j.formparam.util;\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/InterceptorExecutor.java",
    "content": "/*\n*  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied.  See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.exception.InterceptorException;\nimport org.wso2.msf4j.internal.MicroservicesRegistryImpl;\nimport org.wso2.msf4j.util.ReflectionUtils;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Class for executing interceptors.\n */\npublic class InterceptorExecutor {\n\n    private InterceptorExecutor() {\n    }\n\n    /**\n     * Execute global request interceptors.\n     *\n     * @param microServicesRegistry current micro-service registry of {@link MicroservicesRegistryImpl}\n     * @param request               {@link Request}\n     * @param response              {@link Response}\n     * @return is request interceptors successful\n     */\n    public static boolean executeGlobalRequestInterceptors(MicroservicesRegistryImpl microServicesRegistry,\n                                                           Request request, Response response) {\n        List<RequestInterceptor> globalRequestInterceptorList = microServicesRegistry.getGlobalRequestInterceptorList();\n        return executeGlobalRequestInterceptors(request, response, globalRequestInterceptorList);\n    }\n\n    /**\n     * Execute request interceptors annotated in class.\n     *\n     * @param request       {@link Request}\n     * @param response      {@link Response}\n     * @param resourceClass method declaring class\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeClassLevelRequestInterceptors(Request request, Response response,\n                                                               Class<?> resourceClass) throws InterceptorException {\n        Collection<Class<? extends RequestInterceptor>> classRequestInterceptorClasses =\n                resourceClass.isAnnotationPresent(org.wso2.msf4j.interceptor.annotation.RequestInterceptor.class)\n                        ? Arrays.asList(resourceClass\n                        .getAnnotation(org.wso2.msf4j.interceptor.annotation.RequestInterceptor.class).value())\n                        : new ArrayList<>();\n        return executeNonGlobalRequestInterceptors(request, response, classRequestInterceptorClasses);\n    }\n\n    /**\n     * Execute request interceptors annotated in method\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param method   method to be executed\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeMethodLevelRequestInterceptors(Request request, Response response, Method method)\n            throws InterceptorException {\n        Collection<Class<? extends RequestInterceptor>> methodRequestInterceptorClasses =\n                method.isAnnotationPresent(org.wso2.msf4j.interceptor.annotation.RequestInterceptor.class)\n                        ? Arrays.asList(method\n                        .getAnnotation(org.wso2.msf4j.interceptor.annotation.RequestInterceptor.class).value())\n                        : new ArrayList<>();\n        return executeNonGlobalRequestInterceptors(request, response, methodRequestInterceptorClasses);\n    }\n\n    /**\n     * Execute global response interceptors.\n     *\n     * @param microServicesRegistry current micro-service registry of {@link MicroservicesRegistryImpl}\n     * @param request               {@link Request}\n     * @param response              {@link Response}\n     * @return is request interceptors successful\n     */\n    public static boolean executeGlobalResponseInterceptors(MicroservicesRegistryImpl microServicesRegistry,\n                                                            Request request, Response response) {\n        List<ResponseInterceptor> globalResponseInterceptorList =\n                microServicesRegistry.getGlobalResponseInterceptorList();\n        return executeGlobalResponseInterceptors(request, response, globalResponseInterceptorList);\n    }\n\n    /**\n     * Execute response interceptors annotated in class.\n     *\n     * @param request       {@link Request}\n     * @param response      {@link Response}\n     * @param resourceClass method declaring class\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeClassLevelResponseInterceptors(Request request, Response response,\n                                                                Class<?> resourceClass) throws InterceptorException {\n        List<Class<? extends ResponseInterceptor>> classResponseInterceptorClasses =\n                resourceClass.isAnnotationPresent(org.wso2.msf4j.interceptor.annotation.ResponseInterceptor.class)\n                        ? Arrays.asList(resourceClass\n                        .getAnnotation(org.wso2.msf4j.interceptor.annotation.ResponseInterceptor.class).value())\n                        : new ArrayList<>();\n        return executeNonGlobalResponseInterceptors(request, response, classResponseInterceptorClasses);\n    }\n\n    /**\n     * Execute response interceptors annotated in class for a list of classes.\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param classes  list of method declaring class\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeClassResponseInterceptorsForClasses(Request request, Response response,\n                                                                     List<Class<?>> classes)\n            throws InterceptorException {\n        if (classes == null) {\n            return true;\n        }\n        for (Class<?> aClass : classes) {\n            if (!(InterceptorExecutor.executeClassLevelResponseInterceptors(request, response, aClass))) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute response interceptors annotated in method\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param method   method to be executed\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeMethodLevelResponseInterceptors(Request request, Response response, Method method)\n            throws InterceptorException {\n        List<Class<? extends ResponseInterceptor>> methodResponseInterceptorClasses =\n                method.isAnnotationPresent(org.wso2.msf4j.interceptor.annotation.ResponseInterceptor.class)\n                        ? Arrays.asList(method\n                        .getAnnotation(org.wso2.msf4j.interceptor.annotation.ResponseInterceptor.class).value())\n                        : new ArrayList<>();\n        return executeNonGlobalResponseInterceptors(request, response, methodResponseInterceptorClasses);\n    }\n\n    /**\n     * Execute response interceptors annotated in method for a list of methods.\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param methods  list of methods to be executed\n     * @return is request interceptors successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    public static boolean executeMethodResponseInterceptorsForMethods(Request request, Response response,\n                                                                      List<Method> methods)\n            throws InterceptorException {\n        if (methods == null) {\n            return true;\n        }\n        for (Method resourceMethod : methods) {\n            if (!(InterceptorExecutor.executeMethodLevelResponseInterceptors(request, response, resourceMethod))) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute request interceptors.\n     *\n     * @param request             {@link Request}\n     * @param response            {@link Response}\n     * @param requestInterceptors request interceptor instances\n     * @return is interception successful\n     */\n    private static boolean executeGlobalRequestInterceptors(Request request, Response response,\n                                                            Collection<RequestInterceptor> requestInterceptors) {\n        if (requestInterceptors == null) {\n            return true;\n        }\n        for (RequestInterceptor interceptor : requestInterceptors) {\n            if (!executeRequestInterceptor(interceptor, request, response)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute response interceptors.\n     *\n     * @param request              {@link Request}\n     * @param response             {@link Response}\n     * @param responseInterceptors response interceptor instances\n     * @return is interception successful\n     */\n    private static boolean executeGlobalResponseInterceptors(Request request, Response response,\n                                                             Collection<ResponseInterceptor> responseInterceptors) {\n        if (responseInterceptors == null) {\n            return true;\n        }\n        for (ResponseInterceptor interceptor : responseInterceptors) {\n            if (!executeResponseInterceptor(interceptor, request, response)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute request interceptors.\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param classes  request interceptor classes\n     * @return is interception successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    private static boolean executeNonGlobalRequestInterceptors(\n            Request request, Response response, Collection<Class<? extends RequestInterceptor>> classes)\n            throws InterceptorException {\n\n        Class<?>[] parameterTypes = new Class[]{};\n        Object[] arguments = new Object[]{};\n\n        if (classes == null) {\n            return true;\n        }\n\n        for (Class<? extends RequestInterceptor> requestInterceptorClass : classes) {\n            RequestInterceptor interceptor;\n            try {\n                interceptor = requestInterceptorClass.cast(ReflectionUtils\n                        .createInstanceFromClass(requestInterceptorClass, parameterTypes, arguments));\n            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |\n                    InstantiationException e) {\n                throw new InterceptorException(\"Error occurred when creating an instance type of the interceptor class \"\n                        + requestInterceptorClass, e);\n            }\n\n            if (!executeRequestInterceptor(interceptor, request, response)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute response interceptors.\n     *\n     * @param request  {@link Request}\n     * @param response {@link Response}\n     * @param classes  response interceptor classes\n     * @return is interception successful\n     * @throws InterceptorException {@link InterceptorException} on interception exception\n     */\n    private static boolean executeNonGlobalResponseInterceptors(\n            Request request, Response response, Collection<Class<? extends ResponseInterceptor>> classes)\n            throws InterceptorException {\n\n        Class<?>[] parameterTypes = new Class[]{};\n        Object[] arguments = new Object[]{};\n\n        if (classes == null) {\n            return true;\n        }\n\n        for (Class<? extends ResponseInterceptor> responseInterceptorClass : classes) {\n            ResponseInterceptor interceptor;\n            try {\n                interceptor = responseInterceptorClass.cast(ReflectionUtils\n                        .createInstanceFromClass(responseInterceptorClass, parameterTypes, arguments));\n            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |\n                    InstantiationException e) {\n                throw new InterceptorException(\"Error occurred when creating an instance type of the interceptor class \"\n                        + responseInterceptorClass, e);\n            }\n\n            if (!executeResponseInterceptor(interceptor, request, response)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Execute a single request interceptor.\n     *\n     * @param interceptor request interceptor\n     * @param request     request instance\n     * @param response    response instance\n     * @return interceptor result\n     */\n    private static boolean executeRequestInterceptor(RequestInterceptor interceptor, Request request,\n                                                     Response response) {\n        try {\n            return interceptor.interceptRequest(request, response);\n        } catch (Exception e) {\n            return interceptor.onRequestInterceptionError(request, response, e);\n        }\n    }\n\n    /**\n     * Execute a single response interceptor.\n     *\n     * @param interceptor response interceptor\n     * @param request     request instance\n     * @param response    response instance\n     * @return interceptor result\n     */\n    private static boolean executeResponseInterceptor(ResponseInterceptor interceptor, Request request,\n                                                      Response response) {\n        try {\n            return interceptor.interceptResponse(request, response);\n        } catch (Exception e) {\n            return interceptor.onResponseInterceptionError(request, response, e);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/OSGiInterceptorConfig.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * OSGi interceptor registration component.\n */\npublic class OSGiInterceptorConfig {\n\n    private final List<RequestInterceptor> globalRequestInterceptorList = new ArrayList<>();\n    private final List<ResponseInterceptor> globalResponseInterceptorList = new ArrayList<>();\n\n    /**\n     * Add global request interceptors.\n     * Order in which the interceptors are added are the execution priority order if the interceptors\n     *\n     * @param globalRequestInterceptors {@link RequestInterceptor}\n     */\n    protected final void addGlobalRequestInterceptors(RequestInterceptor... globalRequestInterceptors) {\n        globalRequestInterceptorList.addAll(Arrays.asList(globalRequestInterceptors));\n    }\n\n    /**\n     * Add global response interceptors.\n     * Order in which the interceptors are added are the execution priority order if the interceptors\n     *\n     * @param globalResponseInterceptors {@link ResponseInterceptor}\n     */\n    protected final void addGlobalResponseInterceptors(ResponseInterceptor... globalResponseInterceptors) {\n        globalResponseInterceptorList.addAll(Arrays.asList(globalResponseInterceptors));\n    }\n\n    /**\n     * Get global request interceptors added.\n     *\n     * @return {@link RequestInterceptor}\n     */\n    public final RequestInterceptor[] getGlobalRequestInterceptorArray() {\n        return globalRequestInterceptorList\n                .toArray(new RequestInterceptor[globalRequestInterceptorList.size()]);\n    }\n\n    /**\n     * Get global response interceptors added.\n     *\n     * @return {@link ResponseInterceptor}\n     */\n    public final ResponseInterceptor[] getGlobalResponseInterceptorArray() {\n        return globalResponseInterceptorList\n                .toArray(new ResponseInterceptor[globalResponseInterceptorList.size()]);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/RequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Interface that needs to be implemented to intercept request method calls\n * <p>\n * Priority of request interceptors will be\n * Global request interceptors -> Class level annotated request interceptors\n * -> Method level annotated interceptors -> Resource method execution\n * -> sub-resource method class level annotated interceptors -> sub-resource method method level annotated interceptors\n * -> sub-resource execution\n * <p>\n * Upon returning false from any interceptor will cause the above flow to break and send the response immediately\n * <p>\n * Upon exception in interceptors \"onRequestInterceptionError\" default method in the interface will be called.\n * Override this method for custom behaviour\n */\n@FunctionalInterface\npublic interface RequestInterceptor {\n\n    /**\n     * Globally, resource vise or sub-resource vise intercept requests\n     * Please not that is you decided to return false ideally you should manually set the entity in response by using\n     * method \"setEntity\". Otherwise the response will be a new Object()\n     *\n     * @param request  MSF4J request.\n     * @param response MSF4J response.\n     * @return is interception successful\n     * @throws Exception on any exception\n     */\n    boolean interceptRequest(Request request, Response response) throws Exception;\n\n    /**\n     * This method will be called open request interception error (unhandled by end developer)\n     * Override this method to manually handle exceptions when an unhandled error is thrown.\n     *\n     * @param request  MSF4J request.\n     * @param response MSF4J Response.\n     * @return should interception flow proceed?\n     */\n    default boolean onRequestInterceptionError(Request request, Response response, Exception e) {\n        String message = \"Exception while executing request interceptor \" + this.getClass();\n        Logger log = LoggerFactory.getLogger(this.getClass());\n        log.error(message, e);\n        response.setEntity(message)\n                .setMediaType(MediaType.TEXT_PLAIN)\n                .setStatus(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());\n        return false;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/ResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Interface that needs to be implemented to intercept response method calls\n * <p>\n * Priority of response interceptors will be\n * sub-resource method method level annotated interceptors -> sub-resource method class level annotated interceptors\n * -> Method level annotated response interceptors -> Class level annotated response interceptors\n * -> Global response interceptors\n * <p>\n * Upon returning false from any interceptor will cause the above flow to break and send the response immediately\n * <p>\n * Upon exception in interceptors \"onResponseInterceptionError\" default method in the interface will be called.\n * Override this method for custom behaviour\n */\n@FunctionalInterface\npublic interface ResponseInterceptor {\n\n    /**\n     * Globally, resource vise or sub-resource vise intercept responses.\n     * Please not that is you decided to return false ideally you should manually set the entity in response by using\n     * method \"setEntity\". Otherwise the response will be a new Object()\n     *\n     * @param request  MSF4J request.\n     * @param response MSF4J response.\n     * @return is interception successful\n     * @throws Exception on any exception\n     */\n    boolean interceptResponse(Request request, Response response) throws Exception;\n\n    /**\n     * This method will be called open response interception error (unhandled by end developer)\n     * Override this method to manually handle exceptions when an unhandled error is thrown.\n     *\n     * @param request  MSF4J request.\n     * @param response MSF4J Response.\n     * @return should interception flow proceed?\n     */\n    default boolean onResponseInterceptionError(Request request, Response response, Exception e) {\n        String message = \"Exception while executing response interceptor \" + this.getClass();\n        Logger log = LoggerFactory.getLogger(this.getClass());\n        log.error(message, e);\n        response.setEntity(message)\n                .setMediaType(MediaType.TEXT_PLAIN)\n                .setStatus(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());\n        return false;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/annotation/RequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotation for intercepting a http request.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\npublic @interface RequestInterceptor {\n\n    /**\n     * Request intercept class name.\n     *\n     * @return request intercept class names.\n     */\n    Class<? extends org.wso2.msf4j.interceptor.RequestInterceptor>[] value();\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/interceptor/annotation/ResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotation for intercepting a http response.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\npublic @interface ResponseInterceptor {\n\n    /**\n     * Response intercept class name.\n     *\n     * @return response intercept class names.\n     */\n    Class<? extends org.wso2.msf4j.interceptor.ResponseInterceptor>[] value();\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/ClassComparator.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.internal;\n\nimport java.io.Serializable;\nimport java.util.Comparator;\n\n/**\n * Compares classes to see if they are subclasses.\n */\npublic class ClassComparator implements Comparator<Class>, Serializable {\n\n    private static final long serialVersionUID = 2101798650978464444L;\n\n    @Override\n    public int compare(Class class1, Class class2) {\n        if (class1.equals(class2)) {\n            return 0;\n        } else if (class1.isAssignableFrom(class2)) {\n            return 1;\n        } else {\n            return -1;\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/DataHolder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.wso2.carbon.config.provider.ConfigProvider;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * DataHolder for MSF4J.\n */\npublic class DataHolder {\n\n    private static final DataHolder instance = new DataHolder();\n    private BundleContext bundleContext;\n    private Map<String, MicroservicesRegistryImpl> microservicesRegistries = new HashMap<>();\n    private ConfigProvider configProvider;\n\n    private DataHolder() {\n    }\n\n    public static DataHolder getInstance() {\n        return instance;\n    }\n\n    public BundleContext getBundleContext() {\n        return bundleContext;\n    }\n\n    public void setBundleContext(BundleContext bundleContext) {\n        this.bundleContext = bundleContext;\n    }\n\n    public Map<String, MicroservicesRegistryImpl> getMicroservicesRegistries() {\n        return microservicesRegistries;\n    }\n\n    public void setConfigProvider(ConfigProvider configProvider) {\n        this.configProvider = configProvider;\n    }\n\n    public ConfigProvider getConfigProvider() {\n        return configProvider;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/HttpConnectorPortBindingListener.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.PortBindingEventListener;\n\n\n/**\n * An implementation of the LifeCycleEventListener. This can be used to listen to the HTTP connector life cycle events.\n *\n * @since 2.5.0\n */\npublic class HttpConnectorPortBindingListener implements PortBindingEventListener {\n\n    private static final Logger log = LoggerFactory.getLogger(HttpConnectorPortBindingListener.class);\n\n    @Override\n    public void onOpen(String serverConnectorId, boolean isHttps) {\n        // Nothing to do when opening the connector port\n    }\n\n    @Override\n    public void onClose(String serverConnectorId, boolean isHttps) {\n        // Nothing to do when closing the connector port\n    }\n\n    @Override\n    public void onError(Throwable throwable) {\n        log.error(\"Error in http server connector\", throwable);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/HttpHeadersImpl.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.Serializable;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.TimeZone;\nimport javax.ws.rs.core.Cookie;\nimport javax.ws.rs.core.HttpHeaders;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.MultivaluedHashMap;\nimport javax.ws.rs.core.MultivaluedMap;\n\n/**\n * This is JAX-RS HttpHeaders implementation for msf4j.\n * This also wraps netty httpHeaders.\n *\n * @since 2.5.0\n */\npublic class HttpHeadersImpl implements HttpHeaders {\n\n    private static final String DATE_FORMAT_PATTERN = \"EEE, dd MMM yyyy HH:mm:ss zzz\";\n    private static final String GMT_TIMEZONE = \"GMT\";\n    private final io.netty.handler.codec.http.HttpHeaders nettyHttpHeaders;\n    private static final Logger log = LoggerFactory.getLogger(HttpHeadersImpl.class);\n\n    public HttpHeadersImpl(io.netty.handler.codec.http.HttpHeaders httpHeaders) {\n        nettyHttpHeaders = httpHeaders;\n    }\n\n    @Override\n    public List<String> getRequestHeader(String name) {\n        return nettyHttpHeaders.getAll(name);\n    }\n\n    @Override\n    public String getHeaderString(String name) {\n        List<String> headerValues = nettyHttpHeaders.getAll(name);\n        if (headerValues == null) {\n            return null;\n        }\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < headerValues.size(); i++) {\n            String value = headerValues.get(i);\n            if (value == null || value.isEmpty()) {\n                continue;\n            }\n            sb.append(value);\n            if (i + 1 < headerValues.size()) {\n                sb.append(\",\");\n            }\n        }\n        return sb.toString();\n    }\n\n    @Override\n    public MultivaluedMap<String, String> getRequestHeaders() {\n        MultivaluedHashMap<String, String> newHeaders =\n                new MultivaluedHashMap<>();\n        for (Map.Entry<String, String> headerEntry : nettyHttpHeaders.entries()) {\n            if (headerEntry != null) {\n                newHeaders.add(headerEntry.getKey(), headerEntry.getValue());\n            }\n        }\n        return newHeaders;\n    }\n\n    @Override\n    public List<MediaType> getAcceptableMediaTypes() {\n        List<String> values = nettyHttpHeaders.getAll(HttpHeaders.ACCEPT);\n        if (values == null || values.isEmpty() || values.get(0) == null) {\n            return Collections.singletonList(MediaType.WILDCARD_TYPE);\n        }\n        List<MediaType> mediaTypes = new LinkedList<>();\n        for (String value : values) {\n            mediaTypes.add(MediaType.valueOf(value));\n        }\n        return mediaTypes;\n    }\n\n    @Override\n    public List<Locale> getAcceptableLanguages() {\n        // Accept-Language: da\n        // Accept-Language: en-gb;q=0.8\n        List<String> values = nettyHttpHeaders.getAll(HttpHeaders.ACCEPT_LANGUAGE);\n        if (values.isEmpty()) {\n            return Collections.singletonList(new Locale(\"*\"));\n        }\n\n        List<Locale> localeValues = new ArrayList<>();\n        Map<Locale, Float> prefs = new HashMap<>();\n        // derive preferences from Accept-Language and sort languages according to the preferences.\n        for (String value : values) {\n            String[] pair = value != null ? value.split(\";\") : new String[0];\n            Locale locale = new Locale(pair[0].trim());\n            localeValues.add(locale);\n            if (pair.length > 1) {\n                String[] pair2 = pair[1] != null ? pair[1].split(\"=\") : new String[0];\n                if (pair2.length > 1) {\n                    prefs.put(locale, getLanguageQualityFactor(pair2[1].trim()));\n                } else {\n                    prefs.put(locale, 1F);\n                }\n            } else {\n                prefs.put(locale, 1F);\n            }\n        }\n\n        if (localeValues.size() <= 1) {\n            return localeValues;\n        }\n        localeValues.sort(new AcceptLanguageComparator(prefs));\n        return localeValues;\n    }\n\n    private float getLanguageQualityFactor(String q) {\n        if (q == null) {\n            return 1;\n        }\n        if (q.charAt(0) == '.') {\n            q = '0' + q;\n        }\n        try {\n            return Float.parseFloat(q);\n        } catch (NumberFormatException ignored) {\n            // ignored parsing exception and return default value.\n        }\n        return 1;\n    }\n\n    private static class AcceptLanguageComparator implements Comparator<Locale>, Serializable {\n        private Map<Locale, Float> preferences;\n        private static final long serialVersionUID = 6006269076155338045L;\n\n        AcceptLanguageComparator(Map<Locale, Float> prefs) {\n            this.preferences = prefs;\n        }\n\n        public int compare(Locale lang1, Locale lang2) {\n            float p1 = preferences.get(lang1);\n            float p2 = preferences.get(lang2);\n            return Float.compare(p1, p2) * -1;\n        }\n    }\n\n    @Override\n    public MediaType getMediaType() {\n        String value = nettyHttpHeaders.get(HttpHeaders.CONTENT_TYPE);\n        return value == null ? null : MediaType.valueOf(value);\n    }\n\n    @Override\n    public Locale getLanguage() {\n        String value = nettyHttpHeaders.get(HttpHeaders.CONTENT_LANGUAGE);\n        return value == null ? null : new Locale(value.trim());\n    }\n\n    @Override\n    public Map<String, Cookie> getCookies() {\n        List<String> values = nettyHttpHeaders.getAll(HttpHeaders.COOKIE);\n        if (values == null || values.isEmpty()) {\n            return Collections.emptyMap();\n        }\n\n        Map<String, Cookie> cookieMap = new HashMap<>();\n        for (String value : values) {\n            if (value == null) {\n                continue;\n            }\n            Cookie cookie = Cookie.valueOf(value);\n            cookieMap.put(cookie.getName(), cookie);\n        }\n        return cookieMap;\n    }\n\n    @Override\n    public Date getDate() {\n        String value = nettyHttpHeaders.get(HttpHeaders.DATE);\n        if (value == null || value.isEmpty()) {\n            return null;\n        }\n        // Preferred date format in internet standard is Sun, 06 Nov 1994 08:49:37 GMT\n        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_PATTERN, Locale.ENGLISH);\n        //All HTTP date/time stamps MUST be represented in Greenwich Mean Time (GMT)\n        dateFormat.setTimeZone(TimeZone.getTimeZone(GMT_TIMEZONE));\n        try {\n            return dateFormat.parse(value);\n        } catch (ParseException e) {\n            log.error(\"Error while parsing the Date value. Hence return null\", e);\n            return null;\n        }\n    }\n\n    @Override\n    public int getLength() {\n        String value = nettyHttpHeaders.get(HttpHeaders.CONTENT_LENGTH);\n        if (value == null || value.isEmpty()) {\n            return -1;\n        }\n        int length = Integer.parseInt(value);\n        return length >= 0 ? length : -1;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MSF4JConstants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\n/**\n * MSF4J Constants.\n */\npublic class MSF4JConstants {\n\n    public static final String SESSION_ID = \"JSESSIONID=\";\n    public static final String CHANNEL_ID = \"listener.interface.id\";\n    public static final String CONTEXT_PATH = \"contextPath\";\n    public static final String WSO2_TRANSPORT_HTTP_CONFIG_NAMESPACE = \"wso2.transport.http\";\n    public static final String STREAMLINED_TRANSPORT_NAMESPACE = \"transports\";\n\n    // Property constants\n    public static final String METHOD_PROPERTY_NAME = \"method\";\n\n    @Deprecated\n    public static final String PROTOCOL_NAME = \"http\";\n\n    public static final String DEPLOYMENT_YAML_SYS_PROPERTY = \"msf4j.conf\";\n    public static final String DEPLOYMENT_YAML_FILE = \"deployment.yaml\";\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MSF4JHttpConnectorListener.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal;\n\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpContent;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport io.netty.handler.codec.http.LastHttpContent;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.config.ConfigProviderFactory;\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.config.MSF4JConfig;\nimport org.wso2.msf4j.delegates.MSF4JResponse;\nimport org.wso2.msf4j.interceptor.InterceptorExecutor;\nimport org.wso2.msf4j.internal.router.HandlerException;\nimport org.wso2.msf4j.internal.router.HttpMethodInfo;\nimport org.wso2.msf4j.internal.router.HttpMethodInfoBuilder;\nimport org.wso2.msf4j.internal.router.HttpResourceModel;\nimport org.wso2.msf4j.internal.router.PatternPathRouter;\nimport org.wso2.msf4j.internal.router.Util;\nimport org.wso2.msf4j.util.HttpUtil;\nimport org.wso2.transport.http.netty.contract.Constants;\nimport org.wso2.transport.http.netty.contract.HttpConnectorListener;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.Locale;\nimport java.util.Optional;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * Process carbon messages for MSF4J.\n *\n * @since 2.5.0\n */\npublic class MSF4JHttpConnectorListener implements HttpConnectorListener {\n\n    private static final Logger log = LoggerFactory.getLogger(MSF4JHttpConnectorListener.class);\n    private ExecutorService executorService;\n\n    public MSF4JHttpConnectorListener() {\n        ConfigProvider configProvider = DataHolder.getInstance().getConfigProvider();\n        MSF4JConfig msf4JConfig;\n        if (configProvider == null) {\n            if (DataHolder.getInstance().getBundleContext() != null) {\n                throw new RuntimeException(\"Failed to populate MSF4J Configuration. Config Provider is Null.\");\n            }\n            //Standalone mode\n            String deploymentYamlPath = System.getProperty(MSF4JConstants.DEPLOYMENT_YAML_SYS_PROPERTY);\n\n            try {\n                if (deploymentYamlPath != null && Files.exists(Paths.get(deploymentYamlPath))) {\n                    configProvider = ConfigProviderFactory.getConfigProvider(Paths.get(deploymentYamlPath), null);\n                    DataHolder.getInstance().setConfigProvider(configProvider);\n                } else {\n                    if (log.isDebugEnabled()) {\n                        log.debug(\"MSF4J Configuration file is not provided. either system property '\" + MSF4JConstants\n                                .DEPLOYMENT_YAML_SYS_PROPERTY + \"' is not set or provided file path not exist. Hence \" +\n                                \"using default configuration.\");\n                    }\n                }\n            } catch (ConfigurationException e) {\n                throw new RuntimeException(\"Error loading deployment.yaml Configuration\", e);\n            }\n        }\n\n        try {\n            if (configProvider != null) {\n                msf4JConfig = DataHolder.getInstance().getConfigProvider().getConfigurationObject(MSF4JConfig.class);\n            } else {\n                msf4JConfig = new MSF4JConfig();\n            }\n        } catch (ConfigurationException e) {\n            throw new RuntimeException(\"Error while loading \" + MSF4JConfig.class.getName() + \" from config provider\",\n                    e);\n        }\n\n        executorService = Executors.newFixedThreadPool(msf4JConfig.getThreadCount(), new MSF4JThreadFactory(\n                new ThreadGroup(msf4JConfig.getThreadPoolName())));\n    }\n\n    public MSF4JHttpConnectorListener(String channelId, MicroservicesRegistryImpl microservicesRegistry) {\n        DataHolder.getInstance().getMicroservicesRegistries().put(channelId, microservicesRegistry);\n    }\n\n    /**\n     * Carbon message handler.\n     */\n    @Override\n    public void onMessage(HttpCarbonMessage httpCarbonMessage) {\n        // If we are running on OSGi mode need to get the registry based on the channel_id.\n        executorService.execute(() -> {\n            //Identify the protocol name before doing the processing\n            MicroservicesRegistryImpl currentMicroservicesRegistry =\n                    DataHolder.getInstance().getMicroservicesRegistries()\n                              .get(httpCarbonMessage.getProperty(MSF4JConstants.CHANNEL_ID));\n\n            Request request = new Request(httpCarbonMessage);\n            request.setSessionManager(currentMicroservicesRegistry.getSessionManager());\n            setBaseUri(request);\n            Response response = new Response(request);\n            try {\n                dispatchMethod(currentMicroservicesRegistry, request, response);\n            } catch (HandlerException e) {\n                handleHandlerException(e, request);\n            } catch (InvocationTargetException e) {\n                Throwable targetException = e.getTargetException();\n                if (targetException instanceof HandlerException) {\n                    handleHandlerException((HandlerException) targetException, request);\n                } else {\n                    handleThrowable(currentMicroservicesRegistry, targetException, request);\n                }\n            } catch (Throwable t) {\n                handleThrowable(currentMicroservicesRegistry, t, request);\n            } finally {\n                MSF4JResponse.clearBaseUri();\n                // Calling the release method to make sure that there won't be any memory leaks from netty\n                if (!httpCarbonMessage.isEmpty()) {\n                    httpCarbonMessage.getHttpContent().release();\n                }\n            }\n        });\n    }\n\n    private void setBaseUri(Request request) {\n        StringBuilder builder = new StringBuilder();\n        builder.append(request.getProperty(Constants.PROTOCOL).toString().toLowerCase(Locale.US)).append(\"://\")\n                .append(request.getHeader(HttpHeaderNames.HOST.toString()));\n        if (builder.charAt(builder.length() - 1) != '/') {\n            builder.append(\"/\");\n        }\n        try {\n            MSF4JResponse.setBaseUri(new URI(builder.toString()));\n        } catch (URISyntaxException e) {\n            log.error(\"Error while setting the Base URI. \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Dispatch appropriate resource method.\n     */\n    private void dispatchMethod(MicroservicesRegistryImpl registry, Request request, Response response)\n            throws Exception {\n        HttpUtil.setConnectionHeader(request, response);\n        PatternPathRouter.RoutableDestination<HttpResourceModel> destination = registry.getMetadata()\n                .getDestinationMethod(\n                        request.getUri(),\n                        request.getHttpMethod(),\n                        request.getContentType(),\n                        request.getAcceptTypes());\n        HttpResourceModel resourceModel = destination.getDestination();\n        response.setMediaType(Util.getResponseType(request.getAcceptTypes(), resourceModel.getProducesMediaTypes()));\n        HttpMethodInfoBuilder httpMethodInfoBuilder =\n                new HttpMethodInfoBuilder().httpResourceModel(resourceModel).httpRequest(request)\n                        .httpResponder(response).requestInfo(destination.getGroupNameValues());\n        HttpMethodInfo httpMethodInfo = httpMethodInfoBuilder.build();\n        if (httpMethodInfo.isStreamingSupported()) {\n            Method method = resourceModel.getMethod();\n            Class<?> clazz = method.getDeclaringClass();\n            // Execute request interceptors\n            if (InterceptorExecutor.executeGlobalRequestInterceptors(registry, request, response)\n                    // Execute class level request interceptors\n                    && InterceptorExecutor.executeClassLevelRequestInterceptors(request, response, clazz)\n                    // Execute method level request interceptors\n                    && InterceptorExecutor.executeMethodLevelRequestInterceptors(request, response, method)) {\n\n                HttpCarbonMessage carbonMessage = getHttpCarbonMessage(request);\n                HttpContent httpContent = carbonMessage.getHttpContent();\n                while (true) {\n                    if (httpContent == null) {\n                        break;\n                    }\n                    httpMethodInfo.chunk(httpContent.content().nioBuffer());\n                    httpContent.release();\n                    // Exit the loop at the end of the content\n                    if (httpContent instanceof LastHttpContent) {\n                        break;\n                    }\n                    httpContent = carbonMessage.getHttpContent();\n                }\n                boolean isResponseInterceptorsSuccessful =\n                        InterceptorExecutor.executeMethodLevelResponseInterceptors(request, response, method)\n                                // Execute class level interceptors (first in - last out order)\n                                && InterceptorExecutor.executeClassLevelResponseInterceptors(request, response,\n                                clazz)\n                                // Execute global interceptors\n                                && InterceptorExecutor.executeGlobalResponseInterceptors(registry, request,\n                                response);\n                httpMethodInfo.end(isResponseInterceptorsSuccessful);\n            }\n        } else {\n            httpMethodInfo.invoke(destination, request, httpMethodInfo, registry);\n        }\n    }\n\n    private HttpCarbonMessage getHttpCarbonMessage(Request request) throws HandlerException {\n        Class<?> clazz = request.getClass();\n        try {\n            Method retrieveCarbonMsg = clazz.getDeclaredMethod(\"getHttpCarbonMessage\");\n            retrieveCarbonMsg.setAccessible(true);\n            return (HttpCarbonMessage) retrieveCarbonMsg.invoke(request);\n        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    String.format(\"Error in executing request: %s %s\", request.getHttpMethod(),\n                            request.getUri()), e);\n        }\n    }\n\n    private void handleThrowable(MicroservicesRegistryImpl currentMicroservicesRegistry, Throwable throwable,\n                                 Request request) {\n        Optional<ExceptionMapper> exceptionMapper = currentMicroservicesRegistry.getExceptionMapper(throwable);\n        if (exceptionMapper.isPresent()) {\n            org.wso2.msf4j.Response msf4jResponse = new org.wso2.msf4j.Response(request);\n            msf4jResponse.setEntity(exceptionMapper.get().toResponse(throwable));\n            msf4jResponse.send();\n        } else {\n            log.warn(\"Unmapped exception\", throwable);\n            try {\n                HttpCarbonMessage response = HttpUtil.createTextResponse(\n                        javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),\n                        \"Exception occurred :\" + throwable.getMessage());\n                response.setHeader(\"Content-type\", \"text/plain\");\n                response.addHttpContent(new DefaultLastHttpContent());\n                request.respond(response);\n            } catch (ServerConnectorException e) {\n                log.error(\"Error while sending the response.\", e);\n            }\n        }\n    }\n\n    private void handleHandlerException(HandlerException e, Request request) {\n        try {\n            HttpCarbonMessage failureResponse = e.getFailureResponse();\n            failureResponse.addHttpContent(new DefaultLastHttpContent());\n            request.respond(failureResponse);\n        } catch (ServerConnectorException e1) {\n            log.error(\"Error while sending the response.\", e);\n        }\n    }\n\n    @Override\n    public void onError(Throwable throwable) {\n        // Adding stacktrace for debug level for better usability\n        log.warn(\"Error in http connector listener : '\" + throwable.getMessage() + \"'\");\n        log.debug(\"Error in http connector listener\", throwable);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MSF4JThreadFactory.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.internal;\n\nimport java.util.concurrent.ThreadFactory;\n\n/**\n * A Thread Factory to be used  when creating threads to handle MSF4J requests.\n */\npublic class MSF4JThreadFactory implements ThreadFactory {\n    private ThreadGroup threadGroup;\n\n    private int counter = 1;\n\n    public MSF4JThreadFactory(ThreadGroup threadGroup) {\n        this.threadGroup = threadGroup;\n    }\n\n    @Override\n    public Thread newThread(Runnable r) {\n        String name = threadGroup.getName() + \"-\" + counter;\n        Thread thread = new Thread(threadGroup, r, name);\n        counter++;\n        return thread;\n    }\n\n}\n\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MSF4JWSConnectorListener.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.internal;\n\nimport org.osgi.service.component.annotations.Component;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.internal.router.PatternPathRouter;\nimport org.wso2.msf4j.internal.websocket.CloseCodeImpl;\nimport org.wso2.msf4j.internal.websocket.EndpointDispatcher;\nimport org.wso2.msf4j.internal.websocket.EndpointsRegistryImpl;\nimport org.wso2.msf4j.internal.websocket.WebSocketPongMessage;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointMethodReturnTypeException;\nimport org.wso2.transport.http.netty.contract.websocket.ServerHandshakeFuture;\nimport org.wso2.transport.http.netty.contract.websocket.ServerHandshakeListener;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketBinaryMessage;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketCloseMessage;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnectorListener;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketControlMessage;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketHandshaker;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketTextMessage;\nimport org.wso2.transport.http.netty.message.HttpCarbonRequest;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.nio.ByteBuffer;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.websocket.CloseReason;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\n\n/**\n * WebSocketConnectorListener implementation for MSF4J.\n *\n * This will process all the websocket messages which are coming to MSF4J.\n */\n@Component(\n        name = \"org.wso2.msf4j.internal.MSF4JWSConnectorListener\",\n        immediate = true,\n        service = WebSocketConnectorListener.class\n)\npublic class MSF4JWSConnectorListener implements WebSocketConnectorListener {\n\n    private static final Logger log = LoggerFactory.getLogger(MSF4JWSConnectorListener.class);\n\n    @Override\n    public void onHandshake(WebSocketHandshaker webSocketHandshaker) {\n        ServerHandshakeFuture handshakeFuture = webSocketHandshaker.handshake();\n        handshakeFuture.setHandshakeListener(new ServerHandshakeListener() {\n            @Override\n            public void onSuccess(WebSocketConnection webSocketConnection) {\n                handleWebSocketHandshake(webSocketHandshaker, webSocketConnection);\n                webSocketConnection.startReadingFrames();\n            }\n\n            @Override\n            public void onError(Throwable throwable) {\n                log.error(\"Unexpected error occur while handshake.\", throwable);\n            }\n        });\n    }\n\n    @Override\n    public void onMessage(WebSocketTextMessage webSocketTextMessage) {\n        EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n        String uri = webSocketTextMessage.getTarget();\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint = endpointsRegistry.getRoutableEndpoint(uri);\n        handleTextWebSocketMessage(webSocketTextMessage, routableEndpoint, webSocketTextMessage\n                .getWebSocketConnection());\n    }\n\n    @Override\n    public void onMessage(WebSocketBinaryMessage webSocketBinaryMessage) {\n        EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n        String uri = webSocketBinaryMessage.getTarget();\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint = endpointsRegistry.getRoutableEndpoint(uri);\n        handleBinaryWebSocketMessage(webSocketBinaryMessage, routableEndpoint,\n                webSocketBinaryMessage.getWebSocketConnection());\n    }\n\n    @Override\n    public void onMessage(WebSocketControlMessage webSocketControlMessage) {\n        EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n        String uri = webSocketControlMessage.getTarget();\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint = endpointsRegistry.getRoutableEndpoint(uri);\n        handleControlCarbonMessage(webSocketControlMessage, routableEndpoint,\n                webSocketControlMessage.getWebSocketConnection());\n    }\n\n    @Override\n    public void onMessage(WebSocketCloseMessage webSocketCloseMessage) {\n        EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n        String uri = webSocketCloseMessage.getTarget();\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint = endpointsRegistry.getRoutableEndpoint(uri);\n        handleCloseWebSocketMessage(webSocketCloseMessage, routableEndpoint, webSocketCloseMessage\n                .getWebSocketConnection());\n    }\n\n    @Override\n    public void onClose(WebSocketConnection webSocketConnection) {\n    }\n\n    @Override\n    public void onError(WebSocketConnection webSocketConnection, Throwable throwable) {\n        log.error(\"Unexpected error occur.\", throwable);\n    }\n\n    @Override\n    public void onIdleTimeout(WebSocketControlMessage webSocketControlMessage) {\n\n    }\n\n    private boolean handleWebSocketHandshake(WebSocketHandshaker carbonMessage,\n                                             WebSocketConnection webSocketConnection) {\n        EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n        String requestUri = carbonMessage.getTarget();\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint =\n                endpointsRegistry.getRoutableEndpoint(requestUri);\n        if (routableEndpoint == null) {\n            throw new RuntimeException(\"Error while connecting to server. Routable endpoint is not registered for the\" +\n                    \" request uri:\" + requestUri);\n        }\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnOpenMethod(routableEndpoint.getDestination());\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        try {\n            List<Object> parameterList = new LinkedList<>();\n            methodOptional.ifPresent(method -> {\n                Arrays.stream(method.getParameters()).forEach(parameter -> {\n                    if (parameter.getType() == WebSocketConnection.class) {\n                        parameterList.add(webSocketConnection);\n                    } else if (parameter.getType() == String.class) {\n                        PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                        if (pathParam != null) {\n                            parameterList.add(paramValues.get(pathParam.value()));\n                        }\n                    } else if (parameter.getType() == HttpCarbonRequest.class) {\n                        parameterList.add(carbonMessage.getHttpCarbonRequest());\n                    } else {\n                        parameterList.add(null);\n                    }\n                });\n                executeMethod(method, routableEndpoint.getDestination(), parameterList, webSocketConnection);\n            });\n            return true;\n        } catch (Throwable throwable) {\n            handleError(throwable, routableEndpoint, webSocketConnection);\n            return false;\n        }\n    }\n\n    private void handleTextWebSocketMessage(WebSocketTextMessage textCarbonMessage,\n                                            PatternPathRouter.RoutableDestination<Object> routableEndpoint,\n                                            WebSocketConnection webSocketConnection) {\n        if (routableEndpoint == null) {\n            throw new RuntimeException(\"Error while handling the message. Routable endpoint is not registered for the\" +\n                    \" request uri:\" + textCarbonMessage.getTarget());\n        }\n        Object endpoint = routableEndpoint.getDestination();\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnStringMessageMethod(endpoint);\n        try {\n            methodOptional.ifPresent(\n                    method -> {\n                        List<Object> parameterList = new LinkedList<>();\n                        Arrays.stream(method.getParameters()).forEach(\n                                parameter -> {\n                                    if (parameter.getType() == String.class) {\n                                        PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                                        if (pathParam == null) {\n                                            parameterList.add(textCarbonMessage.getText());\n                                        } else {\n                                            parameterList.add(paramValues.get(pathParam.value()));\n                                        }\n                                    } else if (parameter.getType() == WebSocketConnection.class) {\n                                        parameterList.add(webSocketConnection);\n                                    } else {\n                                        parameterList.add(null);\n                                    }\n                                }\n                        );\n                        executeMethod(method, endpoint, parameterList, webSocketConnection);\n                    }\n            );\n        } catch (Throwable throwable) {\n            handleError(throwable, routableEndpoint, webSocketConnection);\n        }\n    }\n\n    private void handleBinaryWebSocketMessage(WebSocketBinaryMessage binaryCarbonMessage,\n                                              PatternPathRouter.RoutableDestination<Object> routableEndpoint,\n                                              WebSocketConnection webSocketConnection) {\n        if (routableEndpoint == null) {\n            throw new RuntimeException(\"Error while handling the message. Routable endpoint is not registered for the\" +\n                    \" request uri:\" + binaryCarbonMessage.getTarget());\n        }\n        Object webSocketEndpoint = routableEndpoint.getDestination();\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnBinaryMessageMethod(webSocketEndpoint);\n        try {\n            methodOptional.ifPresent(method -> {\n                List<Object> parameterList = new LinkedList<>();\n                Arrays.stream(method.getParameters()).forEach(parameter -> {\n                    if (parameter.getType() == ByteBuffer.class) {\n                        parameterList.add(binaryCarbonMessage.getByteBuffer());\n                    } else if (parameter.getType() == byte[].class) {\n                        ByteBuffer buffer = binaryCarbonMessage.getByteBuffer();\n                        byte[] bytes = new byte[buffer.capacity()];\n                        for (int i = 0; i < buffer.capacity(); i++) {\n                            bytes[i] = buffer.get();\n                        }\n                        parameterList.add(bytes);\n                    } else if (parameter.getType() == boolean.class) {\n                        parameterList.add(binaryCarbonMessage.isFinalFragment());\n                    } else if (parameter.getType() == WebSocketConnection.class) {\n                        parameterList.add(webSocketConnection);\n                    } else if (parameter.getType() == String.class) {\n                        PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                        if (pathParam != null) {\n                            parameterList.add(paramValues.get(pathParam.value()));\n                        }\n                    } else {\n                        parameterList.add(null);\n                    }\n                });\n                executeMethod(method, webSocketEndpoint, parameterList, webSocketConnection);\n            });\n        } catch (Throwable throwable) {\n            handleError(throwable, routableEndpoint, webSocketConnection);\n        }\n    }\n\n    private void handleCloseWebSocketMessage(WebSocketCloseMessage closeCarbonMessage,\n                                             PatternPathRouter.RoutableDestination<Object> routableEndpoint,\n                                             WebSocketConnection webSocketConnection) {\n        if (routableEndpoint == null) {\n            throw new RuntimeException(\"Error while handling the message. Routable endpoint is not registered for the\" +\n                    \" request uri:\" + closeCarbonMessage.getTarget());\n        }\n        Object webSocketEndpoint = routableEndpoint.getDestination();\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnCloseMethod(webSocketEndpoint);\n        try {\n            methodOptional.ifPresent(method -> {\n                List<Object> parameterList = new LinkedList<>();\n                Arrays.stream(method.getParameters()).forEach(parameter -> {\n                    if (parameter.getType() == CloseReason.class) {\n                        CloseReason.CloseCode closeCode = new CloseCodeImpl(closeCarbonMessage.getCloseCode());\n                        CloseReason closeReason = new CloseReason(closeCode, closeCarbonMessage.getCloseReason());\n                        parameterList.add(closeReason);\n                    } else if (parameter.getType() == WebSocketConnection.class) {\n                        parameterList.add(webSocketConnection);\n                    } else if (parameter.getType() == String.class) {\n                        PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                        if (pathParam != null) {\n                            parameterList.add(paramValues.get(pathParam.value()));\n                        }\n                    } else {\n                        parameterList.add(null);\n                    }\n                });\n                executeMethod(method, webSocketEndpoint, parameterList, webSocketConnection);\n            });\n        } catch (Throwable throwable) {\n            handleError(throwable, routableEndpoint, webSocketConnection);\n        } finally {\n            // TODO: this is temp fix assuming websocket connection is blocking call.\n            if (webSocketConnection.isOpen()) {\n                webSocketConnection.terminateConnection();\n            }\n        }\n\n    }\n\n    private void handleControlCarbonMessage(WebSocketControlMessage controlCarbonMessage, PatternPathRouter.\n            RoutableDestination<Object> routableEndpoint, WebSocketConnection webSocketConnection) {\n        if (routableEndpoint == null) {\n            throw new RuntimeException(\"Error while handling the message. Routable endpoint is not registered for the\" +\n                    \" request uri:\" + controlCarbonMessage.getTarget());\n        }\n        Object webSocketEndpoint = routableEndpoint.getDestination();\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnPongMessageMethod(webSocketEndpoint);\n        try {\n            methodOptional.ifPresent(method -> {\n                List<Object> parameterList = new LinkedList<>();\n                Arrays.stream(method.getParameters()).forEach(parameter -> {\n                    if (parameter.getType() == PongMessage.class) {\n                        parameterList.add(new WebSocketPongMessage(controlCarbonMessage.getByteBuffer()));\n                    } else if (parameter.getType() == WebSocketConnection.class) {\n                        parameterList.add(webSocketConnection);\n                    } else if (parameter.getType() == String.class) {\n                        PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                        if (pathParam != null) {\n                            parameterList.add(paramValues.get(pathParam.value()));\n                        }\n                    } else {\n                        parameterList.add(null);\n                    }\n                });\n                executeMethod(method, webSocketEndpoint, parameterList, webSocketConnection);\n            });\n        } catch (Throwable throwable) {\n            handleError(throwable, routableEndpoint, webSocketConnection);\n        }\n    }\n\n    private void handleError(Throwable throwable, PatternPathRouter.RoutableDestination<Object> routableEndpoint,\n                             WebSocketConnection webSocketConnection) {\n        Object webSocketEndpoint = routableEndpoint.getDestination();\n        Map<String, String> paramValues = routableEndpoint.getGroupNameValues();\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnErrorMethod(webSocketEndpoint);\n        methodOptional.ifPresent(method -> {\n            List<Object> parameterList = new LinkedList<>();\n            Arrays.stream(method.getParameters()).forEach(parameter -> {\n                if (parameter.getType() == Throwable.class) {\n                    parameterList.add(throwable);\n                } else if (parameter.getType() == WebSocketConnection.class) {\n                    parameterList.add(webSocketConnection);\n                } else if (parameter.getType() == String.class) {\n                    PathParam pathParam = parameter.getAnnotation(PathParam.class);\n                    if (pathParam != null) {\n                        parameterList.add(paramValues.get(pathParam.value()));\n                    }\n                } else {\n                    parameterList.add(null);\n                }\n            });\n            executeMethod(method, webSocketEndpoint, parameterList, webSocketConnection);\n        });\n    }\n\n    private void executeMethod(Method method, Object webSocketEndpoint, List<Object> parameterList,\n                               WebSocketConnection webSocketConnection) {\n        try {\n            if (method.getReturnType() == String.class) {\n                String returnStr = (String) method.invoke(webSocketEndpoint, parameterList.toArray());\n                webSocketConnection.pushText(returnStr);\n            } else if (method.getReturnType() == ByteBuffer.class) {\n                ByteBuffer buffer = (ByteBuffer) method.invoke(webSocketEndpoint, parameterList.toArray());\n                webSocketConnection.pushBinary(buffer);\n            } else if (method.getReturnType() == byte[].class) {\n                byte[] bytes = (byte[]) method.invoke(webSocketEndpoint, parameterList.toArray());\n                webSocketConnection.pushBinary(ByteBuffer.wrap(bytes));\n            } else if (method.getReturnType() == void.class) {\n                method.invoke(webSocketEndpoint, parameterList.toArray());\n            } else if (method.getReturnType() == PongMessage.class) {\n                PongMessage pongMessage = (PongMessage) method.invoke(webSocketEndpoint, parameterList.toArray());\n                webSocketConnection.pong(pongMessage.getApplicationData());\n            } else {\n                throw new WebSocketEndpointMethodReturnTypeException(\"Unknown return type.\");\n            }\n        } catch (IllegalAccessException e) {\n            log.error(\"Illegal access exception occurred: \" + e.toString());\n        } catch (InvocationTargetException e) {\n            log.error(\"Method invocation failed: \" + e.toString());\n        } catch (WebSocketEndpointMethodReturnTypeException e) {\n            log.error(\"WebSocket method return type exception occurred: \" + e.toString());\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MicroservicesLCException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal;\n\n/**\n * This Exception can be used with Lifecycle methods.\n */\npublic class MicroservicesLCException extends RuntimeException {\n\n    public MicroservicesLCException(String message, Throwable throwable) {\n        super(message, throwable);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MicroservicesRegistryImpl.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.DefaultSessionManager;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.SessionManager;\nimport org.wso2.msf4j.SwaggerService;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\nimport org.wso2.msf4j.internal.router.MicroserviceMetadata;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.ServiceLoader;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.stream.Collectors;\nimport javax.annotation.PostConstruct;\nimport javax.annotation.PreDestroy;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * MicroservicesRegistry for the MSF4J component.\n */\npublic class MicroservicesRegistryImpl implements MicroservicesRegistry {\n\n    private static final Logger log = LoggerFactory.getLogger(MicroservicesRegistryImpl.class);\n    private final Map<String, Object> services = new HashMap<>();\n    private List<RequestInterceptor> globalRequestInterceptorList = new ArrayList<>();\n    private List<ResponseInterceptor> globalResponseInterceptorList = new ArrayList<>();\n    private volatile MicroserviceMetadata metadata = new MicroserviceMetadata(Collections.emptyMap());\n    private Map<Class, ExceptionMapper> exceptionMappers = new TreeMap<>(new ClassComparator());\n    private SessionManager sessionManager = new DefaultSessionManager();\n\n    public MicroservicesRegistryImpl() {\n        /* In non OSGi mode, if we can find the SwaggerDefinitionService, Deploy the Swagger definition service which\n        will return the Swagger definition.*/\n        if (DataHolder.getInstance().getBundleContext() == null) {\n            ServiceLoader<SwaggerService> swaggerServices = ServiceLoader.load(SwaggerService.class);\n            Iterator<SwaggerService> iterator = swaggerServices.iterator();\n            if (iterator.hasNext()) {\n                SwaggerService swaggerService = iterator.next();\n                swaggerService.init(this);\n                services.put(\"/swagger\", swaggerService);\n            }\n        }\n    }\n\n    public void addService(Object... service) {\n        for (Object svc : service) {\n            services.put(svc.getClass().getAnnotation(Path.class).value(), svc);\n        }\n        updateMetadata();\n        if (log.isDebugEnabled()) {\n            Arrays.stream(service).forEach(svc -> log.debug(\"Added microservice: {}.\", svc));\n        }\n    }\n\n    public void addService(String basePath, Object service) {\n        services.put(basePath, service);\n        metadata.addMicroserviceMetadata(service, basePath);\n        log.debug(\"Added microservice: {}.\", service);\n    }\n\n    public Optional<Map.Entry<String, Object>> getServiceWithBasePath(String path) {\n        return services.entrySet().stream().filter(svc -> svc.getKey().equals(path)).findAny();\n    }\n\n    public void removeService(Object service) {\n        if (service == null) {\n            log.error(\"Service cannot be null.\");\n            return;\n        }\n        Path path = service.getClass().getAnnotation(Path.class);\n        if (path == null) {\n            log.warn(\"Service removal failed. Microservice class '\" + service.getClass().getName() +\n                     \"' doesn't contain a root Path.\");\n            return;\n        }\n        services.remove(path.value());\n        updateMetadata();\n    }\n\n    public void setSessionManager(SessionManager sessionManager) {\n        if (sessionManager == null) {\n            throw new IllegalArgumentException(\"SessionManager cannot be null\");\n        }\n        this.sessionManager = sessionManager;\n    }\n\n    public void addInterceptor(Interceptor... interceptor) {\n        Collections.addAll(globalRequestInterceptorList, interceptor);\n        Collections.addAll(globalResponseInterceptorList, interceptor);\n    }\n\n    public void removeInterceptor(Interceptor interceptor) {\n        globalRequestInterceptorList.remove(interceptor);\n        globalResponseInterceptorList.remove(interceptor);\n    }\n\n    public MicroserviceMetadata getMetadata() {\n        return metadata;\n    }\n\n    public Set<Object> getHttpServices() {\n        return Collections.unmodifiableSet(services.values().stream().collect(Collectors.toSet()));\n    }\n\n    /**\n     * Register request interceptors.\n     *\n     * @param requestInterceptor interceptor instances.\n     */\n    public void addGlobalRequestInterceptor(RequestInterceptor... requestInterceptor) {\n        Collections.addAll(globalRequestInterceptorList, requestInterceptor);\n    }\n\n    /**\n     * Register response interceptors.\n     *\n     * @param responseInterceptor interceptor instances.\n     */\n    public void addGlobalResponseInterceptor(ResponseInterceptor... responseInterceptor) {\n        Collections.addAll(globalResponseInterceptorList, responseInterceptor);\n    }\n\n    /**\n     * Remove msf4j request interceptor.\n     *\n     * @param requestInterceptor MSF4J interceptor instance.\n     */\n    public void removeGlobalRequestInterceptor(RequestInterceptor requestInterceptor) {\n        globalRequestInterceptorList.remove(requestInterceptor);\n    }\n\n    /**\n     * Remove msf4j response interceptor.\n     *\n     * @param responseInterceptor MSF4J interceptor instance.\n     */\n    public void removeGlobalResponseInterceptor(ResponseInterceptor responseInterceptor) {\n        globalResponseInterceptorList.remove(responseInterceptor);\n    }\n\n    /**\n     * Get global request interceptor list.\n     *\n     * @return global request interceptor list\n     */\n    public List<RequestInterceptor> getGlobalRequestInterceptorList() {\n        return globalRequestInterceptorList;\n    }\n\n    /**\n     * Get global response interceptor list.\n     *\n     * @return global response interceptor list\n     */\n    public List<ResponseInterceptor> getGlobalResponseInterceptorList() {\n        return globalResponseInterceptorList;\n    }\n\n    public void addExceptionMapper(ExceptionMapper... mapper) {\n        Arrays.stream(mapper).forEach(em -> {\n            Arrays.stream(em.getClass().getMethods()).\n                    filter(method -> \"toResponse\".equals(method.getName()) && method.getParameterCount() == 1 &&\n                            !Throwable.class.getName().equals(method.getParameterTypes()[0].getTypeName())).\n                    findAny().\n                    ifPresent(method -> {\n                        try {\n                            exceptionMappers.put(Class.forName(method.getParameterTypes()[0].getTypeName(), false,\n                                    em.getClass().getClassLoader()), em);\n                        } catch (ClassNotFoundException e) {\n                            log.error(\"Could not load class\", e);\n                        }\n                    });\n        });\n    }\n\n    Optional<ExceptionMapper> getExceptionMapper(Throwable throwable) {\n        return exceptionMappers.entrySet().\n                stream().\n                filter(entry -> entry.getKey().isAssignableFrom(throwable.getClass())).\n                findFirst().\n                flatMap(entry -> Optional.ofNullable(entry.getValue()));\n    }\n\n    public void removeExceptionMapper(ExceptionMapper em) {\n        Arrays.stream(em.getClass().getMethods()).\n                filter(method -> method.getName().equals(\"toResponse\") && method.getParameterCount() == 1).\n                findAny().\n                ifPresent(method -> {\n                    try {\n                        exceptionMappers.remove(Class.forName(method.getGenericParameterTypes()[0].getTypeName(),\n                                false, em.getClass().getClassLoader()));\n                    } catch (ClassNotFoundException e) {\n                        log.error(\"Could not load class\", e);\n                    }\n                });\n    }\n\n    public int getServiceCount() {\n        return services.size();\n    }\n\n    private void updateMetadata() {\n        metadata = new MicroserviceMetadata(Collections.unmodifiableMap(services));\n    }\n\n    public void initServices() {\n        invokeLifecycleMethods(PostConstruct.class);\n    }\n\n    public void initService(Object httpService) {\n        invokeLifecycleMethod(httpService, PostConstruct.class);\n    }\n\n    public void preDestroyServices() {\n        invokeLifecycleMethods(PreDestroy.class);\n    }\n\n    public void preDestroyService(Object httpService) {\n        invokeLifecycleMethod(httpService, PreDestroy.class);\n    }\n\n    public SessionManager getSessionManager() {\n        return sessionManager;\n    }\n\n    private void invokeLifecycleMethods(Class lcAnnotation) {\n        services.values().stream().forEach(httpService -> invokeLifecycleMethod(httpService, lcAnnotation));\n    }\n\n    private void invokeLifecycleMethod(Object httpService, Class lcAnnotation) {\n        Optional<Method> lcMethod = Optional.ofNullable(getLifecycleMethod(httpService, lcAnnotation));\n        if (lcMethod.isPresent()) {\n            try {\n                lcMethod.get().invoke(httpService);\n            } catch (IllegalAccessException | InvocationTargetException e) {\n                throw new MicroservicesLCException(\"Exception occurs calling lifecycle method\", e);\n            }\n        }\n    }\n\n    private Method getLifecycleMethod(Object httpService, Class lcAnnotation) {\n        return Arrays.stream(httpService.getClass().getDeclaredMethods()).filter(m -> isValidLifecycleMethod\n                (Optional.of(m), lcAnnotation)).findFirst().orElse(null);\n    }\n\n    private boolean isValidLifecycleMethod(Optional<Method> method, Class lcAnnotation) {\n        return method.filter(m -> Modifier.isPublic(m.getModifiers())\n                && m.getAnnotation(lcAnnotation) != null).isPresent();\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MicroservicesServerActivator.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.osgi.framework.BundleActivator;\nimport org.osgi.framework.BundleContext;\n\n\n/**\n * OSGi Bundle Activator of the MSF4J component.\n */\npublic class MicroservicesServerActivator implements BundleActivator {\n\n    public void start(BundleContext bundleContext) throws Exception {\n        DataHolder.getInstance().setBundleContext(bundleContext);\n    }\n\n    public void stop(BundleContext bundleContext) throws Exception {\n\n    }\n}\n\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MicroservicesServerImpl.java",
    "content": "/*\n *  Copyright (c) 2017 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.internal;\n\nimport org.wso2.msf4j.MicroservicesServer;\nimport org.wso2.transport.http.netty.contract.config.ListenerConfiguration;\n\nimport java.util.Collections;\nimport java.util.Map;\n\n/**\n * Handles details relates microservices server. transport details etc.\n */\npublic class MicroservicesServerImpl implements MicroservicesServer {\n\n    private final Map<String, ListenerConfiguration> listenerConfigurationMap;\n\n    public MicroservicesServerImpl(Map<String, ListenerConfiguration> configurationMap) {\n        listenerConfigurationMap = Collections.unmodifiableMap(configurationMap);\n    }\n\n    @Override\n    public Map<String, ListenerConfiguration> getListenerConfigurations() {\n        return listenerConfigurationMap;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/MicroservicesServerSC.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.framework.InvalidSyntaxException;\nimport org.osgi.framework.ServiceReference;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.carbon.config.provider.ConfigProvider;\nimport org.wso2.carbon.kernel.config.model.CarbonConfiguration;\nimport org.wso2.carbon.kernel.startupresolver.RequiredCapabilityListener;\nimport org.wso2.carbon.kernel.startupresolver.StartupServiceUtils;\nimport org.wso2.msf4j.DefaultSessionManager;\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.MicroservicesServer;\nimport org.wso2.msf4j.SessionManager;\nimport org.wso2.msf4j.SwaggerService;\nimport org.wso2.msf4j.exception.OSGiDeclarativeServiceException;\nimport org.wso2.msf4j.interceptor.OSGiInterceptorConfig;\nimport org.wso2.msf4j.util.RuntimeAnnotations;\nimport org.wso2.msf4j.util.Utils;\nimport org.wso2.transport.http.netty.contract.HttpConnectorListener;\nimport org.wso2.transport.http.netty.contract.HttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.contract.ServerConnector;\nimport org.wso2.transport.http.netty.contract.ServerConnectorFuture;\nimport org.wso2.transport.http.netty.contract.config.ListenerConfiguration;\nimport org.wso2.transport.http.netty.contract.config.ServerBootstrapConfiguration;\nimport org.wso2.transport.http.netty.contract.config.TransportsConfiguration;\nimport org.wso2.transport.http.netty.contractimpl.DefaultHttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.message.HttpConnectorUtil;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Dictionary;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Hashtable;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.ext.ExceptionMapper;\n\nimport static org.wso2.msf4j.internal.MSF4JConstants.STREAMLINED_TRANSPORT_NAMESPACE;\n\n/**\n * OSGi service component for MicroServicesServer.\n */\n@Component(\n        name = \"org.wso2.msf4j.internal.MicroServicesServerSC\",\n        immediate = true,\n        property = {\n                \"componentName=wso2-microservices-server\"\n        }\n)\n@SuppressWarnings(\"unused\")\npublic class MicroservicesServerSC implements RequiredCapabilityListener {\n    private static final Logger log = LoggerFactory.getLogger(MicroservicesServerSC.class);\n    private boolean isAllRequiredCapabilitiesAvailable;\n    private List<ServerConnector> serverConnectors = new ArrayList<>();\n    private MSF4JHttpConnectorListener msf4JHttpConnectorListener;\n    private MSF4JWSConnectorListener msf4JWSConnectorListener;\n    private Map<String, ListenerConfiguration> listenerConfigurationMap = new HashMap<>();\n\n    @Activate\n    protected void start(final BundleContext bundleContext) {\n    }\n\n    @Reference(\n            name = \"microservice\",\n            service = Microservice.class,\n            cardinality = ReferenceCardinality.MULTIPLE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeService\"\n    )\n    protected void addService(Microservice service, Map properties) {\n        /*\n        Some Microservices might get register even after #onAllRequiredCapabilitiesAvailable\n        That is due to the UUF doesn't know the actual service count before hand.\n        Therefore we need to handle those services separately.\n         */\n        if (isAllRequiredCapabilitiesAvailable) {\n            Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n            Object contextPath = properties.get(MSF4JConstants.CONTEXT_PATH);\n            addMicroserviceToRegistry(service, channelId, contextPath);\n        }\n        StartupServiceUtils.updateServiceCache(\"wso2-microservices-server\", Microservice.class);\n    }\n\n    protected void removeService(Microservice service, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry != null) {\n                microservicesRegistry.removeService(service);\n            }\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.removeService(service));\n        }\n    }\n\n    @Reference(\n            name = \"swaggerservice\",\n            service = SwaggerService.class,\n            cardinality = ReferenceCardinality.MULTIPLE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeSwaggerService\"\n    )\n    protected void addSwaggerService(SwaggerService service, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new RuntimeException(\"Couldn't found the registry for channel ID \" + channelId);\n            }\n            microservicesRegistry.addService(service);\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.addService(service));\n        }\n    }\n\n    protected void removeSwaggerService(SwaggerService service, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry != null) {\n                microservicesRegistry.removeService(service);\n            }\n        }\n    }\n\n    protected void removeCarbonTransport(ServerConnector serverConnector) {\n        DataHolder.getInstance().getMicroservicesRegistries().remove(serverConnector.getConnectorID());\n    }\n\n    @Reference(\n            name = \"carbon.config.provider\",\n            service = ConfigProvider.class,\n            cardinality = ReferenceCardinality.MANDATORY,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"unregisterConfigProvider\"\n    )\n    protected void registerConfigProvider(ConfigProvider configProvider) {\n        DataHolder.getInstance().setConfigProvider(configProvider);\n        try {\n            final TransportsConfiguration transportsConfiguration;\n            Object transportConf = configProvider.getConfigurationObject(STREAMLINED_TRANSPORT_NAMESPACE);\n            if (transportConf != null) {\n                transportsConfiguration = Utils.resolveTransportsNSConfiguration(transportConf);\n            } else {\n                transportsConfiguration = configProvider.getConfigurationObject\n                        (MSF4JConstants.WSO2_TRANSPORT_HTTP_CONFIG_NAMESPACE, TransportsConfiguration.class);\n            }\n\n            CarbonConfiguration carbonConfig = configProvider.getConfigurationObject(CarbonConfiguration.class);\n            transportsConfiguration.getListenerConfigurations().forEach(\n                    listenerConfiguration -> listenerConfiguration.setPort(\n                            listenerConfiguration.getPort() + carbonConfig.getPortsConfig().getOffset()));\n\n            Set<ListenerConfiguration> listenerConfigurations =\n                    transportsConfiguration.getListenerConfigurations();\n            if (listenerConfigurations.isEmpty()) {\n                listenerConfigurations = new HashSet<>();\n                listenerConfigurations.add(new ListenerConfiguration());\n            }\n\n            ServerBootstrapConfiguration serverBootstrapConfiguration =\n                    HttpConnectorUtil.getServerBootstrapConfiguration(transportsConfiguration.getTransportProperties());\n            HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory();\n            listenerConfigurations.forEach(listenerConfiguration -> {\n                ServerConnector serverConnector =\n                        connectorFactory.createServerConnector(serverBootstrapConfiguration, listenerConfiguration);\n                MicroservicesRegistryImpl microservicesRegistry = new MicroservicesRegistryImpl();\n                Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                        DataHolder.getInstance().getMicroservicesRegistries();\n                Dictionary<String, String> properties = new Hashtable<>();\n                properties.put(MSF4JConstants.CHANNEL_ID, serverConnector.getConnectorID());\n                microservicesRegistries.put(serverConnector.getConnectorID(), microservicesRegistry);\n                DataHolder.getInstance().getBundleContext()\n                        .registerService(MicroservicesRegistry.class, microservicesRegistry, properties);\n                listenerConfigurationMap.put(serverConnector.getConnectorID(), listenerConfiguration);\n                serverConnectors.add(serverConnector);\n            });\n        } catch (ConfigurationException e) {\n            log.error(\"Error while loading TransportsConfiguration\", e);\n            throw new RuntimeException(\"Error while loading TransportsConfiguration\", e);\n        }\n        StartupServiceUtils.updateServiceCache(\"wso2-microservices-server\", ConfigProvider.class);\n    }\n\n    protected void unregisterConfigProvider(ConfigProvider configProvider) {\n        DataHolder.getInstance().setConfigProvider(null);\n    }\n\n    @Reference(\n            name = \"interceptor-config\",\n            service = OSGiInterceptorConfig.class,\n            cardinality = ReferenceCardinality.MULTIPLE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeInterceptorConfig\"\n    )\n    protected void addInterceptorConfig(OSGiInterceptorConfig interceptorConfig, Map properties) {\n        StartupServiceUtils.updateServiceCache(\"wso2-microservices-server\", OSGiInterceptorConfig.class);\n    }\n\n    protected void removeInterceptorConfig(OSGiInterceptorConfig interceptorConfig, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microServicesRegistry = microservicesRegistries.get(channelId.toString());\n            Arrays.stream(interceptorConfig.getGlobalRequestInterceptorArray()).forEach(\n                    microServicesRegistry::removeGlobalRequestInterceptor);\n            Arrays.stream(interceptorConfig.getGlobalResponseInterceptorArray()).forEach(\n                    microServicesRegistry::removeGlobalResponseInterceptor);\n        } else {\n            microservicesRegistries.values().forEach(registry -> {\n                Arrays.stream(interceptorConfig.getGlobalRequestInterceptorArray()).forEach(\n                        registry::removeGlobalRequestInterceptor);\n                Arrays.stream(interceptorConfig.getGlobalResponseInterceptorArray()).forEach(\n                        registry::removeGlobalResponseInterceptor);\n            });\n        }\n    }\n\n    @Reference(\n            name = \"interceptor\",\n            service = Interceptor.class,\n            cardinality = ReferenceCardinality.MULTIPLE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeInterceptor\"\n    )\n    protected void addInterceptor(Interceptor interceptor, Map properties) {\n        StartupServiceUtils.updateServiceCache(\"wso2-microservices-server\", Interceptor.class);\n    }\n\n    /**\n     * Remove interceptor.\n     *\n     * @param interceptor interceptor to be removed\n     * @param properties  map of interceptor component properties\n     * @deprecated\n     */\n    protected void removeInterceptor(Interceptor interceptor, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            microservicesRegistries.get(channelId.toString()).removeGlobalRequestInterceptor(interceptor);\n            microservicesRegistries.get(channelId.toString()).removeGlobalResponseInterceptor(interceptor);\n        } else {\n            microservicesRegistries.values().forEach(registry -> {\n                registry.removeGlobalRequestInterceptor(interceptor);\n                registry.removeGlobalResponseInterceptor(interceptor);\n            });\n        }\n    }\n\n    @Reference(\n            name = \"exception-mapper\",\n            service = ExceptionMapper.class,\n            cardinality = ReferenceCardinality.MULTIPLE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeExceptionMapper\"\n    )\n    protected void addExceptionMapper(ExceptionMapper exceptionMapper, Map properties) {\n    }\n\n    protected void removeExceptionMapper(ExceptionMapper exceptionMapper, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            microservicesRegistries.get(channelId.toString()).removeExceptionMapper(exceptionMapper);\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.removeExceptionMapper(exceptionMapper));\n        }\n    }\n\n    @Reference(\n            name = \"session-manager\",\n            service = SessionManager.class,\n            cardinality = ReferenceCardinality.OPTIONAL,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeSessionManager\"\n    )\n    protected void addSessionManager(SessionManager sessionManager, Map properties) {\n    }\n\n    protected void removeSessionManager(SessionManager sessionManager, Map properties) {\n        Object channelId = properties.get(MSF4JConstants.CHANNEL_ID);\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        sessionManager.stop();\n        DefaultSessionManager defaultSessionManager = new DefaultSessionManager();\n        defaultSessionManager.init();\n        if (channelId != null) {\n            microservicesRegistries.get(channelId.toString()).setSessionManager(defaultSessionManager);\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.setSessionManager(defaultSessionManager));\n        }\n    }\n\n    @Override\n    public void onAllRequiredCapabilitiesAvailable() {\n        try {\n            ServiceReference[] serviceReferences = DataHolder.getInstance().getBundleContext()\n                    .getServiceReferences(Microservice.class.getName(), null);\n            if (serviceReferences != null && serviceReferences.length > 0) {\n                Arrays.stream(serviceReferences).forEach(serviceReference -> {\n                    Microservice service =\n                            (Microservice) DataHolder.getInstance().getBundleContext().getService(serviceReference);\n                    Object channelId = serviceReference.getProperty(MSF4JConstants.CHANNEL_ID);\n                    Object contextPath = serviceReference.getProperty(\"contextPath\");\n                    addMicroserviceToRegistry(service, channelId, contextPath);\n                });\n            }\n\n            // Add request and response interceptors\n            serviceReferences = DataHolder.getInstance().getBundleContext()\n                    .getServiceReferences(OSGiInterceptorConfig.class.getName(), null);\n            if (serviceReferences != null && serviceReferences.length > 0) {\n                Arrays.stream(serviceReferences).forEach(serviceReference -> {\n                    OSGiInterceptorConfig interceptorConfig =\n                            (OSGiInterceptorConfig) DataHolder.getInstance().getBundleContext()\n                                    .getService(serviceReference);\n                    Object channelId = serviceReference.getProperty(MSF4JConstants.CHANNEL_ID);\n                    addRequestResponseInterceptorsToRegistry(interceptorConfig, channelId);\n                });\n            }\n\n            serviceReferences =\n                    DataHolder.getInstance().getBundleContext().getServiceReferences(Interceptor.class.getName(), null);\n            if (serviceReferences != null && serviceReferences.length > 0) {\n                Arrays.stream(serviceReferences).forEach(serviceReference -> {\n                    Interceptor interceptor =\n                            (Interceptor) DataHolder.getInstance().getBundleContext().getService(serviceReference);\n                    Object channelId = serviceReference.getProperty(MSF4JConstants.CHANNEL_ID);\n                    addInterceptorToRegistry(interceptor, channelId);\n                });\n            }\n\n            serviceReferences = DataHolder.getInstance().getBundleContext()\n                    .getServiceReferences(ExceptionMapper.class.getName(), null);\n            if (serviceReferences != null && serviceReferences.length > 0) {\n                Arrays.stream(serviceReferences).forEach(serviceReference -> {\n                    ExceptionMapper exceptionMapper =\n                            (ExceptionMapper) DataHolder.getInstance().getBundleContext().getService(serviceReference);\n                    Object channelId = serviceReference.getProperty(MSF4JConstants.CHANNEL_ID);\n                    addExceptionMapperToRegistry(exceptionMapper, channelId);\n                });\n            }\n\n            serviceReferences = DataHolder.getInstance().getBundleContext()\n                    .getServiceReferences(SessionManager.class.getName(), null);\n            if (serviceReferences != null && serviceReferences.length > 0) {\n                Arrays.stream(serviceReferences).forEach(serviceReference -> {\n                    SessionManager sessionManager =\n                            (SessionManager) DataHolder.getInstance().getBundleContext().getService(serviceReference);\n                    Object channelId = serviceReference.getProperty(MSF4JConstants.CHANNEL_ID);\n                    addSessionManagerToRegistry(sessionManager, channelId);\n                });\n            }\n        } catch (InvalidSyntaxException e) {\n            log.error(\"Error while registering required capabilities. \" + e.getMessage());\n        } finally {\n            isAllRequiredCapabilitiesAvailable = true;\n        }\n\n        msf4JHttpConnectorListener = new MSF4JHttpConnectorListener();\n        msf4JWSConnectorListener = new MSF4JWSConnectorListener();\n        DataHolder.getInstance().getBundleContext()\n                .registerService(HttpConnectorListener.class, msf4JHttpConnectorListener, null);\n        DataHolder.getInstance().getBundleContext().registerService(MicroservicesServerSC.class, this, null);\n        DataHolder.getInstance().getBundleContext().registerService(MicroservicesServer.class, new\n                MicroservicesServerImpl(listenerConfigurationMap), null);\n        log.info(\"All microservices are available\");\n        serverConnectors.forEach(serverConnector -> {\n            final ServerConnectorFuture serverConnectorFuture = serverConnector.start();\n            serverConnectorFuture.setHttpConnectorListener(msf4JHttpConnectorListener);\n            serverConnectorFuture.setWebSocketConnectorListener(msf4JWSConnectorListener);\n        });\n    }\n\n    private void addMicroserviceToRegistry(Microservice service, Object channelId, Object contextPath) {\n        if (contextPath != null) {\n            Map<String, Object> valuesMap = new HashMap<>();\n            valuesMap.put(\"value\", contextPath);\n            RuntimeAnnotations.putAnnotation(service.getClass(), Path.class, valuesMap);\n        }\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new RuntimeException(\"Couldn't found the registry for channel ID \" + channelId);\n            }\n            if (contextPath == null) {\n                microservicesRegistry.addService(service);\n            } else {\n                microservicesRegistry.addService(contextPath.toString(), service);\n            }\n        } else {\n            if (contextPath == null) {\n                microservicesRegistries.values().forEach(registry -> registry.addService(service));\n            } else {\n                microservicesRegistries.values()\n                        .forEach(registry -> registry.addService(contextPath.toString(), service));\n            }\n        }\n    }\n\n    /**\n     * Add request and response interceptors to registry.\n     *\n     * @param interceptorConfig interceptor configuration\n     * @param channelId         micro-service channel id\n     */\n    private void addRequestResponseInterceptorsToRegistry(OSGiInterceptorConfig interceptorConfig, Object channelId) {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new OSGiDeclarativeServiceException(\"Couldn't find the registry for channel ID \" +\n                        channelId);\n            }\n            microservicesRegistry.addGlobalRequestInterceptor(interceptorConfig.getGlobalRequestInterceptorArray());\n            microservicesRegistry.addGlobalResponseInterceptor(interceptorConfig.getGlobalResponseInterceptorArray());\n        } else {\n            microservicesRegistries.values().forEach(registry -> {\n                registry.addGlobalRequestInterceptor(interceptorConfig.getGlobalRequestInterceptorArray());\n                registry.addGlobalResponseInterceptor(interceptorConfig.getGlobalResponseInterceptorArray());\n            });\n        }\n    }\n\n    /**\n     * Add interceptor to registry.\n     *\n     * @param interceptor interceptor\n     * @param channelId   micro-service channel it\n     */\n    @Deprecated\n    private void addInterceptorToRegistry(Interceptor interceptor, Object channelId) {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new OSGiDeclarativeServiceException(\"Couldn't found the registry for channel ID \" + channelId);\n            }\n            microservicesRegistry.addGlobalRequestInterceptor(interceptor);\n            microservicesRegistry.addGlobalResponseInterceptor(interceptor);\n        } else {\n            microservicesRegistries.values().forEach(registry -> {\n                registry.addGlobalRequestInterceptor(interceptor);\n                registry.addGlobalResponseInterceptor(interceptor);\n            });\n        }\n    }\n\n    private void addExceptionMapperToRegistry(ExceptionMapper exceptionMapper, Object channelId) {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new RuntimeException(\"Couldn't found the registry for channel ID \" + channelId);\n            }\n            microservicesRegistry.addExceptionMapper(exceptionMapper);\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.addExceptionMapper(exceptionMapper));\n        }\n    }\n\n    private void addSessionManagerToRegistry(SessionManager sessionManager, Object channelId) {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        sessionManager.init();\n        if (channelId != null) {\n            MicroservicesRegistryImpl microservicesRegistry = microservicesRegistries.get(channelId.toString());\n            if (microservicesRegistry == null) {\n                throw new RuntimeException(\"Couldn't found the registry for channel ID \" + channelId);\n            }\n            microservicesRegistry.setSessionManager(sessionManager);\n        } else {\n            microservicesRegistries.values().forEach(registry -> registry.setSessionManager(sessionManager));\n        }\n    }\n}\n\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/beanconversion/BeanConverter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.beanconversion;\n\nimport org.wso2.msf4j.beanconversion.MediaTypeConverter;\n\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\n/**\n * Factory class for getting correct media type conversion\n * instance for a given mime type.\n */\npublic class BeanConverter {\n\n    private static final MediaTypeConverter DEFAULT_CONVERTER = new TextPlainConverter();\n    private static final Map<String, MediaTypeConverter> converterMap = new HashMap<>();\n\n    private BeanConverter() {\n    }\n\n    static {\n        addMediaTypeConverter(new JsonConverter());\n        addMediaTypeConverter(new XmlConverter());\n    }\n\n    /**\n     * Get a media type converter for a given media type string.\n     *\n     * @param mediaType media type String\n     * @return MediaTypeConverter\n     */\n    public static MediaTypeConverter getConverter(String mediaType) {\n        MediaTypeConverter mediaTypeConverter = converterMap.get(mediaType.toLowerCase(Locale.US));\n        if (mediaTypeConverter == null) {\n            mediaTypeConverter = DEFAULT_CONVERTER;\n        }\n        return mediaTypeConverter;\n    }\n\n    /**\n     * Register a media type converter.\n     */\n    private static void addMediaTypeConverter(MediaTypeConverter mediaTypeConverter) {\n        for (String mediaType : mediaTypeConverter.getSupportedMediaTypes()) {\n            converterMap.put(mediaType.toLowerCase(Locale.US), mediaTypeConverter);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/beanconversion/JsonConverter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.beanconversion;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonSyntaxException;\nimport org.wso2.msf4j.beanconversion.BeanConversionException;\nimport org.wso2.msf4j.beanconversion.MediaTypeConverter;\n\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.io.UnsupportedEncodingException;\nimport java.lang.reflect.Type;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Media type converter for text/json,\n * application/json mime types.\n */\npublic class JsonConverter extends MediaTypeConverter {\n\n    private static final Gson gson = new Gson();\n    private static final String TEXT_JSON = \"text/json\";\n\n    /**\n     * Provides the supported media types for bean conversions.\n     */\n    @Override\n    public String[] getSupportedMediaTypes() {\n        return new String[]{MediaType.APPLICATION_JSON, TEXT_JSON};\n    }\n\n    /**\n     * Convert an Object to a Json encoded byte buffer.\n     *\n     * @param object object that needs to be converted to a media content\n     * @return Json encoded byte buffer\n     */\n    @Override\n    public ByteBuffer toMedia(Object object) {\n        String value = (object instanceof String || object instanceof JsonArray || object instanceof JsonObject) ?\n                       object.toString() : gson.toJson(object);\n        return ByteBuffer.wrap(value.getBytes(Charset.defaultCharset()));\n    }\n\n    /**\n     * Convert a Json ByteBuffer content to an object.\n     *\n     * @param content    content that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return Object that maps the Json data\n     * @throws BeanConversionException if error occure while converting the content\n     */\n    @Override\n    public Object toObject(ByteBuffer content, Type targetType) throws BeanConversionException {\n        try {\n            String str = Charset.defaultCharset().decode(content).toString();\n            Object object = gson.fromJson(str, targetType);\n            if (object == null) {\n                throw new BeanConversionException(\"Unable to perform json to object conversion\");\n            }\n            return object;\n        } catch (JsonSyntaxException ex) {\n            throw new BeanConversionException(\"Unable to perform json to object conversion\", ex);\n        }\n    }\n\n    @Override\n    protected Object toObject(InputStream inputStream, Type targetType) throws BeanConversionException {\n        try {\n            Reader reader = new InputStreamReader(inputStream, UTF_8_CHARSET);\n            Object object = gson.fromJson(reader, targetType);\n            if (object == null) {\n                throw new BeanConversionException(\"Unable to perform json to object conversion\");\n            }\n            return object;\n        } catch (UnsupportedEncodingException ex) {\n            throw new BeanConversionException(\"Unable to perform json to object conversion\", ex);\n        }\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/beanconversion/TextPlainConverter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.beanconversion;\n\nimport org.apache.commons.io.IOUtils;\nimport org.wso2.msf4j.beanconversion.BeanConversionException;\nimport org.wso2.msf4j.beanconversion.MediaTypeConverter;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Type;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\n\n/**\n * Media type converter for text/plain mime type. This will be\n * applied by default for unsupported media types.\n */\npublic class TextPlainConverter extends MediaTypeConverter {\n\n    /**\n     * Provides the supported media types for bean conversions.\n     */\n    @Override\n    public String[] getSupportedMediaTypes() {\n        return new String[0];\n    }\n\n    /**\n     * Convert an Object to a text ByteBuffer.\n     *\n     * @param object object that needs to be converted to a media content\n     * @return Byte buffer that contains the text\n     */\n    @Override\n    public ByteBuffer toMedia(Object object) {\n        return ByteBuffer.wrap(object.toString().getBytes(Charset.defaultCharset()));\n    }\n\n    /**\n     * Convert a text ByteBuffer content to an object.\n     *\n     * @param content    content that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return String object that contains the text data\n     */\n    @Override\n    public Object toObject(ByteBuffer content, Type targetType) {\n        return Charset.defaultCharset().decode(content).toString();\n    }\n\n    @Override\n    protected Object toObject(InputStream inputStream, Type targetType) throws BeanConversionException {\n        try {\n            return IOUtils.toString(inputStream, UTF_8_CHARSET);\n        } catch (IOException e) {\n            throw new BeanConversionException(\"Unable to perform string conversion\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/beanconversion/XmlConverter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.beanconversion;\n\nimport org.wso2.msf4j.beanconversion.BeanConversionException;\nimport org.wso2.msf4j.beanconversion.MediaTypeConverter;\n\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.io.StringReader;\nimport java.io.StringWriter;\nimport java.io.UnsupportedEncodingException;\nimport java.lang.reflect.Type;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport javax.ws.rs.core.MediaType;\nimport javax.xml.bind.JAXBContext;\nimport javax.xml.bind.JAXBException;\nimport javax.xml.bind.Marshaller;\n\n/**\n * Media type converter for text/xml mime type.\n */\npublic class XmlConverter extends MediaTypeConverter {\n\n    private static final String TEXT_XML = \"text/xml\";\n\n    /**\n     * Provides the supported media types for bean conversions.\n     */\n    @Override\n    public String[] getSupportedMediaTypes() {\n        return new String[]{MediaType.APPLICATION_XML, TEXT_XML};\n    }\n\n\n    /**\n     * Convert an Object to a xml encoded ByteBuffer.\n     *\n     * @param object object that needs to be converted to a media content\n     * @return xml encoded byte buffer\n     */\n    @Override\n    public ByteBuffer toMedia(Object object) throws BeanConversionException {\n        try {\n            JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());\n            Marshaller marshaller = jaxbContext.createMarshaller();\n            StringWriter stringWriter = new StringWriter();\n            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\n            marshaller.marshal(object, stringWriter);\n            return ByteBuffer.wrap(stringWriter.toString().getBytes(Charset.defaultCharset()));\n        } catch (JAXBException e) {\n            throw new BeanConversionException(\"Unable to perform object to xml conversion\", e);\n        }\n    }\n\n    /**\n     * Convert a xml ByteBuffer content to an object.\n     *\n     * @param content    content that needs to be converted to an object\n     * @param targetType media type of the content\n     * @return Object that maps the xml data\n     */\n    @Override\n    public Object toObject(ByteBuffer content, Type targetType) throws BeanConversionException {\n        try {\n            String str = Charset.defaultCharset().decode(content).toString();\n            JAXBContext jaxbContext = null;\n            if (targetType instanceof Class) {\n                jaxbContext = JAXBContext.newInstance((Class) targetType);\n                return jaxbContext.createUnmarshaller().unmarshal(new StringReader(str));\n            }\n        } catch (JAXBException e) {\n            throw new BeanConversionException(\"Unable to perform xml to object conversion\", e);\n        }\n        return null;\n    }\n\n    @Override\n    protected Object toObject(InputStream inputStream, Type targetType) throws BeanConversionException {\n        try {\n            JAXBContext jaxbContext;\n            Reader reader = new InputStreamReader(inputStream, UTF_8_CHARSET);\n            if (targetType instanceof Class) {\n                jaxbContext = JAXBContext.newInstance((Class) targetType);\n                return jaxbContext.createUnmarshaller().unmarshal(reader);\n            }\n        } catch (JAXBException | UnsupportedEncodingException e) {\n            throw new BeanConversionException(\"Unable to perform xml to object conversion\", e);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/EntityWriter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\n/**\n * Interface that provides the capability of writing an entity type to\n * a carbon message.\n *\n * @param <T> type of the entity\n */\npublic interface EntityWriter<T> {\n\n    String CHUNKED = \"chunked\";\n\n    /**\n     * Provide supported entity type.\n     *\n     * @return entity type\n     */\n    Class<T> getType();\n\n    /**\n     * Write the entity object to the carbon message by considering the\n     * provided chunk size and media type.\n     *\n     * @param carbonMessage response message\n     * @param entity    object\n     * @param mediaType user defined media type\n     * @param chunkSize user defined chunk size\n     *                  0 to signify none chunked response\n     *                  -1 to signify default chunk size of the EntityWriter\n     * @param responder HttpCarbonMessage that should be used to start sending the response payload\n     */\n    void writeData(HttpCarbonMessage carbonMessage, T entity, String mediaType, int chunkSize,\n                   HttpCarbonMessage responder);\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/EntityWriterRegistry.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport org.wso2.msf4j.internal.ClassComparator;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.TreeMap;\n\n/**\n * Registry that stores entity writers for different entity types.\n */\npublic class EntityWriterRegistry {\n\n    private static final EntityWriter DEFAULT_ENTITY_WRITER = new ObjectEntityWriter();\n    private static final Map<Class, EntityWriter> writers = new TreeMap<>(new ClassComparator());\n\n    static {\n        registerEntityWriter(new FileEntityWriter());\n        registerEntityWriter(new InputStreamEntityWriter());\n        registerEntityWriter(new StreamingOutputEntityWriter());\n    }\n\n    private EntityWriterRegistry() {\n    }\n\n    /**\n     * Register an entity writer.\n     *\n     * @param entityWriter entity writer for a specific entity type\n     */\n    private static void registerEntityWriter(EntityWriter entityWriter) {\n        writers.put(entityWriter.getType(), entityWriter);\n    }\n\n    /**\n     * Get entity writer for a given type.\n     *\n     * @param type type of the entity to be written to a carbon message\n     * @return entity writer\n     */\n    public static EntityWriter getEntityWriter(Class type) {\n        return writers.entrySet().\n                stream().\n                filter(entry -> entry.getKey().isAssignableFrom(type)).\n                findFirst().\n                flatMap(entry -> Optional.ofNullable(entry.getValue())).orElse(DEFAULT_ENTITY_WRITER);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/FileEntityWriter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport io.netty.buffer.Unpooled;\nimport io.netty.handler.codec.http.DefaultHttpContent;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.FilenameUtils;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.internal.mime.MimeMapper;\nimport org.wso2.msf4j.internal.mime.MimeMappingException;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * EntityWriter for entity of type File.\n */\npublic class FileEntityWriter implements EntityWriter<File> {\n\n    public static final int DEFAULT_CHUNK_SIZE = 1024;\n\n    /**\n     * Supported entity type.\n     */\n    @Override\n    public Class<File> getType() {\n        return File.class;\n    }\n\n    /**\n     * Write the entity to the carbon message.\n     */\n    @Override\n    public void writeData(HttpCarbonMessage httpCarbonMessage, File file, String mediaType, int chunkSize,\n                          HttpCarbonMessage responder) {\n        if (mediaType == null || mediaType.equals(MediaType.WILDCARD)) {\n            try {\n                mediaType = MimeMapper.getMimeType(FilenameUtils.getExtension(file.getName()));\n            } catch (MimeMappingException e) {\n                mediaType = MediaType.WILDCARD;\n            }\n        }\n        try {\n            FileChannel fileChannel = new FileInputStream(file).getChannel();\n            if (chunkSize == Response.NO_CHUNK || chunkSize == Response.DEFAULT_CHUNK_SIZE) {\n                chunkSize = DEFAULT_CHUNK_SIZE;\n            }\n            httpCarbonMessage.setHeader(HttpHeaderNames.TRANSFER_ENCODING.toString(), CHUNKED);\n            httpCarbonMessage.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), mediaType);\n\n            try {\n                responder.respond(httpCarbonMessage);\n            } catch (ServerConnectorException e) {\n                throw new RuntimeException(\"Error while sending the response.\", e);\n            }\n\n            ByteBuffer buffer = ByteBuffer.allocate(chunkSize);\n            while (fileChannel.read(buffer) != -1) {\n                buffer.flip();\n                httpCarbonMessage.addHttpContent(new DefaultHttpContent(Unpooled.wrappedBuffer(buffer)));\n                buffer = ByteBuffer.allocate(chunkSize);\n            }\n            fileChannel.close();\n            httpCarbonMessage.addHttpContent(new DefaultLastHttpContent());\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error occurred while reading from file\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/InputStreamEntityWriter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport io.netty.buffer.Unpooled;\nimport io.netty.handler.codec.http.DefaultHttpContent;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.wso2.msf4j.Response;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.util.concurrent.Executors;\n\n/**\n * EntityWriter for entity of type InputStream.\n */\npublic class InputStreamEntityWriter implements EntityWriter<InputStream> {\n\n    public static final int DEFAULT_CHUNK_SIZE = 1024;\n\n    /**\n     * Supported entity type.\n     */\n    @Override\n    public Class<InputStream> getType() {\n        return InputStream.class;\n    }\n\n    /**\n     * Write the entity to the carbon message.\n     */\n    @Override\n    public void writeData(HttpCarbonMessage carbonMessage, InputStream ipStream,\n                          String mediaType, int chunkSize, HttpCarbonMessage responder) {\n        try {\n            if (chunkSize == Response.NO_CHUNK || chunkSize == Response.DEFAULT_CHUNK_SIZE) {\n                chunkSize = DEFAULT_CHUNK_SIZE;\n            }\n            carbonMessage.setHeader(HttpHeaderNames.TRANSFER_ENCODING.toString(), CHUNKED);\n            carbonMessage.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), mediaType);\n            Executors.newSingleThreadExecutor().execute(() -> {\n                try {\n                    responder.respond(carbonMessage);\n                } catch (ServerConnectorException e) {\n                    throw new RuntimeException(\"Error while sending the response.\", e);\n                }\n            });\n            byte[] data = new byte[chunkSize];\n            int len;\n            while ((len = ipStream.read(data)) != -1) {\n                carbonMessage.addHttpContent(new DefaultHttpContent(Unpooled.wrappedBuffer(ByteBuffer.wrap(data, 0,\n                        len))));\n                data = new byte[chunkSize];\n            }\n            carbonMessage.addHttpContent(new DefaultLastHttpContent());\n\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error occurred while reading from InputStream\", e);\n        } finally {\n            if (ipStream != null) {\n                try {\n                    ipStream.close();\n                } catch (IOException ignore) {\n\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/ObjectEntityWriter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport io.netty.buffer.Unpooled;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.internal.beanconversion.BeanConverter;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.nio.ByteBuffer;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * EntityWriter for  entity of type Object.\n */\npublic class ObjectEntityWriter implements EntityWriter<Object> {\n\n    /**\n     * Supported entity type.\n     */\n    @Override\n    public Class<Object> getType() {\n        return Object.class;\n    }\n\n    /**\n     * Write the entity to the carbon message.\n     */\n    @Override\n    public void writeData(HttpCarbonMessage carbonMessage, Object entity, String mediaType, int chunkSize,\n                          HttpCarbonMessage responder) {\n        mediaType = (mediaType != null) ? mediaType : MediaType.WILDCARD;\n        ByteBuffer byteBuffer = BeanConverter.getConverter(mediaType).convertToMedia(entity);\n        carbonMessage.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(byteBuffer)));\n        if (chunkSize == Response.NO_CHUNK) {\n            carbonMessage.setHeader(HttpHeaderNames.CONTENT_LENGTH.toString(), String.valueOf(byteBuffer.remaining()));\n        } else {\n            carbonMessage.setHeader(HttpHeaderNames.TRANSFER_ENCODING.toString(), CHUNKED);\n        }\n        carbonMessage.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), mediaType);\n        try {\n            responder.respond(carbonMessage);\n        } catch (ServerConnectorException e) {\n            throw new RuntimeException(\"Error while sending the response.\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/entitywriter/StreamingOutputEntityWriter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.entitywriter;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.wso2.transport.http.netty.contract.exceptions.ServerConnectorException;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\nimport org.wso2.transport.http.netty.message.HttpMessageDataStreamer;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.concurrent.Executors;\nimport javax.ws.rs.core.StreamingOutput;\n\n/**\n * EntityWriter for entity of type {@link javax.ws.rs.core.StreamingOutput}.\n */\npublic class StreamingOutputEntityWriter implements EntityWriter<StreamingOutput> {\n\n    /**\n     * Supported entity type.\n     */\n    @Override\n    public Class<StreamingOutput> getType() {\n        return StreamingOutput.class;\n    }\n\n    /**\n     * Write the entity to the carbon message.\n     */\n    @Override\n    public void writeData(HttpCarbonMessage carbonMessage, StreamingOutput output,\n                          String mediaType, int chunkSize, HttpCarbonMessage responder) {\n        try {\n            carbonMessage.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), mediaType);\n            carbonMessage.setHeader(HttpHeaderNames.TRANSFER_ENCODING.toString(), CHUNKED);\n            Executors.newSingleThreadExecutor().execute(() -> {\n                try {\n                    responder.respond(carbonMessage);\n                } catch (ServerConnectorException e) {\n                    throw new RuntimeException(\"Error while sending the response.\", e);\n                }\n            });\n            OutputStream outputStream = new HttpMessageDataStreamer(carbonMessage).getOutputStream();\n            output.write(outputStream);\n            outputStream.close();\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error occurred while streaming output\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/mime/MimeMapper.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.mime;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Properties;\n\n/**\n * This class lazily loads the mime-map.properties file\n * and maps file extension to mime type using the file.\n */\npublic class MimeMapper {\n\n    private static Properties mimeMap = null;\n    private static final Logger log = LoggerFactory.getLogger(MimeMapper.class);\n\n    private static void loadMimeMap() throws IOException {\n        mimeMap = new Properties();\n        InputStream inputStream = MimeMapper.class.getClassLoader()\n                .getResourceAsStream(\"mime-map.properties\");\n        if (inputStream != null) {\n            mimeMap.load(inputStream);\n            try {\n                inputStream.close();\n            } catch (IOException e) {\n                log.warn(\"Could not close input stream\", e);\n            }\n        }\n    }\n\n    public static String getMimeType(String extension) throws MimeMappingException {\n        try {\n            if (mimeMap == null) {\n                loadMimeMap();\n            }\n        } catch (IOException e) {\n            throw new MimeMappingException(\"Could not load mime map\", e);\n        }\n        String mimeType = mimeMap.getProperty(extension);\n        if (mimeType == null) {\n            throw new MimeMappingException(\"Could not find mime type\");\n        }\n        return mimeType;\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/mime/MimeMappingException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.mime;\n\n/**\n * This exception will be thrown in case a\n * file extension cannot be mapped to a mime type.\n */\npublic class MimeMappingException extends RuntimeException {\n\n    public MimeMappingException(String msg) {\n        super(msg);\n    }\n\n    public MimeMappingException(Exception cause) {\n        super(cause);\n    }\n\n    public MimeMappingException(String msg, Exception cause) {\n        super(msg, cause);\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/HandlerException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.wso2.msf4j.util.HttpUtil;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport javax.ws.rs.core.Response;\n\n/**\n * Creating Http Response for Exception messages.\n */\npublic class HandlerException extends Exception {\n\n    private final Response.Status failureStatus;\n    private final String message;\n\n    public HandlerException(Response.Status failureStatus, String message) {\n        super(message);\n        this.failureStatus = failureStatus;\n        this.message = message;\n    }\n\n    public HandlerException(Response.Status failureStatus, String message, Throwable cause) {\n        super(message, cause);\n        this.failureStatus = failureStatus;\n        this.message = message;\n    }\n\n    public HttpCarbonMessage getFailureResponse() {\n        return HttpUtil.createTextResponse(failureStatus.getStatusCode(), message);\n    }\n\n    public Response.Status getFailureStatus() {\n        return failureStatus;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/HttpMethodInfo.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.HttpStreamHandler;\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.InterceptorExecutor;\nimport org.wso2.msf4j.internal.MSF4JConstants;\nimport org.wso2.msf4j.internal.MicroservicesRegistryImpl;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.MultivaluedMap;\n\nimport static org.wso2.msf4j.internal.router.Util.GROUP_PATTERN;\nimport static org.wso2.msf4j.internal.router.Util.GROUP_PATTERN_REGEX;\nimport static org.wso2.msf4j.internal.router.Util.WILD_CARD_PATTERN;\n\n/**\n * HttpMethodInfo is a helper class having state information about the http handler method to be invoked, the handler\n * and arguments required for invocation by the Dispatcher. RequestRouter populates this class and stores in its\n * context as attachment.\n */\npublic class HttpMethodInfo {\n\n    private final Method method;\n    private final Object handler;\n    private final Object[] args;\n    private MultivaluedMap<String, Object> formParameters = null;\n    private Response responder;\n    private HttpStreamHandler httpStreamHandler;\n    private static final Logger log = LoggerFactory.getLogger(HttpMethodInfo.class);\n    private static final String DECLARING_CLASS_LIST_CONSTANT = \"declaringClassList\";\n    private static final String RESOURCE_METHOD_LIST_CONSTANT = \"resourceMethodList\";\n\n    /**\n     * Construct HttpMethodInfo object for a handler\n     * method that does not support streaming.\n     *\n     * @param method    handler method\n     * @param handler   object of the handler method\n     * @param args      method arguments array\n     * @param responder responder object\n     */\n    public HttpMethodInfo(Method method,\n                          Object handler,\n                          Object[] args,\n                          MultivaluedMap<String, Object> formParameters,\n                          Response responder) {\n        this.method = method;\n        this.handler = handler;\n        this.args = Arrays.copyOf(args, args.length);\n        this.formParameters = formParameters;\n        this.responder = responder;\n    }\n\n    /**\n     * Construct HttpMethodInfo object for a streaming\n     * supported handler method.\n     *\n     * @param method       handler method\n     * @param handler      object of the handler method\n     * @param args         method arguments array\n     * @param responder    responder object\n     * @param httpStreamer streaming handler\n     * @throws HandlerException throws when HttpMethodInfo construction is unsuccessful\n     */\n    public HttpMethodInfo(Method method,\n                          Object handler,\n                          Object[] args,\n                          MultivaluedMap<String, Object> formParameters,\n                          Response responder,\n                          HttpStreamer httpStreamer) throws HandlerException {\n        this(method, handler, args, formParameters, responder);\n\n        if (!method.getReturnType().equals(Void.TYPE)) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    \"Resource method should be void if it accepts chunked requests\");\n        }\n        try {\n            method.invoke(handler, args);\n        } catch (InvocationTargetException e) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    \"Resource method invocation failed\", e.getTargetException());\n        } catch (IllegalAccessException e) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    \"Resource method invocation access failed\", e);\n        }\n        httpStreamHandler = httpStreamer.getHttpStreamHandler();\n        if (httpStreamHandler == null) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    \"Streaming unsupported\");\n        }\n        httpStreamHandler.init(this.responder);\n    }\n\n    /**\n     * Calls the http resource method.\n     *\n     * @param destination           matching Destinations for the route\n     * @param request               original request\n     * @param httpMethodInfo        http method information\n     * @param microservicesRegistry micro-services registry\n     * @throws Exception if error occurs while invoking the resource method\n     */\n    public void invoke(PatternPathRouter.RoutableDestination<HttpResourceModel> destination, Request request,\n                       HttpMethodInfo httpMethodInfo, MicroservicesRegistryImpl microservicesRegistry)\n            throws Exception {\n        request.setProperty(DECLARING_CLASS_LIST_CONSTANT, new ArrayList<Class<?>>());\n        request.setProperty(RESOURCE_METHOD_LIST_CONSTANT, new ArrayList<Method>());\n        ImmutablePair<Boolean, Object> returnVal =\n                invokeResource(destination, httpMethodInfo, request, microservicesRegistry, false);\n\n        // Execute method level interceptors of sub-resources and resources (first in - last out order)\n        if (returnVal.getFirst()\n                && InterceptorExecutor.executeMethodResponseInterceptorsForMethods(request, httpMethodInfo.responder,\n                (ArrayList<Method>) request.getProperty(RESOURCE_METHOD_LIST_CONSTANT))\n                // Execute class level interceptors of sub-resources and resources (first in - last out order)\n                && InterceptorExecutor.executeClassResponseInterceptorsForClasses(request, httpMethodInfo.responder,\n                (ArrayList<Class<?>>) request.getProperty(DECLARING_CLASS_LIST_CONSTANT))\n                // Execute global interceptors\n                && InterceptorExecutor.executeGlobalResponseInterceptors(microservicesRegistry, request,\n                httpMethodInfo.responder)) {\n            responder.setEntity(returnVal.getSecond());\n        }\n        responder.send();\n    }\n\n    /**\n     * Execute http resource.\n     *\n     * @param destination           matching Destinations for the route\n     * @param httpMethodInfo        http method information\n     * @param request               original request\n     * @param microservicesRegistry micro-services registry\n     * @return value returned from executing the sub-resource method\n     * @throws Exception if error occurs while invoking the sub-resource method\n     */\n    private ImmutablePair<Boolean, Object> invokeResource(\n            PatternPathRouter.RoutableDestination<HttpResourceModel> destination, HttpMethodInfo httpMethodInfo,\n            Request request, MicroservicesRegistryImpl microservicesRegistry, boolean isSubResource) throws Exception {\n        Class<?> clazz = httpMethodInfo.method.getDeclaringClass();\n        request.setProperty(MSF4JConstants.METHOD_PROPERTY_NAME, httpMethodInfo.method); // Required for analytics\n\n        // Execute global request interceptors if not a sub-resource (global interceptors will only be executed\n        // at the parent resource\n        if (!isSubResource && !InterceptorExecutor\n                .executeGlobalRequestInterceptors(microservicesRegistry, request, httpMethodInfo.responder)) {\n            return ImmutablePair.of(false, new Object());\n        }\n        // Execute class level request interceptors\n        if (InterceptorExecutor.executeClassLevelRequestInterceptors(request, httpMethodInfo.responder, clazz)\n                // Execute method level request interceptors\n                && InterceptorExecutor.executeMethodLevelRequestInterceptors(request, httpMethodInfo.responder,\n                httpMethodInfo.method)) {\n            Object returnedValue = httpMethodInfo.method.invoke(httpMethodInfo.handler, httpMethodInfo.args);\n\n            // Class level response interceptors - add to the top of the execution stack\n            ((ArrayList<Class<?>>) request.getProperty(DECLARING_CLASS_LIST_CONSTANT)).add(0, clazz);\n            // Method level response interceptors - add to the top of the execution stack\n            ((ArrayList<Method>) request.getProperty(RESOURCE_METHOD_LIST_CONSTANT)).add(0, httpMethodInfo.method);\n            return httpMethodInfo\n                    .invokeSubResource(request, destination, returnedValue, microservicesRegistry);\n        }\n        return ImmutablePair.of(false, new Object());\n    }\n\n    /**\n     * Calls http sub-resource method.\n     *\n     * @param request               original request\n     * @param destination           matching Destinations for the route\n     * @param returnVal             value returned from the method execution\n     * @param microservicesRegistry micro-services registry\n     * @return value returned from executing the sub-resource method\n     * @throws Exception if error occurs while invoking the sub-resource method\n     */\n    private ImmutablePair<Boolean, Object> invokeSubResource(\n            Request request, PatternPathRouter.RoutableDestination<HttpResourceModel> destination, Object returnVal,\n            MicroservicesRegistryImpl microservicesRegistry) throws Exception {\n        // If this is a sub resource locator need to find and invoke the correct method\n        if (destination.getDestination().isSubResourceLocator()) {\n            String requestPath = request.getUri();\n            if (requestPath.endsWith(\"/\")) {\n                requestPath = requestPath.substring(0, requestPath.length() - 1);\n            }\n            if (requestPath.contains(\"?\")) {\n                requestPath = requestPath.substring(0, requestPath.indexOf(\"?\"));\n            }\n\n            if (!destination.getDestination().isSubResourceScanned()) {\n                // Scan the return object class to search the methods\n                for (Method method : returnVal.getClass().getMethods()) {\n                    if (Modifier.isPublic(method.getModifiers()) && Util.isHttpMethodAvailable(method)) {\n                        String relativePath = \"\";\n                        if (method.getAnnotation(Path.class) != null) {\n                            relativePath = method.getAnnotation(Path.class).value();\n                        }\n                        if (relativePath.startsWith(\"/\")) {\n                            relativePath = relativePath.substring(1);\n                        }\n                        String absolutePath = relativePath.isEmpty() ? destination.getDestination().getPath() :\n                                              String.format(\"%s/%s\", destination.getDestination().getPath(),\n                                                            relativePath);\n                        HttpResourceModel resourceModel = new HttpResourceModel(absolutePath, method, returnVal, false);\n                        resourceModel.setParent(destination.getDestination());\n                        SubresourceKey subResKey = new SubresourceKey(absolutePath, method.getDeclaringClass(),\n                                                                      resourceModel.getHttpMethod());\n                        destination.getDestination().addSubResources(subResKey, resourceModel);\n                    } else if (Modifier.isPublic(method.getModifiers()) && method.getAnnotation(Path.class) != null) {\n                        // Sub resource locator method\n                        String relativePath = method.getAnnotation(Path.class).value();\n                        if (relativePath.startsWith(\"/\")) {\n                            relativePath = relativePath.substring(1);\n                        }\n                        String absolutePath = relativePath.isEmpty() ? destination.getDestination().getPath() :\n                                              String.format(\"%s/%s\", destination.getDestination().getPath(),\n                                                            relativePath);\n                        HttpResourceModel resourceModel = new HttpResourceModel(absolutePath, method, returnVal, true);\n                        resourceModel.setParent(destination.getDestination());\n                        SubresourceKey subResKey =\n                                new SubresourceKey(absolutePath, method.getDeclaringClass(), Collections.emptySet());\n                        destination.getDestination().addSubResources(subResKey, resourceModel);\n                    }\n                }\n                destination.getDestination().setSubResourceScanned(true);\n            }\n            String finalRequestPath = requestPath;\n\n            List<Map.Entry<SubresourceKey, HttpResourceModel>> entries =\n                    destination.getDestination().getSubResources().entrySet().stream()\n                               .filter(e -> e.getValue().getHttpMethod().contains(request.getHttpMethod()) &&\n                                            finalRequestPath.matches(e.getKey().getPath().replaceAll(GROUP_PATTERN,\n                                                                                                GROUP_PATTERN_REGEX)) &&\n                                            returnVal.getClass().equals(e.getKey().getTypedClass()))\n                               .collect(Collectors.toList());\n            Optional<Map.Entry<SubresourceKey, HttpResourceModel>> entry = entries.stream().filter(\n                    entryPair -> entryPair.getValue().matchConsumeMediaType(request.getContentType()) &&\n                                 entryPair.getValue().matchProduceMediaType(request.getAcceptTypes()))\n                                                                                  .findFirst();\n\n            HttpResourceModel resourceModel;\n            if (entry.isPresent()) {\n                resourceModel = entry.get().getValue();\n            } else {\n                // Another sub-resource call\n                String finalRequestPath1 = requestPath;\n                entries = destination.getDestination().getSubResources().entrySet().stream()\n                           .filter(e -> finalRequestPath1\n                                                .matches(e.getKey().getPath()\n                                                          .replaceAll(GROUP_PATTERN, GROUP_PATTERN_REGEX).concat(\".*\"))\n                               && e.getValue().isSubResourceLocator()\n                               && returnVal.getClass().equals(e.getKey().getTypedClass())).collect(Collectors.toList());\n                entry = entries.stream().filter(entryPair ->\n                                                entryPair\n                                                        .getValue()\n                                                        .matchConsumeMediaType(\n                                                                request.getContentType()) &&\n                                                entryPair\n                                                        .getValue()\n                                                        .matchProduceMediaType(\n                                                                request.getAcceptTypes()))\n                       .findFirst();\n                if (entry.isPresent()) {\n                    resourceModel = entry.get().getValue();\n                } else {\n                    throw new HandlerException(javax.ws.rs.core.Response.Status.NOT_FOUND,\n                                               String.format(\"Problem accessing: %s. Reason: Not Found\", requestPath));\n                }\n            }\n\n            // Process path to get the PathParam values\n            Path declaredAnnotation = resourceModel.getMethod().getDeclaredAnnotation(Path.class);\n            String[] parts = declaredAnnotation.value().split(\"/\");\n            StringBuilder sb = new StringBuilder();\n            List<String> groupNames = new ArrayList<>();\n            for (String part : parts) {\n                Matcher groupMatcher = Pattern.compile(GROUP_PATTERN).matcher(part);\n                if (groupMatcher.matches()) {\n                    groupNames.add(Util.stripBraces(part));\n                    sb.append(\"([^/]+)\");\n                } else if (WILD_CARD_PATTERN.matcher(part).matches()) {\n                    sb.append(\".*?\");\n                } else {\n                    sb.append(part);\n                }\n                sb.append(\"/\");\n            }\n            if (sb.length() > 0) {\n                sb.setLength(sb.length() - 1);\n            }\n\n            Map<String, String> groupNameValues = new HashMap<>();\n            destination.getGroupNameValues().entrySet().forEach(e -> groupNameValues.put(e.getKey(), e.getValue()));\n\n            //Get the sub resource path\n            String[] paths =\n                    requestPath.split(destination.getDestination().getPath().replaceAll(GROUP_PATTERN, \"([^/]+)\"));\n            String subResPath = \"/\";\n            if (paths.length != 0) {\n                subResPath = paths[1];\n            }\n\n            Pattern pattern = Pattern.compile(sb.toString() + \".*\");\n            Matcher matcher = pattern.matcher(subResPath);\n            if (matcher.matches()) {\n                for (int i = 1; i <= matcher.groupCount(); i++) {\n                    groupNameValues.putIfAbsent(groupNames.get(i - 1), matcher.group(i));\n                }\n            }\n            // Invoke the sub-resource method\n            HttpResourceModelProcessor httpSubResourceModelProcessor = new HttpResourceModelProcessor(resourceModel);\n            httpSubResourceModelProcessor.setFormParameters(formParameters);\n            responder.setMediaType(\n                    Util.getResponseType(request.getAcceptTypes(), resourceModel.getProducesMediaTypes()));\n            HttpMethodInfo httpMethodInfo = httpSubResourceModelProcessor\n                    .buildHttpMethodInfo(request, responder, groupNameValues);\n\n            PatternPathRouter.RoutableDestination<HttpResourceModel> newDestination =\n                    new PatternPathRouter.RoutableDestination<>(resourceModel, groupNameValues);\n            return invokeResource(newDestination, httpMethodInfo, request, microservicesRegistry, true);\n        }\n        return ImmutablePair.of(true, returnVal);\n    }\n\n    /**\n     * If chunk handling is supported provide chunks directly.\n     *\n     * @param chunk chunk content\n     * @throws Exception if error occurs while invoking streaming handlers\n     */\n    public void chunk(ByteBuffer chunk) throws Exception {\n        try {\n            httpStreamHandler.chunk(chunk);\n        } catch (Throwable e) {\n            log.error(\"Exception while invoking streaming handlers\", e);\n            httpStreamHandler.error(e);\n            throw e;\n        }\n    }\n\n    /**\n     * If chunk handling is supported end streaming chunks.\n     *\n     * @param isResponseInterceptorsSuccessful have the response interceptors successfully executed\n     * @throws Exception if error occurs while stopping streaming handlers\n     */\n    public void end(boolean isResponseInterceptorsSuccessful) throws Exception {\n        try {\n            httpStreamHandler.end();\n        } catch (Throwable e) {\n            log.error(\"Exception while invoking streaming handlers\", e);\n            log.error(\"Response interceptor execute is successful : \" + isResponseInterceptorsSuccessful, e);\n            httpStreamHandler.error(e);\n            throw e;\n        }\n    }\n\n    /**\n     * Return true if the handler method supports streaming.\n     *\n     * @return boolean true if streaming is supported\n     */\n    public boolean isStreamingSupported() {\n        return httpStreamHandler != null;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/HttpMethodInfoBuilder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.Map;\n\n/**\n * Builder for HttpMethodInfo that will hold HttpResourceModel and\n * request information in order to process the request when all\n * data is ready.\n */\npublic class HttpMethodInfoBuilder {\n\n    private HttpResourceModel httpResourceModel;\n    private Request request;\n    private Response responder;\n    private Map<String, String> groupValues;\n    private HttpMethodInfo httpMethodInfo;\n\n    /**\n     * Set the associated HttpResourceModel object.\n     *\n     * @param httpResourceModel resource model for the request\n     * @return HttpMethodInfoBuilder object\n     */\n    public HttpMethodInfoBuilder httpResourceModel(HttpResourceModel httpResourceModel) {\n        this.httpResourceModel = httpResourceModel;\n        return this;\n    }\n\n    /**\n     * Set the associated Request object.\n     *\n     * @param request Request object\n     * @return HttpMethodInfoBuilder object\n     */\n    public HttpMethodInfoBuilder httpRequest(Request request) {\n        this.request = request;\n        return this;\n    }\n\n    /**\n     * Set the associated Response object.\n     *\n     * @param responder Response object\n     * @return HttpMethodInfoBuilder object\n     */\n    public HttpMethodInfoBuilder httpResponder(Response responder) {\n        this.responder = responder;\n        return this;\n    }\n\n    /**\n     * Set information of the request that were processed\n     * when searching for the route.\n     *\n     * @param groupValues request info to be set\n     * @return HttpMethodInfoBuilder object\n     */\n    public HttpMethodInfoBuilder requestInfo(Map<String, String> groupValues) {\n        this.groupValues = groupValues;\n        return this;\n    }\n\n    /**\n     * Build HttpMethodInfo instance.\n     *\n     * @return HttpMethodInfo object\n     * @throws HandlerException if error occurs while executing the request\n     */\n    public HttpMethodInfo build() throws HandlerException {\n        if (httpMethodInfo == null) {\n            httpMethodInfo = (new HttpResourceModelProcessor(httpResourceModel))\n                    .buildHttpMethodInfo(request, responder, groupValues);\n        }\n        return httpMethodInfo;\n    }\n\n    public HttpResourceModel getHttpResourceModel() {\n        return httpResourceModel;\n    }\n\n    public Response getResponder() {\n        return responder;\n    }\n\n    public Request getRequest() {\n        return request;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/HttpResourceModel.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.formparam.FormDataParam;\nimport org.wso2.msf4j.util.Utils;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.function.Function;\nimport javax.annotation.Nullable;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.CookieParam;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.DefaultValue;\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HEAD;\nimport javax.ws.rs.HeaderParam;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.OPTIONS;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.QueryParam;\nimport javax.ws.rs.core.Context;\n\n/**\n * HttpResourceModel contains information needed to handle Http call for a given path. Used as a destination in\n * {@code PatternPathRouter} to route URI paths to right Http end points.\n */\npublic final class HttpResourceModel {\n\n    private static final Set<Class<? extends Annotation>> SUPPORTED_PARAM_ANNOTATIONS;\n\n    static {\n        Set<Class<? extends Annotation>> supportedAnnotation =\n                new HashSet<>();\n        supportedAnnotation.add(PathParam.class);\n        supportedAnnotation.add(QueryParam.class);\n        supportedAnnotation.add(HeaderParam.class);\n        supportedAnnotation.add(Context.class);\n        supportedAnnotation.add(FormParam.class);\n        supportedAnnotation.add(FormDataParam.class);\n        supportedAnnotation.add(CookieParam.class);\n\n        SUPPORTED_PARAM_ANNOTATIONS = Collections.unmodifiableSet(supportedAnnotation);\n    }\n\n    private static final String[] ANY_MEDIA_TYPE = new String[]{\"*/*\"};\n    private static final int STREAMING_REQ_UNKNOWN = 0, STREAMING_REQ_SUPPORTED = 1, STREAMING_REQ_UNSUPPORTED = 2;\n\n    private final Set<String> httpMethods;\n    private final String path;\n    private final Method method;\n    private final Object handler;\n    private final List<ParameterInfo<?>> paramInfoList;\n    private List<String> consumesMediaTypes;\n    private List<String> producesMediaTypes;\n    private int isStreamingReqSupported = STREAMING_REQ_UNKNOWN;\n    private Map<SubresourceKey, HttpResourceModel> subResources = new HashMap<>();\n    private boolean isSubResourceLocator;\n    private boolean isSubResourceScanned;\n    private HttpResourceModel parent;\n\n    /**\n     * If this is a subresource locator, get the parent of this Model.\n     * @return HttpResourceModel parent model.\n     */\n    public HttpResourceModel getParent() {\n        return parent;\n    }\n\n    /**\n     * If this is a subresource locator, set the parent Model.\n     * @param parent HttpResourceModel of this.\n     */\n    public void setParent(HttpResourceModel parent) {\n        this.parent = parent;\n        consumesMediaTypes = parseConsumesMediaTypes();\n        producesMediaTypes = parseProducesMediaTypes();\n    }\n\n    /**\n     * Get the sub resource locators of this model.\n     * @return Map of subresource locators of this.\n     */\n    public Map<SubresourceKey, HttpResourceModel> getSubResources() {\n        return subResources;\n    }\n\n    /**\n     * Set the sub resource locators of this model.\n     * @param subResources Map of sub resource locators.\n     */\n    public void setSubResources(Map<SubresourceKey, HttpResourceModel> subResources) {\n        this.subResources = subResources;\n    }\n\n    public void addSubResources(SubresourceKey subresourceKey, HttpResourceModel httpResourceModel) {\n        subResources.put(subresourceKey, httpResourceModel);\n    }\n\n    /**\n     * Set if this model is already scanned for sub resource locators.\n     * @param subResourceScanned boolean indicate whether this already scanned for sub resource locators.\n     */\n    public void setSubResourceScanned(boolean subResourceScanned) {\n        isSubResourceScanned = subResourceScanned;\n    }\n\n    /**\n     * Check if this model is already scanned for sub resource locators.\n     * @return boolean whether this model already scanned for sub resources.\n     */\n    public boolean isSubResourceScanned() {\n        return isSubResourceScanned;\n    }\n\n    /**\n     * Construct a resource model with HttpMethod, method that handles httprequest, Object that contains the method.\n     *\n     * @param path             path associated with this model.\n     * @param method           handler that handles the http request.\n     * @param handler          instance {@code HttpHandler}.\n     * @param isSubResourceLocator indicate if this is a subresource locator method\n     */\n    public HttpResourceModel(String path, Method method, Object handler, boolean isSubResourceLocator) {\n        this.httpMethods = getHttpMethods(method);\n        this.path = path;\n        this.method = method;\n        this.handler = handler;\n        this.isSubResourceLocator = isSubResourceLocator;\n        this.paramInfoList = makeParamInfoList(method);\n        consumesMediaTypes = parseConsumesMediaTypes();\n        producesMediaTypes = parseProducesMediaTypes();\n    }\n\n    private List<String> parseConsumesMediaTypes() {\n        String[] consumesMediaTypeArr =\n                method.isAnnotationPresent(Consumes.class) ? method.getAnnotation(Consumes.class).value() :\n                handler.getClass().isAnnotationPresent(Consumes.class) ?\n                handler.getClass().getAnnotation(Consumes.class).value() :\n                parent == null ? ANY_MEDIA_TYPE : new String[] {};\n        if (parent != null && consumesMediaTypeArr.length == 0) {\n            HttpResourceModel tmpParent = parent;\n            while (tmpParent.getConsumesMediaTypes().size() != 0 && tmpParent.getParent() != null) {\n                tmpParent = parent.getParent();\n            }\n            consumesMediaTypeArr = tmpParent.getMethod().isAnnotationPresent(Consumes.class) ?\n                                   tmpParent.getMethod().getAnnotation(Consumes.class).value() :\n                                   handler.getClass().isAnnotationPresent(Consumes.class) ?\n                                   handler.getClass().getAnnotation(Consumes.class).value() : ANY_MEDIA_TYPE;\n        }\n        return Arrays.asList(consumesMediaTypeArr);\n    }\n\n    private List<String> parseProducesMediaTypes() {\n        String[] producesMediaTypeArr =\n                method.isAnnotationPresent(Produces.class) ? method.getAnnotation(Produces.class).value() :\n                handler.getClass().isAnnotationPresent(Produces.class) ?\n                handler.getClass().getAnnotation(Produces.class).value() :\n                parent == null ? ANY_MEDIA_TYPE : new String[] {};\n        if (parent != null && producesMediaTypeArr.length == 0) {\n            HttpResourceModel tmpParent = parent;\n            while (tmpParent.getProducesMediaTypes().size() != 0 && tmpParent.getParent() != null) {\n                tmpParent = parent.getParent();\n            }\n            producesMediaTypeArr = tmpParent.getMethod().isAnnotationPresent(Produces.class) ?\n                                   tmpParent.getMethod().getAnnotation(Produces.class).value() :\n                                   handler.getClass().isAnnotationPresent(Produces.class) ?\n                                   handler.getClass().getAnnotation(Produces.class).value() : ANY_MEDIA_TYPE;\n        }\n        return Arrays.asList(producesMediaTypeArr);\n    }\n\n    public boolean matchConsumeMediaType(String consumesMediaType) {\n        return consumesMediaType == null\n                || consumesMediaType.isEmpty()\n                || consumesMediaType.equals(\"*/*\")\n                || this.consumesMediaTypes.contains(\"*/*\")\n                || this.consumesMediaTypes.contains(consumesMediaType);\n    }\n\n    public boolean matchProduceMediaType(List<String> producesMediaTypes) {\n        return producesMediaTypes == null\n                || producesMediaTypes.contains(\"*/*\")\n                || this.producesMediaTypes.contains(\"*/*\")\n                || this.producesMediaTypes\n                .stream().filter\n                        (producesMediaTypes::contains).findAny().isPresent();\n    }\n\n    /**\n     * @return httpMethods.\n     */\n    public Set<String> getHttpMethod() {\n        return httpMethods;\n    }\n\n    /**\n     * @return path associated with this model.\n     */\n    public String getPath() {\n        return path;\n    }\n\n    /**\n     * @return handler method that handles an http end-point.\n     */\n    public Method getMethod() {\n        return method;\n    }\n\n    /**\n     * @return instance of {@code HttpHandler}.\n     */\n    public Object getHttpHandler() {\n        return handler;\n    }\n\n    /**\n     * Indicate this method as subresource locator method.\n     * @param subResourceLocator boolean value to set method\n     */\n    public void setSubResourceLocator(boolean subResourceLocator) {\n        isSubResourceLocator = subResourceLocator;\n    }\n\n    /**\n     * Return true if this method is a subresource locator method.\n     *\n     * @return boolean true if this method is a subresource locator method.\n     */\n    public boolean isSubResourceLocator() {\n        return isSubResourceLocator;\n    }\n\n    @Override\n    public String toString() {\n        return Utils.toString(this, new String[] { \"httpMethods\", \"path\", \"method\", \"handler\" });\n    }\n\n    /**\n     * Fetches the HttpMethod from annotations and returns String representation of HttpMethod.\n     * Return emptyString if not present.\n     *\n     * @param method Method handling the http request.\n     * @return String representation of HttpMethod from annotations or emptyString as a default.\n     */\n    private Set<String> getHttpMethods(Method method) {\n        Set<String> httpMethods = new HashSet();\n        boolean isSubResourceLocator = true;\n        if (method.isAnnotationPresent(GET.class)) {\n            httpMethods.add(HttpMethod.GET);\n            isSubResourceLocator = false;\n        }\n        if (method.isAnnotationPresent(PUT.class)) {\n            httpMethods.add(HttpMethod.PUT);\n            isSubResourceLocator = false;\n        }\n        if (method.isAnnotationPresent(POST.class)) {\n            httpMethods.add(HttpMethod.POST);\n            isSubResourceLocator = false;\n        }\n        if (method.isAnnotationPresent(DELETE.class)) {\n            httpMethods.add(HttpMethod.DELETE);\n            isSubResourceLocator = false;\n        }\n        if (method.isAnnotationPresent(HEAD.class)) {\n            httpMethods.add(HttpMethod.HEAD);\n            isSubResourceLocator = false;\n        }\n        if (method.isAnnotationPresent(OPTIONS.class)) {\n            httpMethods.add(HttpMethod.OPTIONS);\n            isSubResourceLocator = false;\n        }\n        // If this is a sub resource locator need to add all the method designator\n        if (isSubResourceLocator) {\n            httpMethods.add(HttpMethod.GET);\n            httpMethods.add(HttpMethod.POST);\n            httpMethods.add(HttpMethod.PUT);\n            httpMethods.add(HttpMethod.DELETE);\n            httpMethods.add(HttpMethod.HEAD);\n            httpMethods.add(HttpMethod.OPTIONS);\n        }\n        return Collections.unmodifiableSet(httpMethods);\n    }\n\n    /**\n     * Gathers all parameters' annotations for the given method, starting from the third parameter.\n     */\n    private List<ParameterInfo<?>> makeParamInfoList(Method method) {\n        List<ParameterInfo<?>> paramInfoList = new ArrayList<>();\n\n        Type[] paramTypes = method.getGenericParameterTypes();\n        Annotation[][] paramAnnotations = method.getParameterAnnotations();\n\n        for (int i = 0; i < paramAnnotations.length; i++) {\n            Annotation[] annotations = paramAnnotations[i];\n\n            //Can have only one from @PathParam, @QueryParam, @HeaderParam or @Context.\n            if (Utils.getIntersection(SUPPORTED_PARAM_ANNOTATIONS,\n                                      Collections.unmodifiableSet(new HashSet(Arrays.asList(annotations)))) > 1) {\n                throw new IllegalArgumentException(\n                        String.format(\"Must have exactly one annotation from %s for parameter %d in method %s\",\n                                SUPPORTED_PARAM_ANNOTATIONS, i, method));\n            }\n\n            Annotation annotation = null;\n            Type parameterType = paramTypes[i];\n            Function<?, Object> converter = null;\n            String defaultVal = null;\n            for (Annotation annotation0 : annotations) {\n                annotation = annotation0;\n                Class<? extends Annotation> annotationType = annotation.annotationType();\n                if (PathParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createPathParamConverter(parameterType);\n                } else if (QueryParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createQueryParamConverter(parameterType);\n                } else if (FormParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createFormParamConverter(parameterType);\n                } else if (FormDataParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createFormDataParamConverter(parameterType);\n                } else if (HeaderParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createHeaderParamConverter(parameterType);\n                } else if (CookieParam.class.isAssignableFrom(annotationType)) {\n                    converter = ParamConvertUtils.createCookieParamConverter(parameterType);\n                } else if (DefaultValue.class.isAssignableFrom(annotationType)) {\n                    defaultVal = ((DefaultValue) annotation).value();\n                }\n            }\n            ParameterInfo<?> parameterInfo = ParameterInfo.create(parameterType, annotation, defaultVal, converter);\n            paramInfoList.add(parameterInfo);\n        }\n\n        return Collections.unmodifiableList(paramInfoList);\n    }\n\n    public boolean isStreamingReqSupported() {\n        if (isStreamingReqSupported == STREAMING_REQ_SUPPORTED) {\n            return true;\n        } else if (isStreamingReqSupported == STREAMING_REQ_UNSUPPORTED) {\n            return false;\n        } else if (paramInfoList.stream().filter(parameterInfo -> parameterInfo\n                .getParameterType().equals(HttpStreamer.class))\n                .findAny().isPresent()) {\n            isStreamingReqSupported = STREAMING_REQ_SUPPORTED;\n            return true;\n        } else {\n            isStreamingReqSupported = STREAMING_REQ_UNSUPPORTED;\n            return false;\n        }\n    }\n\n    public List<ParameterInfo<?>> getParamInfoList() {\n        return paramInfoList;\n    }\n\n    public List<String> getConsumesMediaTypes() {\n        return consumesMediaTypes;\n    }\n\n    public List<String> getProducesMediaTypes() {\n        return producesMediaTypes;\n    }\n\n    /**\n     * A container class to hold information about a handler method parameters.\n     * @param <T> type of parameter\n     */\n    public static final class ParameterInfo<T> {\n        private final Annotation annotation;\n        private final Function<T, Object> converter;\n        private final Type parameterType;\n        private final String defaultVal;\n\n        private ParameterInfo(Type parameterType, Annotation annotation, String defaultVal, @Nullable Function<T,\n                Object>\n                converter) {\n            this.parameterType = parameterType;\n            this.annotation = annotation;\n            this.defaultVal = defaultVal;\n            this.converter = converter;\n        }\n\n        static <V> ParameterInfo<V> create(Type parameterType, Annotation annotation, String defaultVal,\n                                           @Nullable Function<V, Object> converter) {\n            return new ParameterInfo<>(parameterType, annotation, defaultVal, converter);\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        <V extends Annotation> V getAnnotation() {\n            return (V) annotation;\n        }\n\n        public Type getParameterType() {\n            return parameterType;\n        }\n\n        public String getDefaultVal() {\n            return defaultVal;\n        }\n\n        Object convert(T input) {\n            return (converter == null) ? null : converter.apply(input);\n        }\n\n        public Function<T, Object> getConverter() {\n            return converter;\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/HttpResourceModelProcessor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.apache.commons.io.FileCleaningTracker;\nimport org.apache.commons.io.FileDeleteStrategy;\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.beanconversion.MediaTypeConverter;\nimport org.wso2.msf4j.formparam.FileInfo;\nimport org.wso2.msf4j.formparam.FormDataParam;\nimport org.wso2.msf4j.formparam.FormItem;\nimport org.wso2.msf4j.formparam.FormParamIterator;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\nimport org.wso2.msf4j.internal.beanconversion.BeanConverter;\nimport org.wso2.msf4j.util.QueryStringDecoderUtil;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.ws.rs.CookieParam;\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.HeaderParam;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.QueryParam;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.MultivaluedHashMap;\nimport javax.ws.rs.core.MultivaluedMap;\n\n/**\n * This class is responsible for processing the HttpResourceModel\n * when a HTTP request arrives.\n */\npublic class HttpResourceModelProcessor {\n\n    private final HttpResourceModel httpResourceModel;\n    private HttpStreamer httpStreamer;\n    private MultivaluedMap<String, Object> formParameters = null;\n    private Map<String, String> formParamContentType = new HashMap<>();\n    private static Path tempRepoPath = Paths.get(System.getProperty(\"java.io.tmpdir\"), \"msf4jtemp\");\n    private Path tmpPathForRequest;\n    // Temp File cleaning thread\n    private static FileCleaningTracker fileCleaningTracker = new FileCleaningTracker();\n    private static final String FILEINFO_POSTFIX = \"file.info\";\n\n    public HttpResourceModelProcessor(HttpResourceModel httpResourceModel) {\n        this.httpResourceModel = httpResourceModel;\n    }\n\n    /**\n     * Build an HttpMethodInfo object to dispatch the request.\n     *\n     * @param request     HttpRequest to be handled.\n     * @param responder   HttpResponder to write the response.\n     * @param groupValues Values needed for the invocation.\n     * @return HttpMethodInfo\n     * @throws HandlerException If an error occurs\n     */\n    @SuppressWarnings(\"unchecked\")\n    public HttpMethodInfo buildHttpMethodInfo(Request request,\n                                              Response responder,\n                                              Map<String, String> groupValues)\n            throws HandlerException {\n        try {\n            //Setup args for reflection call\n            List<HttpResourceModel.ParameterInfo<?>> paramInfoList = httpResourceModel.getParamInfoList();\n            Object[] args = new Object[paramInfoList.size()];\n            int idx = 0;\n            for (HttpResourceModel.ParameterInfo<?> paramInfo : paramInfoList) {\n                if (paramInfo.getAnnotation() != null) {\n                    Class<? extends Annotation> annotationType = paramInfo.getAnnotation().annotationType();\n                    if (PathParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getPathParamValue((HttpResourceModel.ParameterInfo<String>) paramInfo,\n                                groupValues);\n                    } else if (QueryParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getQueryParamValue((HttpResourceModel.ParameterInfo<List<String>>) paramInfo,\n                                request.getUri());\n                    } else if (HeaderParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getHeaderParamValue((HttpResourceModel.ParameterInfo<List<String>>) paramInfo,\n                                request);\n                    } else if (CookieParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getCookieParamValue((HttpResourceModel.ParameterInfo<String>) paramInfo,\n                                request);\n                    } else if (Context.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getContextParamValue((HttpResourceModel.ParameterInfo<Object>) paramInfo,\n                                request, responder);\n                    } else if (FormParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getFormParamValue((HttpResourceModel.ParameterInfo<List<Object>>) paramInfo,\n                                request);\n                    } else if (FormDataParam.class.isAssignableFrom(annotationType)) {\n                        args[idx] = getFormDataParamValue((HttpResourceModel.ParameterInfo<List<Object>>) paramInfo,\n                                request);\n                    } else {\n                        createObject(request, args, idx, paramInfo);\n                    }\n                } else {\n                    // If an annotation is not present the parameter is considered a\n                    // request body data parameter\n                    createObject(request, args, idx, paramInfo);\n                }\n                idx++;\n            }\n\n            if (httpStreamer == null) {\n                return new HttpMethodInfo(httpResourceModel.getMethod(),\n                        httpResourceModel.getHttpHandler(),\n                        args, formParameters,\n                        responder);\n            } else {\n                return new HttpMethodInfo(httpResourceModel.getMethod(),\n                        httpResourceModel.getHttpHandler(),\n                        args, formParameters,\n                        responder,\n                        httpStreamer);\n            }\n        } catch (Throwable e) {\n            throw new HandlerException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR,\n                    String.format(\"Error in executing request: %s %s\", request.getHttpMethod(),\n                            request.getUri()), e);\n        }\n    }\n\n    private void createObject(Request request, Object[] args, int idx, HttpResourceModel.ParameterInfo<?> paramInfo)\n            throws IOException {\n        try (InputStream inputStream = request.getMessageContentStream()) {\n            Type paramType = paramInfo.getParameterType();\n            args[idx] =\n                    BeanConverter.getConverter((request.getContentType() != null) ? request.getContentType() :\n                            MediaType.WILDCARD).convertToObject(inputStream, paramType);\n        }\n    }\n\n    private Object getFormDataParamValue(HttpResourceModel.ParameterInfo<List<Object>> paramInfo, Request request)\n            throws FormUploadException, IOException {\n        Type paramType = paramInfo.getParameterType();\n        FormDataParam formDataParam = paramInfo.getAnnotation();\n        if (getFormParameters() == null) {\n            setFormParameters(extractRequestFormParams(request, paramInfo, true));\n        }\n\n        List<Object> parameter = getParameter(formDataParam.value());\n        boolean isNotNull = (parameter != null);\n        if (paramInfo.getConverter() != null) {\n            // We need to skip the conversion for java.io.File types and handle special cases\n            if (paramType instanceof ParameterizedType && isNotNull &&\n                    parameter.get(0).getClass().isAssignableFrom(File.class)) {\n                return parameter;\n            } else if (isNotNull && parameter.get(0).getClass().isAssignableFrom(File.class)) {\n                return parameter.get(0);\n            } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(formParamContentType.get(formDataParam.value()))) {\n                return paramInfo.convert(parameter);\n            } else if (MediaType.APPLICATION_FORM_URLENCODED.equals(request.getContentType())) {\n                return paramInfo.convert(parameter);\n            }\n            // Beans with string constructor\n            return createBean(parameter, formDataParam, paramType, isNotNull);\n        }\n        // We only support InputStream for a single file. Therefore only get first element from the list\n        if (paramType == InputStream.class && isNotNull && parameter.get(0).getClass().isAssignableFrom(File.class)) {\n            return new FileInputStream((File) parameter.get(0));\n        } else if (paramType == FileInfo.class) {\n            List<Object> fileInfo = getParameter(formDataParam.value() + FILEINFO_POSTFIX);\n            return fileInfo == null ? null : fileInfo.get(0);\n        }\n        // These are beans without having string constructor. Convert using existing BeanConverter\n        return createBean(parameter, formDataParam, paramType, isNotNull);\n    }\n\n    /**\n     * Extract the form items in the request.\n     *\n     * @param request     Request which need to be processed\n     * @param paramInfo   of the method\n     * @param addFileInfo if FileInfo object needed to be added to params. In a case of InputStream this should be true\n     * @return MultivaluedMap of form items\n     * @throws IOException if error occurs while processing the multipart/form-data request\n     */\n    private MultivaluedMap<String, Object> extractRequestFormParams(Request request,\n                                                                    HttpResourceModel.ParameterInfo paramInfo,\n                                                                    boolean addFileInfo) throws IOException {\n        MultivaluedMap<String, Object> parameters = new MultivaluedHashMap<>();\n        if (MediaType.MULTIPART_FORM_DATA.equals(request.getContentType())) {\n            FormParamIterator formParamIterator = new FormParamIterator(request);\n            while (formParamIterator.hasNext()) {\n                FormItem item = formParamIterator.next();\n\n                String cType = item.getContentType();\n                if (cType != null && cType.contains(\";\")) {\n                    cType = cType.split(\";\")[0];\n                }\n                if (cType == null) {\n                    cType = MediaType.TEXT_PLAIN;\n                }\n                boolean isFile = item.getHeaders().getHeader(\"content-disposition\").contains(\"filename\") ||\n                        MediaType.APPLICATION_OCTET_STREAM.equals(item.getHeaders().getHeader(\"content-type\"));\n                formParamContentType.putIfAbsent(item.getFieldName(), cType);\n\n                List<Object> existingValues = parameters.get(item.getFieldName());\n                if (existingValues == null) {\n                    parameters.put(item.getFieldName(),\n                            isFile ? new ArrayList<>(Collections.singletonList(createAndTrackTempFile(item))) :\n                                    new ArrayList<>(Collections.singletonList(StreamUtil.asString(item.openStream()))));\n                } else {\n                    existingValues.add(isFile ? createAndTrackTempFile(item) : StreamUtil.asString(item.openStream()));\n                }\n\n                if (addFileInfo && isFile) {\n                    //Create FileInfo bean to handle InputStream\n                    FileInfo fileInfo = new FileInfo();\n                    fileInfo.setFileName(item.getName());\n                    fileInfo.setContentType(item.getContentType());\n                    parameters.putSingle(item.getFieldName() + FILEINFO_POSTFIX, fileInfo);\n                }\n            }\n        } else if (MediaType.APPLICATION_FORM_URLENCODED.equals(request.getContentType())) {\n            try (InputStream inputStream = request.getMessageContentStream()) {\n                String bodyStr = BeanConverter\n                        .getConverter((request.getContentType() != null) ? request.getContentType() : MediaType\n                                .WILDCARD).convertToObject(inputStream, paramInfo.getParameterType()).toString();\n                QueryStringDecoderUtil queryStringDecoderUtil = new QueryStringDecoderUtil(bodyStr, false);\n                queryStringDecoderUtil.parameters().entrySet().\n                        forEach(entry -> parameters.put(entry.getKey(), new ArrayList<>(entry.getValue())));\n            }\n        }\n        return parameters;\n    }\n\n    private Object createBean(List<Object> parameter, FormDataParam formDataParam, Type paramType, boolean isNotNull) {\n        if (isNotNull) {\n            MediaTypeConverter converter = BeanConverter.getConverter(formParamContentType.get(formDataParam.value()));\n            ByteBuffer value = ByteBuffer.wrap(parameter.get(0).toString().getBytes(Charset.defaultCharset()));\n            return converter.convertToObject(value, paramType);\n        }\n        return null;\n    }\n\n    private File createAndTrackTempFile(FormItem item) throws IOException {\n        if (tmpPathForRequest == null) {\n            if (Files.notExists(tempRepoPath)) {\n                Files.createDirectory(tempRepoPath);\n            }\n            tmpPathForRequest = Files.createTempDirectory(tempRepoPath, \"tmp\");\n        }\n        Path path = Paths.get(tmpPathForRequest.toString(), item.getName());\n        File file = path.toFile();\n        StreamUtil.copy(item.openStream(), new FileOutputStream(file), true);\n        fileCleaningTracker.track(file, file);\n        fileCleaningTracker.track(tmpPathForRequest.toFile(), file, FileDeleteStrategy.FORCE);\n        return file;\n    }\n\n    private Object getFormParamValue(HttpResourceModel.ParameterInfo<List<Object>> paramInfo, Request request)\n            throws FormUploadException, IOException {\n        FormParam formParam = paramInfo.getAnnotation();\n        if (getFormParameters() == null) {\n            MultivaluedMap<String, Object> parameters = new MultivaluedHashMap<>();\n            if (MediaType.MULTIPART_FORM_DATA.equals(request.getContentType())) {\n                FormParamIterator formParamIterator = new FormParamIterator(request);\n                while (formParamIterator.hasNext()) {\n                    FormItem item = formParamIterator.next();\n                    List<Object> existingValues = parameters.get(item.getFieldName());\n                    if (existingValues == null) {\n                        parameters.put(item.getFieldName(), new ArrayList<>(\n                                Collections.singletonList(StreamUtil.asString(item.openStream()))));\n                    } else {\n                        existingValues.add(StreamUtil.asString(item.openStream()));\n                    }\n                }\n            } else if (MediaType.APPLICATION_FORM_URLENCODED.equals(request.getContentType())) {\n                try (InputStream inputStream = request.getMessageContentStream()) {\n                    String bodyStr = BeanConverter.getConverter(\n                            (request.getContentType() != null) ? request.getContentType() : MediaType.WILDCARD)\n                            .convertToObject(inputStream, paramInfo.getParameterType()).toString();\n                    QueryStringDecoderUtil queryStringDecoderUtil = new QueryStringDecoderUtil(bodyStr, false);\n                    queryStringDecoderUtil.parameters().entrySet().\n                            forEach(entry -> parameters.put(entry.getKey(), new ArrayList<>(entry.getValue())));\n                }\n            }\n            setFormParameters(parameters);\n        }\n\n        List<Object> paramValue = getParameter(formParam.value());\n        if (paramValue == null) {\n            String defaultVal = paramInfo.getDefaultVal();\n            if (defaultVal != null) {\n                paramValue = Collections.singletonList(defaultVal);\n            }\n        }\n        return paramInfo.convert(paramValue);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object getContextParamValue(HttpResourceModel.ParameterInfo<Object> paramInfo, Request request,\n                                        Response responder) throws FormUploadException, IOException {\n        Type paramType = paramInfo.getParameterType();\n        Object value = null;\n        if (((Class) paramType).isAssignableFrom(Request.class)) {\n            value = request;\n        } else if (((Class) paramType).isAssignableFrom(Response.class)) {\n            value = responder;\n        } else if (((Class) paramType).isAssignableFrom(HttpStreamer.class)) {\n            if (httpStreamer == null) {\n                httpStreamer = new HttpStreamer();\n            }\n            value = httpStreamer;\n        } else if (((Class) paramType).isAssignableFrom(FormParamIterator.class)) {\n            value = new FormParamIterator(request);\n        } else if (((Class) paramType).isAssignableFrom(MultivaluedMap.class)) {\n            MultivaluedMap<String, Object> listMultivaluedMap = new MultivaluedHashMap<>();\n            if (MediaType.MULTIPART_FORM_DATA.equals(request.getContentType())) {\n                listMultivaluedMap = extractRequestFormParams(request, paramInfo, false);\n            } else if (MediaType.APPLICATION_FORM_URLENCODED.equals(request.getContentType())) {\n                try (InputStream inputStream = request.getMessageContentStream()) {\n                    String bodyStr = BeanConverter.getConverter(\n                            (request.getContentType() != null) ? request.getContentType() : MediaType.WILDCARD)\n                            .convertToObject(inputStream, paramInfo.getParameterType()).toString();\n                    QueryStringDecoderUtil queryStringDecoderUtil = new QueryStringDecoderUtil(bodyStr, false);\n                    MultivaluedMap<String, Object> finalListMultivaluedMap = listMultivaluedMap;\n                    queryStringDecoderUtil.parameters().entrySet().forEach(entry -> finalListMultivaluedMap.put(entry\n                            .getKey(), new ArrayList(entry.getValue())));\n                }\n            }\n            value = listMultivaluedMap;\n        }\n        Objects.requireNonNull(value, String.format(\"Could not resolve parameter %s\", paramType.getTypeName()));\n        return value;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object getPathParamValue(HttpResourceModel.ParameterInfo<String> info, Map<String, String> groupValues) {\n        PathParam pathParam = info.getAnnotation();\n        String value = groupValues.get(pathParam.value());\n        if (value == null) {\n            String defaultVal = info.getDefaultVal();\n            if (defaultVal != null) {\n                value = defaultVal;\n            }\n        }\n        Objects.requireNonNull(value, String.format(\"Could not resolve value for parameter %s\", pathParam.value()));\n        return info.convert(value);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object getQueryParamValue(HttpResourceModel.ParameterInfo<List<String>> info, String uri) {\n        QueryParam queryParam = info.getAnnotation();\n        List<String> values = new QueryStringDecoderUtil(uri).parameters().get(queryParam.value());\n        if (values == null || values.isEmpty()) {\n            String defaultVal = info.getDefaultVal();\n            if (defaultVal != null) {\n                values = Collections.singletonList(defaultVal);\n            }\n        }\n        return info.convert(values);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object getHeaderParamValue(HttpResourceModel.ParameterInfo<List<String>> info, Request request) {\n        HeaderParam headerParam = info.getAnnotation();\n        String headerName = headerParam.value();\n        String header = request.getHeader(headerName);\n        if (header == null || header.isEmpty()) {\n            String defaultVal = info.getDefaultVal();\n            if (defaultVal != null) {\n                header = defaultVal;\n            }\n        }\n        return info.convert(Collections.singletonList(header));\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object getCookieParamValue(HttpResourceModel.ParameterInfo<String> info, Request request) {\n        CookieParam cookieParam = info.getAnnotation();\n        String cookieName = cookieParam.value();\n        String cookieHeader = request.getHeader(\"Cookie\");\n        if (cookieHeader != null) {\n            String cookieValue = Arrays.stream(cookieHeader.split(\";\"))\n                    .filter(cookie -> cookie.startsWith(cookieName + \"=\"))\n                    .findFirst()\n                    .map(cookie -> cookie.substring((cookieName + \"=\").length()))\n                    .orElseGet(info::getDefaultVal);\n            return info.convert(cookieValue);\n        }\n        return null;\n    }\n\n    /**\n     * @param key parameter name.\n     * @return parameter value of the given key.\n     */\n    private List<Object> getParameter(String key) {\n        return formParameters.get(key);\n    }\n\n    /**\n     * @return Map of request formParameters\n     */\n    public Map<String, List<Object>> getFormParameters() {\n        return formParameters;\n    }\n\n    /**\n     * Set the request formParameters.\n     *\n     * @param parameters request formParameters\n     */\n    public void setFormParameters(MultivaluedMap<String, Object> parameters) {\n        this.formParameters = parameters;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/ImmutablePair.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.wso2.msf4j.util.Utils;\n\nimport java.util.Arrays;\nimport java.util.Objects;\n\n/**\n * An {@link ImmutablePair} consists of two elements within. The elements once set\n * in the ImmutablePair cannot be modified. The class itself is final, so that it\n * cannot be subclassed. This is general norm for creating Immutable classes.\n * Please note that the {@link ImmutablePair} cannot be modified once set, but the\n * objects within them can be, so in general it means that if there are mutable objects\n * within the pair then the pair itself is effectively mutable.\n *\n * <pre>\n *   ImmutablePair<Tuple, TupleInputStreamIdentifier> tupleStreamPair= new\n *    ImmutablePair<Tuple, TupleInputStreamIdentifier> (tuple, identifier);\n *   ...\n *   ...\n *   Tuple t = tupleStreamPair.getFirst();\n *   TupleInputStreamIdentifier identifier = tupleStreamPair.getSecond();\n *   ...\n * </pre>\n *\n * @param <A> type A\n * @param <B> type B\n */\nfinal class ImmutablePair<A, B> {\n    private final A first;\n    private final B second;\n\n    /**\n     * Constructs a Immutable Pair.\n     *\n     * @param first  object in pair\n     * @param second object in pair\n     */\n    private ImmutablePair(A first, B second) {\n        this.first = first;\n        this.second = second;\n    }\n\n    public static <A, B> ImmutablePair<A, B> of(A first, B second) {\n        return new ImmutablePair<>(first, second);\n    }\n\n    /**\n     * Returns first object from pair.\n     *\n     * @return first object from pair.\n     */\n    public A getFirst() {\n        return first;\n    }\n\n    /**\n     * Return second object from pair.\n     *\n     * @return second object from pair.\n     */\n    public B getSecond() {\n        return second;\n    }\n\n    /**\n     * Returns a string representation of {@link ImmutablePair} object.\n     *\n     * @return string representation of this object.\n     */\n    @Override\n    public String toString() {\n        return Utils.toString(this, new String[] { \"first\", \"second\" });\n    }\n\n    /**\n     * Returns a hash code value for this object.\n     *\n     * @return hash code value of this object.\n     */\n    @Override\n    public int hashCode() {\n        return Arrays.hashCode(new ImmutablePair[]{ (ImmutablePair) first, (ImmutablePair) second });\n    }\n\n    /**\n     * Returns whether some other object \"is equal\" to this object.\n     *\n     * @param o reference object with which to compare\n     * @return true if object is the same as the obj argument; false otherwise.\n     */\n    @Override\n    public boolean equals(Object o) {\n        if (o == null) {\n            return false;\n        }\n        if (!(o instanceof ImmutablePair)) {\n            return false;\n        }\n        ImmutablePair<?, ?> other = (ImmutablePair<?, ?>) o;\n        return Objects.equals(first, other.first) && Objects.equals(second, other.second);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/MicroserviceMetadata.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.util.Utils;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport javax.annotation.PostConstruct;\nimport javax.annotation.PreDestroy;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HEAD;\nimport javax.ws.rs.OPTIONS;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Response;\n\n/**\n * MicroserviceMetadata handles the http request. HttpResourceHandler looks up all Jax-rs annotations in classes\n * and dispatches to appropriate method on receiving requests.\n */\npublic final class MicroserviceMetadata {\n\n    private static final Logger log = LoggerFactory.getLogger(MicroserviceMetadata.class);\n\n    private final PatternPathRouter<HttpResourceModel> patternRouter = PatternPathRouter.create();\n\n    /**\n     * Construct HttpResourceHandler. Reads all annotations from all the handler classes and methods passed in,\n     * constructs patternPathRouter which is routable by path to {@code HttpResourceModel} as destination of the route.\n     *\n     * @param services Map of base paths and services.\n     */\n    public MicroserviceMetadata(Map<String, Object> services) {\n        //Store the services to call init and destroy on all services.\n        services.forEach((basePath, service) -> {\n            for (Method method : service.getClass().getMethods()) {\n                if (method.isAnnotationPresent(PostConstruct.class) || method.isAnnotationPresent(PreDestroy.class)) {\n                    continue;\n                }\n\n                if (Modifier.isPublic(method.getModifiers()) && isHttpMethodAvailable(method)) {\n                    String relativePath = \"\";\n                    if (method.getAnnotation(Path.class) != null) {\n                        relativePath = method.getAnnotation(Path.class).value();\n                    }\n                    String absolutePath = String.format(\"%s/%s\", basePath, relativePath);\n                    patternRouter.add(absolutePath, new HttpResourceModel(absolutePath, method, service, false));\n                } else if (Modifier.isPublic(method.getModifiers()) && method.getAnnotation(Path.class) != null) {\n                    // Sub resource locator method\n                    String relativePath = method.getAnnotation(Path.class).value();\n                    if (relativePath.startsWith(\"/\")) {\n                        relativePath = relativePath.substring(1);\n                    }\n                    String absolutePath = String.format(\"%s/%s\", basePath, relativePath);\n                    patternRouter.add(absolutePath, new HttpResourceModel(absolutePath, method, service, true));\n                } else {\n                    log.trace(\"Not adding method {}({}) to path routing like. \" +\n                                    \"HTTP calls will not be routed to this method\",\n                            method.getName(), method.getParameterTypes());\n                }\n            }\n        });\n    }\n\n    /**\n     * Register given service object with the given base path. Path annotion of the service class will be ignore,\n     * instead use the provided base path.\n     *\n     * @param service HttpHandler object\n     * @param basePath Path the handler should be registered\n     */\n    public void addMicroserviceMetadata(final Object service, String basePath) {\n        //Store the services to call init and destroy on all services.\n        for (Method method : service.getClass().getMethods()) {\n            if (method.isAnnotationPresent(PostConstruct.class) || method.isAnnotationPresent(PreDestroy.class)) {\n                continue;\n            }\n\n            if (Modifier.isPublic(method.getModifiers()) && isHttpMethodAvailable(method)) {\n                String relativePath = \"\";\n                if (method.getAnnotation(Path.class) != null) {\n                    relativePath = method.getAnnotation(Path.class).value();\n                }\n                String absolutePath = String.format(\"%s/%s\", basePath, relativePath);\n                patternRouter.add(absolutePath, new HttpResourceModel(absolutePath, method, service, false));\n            } else {\n                log.trace(\"Not adding method {}({}) to path routing like. \" +\n                          \"HTTP calls will not be routed to this method\", method.getName(), method.getParameterTypes());\n            }\n        }\n\n    }\n\n    private boolean isHttpMethodAvailable(Method method) {\n        return method.isAnnotationPresent(GET.class) ||\n                method.isAnnotationPresent(PUT.class) ||\n                method.isAnnotationPresent(POST.class) ||\n                method.isAnnotationPresent(DELETE.class) ||\n                method.isAnnotationPresent(HEAD.class) ||\n                method.isAnnotationPresent(OPTIONS.class);\n    }\n\n    /**\n     * Get destination resource method to match the arrived request.\n     * 404 if path is not found. 405 if httpMethod does not match what's configured.\n     * 415 if mediatype does not match.\n     *\n     * @param uri               request uri\n     * @param httpMethod        http method of the request\n     * @param contentTypeHeader content type of the request\n     * @param acceptHeader      accept type of the request\n     * @return matching resource method\n     * @throws HandlerException if the method not found or content type mismatch\n     */\n    public PatternPathRouter\n            .RoutableDestination<HttpResourceModel> getDestinationMethod(String uri,\n                                                                         String httpMethod,\n                                                                         String contentTypeHeader,\n                                                                         List<String> acceptHeader)\n            throws HandlerException {\n        try {\n            String path = URI.create(uri).normalize().getPath();\n\n            List<PatternPathRouter.RoutableDestination<HttpResourceModel>>\n                    routableDestinations = patternRouter.getDestinations(path);\n\n            List<PatternPathRouter.RoutableDestination<HttpResourceModel>>\n                    matchedDestinations = getMatchedDestination(routableDestinations, httpMethod, path);\n\n            if (!matchedDestinations.isEmpty()) {\n                if (matchedDestinations.size() == 1) {\n                    return matchedDestinations.stream().filter(matchedDestination1 ->\n                                                                       matchedDestination1.getDestination()\n                                                                                          .matchConsumeMediaType(\n                                                                                                  contentTypeHeader) &&\n                                                                       matchedDestination1.getDestination()\n                                                                                          .matchProduceMediaType(\n                                                                                                  acceptHeader))\n                                              .findFirst().get();\n                } else {\n                    return matchedDestinations.stream().filter(matchedDestination1 ->\n                                                                       matchedDestination1.getDestination()\n                                                                                          .matchConsumeMediaType(\n                                                                                                  contentTypeHeader) &&\n                                                                       matchedDestination1.getDestination()\n                                                                                          .matchProduceMediaType(\n                                                                                                  acceptHeader))\n                                              .filter(destination -> destination.getDestination().getHttpHandler()\n                                                                                .getClass() ==\n                                                                     destination.getDestination().getMethod()\n                                                                                .getDeclaringClass()).findFirst().get();\n                }\n            } else if (!routableDestinations.isEmpty()) {\n                //Found a matching resource but could not find the right HttpMethod so return 405\n                throw new HandlerException(Response.Status.METHOD_NOT_ALLOWED, uri);\n            } else {\n                throw new HandlerException(Response.Status.NOT_FOUND,\n                        String.format(\"Problem accessing: %s. Reason: Not Found\", uri));\n            }\n        } catch (NoSuchElementException ex) {\n            throw new HandlerException(Response.Status.UNSUPPORTED_MEDIA_TYPE,\n                    String.format(\"Problem accessing: %s. Reason: Unsupported Media Type\", uri), ex);\n        } catch (IllegalArgumentException ex) {\n            throw new HandlerException(Response.Status.BAD_REQUEST,\n                    String.format(\"Problem accessing: %s. Reason: Bad Request\", uri), ex);\n        }\n    }\n\n    /**\n     * Get HttpResourceModel which matches the HttpMethod of the request.\n     *\n     * @param routableDestinations List of ResourceModels.\n     * @param targetHttpMethod     HttpMethod.\n     * @param requestUri           request URI.\n     * @return RoutableDestination that matches httpMethod that needs to be handled. null if there are no matches.\n     */\n    private List<PatternPathRouter.RoutableDestination<HttpResourceModel>>\n    getMatchedDestination(List<PatternPathRouter.RoutableDestination<HttpResourceModel>> routableDestinations,\n                          String targetHttpMethod, String requestUri) {\n\n        Iterable<String> requestUriParts = Collections.unmodifiableList(Utils.split(requestUri, \"/\", true));\n        List<PatternPathRouter.RoutableDestination<HttpResourceModel>> matchedDestinations =\n                new ArrayList<>(routableDestinations.size());\n        int maxExactMatch = 0;\n        int maxGroupMatch = 0;\n        int maxPatternLength = 0;\n\n        for (PatternPathRouter.RoutableDestination<HttpResourceModel> destination : routableDestinations) {\n            HttpResourceModel resourceModel = destination.getDestination();\n            int groupMatch = destination.getGroupNameValues().size();\n\n            for (String httpMethod : resourceModel.getHttpMethod()) {\n                if (targetHttpMethod.equals(httpMethod)) {\n                    int exactMatch = getExactPrefixMatchCount(requestUriParts, Collections\n                            .unmodifiableList(Utils.split(resourceModel.getPath(), \"/\", true)));\n\n                    // When there are multiple matches present, the following precedence order is used -\n                    // 1. template path that has highest exact prefix match with the url is chosen.\n                    // 2. template path has the maximum groups is chosen.\n                    // 3. finally, template path that has the longest length is chosen.\n                    if (exactMatch > maxExactMatch) {\n                        maxExactMatch = exactMatch;\n                        maxGroupMatch = groupMatch;\n                        maxPatternLength = resourceModel.getPath().length();\n\n                        matchedDestinations.clear();\n                        matchedDestinations.add(destination);\n                    } else if (exactMatch == maxExactMatch && groupMatch >= maxGroupMatch) {\n                        if (groupMatch > maxGroupMatch || resourceModel.getPath().length() > maxPatternLength) {\n                            maxGroupMatch = groupMatch;\n                            maxPatternLength = resourceModel.getPath().length();\n                            matchedDestinations.clear();\n                        }\n                        matchedDestinations.add(destination);\n                    }\n                }\n            }\n        }\n        return matchedDestinations;\n    }\n\n    /**\n     * @return the number of path components that match from left to right.\n     */\n    private int getExactPrefixMatchCount(Iterable<String> first, Iterable<String> second) {\n        int count = 0;\n        for (Iterator<String> fit = first.iterator(), sit = second.iterator(); fit.hasNext() && sit.hasNext(); ) {\n            if (fit.next().equals(sit.next())) {\n                ++count;\n            } else {\n                break;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/ParamConvertUtils.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport com.google.gson.reflect.TypeToken;\nimport org.apache.commons.beanutils.ConvertUtils;\nimport org.wso2.msf4j.util.Defaults;\nimport org.wso2.msf4j.util.Primitives;\n\nimport java.io.File;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport java.util.function.Function;\n\n/**\n * Util class to convert request parameters.\n */\npublic final class ParamConvertUtils {\n\n    private static final Map<Class<?>, Method> PRIMITIVES_PARSE_METHODS;\n\n    // Setup methods for converting string into primitive/boxed types\n    static {\n        Map<Class<?>, Method> methods = new HashMap<>();\n        for (Class<?> wrappedType : Primitives.allWrapperTypes()) {\n            try {\n                methods.put(wrappedType, wrappedType.getMethod(\"valueOf\", String.class));\n            } catch (NoSuchMethodException e) {\n                // Void and Character has no valueOf. It's ok to ignore them\n            }\n        }\n\n        PRIMITIVES_PARSE_METHODS = methods;\n    }\n\n    private ParamConvertUtils() {\n    }\n\n    /**\n     * Creates a converter function that converts a path segment into the given result type.\n     * Current implementation doesn't follow the {@link javax.ws.rs.PathParam} specification to maintain backward\n     * compatibility.\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<String, Object> createPathParamConverter(final Type resultType) {\n        if (!(resultType instanceof Class)) {\n            throw new IllegalArgumentException(\"Unsupported @PathParam type \" + resultType);\n        }\n        return value -> ConvertUtils.convert(value, (Class<?>) resultType);\n    }\n\n    /**\n     * Creates a converter function that converts header value into an object of the given result type.\n     * It follows the supported types of {@link javax.ws.rs.HeaderParam} with the following exceptions:\n     * <ol>\n     * <li>Does not support types registered with {@link javax.ws.rs.ext.ParamConverterProvider}</li>\n     * </ol>\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<List<String>, Object> createHeaderParamConverter(Type resultType) {\n        return createListConverter(resultType);\n    }\n\n    /**\n     * Creates a converter function that converts cookie value into an object of the given result type.\n     * It follows the supported types of {@link javax.ws.rs.CookieParam} with the following exceptions:\n     * <ol>\n     * <li>Does not support types registered with {@link javax.ws.rs.ext.ParamConverterProvider}</li>\n     * </ol>\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<String, Object> createCookieParamConverter(Type resultType) {\n        return value -> ConvertUtils.convert(value, (Class<?>) resultType);\n    }\n\n    /**\n     * Creates a converter function that converts query parameter into an object of the given result type.\n     * It follows the supported types of {@link javax.ws.rs.QueryParam} with the following exceptions:\n     * <ol>\n     * <li>Does not support types registered with {@link javax.ws.rs.ext.ParamConverterProvider}</li>\n     * </ol>\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<List<String>, Object> createQueryParamConverter(Type resultType) {\n        return createListConverter(resultType);\n    }\n\n    /**\n     * Creates a converter function that converts form parameter into an object of the given result type.\n     * It follows the supported types of {@link javax.ws.rs.FormParam} with the following exceptions:\n     * <ol>\n     * <li>Does not support types registered with {@link javax.ws.rs.ext.ParamConverterProvider}</li>\n     * </ol>\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<List<String>, Object> createFormParamConverter(Type resultType) {\n        return createListConverter(resultType);\n    }\n\n    /**\n     * Creates a converter function that converts form parameter into an object of the given result type.\n     * It follows the supported types of {@link org.wso2.msf4j.formparam.FormDataParam} with the following exceptions:\n     * <ol>\n     * <li>Does not support types registered with {@link javax.ws.rs.ext.ParamConverterProvider}</li>\n     * </ol>\n     *\n     * @param resultType Result type\n     * @return Function the function\n     */\n    public static Function<List<String>, Object> createFormDataParamConverter(Type resultType) {\n        // For java.io.File we only support List ParameterizedType\n        if (resultType instanceof ParameterizedType) {\n            ParameterizedType type = (ParameterizedType) resultType;\n            Type elementType = type.getActualTypeArguments()[0];\n            if (elementType == File.class && type.getRawType() != List.class) {\n                throw new IllegalArgumentException(\"Unsupported type \" + resultType);\n            }\n        }\n        Function<List<String>, Object> listConverter = null;\n        try {\n            listConverter = createListConverter(resultType);\n        } catch (Throwable e) {\n            // Ignore the exceptions since from the logic we will handle the beans and Files\n        }\n        return listConverter;\n    }\n\n    /**\n     * Common helper method to convert value for {@link javax.ws.rs.HeaderParam} and {@link javax.ws.rs.QueryParam}.\n     *\n     * @param resultType Result type\n     * @return Function the function\n     * @see #createHeaderParamConverter(Type)\n     * @see #createQueryParamConverter(Type)\n     */\n    private static Function<List<String>, Object> createListConverter(Type resultType) {\n        TypeToken<?> typeToken = TypeToken.get(resultType);\n\n        // Use boxed type if raw type is primitive type. Otherwise the type won't change.\n        Class<?> resultClass = typeToken.getRawType();\n\n        // For string, just return the first value\n        if (resultClass == String.class) {\n            return new BasicConverter(Defaults.defaultValue(resultClass)) {\n                @Override\n                protected Object convert(String value) throws Exception {\n                    return value;\n                }\n            };\n        }\n\n        // Creates converter based on the type\n\n        // Primitive\n        Function<List<String>, Object> converter = createPrimitiveTypeConverter(resultClass);\n        if (converter != null) {\n            return converter;\n        }\n\n        // String constructor\n        converter = createStringConstructorConverter(resultClass);\n        if (converter != null) {\n            return converter;\n        }\n\n        // Static string argument methods\n        converter = createStringMethodConverter(resultClass);\n        if (converter != null) {\n            return converter;\n        }\n\n        // Collection\n        converter = createCollectionConverter(typeToken);\n        if (converter != null) {\n            return converter;\n        }\n\n        throw new IllegalArgumentException(\"Unsupported type \" + typeToken);\n    }\n\n    /**\n     * Creates a converter function that converts value into primitive type.\n     *\n     * @param resultClass The result class\n     * @return A converter function or {@code null} if the given type is not primitive type\n     */\n    private static Function<List<String>, Object> createPrimitiveTypeConverter(Class<?> resultClass) {\n        Object defaultValue = Defaults.defaultValue(resultClass);\n        final Class<?> boxedType = Primitives.wrap(resultClass);\n\n        if (!Primitives.isWrapperType(boxedType)) {\n            return null;\n        }\n\n        return new BasicConverter(defaultValue) {\n            @Override\n            protected Object convert(String value) throws Exception {\n                Method method = PRIMITIVES_PARSE_METHODS.get(boxedType);\n                if (method != null) {\n                    // It's primitive/wrapper type (except char)\n                    return method.invoke(null, value);\n                }\n                // One exception is char type\n                if (boxedType == Character.class) {\n                    return value.charAt(0);\n                }\n\n                // Should not happen.\n                return null;\n            }\n        };\n    }\n\n    /**\n     * Creates a converter function that converts value using a constructor that accepts a single String argument.\n     *\n     * @param resultClass Result class\n     * @return A converter function or {@code null} if the given type doesn't have a public constructor that accepts\n     * a single String argument.\n     */\n    private static Function<List<String>, Object> createStringConstructorConverter(Class<?> resultClass) {\n        try {\n            final Constructor<?> constructor = resultClass.getConstructor(String.class);\n            return new BasicConverter(Defaults.defaultValue(resultClass)) {\n                @Override\n                protected Object convert(String value) throws Exception {\n                    return constructor.newInstance(value);\n                }\n            };\n        } catch (NoSuchMethodException e) {\n            return null;\n        }\n    }\n\n    /**\n     * Creates a converter function that converts value using a public static method named\n     * {@code valueOf} or {@code fromString} that accepts a single String argument.\n     *\n     * @param resultClass Result class\n     * @return A converter function or {@code null} if the given type doesn't have a public static method\n     * named {@code valueOf} or {@code fromString} that accepts a single String argument.\n     */\n    private static Function<List<String>, Object> createStringMethodConverter(Class<?> resultClass) {\n        Method method;\n        try {\n            method = resultClass.getMethod(\"valueOf\", String.class);\n        } catch (NoSuchMethodException e) {\n            try {\n                method = resultClass.getMethod(\"fromString\", String.class);\n            } catch (NoSuchMethodException ex) {\n                return null;\n            }\n        }\n\n        final Method convertMethod = method;\n        return new BasicConverter(Defaults.defaultValue(resultClass)) {\n            @Override\n            protected Object convert(String value) throws Exception {\n                return convertMethod.invoke(null, value);\n            }\n        };\n    }\n\n    /**\n     * Creates a converter function that converts value into a {@link List}, {@link Set} or {@link SortedSet}.\n     *\n     * @param resultType Result type\n     * @return A converter function or {@code null} if the given type is not a {@link ParameterizedType} with raw type\n     * as {@link List}, {@link Set} or {@link SortedSet}. Also, for {@link SortedSet} type, if the element type\n     * doesn't implements {@link Comparable}, {@code null} is returned.\n     */\n    @SuppressWarnings(\"unchecked\")\n    private static Function<List<String>, Object> createCollectionConverter(TypeToken<?> resultType) {\n        final Class<?> rawType = resultType.getRawType();\n\n        // Collection. It must be List or Set\n        if (rawType != List.class && rawType != Set.class && rawType != SortedSet.class) {\n            return null;\n        }\n\n        // Must be ParameterizedType\n        if (!(resultType.getType() instanceof ParameterizedType)) {\n            return null;\n        }\n\n        // Must have 1 type parameter\n        ParameterizedType type = (ParameterizedType) resultType.getType();\n        if (type.getActualTypeArguments().length != 1) {\n            return null;\n        }\n\n        // For SortedSet, the entry type must be Comparable.\n        Type elementType = type.getActualTypeArguments()[0];\n        if (rawType == SortedSet.class && !Comparable.class.isAssignableFrom(TypeToken.get(elementType).getRawType())) {\n            return null;\n        }\n\n        //We only support List type for java.io.File\n        if (elementType == File.class && rawType != List.class) {\n            throw new IllegalArgumentException(\"File doesn't support \" + rawType);\n        }\n\n        // Get the converter for the collection element.\n        final Function<List<String>, Object> elementConverter = createQueryParamConverter(elementType);\n\n        return new Function<List<String>, Object>() {\n            @Override\n            public Object apply(List<String> values) {\n                Collection<? extends Comparable> collection;\n                if (rawType == List.class) {\n                    collection = new ArrayList<>();\n                } else if (rawType == Set.class) {\n                    collection = new HashSet<>();\n                } else {\n                    collection = new TreeSet<>();\n                }\n\n                if (values != null) {\n                    for (String value : values) {\n                        add(collection, elementConverter.apply(Collections.singletonList(value)));\n                    }\n                }\n                return collection;\n            }\n\n            @SuppressWarnings(\"unchecked\")\n            private <T> void add(Collection<T> collection, Object element) {\n                collection.add((T) element);\n            }\n        };\n    }\n\n    /**\n     * A converter that converts first String value from a List of String.\n     */\n    private abstract static class BasicConverter implements Function<List<String>, Object> {\n\n        private final Object defaultValue;\n\n        protected BasicConverter(Object defaultValue) {\n            this.defaultValue = defaultValue;\n        }\n\n        @Override\n        public final Object apply(List<String> values) {\n            if (values == null || values.isEmpty()) {\n                return getDefaultValue();\n            }\n            try {\n                return convert(values.get(0));\n            } catch (Exception e) {\n                Objects.requireNonNull(e);\n                if (e instanceof RuntimeException) {\n                    throw (RuntimeException) e;\n                }\n                throw new RuntimeException(e);\n            }\n        }\n\n        protected Object getDefaultValue() {\n            return defaultValue;\n        }\n\n        protected abstract Object convert(String value) throws Exception;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/PatternPathRouter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport org.wso2.msf4j.util.Utils;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Matches incoming un-matched paths to destinations. Designed to be used for routing URI paths to http resources.\n * Parameters within braces \"{}\" are treated as template parameter (a named wild-card pattern).\n *\n * @param <T> represents the destination of the routes.\n */\npublic final class PatternPathRouter<T> {\n\n    //GROUP_PATTERN is used for named wild card pattern in paths which is specified within braces.\n    //Example: {id}\n    private static final Pattern GROUP_PATTERN = Pattern.compile(\"\\\\{(.*?)\\\\}\");\n\n    // non-greedy wild card match.\n    private static final Pattern WILD_CARD_PATTERN = Pattern.compile(\"\\\\*\\\\*\");\n\n    private static final Pattern VARIABLE_PATTERN = Pattern.compile(\"(\\\\w[-\\\\w\\\\.]*[ ]*)(\\\\:(.+))?\");\n\n    private static final String PATH_SLASH = \"/\";\n\n    private final List<ImmutablePair<Pattern, RouteDestinationWithGroups>> patternRouteList;\n\n    /**\n     * Initialize PatternPathRouter.\n     */\n    public PatternPathRouter() {\n        this.patternRouteList = new ArrayList<>();\n    }\n\n    public static <T> PatternPathRouter<T> create() {\n        return new PatternPathRouter<>();\n    }\n\n    /**\n     * Add a source and destination.\n     *\n     * @param source      Source path to be routed. Routed path can have named wild-card pattern with braces \"{}\".\n     * @param destination Destination of the path.\n     */\n    public void add(final String source, final T destination) {\n\n        // replace multiple slashes with a single slash.\n        String path = source.replaceAll(\"/+\", PATH_SLASH);\n\n        path = (path.endsWith(PATH_SLASH) && path.length() > 1)\n                ? path.substring(0, path.length() - 1) : path;\n\n\n        String[] parts = path.split(PATH_SLASH);\n        StringBuilder sb = new StringBuilder();\n        List<String> groupNames = new ArrayList<>();\n\n        for (String part : parts) {\n            Matcher groupMatcher = GROUP_PATTERN.matcher(part);\n            if (groupMatcher.matches()) {\n                PathPart pathPart = createPathPart(groupMatcher.group(1));\n                groupNames.add(pathPart.getName());\n                if (pathPart.getPattern() != null) {\n                    sb.append('(');\n                    sb.append(pathPart.getPattern());\n                    sb.append(')');\n                } else {\n                    sb.append(\"([^/]+?)\");\n                }\n            } else if (WILD_CARD_PATTERN.matcher(part).matches()) {\n                sb.append(\".*?\");\n            } else {\n                sb.append(part);\n            }\n            sb.append(PATH_SLASH);\n        }\n\n        //Ignore the last \"/\"\n        if (sb.length() > 0) {\n            sb.setLength(sb.length() - 1);\n        }\n\n        Pattern pattern = Pattern.compile(sb.toString());\n        patternRouteList.add(ImmutablePair.of(pattern, new RouteDestinationWithGroups(destination, groupNames)));\n    }\n\n    private static PathPart createPathPart(String uriChunk) {\n        PathPart pathPart = new PathPart();\n        uriChunk = stripBraces(uriChunk).trim();\n        Matcher matcher = VARIABLE_PATTERN.matcher(uriChunk);\n        if (matcher.matches()) {\n            pathPart.setName(matcher.group(1).trim());\n            if (matcher.group(2) != null && matcher.group(3) != null) {\n                pathPart.setPattern(matcher.group(3).trim());\n            }\n        } else {\n            pathPart.setName(uriChunk);\n        }\n        return pathPart;\n    }\n\n    private static String stripBraces(String token) {\n        return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}' ?\n               token.substring(1, token.length() - 1) : token;\n    }\n\n    /**\n     * Represents Paths parts.\n     */\n    private static class PathPart {\n        private String name;\n        private String pattern;\n\n        public String getPattern() {\n            return pattern;\n        }\n\n        public void setPattern(String pattern) {\n            this.pattern = pattern;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n    }\n\n    /**\n     * Get a list of destinations and the values matching templated parameter for the given path.\n     * Returns an empty list when there are no destinations that are matched.\n     *\n     * @param path path to be routed.\n     * @return List of Destinations matching the given route.\n     */\n    public List<RoutableDestination<T>> getDestinations(String path) {\n\n        String cleanPath = (path.endsWith(PATH_SLASH) && path.length() > 0)\n                ? path.substring(0, path.length() - 1) : path;\n\n        List<RoutableDestination<T>> result = new ArrayList<>();\n\n        for (ImmutablePair<Pattern, RouteDestinationWithGroups> patternRoute : patternRouteList) {\n            Map<String, String> groupNameValues = new HashMap<>();\n            Matcher matcher = patternRoute.getFirst().matcher(cleanPath);\n            if (matcher.matches()) {\n                int matchIndex = 1;\n                for (String name : patternRoute.getSecond().getGroupNames()) {\n                    String value = matcher.group(matchIndex);\n                    groupNameValues.put(name, value);\n                    matchIndex++;\n                }\n                result.add(new RoutableDestination<>(patternRoute.getSecond().getDestination(),\n                                                     Collections.unmodifiableMap(groupNameValues)));\n            }\n        }\n        //Check for sub-resource locator\n        if (result.isEmpty()) {\n            patternRouteList.stream()\n                            .filter(patternRoute -> patternRoute.getSecond().destination instanceof HttpResourceModel &&\n                                                    ((HttpResourceModel) patternRoute.getSecond().destination)\n                                                            .isSubResourceLocator()).forEach(patternRoute -> {\n                Map<String, String> groupNameValues = new HashMap<>();\n                Pattern pattern = Pattern.compile(patternRoute.getFirst().pattern() + \".*\");\n                Matcher matcher = pattern.matcher(cleanPath);\n                if (matcher.matches()) {\n                    int matchIndex = 1;\n                    for (String name : patternRoute.getSecond().getGroupNames()) {\n                        String value = matcher.group(matchIndex);\n                        groupNameValues.put(name, value);\n                        matchIndex++;\n                    }\n                    result.add(new RoutableDestination<>(patternRoute.getSecond().getDestination(),\n                                                         Collections.unmodifiableMap(groupNameValues)));\n                }\n            });\n        }\n        return result;\n    }\n\n    /**\n     * Represents a matched destination.\n     *\n     * @param <T> Type of destination.\n     */\n    public static final class RoutableDestination<T> {\n        private final T destination;\n        private final Map<String, String> groupNameValues;\n\n        /**\n         * Construct the RouteableDestination with the given parameters.\n         *\n         * @param destination     destination of the route.\n         * @param groupNameValues parameters\n         */\n        public RoutableDestination(T destination, Map<String, String> groupNameValues) {\n            this.destination = destination;\n            this.groupNameValues = groupNameValues;\n        }\n\n        /**\n         * @return destination of the route.\n         */\n        public T getDestination() {\n            return destination;\n        }\n\n        /**\n         * @return Map of templated parameter and string representation group value matching the templated parameter as\n         * the value.\n         */\n        public Map<String, String> getGroupNameValues() {\n            return groupNameValues;\n        }\n\n        @Override\n        public String toString() {\n            return Utils.toString(this, new String[] { \"destination\", \"groupNameValues\" });\n        }\n    }\n\n    /**\n     * Helper class to store the groupNames and Destination.\n     */\n    private final class RouteDestinationWithGroups {\n\n        private final T destination;\n        private final List<String> groupNames;\n\n        public RouteDestinationWithGroups(T destination, List<String> groupNames) {\n            this.destination = destination;\n            this.groupNames = groupNames;\n        }\n\n        public T getDestination() {\n            return destination;\n        }\n\n        public List<String> getGroupNames() {\n            return groupNames;\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/SubresourceKey.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * This class is used to track the sub-resources.\n *\n */\npublic class SubresourceKey {\n    private Class<?> typedClass;\n    private String path;\n    private Set<String> httpMethods = new HashSet<>();\n\n\n    public SubresourceKey(String path, Class<?> tClass, Set<String> httpMethods) {\n        this.path = path;\n        typedClass = tClass;\n        this.httpMethods = httpMethods;\n    }\n\n    /**\n     * Get the sub-resource method type.\n     *\n     * @return Class get the type of the sub-resource\n     */\n    public Class<?> getTypedClass() {\n        return typedClass;\n    }\n\n    /**\n     * Get sub-resource absolute path.\n     *\n     * @return String absolute path of the sub-resource\n     */\n    public String getPath() {\n        return path;\n    }\n\n    /**\n     * Get method's http verbs.\n     *\n     * @return available http methods\n     */\n    public Set<String> getHttpMethods() {\n        return httpMethods;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof SubresourceKey)) {\n            return false;\n        }\n        SubresourceKey other = (SubresourceKey) o;\n        return path.equals(other.path) && typedClass == other.typedClass &&\n               httpMethods.equals(((SubresourceKey) o).httpMethods);\n    }\n\n    @Override\n    public int hashCode() {\n        return typedClass.hashCode() + 37 * path.hashCode();\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/Util.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.internal.router;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\nimport java.util.regex.Pattern;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HEAD;\nimport javax.ws.rs.OPTIONS;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Util class.\n */\npublic class Util {\n\n    public static final String GROUP_PATTERN = \"\\\\{(.*?)\\\\}\";\n    public static final String GROUP_PATTERN_REGEX = \"([^/]+?)\";\n    public static final Pattern WILD_CARD_PATTERN = Pattern.compile(\"\\\\*\\\\*\");\n\n    /**\n     * Check if http verb is available for the method.\n     *\n     * @param method\n     * @return\n     */\n    public static boolean isHttpMethodAvailable(Method method) {\n        return method.isAnnotationPresent(GET.class) ||\n               method.isAnnotationPresent(PUT.class) ||\n               method.isAnnotationPresent(POST.class) ||\n               method.isAnnotationPresent(DELETE.class) ||\n               method.isAnnotationPresent(HEAD.class) ||\n               method.isAnnotationPresent(OPTIONS.class);\n    }\n\n    /**\n     * Remove the curly braces if the token is wrapped with curly braces.\n     *\n     * @param token\n     * @return\n     */\n    public static String stripBraces(String token) {\n        return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}' ?\n               token.substring(1, token.length() - 1) : token;\n    }\n\n    /**\n     * Process accept type considering the produce type and the\n     * accept types of the request header.\n     *\n     * @param acceptTypes accept types of the request.\n     * @return processed accept type\n     */\n    public static String getResponseType(List<String> acceptTypes, List<String> producesMediaTypes) {\n        String responseType = MediaType.WILDCARD;\n        if (!producesMediaTypes.contains(MediaType.WILDCARD) && acceptTypes != null) {\n            responseType =\n                    (acceptTypes.contains(MediaType.WILDCARD)) ? producesMediaTypes.get(0) :\n                    producesMediaTypes.stream().filter(acceptTypes::contains).findFirst().get();\n        } else if (acceptTypes == null && !producesMediaTypes.isEmpty()) {\n            responseType = producesMediaTypes.get(0);\n        }\n        return responseType;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/router/package-info.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 * Service and components to build Netty based Http web service.\n * {@code NettyHttpService} sets up the necessary pipeline and manages starting, stopping,\n * state-management of the web service.\n *\n *\n * In-order to handle http requests, {@code HttpHandler} must be implemented. The methods\n * in the classes implemented from {@code HttpHandler} must be annotated with Jersey annotations to\n * specify http uri paths and http methods.\n * Note: Only supports the following annotations:\n * {@link javax.ws.rs.Path Path},\n * {@link javax.ws.rs.PathParam PathParam},\n * {@link javax.ws.rs.GET GET},\n * {@link javax.ws.rs.PUT PUT},\n * {@link javax.ws.rs.POST POST},\n * {@link javax.ws.rs.DELETE DELETE},\n * {@link javax.ws.rs.HEAD HEAD},\n * {@link javax.ws.rs.OPTIONS OPTIONS}.\n *\n * Note: Doesn't support getting Annotations from base class if the HttpHandler implements also extends\n * a class with annotation.\n *\n * Sample usage Handlers and Netty service setup:\n *\n * <pre>\n * //Setup Handlers\n *\n * {@literal @}Path(\"/common/v1/\")\n * public class ApiHandler implements HttpHandler {\n *\n *   {@literal @}Path(\"widgets\")\n *   {@literal @}GET\n *   public void widgetHandler(HttpRequest request, HttpResponder responder) {\n *     responder.sendJson(HttpResponseStatus.OK, \"{\\\"key\\\": \\\"value\\\"}\");\n *   }\n *\n *   {@literal @}Override\n *   public void init(HandlerContext context) {\n *     //Perform bootstrap operations before any of the handlers in this class gets called.\n *   }\n *\n *   {@literal @}Override\n *   public void destroy(HandlerContext context) {\n *    //Perform teardown operations the server shuts down.\n *   }\n * }\n *\n * //Set up and start the http service\n * NettyHttpService service = NettyHttpService.builder()\n *                                            .addHttpHandlers(ImmutableList.of(new Handler())\n *                                            .setPort(8989)\n *                                            .build();\n * service.startAndWait();\n *\n * // ....\n *\n * //Stop the web-service\n * service.shutdown();\n *\n * </pre>\n */\npackage org.wso2.msf4j.internal.router;\n\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/session/SessionIdGenerator.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.internal.session;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\nimport java.security.SecureRandom;\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedQueue;\n\n/**\n * SessionIdGenerator util class. Borrowed from Tomcat 8.\n */\n@SuppressWarnings(\"unused\")\npublic class SessionIdGenerator {\n    private static final Logger log = LoggerFactory.getLogger(SessionIdGenerator.class);\n\n    private int sessionIdLength = 16;\n\n    /**\n     * Queue of random number generator objects to be used when creating session\n     * identifiers. If the queue is empty when a random number generator is\n     * required, a new random number generator object is created. This is\n     * designed this way since random number generators use a sync to make them\n     * thread-safe and the sync makes using a a single object slow(er).\n     */\n    private final Queue<SecureRandom> randoms = new ConcurrentLinkedQueue<>();\n\n    private String secureRandomClass = null;\n\n    private String secureRandomAlgorithm = \"SHA1PRNG\";\n\n    private String secureRandomProvider = null;\n\n\n    /**\n     * Node identifier when in a cluster. Defaults to the empty string.\n     */\n    private String jvmRoute = \"\";\n\n    public void setSessionIdLength(int sessionIdLength) {\n        this.sessionIdLength = sessionIdLength;\n    }\n\n    public void setSecureRandomClass(String secureRandomClass) {\n        this.secureRandomClass = secureRandomClass;\n    }\n\n    public void setSecureRandomAlgorithm(String secureRandomAlgorithm) {\n        this.secureRandomAlgorithm = secureRandomAlgorithm;\n    }\n\n    public void setSecureRandomProvider(String secureRandomProvider) {\n        this.secureRandomProvider = secureRandomProvider;\n    }\n\n    public void setJvmRoute(String jvmRoute) {\n        this.jvmRoute = jvmRoute;\n    }\n\n    public String generateSessionId(String route) {\n\n        byte random[] = new byte[16];\n\n        // Render the result as a String of hexadecimal digits\n        // Start with enough space for sessionIdLength and medium route size\n        StringBuilder buffer = new StringBuilder(2 * sessionIdLength + 20);\n\n        int resultLenBytes = 0;\n\n        while (resultLenBytes < sessionIdLength) {\n            getRandomBytes(random);\n            for (int j = 0; j < random.length && resultLenBytes < sessionIdLength; j++) {\n                byte b1 = (byte) ((random[j] & 0xf0) >> 4);\n                byte b2 = (byte) (random[j] & 0x0f);\n                if (b1 < 10) {\n                    buffer.append((char) ('0' + b1));\n                } else {\n                    buffer.append((char) ('A' + (b1 - 10)));\n                }\n                if (b2 < 10) {\n                    buffer.append((char) ('0' + b2));\n                } else {\n                    buffer.append((char) ('A' + (b2 - 10)));\n                }\n                resultLenBytes++;\n            }\n        }\n\n        if (route != null && route.length() > 0) {\n            buffer.append('.').append(route);\n        } else {\n            if (jvmRoute != null && jvmRoute.length() > 0) {\n                buffer.append('.').append(jvmRoute);\n            }\n        }\n\n        return buffer.toString();\n    }\n\n    protected void getRandomBytes(byte bytes[]) {\n\n        SecureRandom random = randoms.poll();\n        if (random == null) {\n            random = createSecureRandom();\n        }\n        random.nextBytes(bytes);\n        randoms.add(random);\n    }\n\n    /**\n     * Create a new random number generator instance we should use for\n     * generating session identifiers.\n     */\n    private SecureRandom createSecureRandom() {\n\n        SecureRandom result = null;\n\n        long t1 = System.currentTimeMillis();\n        if (secureRandomClass != null) {\n            try {\n                // Construct and seed a new random number generator\n                Class<?> clazz = Class.forName(secureRandomClass);\n                result = (SecureRandom) clazz.newInstance();\n            } catch (Exception e) {\n                log.error(\"Cannot load secureRandomClass: \" + secureRandomClass, e);\n            }\n        }\n\n        if (result == null) {\n            // No secureRandomClass or creation failed. Use SecureRandom.\n            try {\n                if (secureRandomProvider != null &&\n                        secureRandomProvider.length() > 0) {\n                    result = SecureRandom.getInstance(secureRandomAlgorithm,\n                            secureRandomProvider);\n                } else if (secureRandomAlgorithm != null &&\n                        secureRandomAlgorithm.length() > 0) {\n                    result = SecureRandom.getInstance(secureRandomAlgorithm);\n                }\n            } catch (NoSuchAlgorithmException e) {\n                log.error(\"SecureRandomAlgorithm \" + secureRandomAlgorithm + \" not found\", e);\n            } catch (NoSuchProviderException e) {\n                log.error(\"SecureRandomProvider not found \" + secureRandomProvider, e);\n            }\n        }\n\n        if (result == null) {\n            // Invalid provider / algorithm\n            try {\n                result = SecureRandom.getInstance(\"SHA1PRNG\");\n            } catch (NoSuchAlgorithmException e) {\n                log.error(\"SecureRandomAlgorithm \" + secureRandomAlgorithm + \" not found\", e);\n            }\n        }\n\n        if (result == null) {\n            // Nothing works - use platform default\n            result = new SecureRandom();\n        }\n\n        // Force seeding to take place\n        result.nextInt();\n\n        long t2 = System.currentTimeMillis();\n        if ((t2 - t1) > 100) {\n            log.warn(\"Session took more than 100ms to create! Time taken: \" + (t2 - t1) + \"ms\");\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/CloseCodeImpl.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\n\nimport javax.websocket.CloseReason;\n\n/**\n * {@link CloseReason.CloseCode} implementation for WebSocket in MSF4J\n */\npublic class CloseCodeImpl implements CloseReason.CloseCode {\n\n    private final int closeCode;\n\n    /**\n     * @param closeCode close code for the reason of closure.\n     */\n    public CloseCodeImpl(int closeCode) {\n        this.closeCode = closeCode;\n    }\n\n    @Override\n    public int getCode() {\n        return this.closeCode;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/EndpointDispatcher.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.nio.ByteBuffer;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Optional;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * Dispatch the registered endpoints.\n * This class will find the best matching resource of an endpoint for a given message type.\n */\npublic class EndpointDispatcher {\n\n    /**\n     * Validate the endpoint against the {@link ServerEndpoint} since without {@link ServerEndpoint} definition\n     * there can't be a WebSocket endpoint.\n     * @param websocketEndpoint endpoint which should be validated.\n     */\n    public boolean validateEndpointUri(Object websocketEndpoint) {\n        if (websocketEndpoint != null) {\n            return websocketEndpoint.getClass().isAnnotationPresent(ServerEndpoint.class);\n        }\n        return false;\n    }\n\n    /**\n     * Extract the URI from the endpoint.\n     * <b>Note that it is better use validateEndpointUri method to validate the endpoint uri\n     * before getting it out if needed. Otherwise it will cause issues. Use this method only and only if\n     * it is sure that endpoint contains {@link ServerEndpoint} defined.</b>\n     *\n     * @param webSocketEndpoint WebSocket endpoint which the URI should be extracted.\n     * @return the URI of the Endpoint as a String.\n     */\n    public String getUri(Object webSocketEndpoint) {\n        return webSocketEndpoint.getClass().getAnnotation(ServerEndpoint.class).value();\n    }\n\n    /**\n     * Extract OnOpen method from the endpoint if exists.\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle new connection.\n     */\n    public Optional<Method> getOnOpenMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnOpen.class)) {\n                returnMethod = method;\n                break;\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n\n    /**\n     * Extract OnClose method from the endpoint if exists.\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle new connection.\n     */\n    public Optional<Method> getOnCloseMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnClose.class)) {\n                returnMethod = method;\n                break;\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n\n    /**\n     * Extract OnError method from the endpoint if exists\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle errors.\n     */\n    public Optional<Method> getOnErrorMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnError.class)) {\n                returnMethod = method;\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n\n    /**\n     * Extract OnMessage method for String from the endpoint if exists.\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle String messages.\n     */\n    public Optional<Method> getOnStringMessageMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnMessage.class)) {\n                Parameter[] parameters = method.getParameters();\n                for (Parameter parameter: parameters) {\n                    if (!parameter.isAnnotationPresent(PathParam.class) &&\n                            parameter.getType() == String.class) {\n                        returnMethod = method;\n                    }\n\n                }\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n\n    /**\n     * Extract OnMessage method for Binary from the endpoint if exists.\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle binary messages.\n     */\n    public Optional<Method> getOnBinaryMessageMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnMessage.class)) {\n                //Adding OnMessage according to their types\n                Class<?>[] paraTypes = method.getParameterTypes();\n                List<Class<?>> paraList = Arrays.asList(paraTypes);\n                if (paraList.contains(byte[].class) || paraList.contains(ByteBuffer.class)) {\n                    returnMethod = method;\n                }\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n\n    /**\n     * Extract OnMessage method for Pong from the endpoint if exists.\n     *\n     * @param webSocketEndpoint Endpoint to extract method.\n     * @return method optional to handle pong messages.\n     */\n    public Optional<Method> getOnPongMessageMethod(Object webSocketEndpoint) {\n        Method[] methods = webSocketEndpoint.getClass().getMethods();\n        Method returnMethod = null;\n        for (Method method : methods) {\n            if (method.isAnnotationPresent(OnMessage.class)) {\n                Class<?>[] paraTypes = method.getParameterTypes();\n                List<Class<?>> paraList = Arrays.asList(paraTypes);\n                if (paraList.contains(PongMessage.class)) {\n                    returnMethod = method;\n                }\n            }\n        }\n        return Optional.ofNullable(returnMethod);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/EndpointValidator.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointAnnotationException;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointMethodReturnTypeException;\nimport org.wso2.msf4j.websocket.exception.WebSocketMethodParameterException;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\nimport org.wso2.transport.http.netty.message.HttpCarbonRequest;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.nio.ByteBuffer;\nimport javax.websocket.CloseReason;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This validates all the methods which are relevant to WebSocket Server endpoint using JSR-356 specification.\n */\npublic class EndpointValidator {\n\n    /**\n     * Validate the whole WebSocket endpoint.\n     *\n     * @return true if validation is completed without any error.\n     * @throws WebSocketEndpointAnnotationException if error on an annotation declaration occurred.\n     * @throws WebSocketMethodParameterException if the method parameters are invalid for a given method according\n     * to JSR-356 specification.\n     */\n    public boolean validate(Object webSocketEndpoint) throws WebSocketEndpointAnnotationException,\n                                                             WebSocketMethodParameterException,\n                                                             WebSocketEndpointMethodReturnTypeException {\n        if (webSocketEndpoint == null) {\n            return false;\n        }\n        return validateURI(webSocketEndpoint) && validateOnStringMethod(webSocketEndpoint) &&\n                validateOnBinaryMethod(webSocketEndpoint) && validateOnPongMethod(webSocketEndpoint) &&\n                validateOnOpenMethod(webSocketEndpoint) && validateOnCloseMethod(webSocketEndpoint) &&\n                validateOnErrorMethod(webSocketEndpoint);\n    }\n\n    private boolean validateURI(Object webSocketEndpoint) throws WebSocketEndpointAnnotationException {\n        if (webSocketEndpoint.getClass().isAnnotationPresent(ServerEndpoint.class)) {\n            return true;\n        }\n        throw new WebSocketEndpointAnnotationException(\"Server Endpoint is not defined.\");\n    }\n\n    private boolean validateOnStringMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnStringMessageMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnStringMessageMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        boolean foundPrimaryString = false;\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    if (foundPrimaryString) {\n                        throw new WebSocketMethodParameterException(\"Invalid parameter found on text message method: \" +\n                                                                            \"More than one string parameter without \" +\n                                                                            \"@PathParam annotation.\");\n                    }\n                    foundPrimaryString = true;\n                }\n            } else if (paraType != WebSocketConnection.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on text message method: \" +\n                                                                    paraType);\n            }\n        }\n        return foundPrimaryString;\n    }\n\n    private boolean validateOnBinaryMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnBinaryMessageMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnBinaryMessageMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        boolean foundPrimaryBuffer = false;\n        boolean foundIsFinal = false;\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on binary message method: \" +\n                                                                        \"string parameter without \" +\n                                                                        \"@PathParam annotation.\");\n                }\n            } else if (paraType == ByteBuffer.class || paraType == byte[].class) {\n                if (foundPrimaryBuffer) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on binary message method: \" +\n                                                                        \"only one ByteBuffer/byte[] \" +\n                                                                        \"should be declared.\");\n                }\n                foundPrimaryBuffer = true;\n\n            } else if (paraType == boolean.class) {\n                if (foundIsFinal) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on binary message method: \" +\n                                                                        \"only one boolean should be declared and \" +\n                                                                        \"found more than one.\");\n                }\n                foundIsFinal = true;\n            } else if (paraType != WebSocketConnection.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on binary message method: \" +\n                                                                    paraType);\n            }\n        }\n        return foundPrimaryBuffer;\n    }\n\n    private boolean validateOnPongMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnPongMessageMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnPongMessageMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        boolean foundPrimaryPong = false;\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on pong message method: \" +\n                                                                        \"string parameter without \" +\n                                                                        \"@PathParam annotation.\");\n                }\n            } else if (paraType == PongMessage.class) {\n                if (foundPrimaryPong) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on pong message method: \" +\n                                                                        \"only one PongMessage should be declared.\");\n                }\n                foundPrimaryPong = true;\n            } else if (paraType != WebSocketConnection.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on pong message method: \" +\n                                                                    paraType);\n            }\n        }\n        return foundPrimaryPong;\n    }\n\n    private boolean validateOnOpenMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnOpenMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnOpenMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on open message method: \" +\n                                                                        \"string parameter without \" +\n                                                                        \"@PathParam annotation.\");\n                }\n            } else if (paraType != WebSocketConnection.class && paraType != HttpCarbonRequest.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on open message method: \" +\n                                                                    paraType);\n            }\n        }\n        return true;\n    }\n\n    private boolean validateOnCloseMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnCloseMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnCloseMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on close message method: \" +\n                                                                        \"string parameter without \" +\n                                                                        \"@PathParam annotation.\");\n                }\n            } else if (paraType != CloseReason.class && paraType != WebSocketConnection.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on close message method: \" +\n                                                                    paraType);\n            }\n        }\n        return true;\n    }\n\n    private boolean validateOnErrorMethod(Object webSocketEndpoint)\n            throws WebSocketMethodParameterException, WebSocketEndpointMethodReturnTypeException {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        Method method;\n        if (dispatcher.getOnErrorMethod(webSocketEndpoint).isPresent()) {\n            method = dispatcher.getOnErrorMethod(webSocketEndpoint).get();\n        } else {\n            return true;\n        }\n        validateReturnType(method);\n        boolean foundPrimaryThrowable = false;\n        for (Parameter parameter: method.getParameters()) {\n            Class<?> paraType = parameter.getType();\n            if (paraType == String.class) {\n                if (parameter.getAnnotation(PathParam.class) == null) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on error message method: \" +\n                                                                        \"string parameter without \" +\n                                                                        \"@PathParam annotation.\");\n                }\n            } else if (paraType == Throwable.class) {\n                if (foundPrimaryThrowable) {\n                    throw new WebSocketMethodParameterException(\"Invalid parameter found on pong message method: \" +\n                                                                        \"only one Throwable should be declared.\");\n                }\n                foundPrimaryThrowable = true;\n            } else if (paraType != WebSocketConnection.class) {\n                throw new WebSocketMethodParameterException(\"Invalid parameter found on error message method: \" +\n                                                                    paraType);\n            }\n        }\n\n        if (!foundPrimaryThrowable) {\n            throw new WebSocketMethodParameterException(\"Mandatory parameter for on error method \" + Throwable.class +\n                                                                \" not found.\");\n        }\n        return foundPrimaryThrowable;\n    }\n\n    private boolean validateReturnType(Method method) throws WebSocketEndpointMethodReturnTypeException {\n        Class<?> returnType = method.getReturnType();\n        boolean foundCorrectReturnType = returnType == String.class || returnType == ByteBuffer.class ||\n                returnType == byte[].class || returnType == PongMessage.class || returnType == void.class;\n        if (!foundCorrectReturnType) {\n            throw new WebSocketEndpointMethodReturnTypeException(\"Unexpected method return type: \" + returnType);\n        }\n        return foundCorrectReturnType;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/EndpointsRegistryImpl.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.internal.router.PatternPathRouter;\nimport org.wso2.msf4j.websocket.WebSocketEndpointsRegistry;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointAnnotationException;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointMethodReturnTypeException;\nimport org.wso2.msf4j.websocket.exception.WebSocketMethodParameterException;\n\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\n/**\n * Implementation for {@link WebSocketEndpointsRegistry}.\n * Endpoints are Dispatched and Stored in a {@link PatternPathRouter}. So when new request comes it will be routed to\n * best matching URI.\n */\npublic class EndpointsRegistryImpl implements WebSocketEndpointsRegistry {\n\n    private static final Logger log = LoggerFactory.getLogger(EndpointsRegistryImpl.class);\n    private static final EndpointsRegistryImpl webSocketEndpointsRegistry = new EndpointsRegistryImpl();\n    private final EndpointValidator validator = new EndpointValidator();\n\n    // Map <uri, WebSocketEndpoint>\n    private final Map<String, Object> webSocketEndpointMap = new ConcurrentHashMap<>();\n    // PatterPathRouter<WebSocketEndpoint>\n    private PatternPathRouter<Object> endpointPatternPathRouter = PatternPathRouter.create();\n\n    // Makes this class singleton.\n    private EndpointsRegistryImpl() {\n    }\n\n    /**\n     * @return this singleton instance of {@link EndpointsRegistryImpl}.\n     */\n    public static EndpointsRegistryImpl getInstance() {\n        return webSocketEndpointsRegistry;\n    }\n\n    /**\n     * Adding endpoints to the registry.\n     *\n     * @param webSocketEndpoints to add.\n     * @return the endpoints which could not deploy due to validation errors.\n     */\n    public List<Object> addEndpoint(Object... webSocketEndpoints) {\n        List<Object> endpointsWithError = new LinkedList<>();\n        Arrays.stream(webSocketEndpoints).forEach(\n                endpoint -> {\n                    EndpointDispatcher dispatcher = new EndpointDispatcher();\n                    try {\n                        if (validator.validate(endpoint)) {\n                            webSocketEndpointMap.put(dispatcher.getUri(endpoint), endpoint);\n                            log.info(\"Endpoint Registered : \" + dispatcher.getUri(endpoint));\n                        }\n                    } catch (WebSocketEndpointAnnotationException e) {\n                        endpointsWithError.add(endpoint);\n                        log.error(\"Cannot deploy endpoint\" +\n                                          \": server endpoint not defined.\" + System.lineSeparator() + e.toString());\n                    } catch (WebSocketMethodParameterException e) {\n                        endpointsWithError.add(endpoint);\n                        log.error(\"Cannot deploy endpoint \" + endpoint.getClass().getName() +\n                                          \": error method definition.\" + System.lineSeparator() + e.toString());\n                    } catch (WebSocketEndpointMethodReturnTypeException e) {\n                        endpointsWithError.add(endpoint);\n                        log.error(\"Cannot deploy endpoint \" + endpoint.getClass().getName() +\n                                          \": invalid method return type.\" + System.lineSeparator() + e.toString());\n                    }\n\n                }\n        );\n        updatePatternPathRouter();\n        return endpointsWithError;\n    }\n\n    /**\n     * Remove WebSocket Endpoint from Registry.\n     *\n     * @param webSocketEndpoint which should be removed.\n     */\n    public void removeEndpoint(Object webSocketEndpoint) {\n        EndpointDispatcher dispatcher = new EndpointDispatcher();\n        webSocketEndpointMap.remove(dispatcher.getUri(webSocketEndpoint));\n        updatePatternPathRouter();\n        log.info(\"Removed endpoint : \" + dispatcher.getUri(webSocketEndpoint));\n    }\n\n    /**\n     * Extract the best possible {@link org.wso2.msf4j.internal.router.PatternPathRouter.RoutableDestination}.\n     *\n     * @param uri String of the desired destination endpoint.\n     * @return the best possible {@link org.wso2.msf4j.internal.router.PatternPathRouter.RoutableDestination}.\n     */\n    public PatternPathRouter.RoutableDestination<Object> getRoutableEndpoint(String uri) {\n        List<PatternPathRouter.RoutableDestination<Object>> routableDestinations =\n                endpointPatternPathRouter.getDestinations(uri);\n        return getBestEndpoint(routableDestinations, uri);\n    }\n\n    @Override\n    public Set<Object> getAllEndpoints() {\n        return webSocketEndpointMap.entrySet().stream()\n                .map(Map.Entry::getValue)\n                .collect(Collectors.toSet());\n    }\n\n    /**\n     * Find the best matching RoutableDestination from the All matching RoutableDestinations.\n     *\n     * @param routableDestinationList routable destication list for a given uri.\n     * @param requestUri uri which the best endpoint should be found for.\n     * @return the best possible routable destination for the requested uri.\n     */\n    private PatternPathRouter.RoutableDestination<Object> getBestEndpoint(\n            List<PatternPathRouter.RoutableDestination<Object>> routableDestinationList, String requestUri) {\n        PatternPathRouter.RoutableDestination<Object> bestRoutableDestination = null;\n        int currentBestHitCount = 0;\n        for (PatternPathRouter.RoutableDestination<Object>\n                currentRoutableDestination: routableDestinationList) {\n            int tempCount = getHitCount(new EndpointDispatcher().getUri(currentRoutableDestination.getDestination())\n                                                .split(\"/\"), requestUri.split(\"/\"));\n            if (tempCount > currentBestHitCount) {\n                bestRoutableDestination = currentRoutableDestination;\n                currentBestHitCount = tempCount;\n            }\n        }\n        return bestRoutableDestination;\n    }\n\n    /**\n     * Update the PatternPathRouter when adding and removing an endpoint.\n     */\n    private void updatePatternPathRouter() {\n        endpointPatternPathRouter = PatternPathRouter.create();\n        webSocketEndpointMap.entrySet().forEach(\n                entry -> endpointPatternPathRouter.add(entry.getKey(), entry.getValue())\n        );\n    }\n\n    //\n\n    /**\n     * Compare and find number of equalities of the Endpoint URI and Requested URI.\n     *\n     * @param destinationUriChunkArray chunk words of the endpoint uri.\n     * @param requestUriChunkArray chunk words of the requested uri.\n     * @return hit count - how many words are matched endpoint uri against requested uri.\n     */\n    private int getHitCount(String[] destinationUriChunkArray, String[] requestUriChunkArray) {\n        int count = 0;\n        for (int i = 0; i < destinationUriChunkArray.length; i++) {\n            if (destinationUriChunkArray[i].equals(requestUriChunkArray[i])) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/WebSocketPongMessage.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\nimport java.nio.ByteBuffer;\nimport javax.websocket.PongMessage;\n\n/**\n * WebSocket pong message implementation of {@link PongMessage}.\n */\npublic class WebSocketPongMessage implements PongMessage {\n\n    private final ByteBuffer applicationData;\n\n    /**\n     * @param byteBuffer application data of the {@link PongMessage}\n     */\n    public WebSocketPongMessage(ByteBuffer byteBuffer) {\n        applicationData = byteBuffer;\n    }\n\n    @Override\n    public ByteBuffer getApplicationData() {\n        return applicationData;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/internal/websocket/WebSocketServerSC.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.internal.websocket;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.kernel.startupresolver.RequiredCapabilityListener;\nimport org.wso2.msf4j.internal.DataHolder;\nimport org.wso2.msf4j.websocket.WebSocketEndpoint;\n\n/**\n * OSGi Service component for WebSocket server. This will identify the endpoints which are trying to identify\n * and register them as WebSocket Server Endpoints\n */\n@Component(\n        name = \"org.wso2.msf4j.internal.websocket.WebSocketServerSC\",\n        immediate = true,\n        property = {\n                \"componentName=wso2-websocket-server\"\n        }\n)\npublic class WebSocketServerSC implements RequiredCapabilityListener {\n\n    private static final Logger log = LoggerFactory.getLogger(WebSocketServerSC.class);\n    private EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n\n    @Activate\n    protected void start(final BundleContext bundleContext) {\n        if (log.isDebugEnabled()) {\n            log.debug(\"Endpoint Activated.\");\n        }\n    }\n\n    /**\n     * Add endpoint to the endpoint registry.\n     *\n     * @param endpoint endpoint which should be added to the registry.\n     */\n    @Reference(\n        name = \"websocketEndpoint\",\n        service = WebSocketEndpoint.class,\n        cardinality = ReferenceCardinality.MULTIPLE,\n        policy = ReferencePolicy.DYNAMIC,\n        unbind = \"removeEndpoint\"\n    )\n    protected void addEndpoint(WebSocketEndpoint endpoint) {\n        endpointsRegistry.addEndpoint(endpoint);\n    }\n\n    /**\n     * Remove endpoint from the endpoint registry.\n     *\n     * @param endpoint endpoint which should be removed from the registry.\n     */\n    protected void removeEndpoint(WebSocketEndpoint endpoint) {\n        endpointsRegistry.removeEndpoint(endpoint);\n    }\n\n    @Override\n    public void onAllRequiredCapabilitiesAvailable() {\n        DataHolder.getInstance().getBundleContext().registerService(WebSocketServerSC.class, this, null);\n        log.info(\"All required capabilities are available of WebSocket service component is available.\");\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/JWTSecurityInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.security;\n\nimport com.nimbusds.jose.JOSEException;\nimport com.nimbusds.jose.JWSVerifier;\nimport com.nimbusds.jose.crypto.RSASSAVerifier;\nimport com.nimbusds.jwt.SignedJWT;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.Key;\nimport java.security.KeyStore;\nimport java.security.KeyStoreException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\nimport java.security.UnrecoverableKeyException;\nimport java.security.cert.CertificateException;\nimport java.security.interfaces.RSAPublicKey;\nimport java.text.ParseException;\nimport java.util.Date;\n\n/**\n * Verify the JWT header in request.\n */\npublic class JWTSecurityInterceptor implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(JWTSecurityInterceptor.class);\n\n    private static final String JWT_HEADER = \"X-JWT-Assertion\";\n    private static final String AUTH_TYPE_JWT = \"JWT\";\n    private static final String KEYSTORE = SystemVariableUtil.getValue(\"PETSTORE_KEYSTORE\", \"wso2carbon.jks\");\n    private static final String ALIAS = SystemVariableUtil.getValue(\"PETSTORE_KEY_ALIAS\", \"wso2carbon\");\n    private static final String KEYSTORE_PASSWORD = SystemVariableUtil.getValue(\"PETSTORE_KEYSTORE_PASS\", \"wso2carbon\");\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        log.info(\"Authentication precall\");\n        boolean isValidSignature;\n        String jwtHeader = request.getHeader(JWT_HEADER);\n        if (jwtHeader != null) {\n            isValidSignature = verifySignature(jwtHeader);\n            if (isValidSignature) {\n                return true;\n            }\n        }\n        response.setHeader(javax.ws.rs.core.HttpHeaders.WWW_AUTHENTICATE, AUTH_TYPE_JWT);\n        response.setStatus(javax.ws.rs.core.Response.Status.UNAUTHORIZED.getStatusCode());\n        return false;\n    }\n\n    private boolean verifySignature(String jwt) {\n        try {\n            SignedJWT signedJWT = SignedJWT.parse(jwt);\n            if (new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {\n                JWSVerifier verifier =\n                        new RSASSAVerifier((RSAPublicKey) getPublicKey(KEYSTORE, KEYSTORE_PASSWORD, ALIAS));\n                return signedJWT.verify(verifier);\n            } else {\n                log.info(\"Token has expired\");\n            }\n        } catch (ParseException | IOException | KeyStoreException | CertificateException |\n                NoSuchAlgorithmException | UnrecoverableKeyException | JOSEException e) {\n            log.error(\"Error occurred while JWT signature verification. JWT=\" + jwt, e);\n        }\n        return false;\n    }\n\n    private PublicKey getPublicKey(String keyStorePath, String keyStorePassword, String alias)\n            throws IOException, KeyStoreException, CertificateException,\n            NoSuchAlgorithmException, UnrecoverableKeyException {\n\n        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(keyStorePath)) {\n            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());\n            keystore.load(inputStream, keyStorePassword.toCharArray());\n\n            Key key = keystore.getKey(alias, keyStorePassword.toCharArray());\n            if (key instanceof PrivateKey) {\n                // Get certificate of public key\n                java.security.cert.Certificate cert = keystore.getCertificate(alias);\n\n                // Get public key\n                return cert.getPublicKey();\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/MSF4JSecurityException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.security;\n\n/**\n * The class {@code MSF4JSecurityException} and its subclasses are a form of\n * {@code Exception} that indicates security related error conditions.\n */\npublic class MSF4JSecurityException extends Exception {\n\n    private SecurityErrorCode errorCode;\n\n    /**\n     * Constructs a new exception with the specified error code and the detail message.\n     *\n     * @param errorCode SecurityErrorCode\n     * @param message   error message\n     */\n    public MSF4JSecurityException(SecurityErrorCode errorCode, String message) {\n        super(message);\n        this.errorCode = errorCode;\n    }\n\n    /**\n     * Constructs a new exception with the specified detail message and the error code.\n     *\n     * @param errorCode SecurityErrorCode\n     * @param message   error message\n     * @param cause     cause the cause (which is saved for later retrieval by the\n     *                  {@link #getCause()} method).  (A <tt>null</tt> value is\n     *                  permitted, and indicates that the cause is nonexistent or\n     *                  unknown.)\n     */\n    public MSF4JSecurityException(SecurityErrorCode errorCode, String message, Throwable cause) {\n        super(message, cause);\n        this.errorCode = errorCode;\n    }\n\n    /**\n     * Returns the associate {@code SecurityErrorCode} value.\n     *\n     * @return an instances of the SecurityErrorCode\n     */\n    public SecurityErrorCode getErrorCode() {\n        return errorCode;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/SecurityErrorCode.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.security;\n\n/**\n * Enum class which represent security error codes.\n */\npublic enum SecurityErrorCode {\n    INVALID_AUTHORIZATION_HEADER(1),\n    AUTHENTICATION_FAILURE(1),\n    AUTHORIZATION_FAILURE(2),\n    GENERIC_ERROR(4);\n\n    private final int code;\n\n    SecurityErrorCode(int code) {\n        this.code = code;\n    }\n\n    public int getCode() {\n        return code;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/basic/AbstractBasicAuthSecurityInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.security.basic;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\nimport java.nio.charset.Charset;\nimport java.util.Base64;\n\n/**\n * AbstractBasicAuthSecurityInterceptor hides Netty based header processing and provide authenticate() method to plug-in\n * custom authentication logic.\n *\n * @since 1.1.0\n */\npublic abstract class AbstractBasicAuthSecurityInterceptor implements RequestInterceptor {\n\n    private static final String AUTH_TYPE_BASIC = \"Basic\";\n    public static final String CHARSET_UTF_8 = \"UTF-8\";\n    private static final int AUTH_TYPE_BASIC_LENGTH = AUTH_TYPE_BASIC.length();\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        String authHeader = request.getHeader(javax.ws.rs.core.HttpHeaders.AUTHORIZATION);\n        if (authHeader != null) {\n            String authType = authHeader.substring(0, AUTH_TYPE_BASIC_LENGTH);\n            String authEncoded = authHeader.substring(AUTH_TYPE_BASIC_LENGTH).trim();\n            if (AUTH_TYPE_BASIC.equals(authType) && !authEncoded.isEmpty()) {\n                byte[] decodedByte = authEncoded.getBytes(Charset.forName(CHARSET_UTF_8));\n                String authDecoded = new String(Base64.getDecoder().decode(decodedByte),\n                        Charset.forName(CHARSET_UTF_8));\n                String[] authParts = authDecoded.split(\":\");\n                String username = authParts[0];\n                String password = authParts[1];\n                if (authenticate(username, password)) {\n                    return true;\n                }\n            }\n\n        }\n        response.setStatus(javax.ws.rs.core.Response.Status.UNAUTHORIZED.getStatusCode());\n        response.setHeader(javax.ws.rs.core.HttpHeaders.WWW_AUTHENTICATE, AUTH_TYPE_BASIC);\n        return false;\n    }\n\n    protected abstract boolean authenticate(String username, String password);\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/oauth2/IntrospectionResponse.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.security.oauth2;\n\n/**\n * Introspection response bean class.\n */\npublic final class IntrospectionResponse {\n\n    /*\n     * REQUIRED. Boolean indicator of whether or not the presented token is currently active. The specifics of a token's\n     * \"active\" state will vary depending on the implementation of the authorization server and the information it keeps\n     * about its tokens, but a \"true\" value return for the \"active\" property will generally indicate that a given token\n     * has been issued by this authorization server, has not been revoked by the resource owner, and is within its given\n     * time window of validity (e.g., after its issuance time and before its expiration time). See Section 4 for\n     * information on implementation of such checks.\n     */\n    public static final String ACTIVE = \"active\";\n\n    /*\n     * OPTIONAL. A JSON string containing a space-separated list of scopes associated with this token, in the format\n     * described in Section 3.3 of OAuth 2.0\n     */\n    public static final String SCOPE = \"scope\";\n\n    /*\n     * OPTIONAL. Client identifier for the OAuth 2.0 client that requested this token.\n     */\n    public static final String CLIENT_ID = \"client_id\";\n\n    /*\n     * OPTIONAL. Human-readable identifier for the resource owner who authorized this token.\n     */\n    public static final String USERNAME = \"username\";\n\n    /*\n     * OPTIONAL. Type of the token as defined in Section 5.1 of OAuth 2.0\n     */\n    public static final String TOKEN_TYPE = \"token_type\";\n\n    /*\n     * OPTIONAL. Integer time-stamp, measured in the number of seconds since January 1 1970 UTC, indicating when this\n     * token is not to be used before, as defined in JWT\n     */\n    public static final String NBF = \"nbf\";\n\n    /*\n     * OPTIONAL. Service-specific string identifier or list of string identifiers representing the intended audience for\n     * this token, as defined in JWT\n     */\n    public static final String AUD = \"aud\";\n\n    /*\n     * OPTIONAL. String representing the issuer of this token, as defined in JWT\n     */\n    public static final String ISS = \"iss\";\n\n    /*\n     * OPTIONAL. String identifier for the token, as defined in JWT\n     */\n    public static final String JTI = \"jti\";\n\n    /*\n     * OPTIONAL. Subject of the token, as defined in JWT [RFC7519]. Usually a machine-readable identifier of the\n     * resource owner who authorized this token.\n     */\n    public static final String SUB = \"sub\";\n\n    /*\n     * OPTIONAL. Integer time-stamp, measured in the number of seconds since January 1 1970 UTC, indicating when this\n     * token will expire, as defined in JWT\n     */\n    public static final String EXP = \"exp\";\n\n    /*\n     * OPTIONAL. Integer time-stamp, measured in the number of seconds since January 1 1970 UTC, indicating when this\n     * token was originally issued, as defined in JWT\n     */\n    public static final String IAT = \"iat\";\n\n\n    /*\n     * The request is missing a required parameter, includes an unsupported parameter value (other than grant type),\n     * repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the\n     * client, or is otherwise malformed.\n     */\n    public static final String INVALID_REQUEST = \"invalid_request\";\n\n    /*\n     * A single ASCII [USASCII] error code\n     */\n    public static final String ERROR = \"error\";\n\n    /*\n     * Human-readable ASCII [USASCII] text providing additional information, used to assist the client developer in\n     * understanding the error that occurred.\n     */\n    public static final String ERROR_DESCRIPTION = \"error_description\";\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/security/oauth2/OAuth2SecurityInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.security.oauth2;\n\nimport com.google.gson.Gson;\nimport com.google.gson.reflect.TypeToken;\nimport org.apache.commons.io.Charsets;\nimport org.apache.commons.io.IOUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.security.MSF4JSecurityException;\nimport org.wso2.msf4j.security.SecurityErrorCode;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport java.lang.reflect.Type;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.Locale;\nimport java.util.Map;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.core.HttpHeaders;\n\n/**\n * Act as a security gateway for resources secured with Oauth2.\n * <p>\n * Verify Oauth2 access token in Authorization Bearer HTTP header and allow access to the resource accordingly.\n *\n * @since 1.0.0\n */\npublic class OAuth2SecurityInterceptor implements RequestInterceptor {\n    private static final Logger log = LoggerFactory.getLogger(OAuth2SecurityInterceptor.class);\n\n    private static final String AUTHORIZATION_HTTP_HEADER = \"Authorization\";\n    private static final String AUTH_TYPE_OAUTH2 = \"OAuth2\";\n    private static final String BEARER_PREFIX = \"bearer\";\n    private static final String AUTH_SERVER_URL_KEY = \"AUTH_SERVER_URL\";\n    private static final String AUTH_SERVER_URL;\n    private static final String TRUST_STORE = \"TRUST_STORE\";\n    private static final String TRUST_STORE_PASSWORD = \"TRUST_STORE_PASSWORD\";\n\n    static {\n        AUTH_SERVER_URL = SystemVariableUtil.getValue(AUTH_SERVER_URL_KEY, null);\n        if (AUTH_SERVER_URL == null) {\n            throw new RuntimeException(AUTH_SERVER_URL_KEY + \" is not specified.\");\n        }\n        String trustStore = SystemVariableUtil.getValue(TRUST_STORE, null);\n        String trustStorePassword = SystemVariableUtil.getValue(TRUST_STORE_PASSWORD, null);\n        if (trustStore != null && !trustStore.isEmpty() &&\n                trustStorePassword != null && !trustStorePassword.isEmpty()) {\n            System.setProperty(\"javax.net.ssl.trustStore\", trustStore);\n            System.setProperty(\"javax.net.ssl.trustStorePassword\", trustStorePassword);\n        }\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        SecurityErrorCode errorCode;\n\n        try {\n            HttpHeaders headers = request.getHeaders();\n            String authHeader = headers.getHeaderString(AUTHORIZATION_HTTP_HEADER);\n            if (authHeader != null && !authHeader.isEmpty()) {\n                return validateToken(authHeader);\n            } else {\n                throw new MSF4JSecurityException(SecurityErrorCode.AUTHENTICATION_FAILURE,\n                        \"Missing Authorization header is the request.`\");\n            }\n        } catch (MSF4JSecurityException e) {\n            errorCode = e.getErrorCode();\n            log.error(e.getMessage() + \" Requested Path: \" + request.getUri());\n        }\n\n        handleSecurityError(errorCode, response);\n        return false;\n    }\n\n    /**\n     * Extract the accessToken from the give Authorization header value and validates the accessToken\n     * with an external key manager.\n     *\n     * @param authHeader Authorization Bearer header which contains the access token\n     * @return true if the token is a valid token\n     */\n    private boolean validateToken(String authHeader) throws MSF4JSecurityException {\n        // 1. Check whether this token is bearer token, if not return false\n        String accessToken = extractAccessToken(authHeader);\n\n        // 2. Send a request to key server's introspect endpoint to validate this token\n        String responseStr = getValidatedTokenResponse(accessToken);\n        Map<String, String> responseData = getResponseDataMap(responseStr);\n\n        //TODO handle NPE\n\n        // 3. Process the response and return true if the token is valid.\n        if (!Boolean.parseBoolean(responseData.get(IntrospectionResponse.ACTIVE))) {\n            throw new MSF4JSecurityException(SecurityErrorCode.AUTHENTICATION_FAILURE,\n                    \"Invalid Access token.\");\n        }\n\n        return true;\n    }\n\n    /**\n     * @param authHeader Authorization Bearer header which contains the access token\n     * @return access token\n     */\n    private String extractAccessToken(String authHeader) throws MSF4JSecurityException {\n        authHeader = authHeader.trim();\n        if (authHeader.toLowerCase(Locale.US).startsWith(BEARER_PREFIX)) {\n            // Split the auth header to get the access token.\n            // Value should be in this format (\"Bearer\" 1*SP b64token)\n            String[] authHeaderParts = authHeader.split(\" \");\n            if (authHeaderParts.length == 2) {\n                return authHeaderParts[1];\n            }\n        }\n\n        throw new MSF4JSecurityException(SecurityErrorCode.INVALID_AUTHORIZATION_HEADER,\n                \"Invalid Authorization header: \" + authHeader);\n    }\n\n    /**\n     * Validated the given accessToken with an external key server.\n     *\n     * @param accessToken AccessToken to be validated.\n     * @return the response from the key manager server.\n     */\n    private String getValidatedTokenResponse(String accessToken) throws MSF4JSecurityException {\n        URL url;\n        try {\n            url = new URL(AUTH_SERVER_URL);\n            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n            urlConn.setDoOutput(true);\n            urlConn.setRequestMethod(HttpMethod.POST);\n            urlConn.getOutputStream()\n                   .write((\"token=\" + accessToken + \"&token_type_hint=\" + BEARER_PREFIX).getBytes(Charsets.UTF_8));\n            return new String(IOUtils.toByteArray(urlConn.getInputStream()), Charsets.UTF_8);\n        } catch (java.io.IOException e) {\n            log.error(\"Error invoking Authorization Server\", e);\n            throw new MSF4JSecurityException(SecurityErrorCode.GENERIC_ERROR, \"Error invoking Authorization Server\", e);\n        }\n    }\n\n    /**\n     * @param responseStr validated token response string returned from the key server.\n     * @return a Map of key, value pairs available the response String.\n     */\n    private Map<String, String> getResponseDataMap(String responseStr) {\n        Gson gson = new Gson();\n        Type typeOfMapOfStrings = new ExtendedTypeToken<Map<String, String>>() {\n        }.getType();\n        return gson.fromJson(responseStr, typeOfMapOfStrings);\n    }\n\n    /**\n     * This class extends the {@link TypeToken}.\n     * Created due to the findbug issue when passing anonymous inner class.\n     *\n     * @param <T> Generic type\n     */\n    private static class ExtendedTypeToken<T> extends TypeToken {\n    }\n\n    /**\n     * @param errorCode Security error code\n     * @param responder HttpResponder instance which is used send error messages back to the client\n     */\n    private void handleSecurityError(SecurityErrorCode errorCode, Response responder)\n            throws Exception {\n        if (errorCode == SecurityErrorCode.AUTHENTICATION_FAILURE ||\n                errorCode == SecurityErrorCode.INVALID_AUTHORIZATION_HEADER) {\n            responder.setStatus(javax.ws.rs.core.Response.Status.UNAUTHORIZED.getStatusCode());\n            responder.setHeader(javax.ws.rs.core.HttpHeaders.WWW_AUTHENTICATE, AUTH_TYPE_OAUTH2);\n        } else if (errorCode == SecurityErrorCode.AUTHORIZATION_FAILURE) {\n            responder.setStatus(javax.ws.rs.core.Response.Status.FORBIDDEN.getStatusCode());\n        } else {\n            responder.setStatus(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/template/RuntimeTemplateException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.template;\n\n/**\n * This runtime exception will be thrown if a runtime\n * error is occurred while processing a template.\n */\npublic class RuntimeTemplateException extends RuntimeException {\n\n    public RuntimeTemplateException() {\n        super();\n    }\n\n    public RuntimeTemplateException(Exception cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/template/TemplateEngine.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.template;\n\n/**\n * MSF4J template engines should implement this interface.\n */\npublic interface TemplateEngine {\n\n    /**\n     * Renders the given model using the given template.\n     *\n     * @param view  name of the template file in resources/templates directory\n     * @param model model to be rendered from the template\n     * @return rendered template\n     */\n    String render(String view, Object model);\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/BufferUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.util;\n\nimport java.nio.Buffer;\nimport java.nio.ByteBuffer;\nimport java.util.List;\n\n/**\n * Utility methods for buffer operations.\n */\npublic class BufferUtil {\n\n    /**\n     * Merge a list of buffers into a single buffer.\n     *\n     * @param byteBuffers list of ByteBuffer objects\n     * @return merged ByteBuffer\n     */\n    public static ByteBuffer merge(List<ByteBuffer> byteBuffers) {\n        if (byteBuffers == null || byteBuffers.size() == 0) {\n            return ByteBuffer.allocate(0);\n        } else if (byteBuffers.size() == 1) {\n            return byteBuffers.get(0);\n        } else {\n            ByteBuffer fullContent = ByteBuffer.allocate(\n                    byteBuffers.stream()\n                            .mapToInt(Buffer::capacity)\n                            .sum()\n            );\n            byteBuffers.forEach(fullContent::put);\n            fullContent.flip();\n            return fullContent;\n        }\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/Defaults.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.util;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.annotation.Nullable;\n\n/**\n * This class represents default values of primitive data types.\n */\npublic class Defaults {\n    private Defaults() {\n    }\n\n    private static final Map<Class<?>, Object> DEFAULTS = new HashMap<>(8);\n\n    static {\n        // Only add to this map via put(Map, Class<T>, T)\n        DEFAULTS.put(boolean.class, false);\n        DEFAULTS.put(char.class, '\\0');\n        DEFAULTS.put(byte.class, (byte) 0);\n        DEFAULTS.put(short.class, (short) 0);\n        DEFAULTS.put(int.class, 0);\n        DEFAULTS.put(long.class, 0L);\n        DEFAULTS.put(float.class, 0f);\n        DEFAULTS.put(double.class, 0d);\n    }\n\n    /**\n     * Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code\n     * false} for {@code boolean} and {@code '\\0'} for {@code char}. For non-primitive types and\n     * {@code void}, {@code null} is returned.\n     *\n     * @param type class of the value.\n     * @return default value of given class.\n     */\n    @Nullable\n    public static <T> T defaultValue(Class<T> type) {\n        // Primitives.wrap(type).cast(...) would avoid the warning, but we can't use that from here\n        @SuppressWarnings(\"unchecked\") // the put method enforces this key-value relationship\n                T t = (T) DEFAULTS.get(Objects.requireNonNull(type));\n        return t;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/HttpUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.util;\n\nimport io.netty.buffer.Unpooled;\nimport io.netty.handler.codec.http.DefaultHttpResponse;\nimport io.netty.handler.codec.http.DefaultLastHttpContent;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport io.netty.handler.codec.http.HttpResponseStatus;\nimport io.netty.handler.codec.http.HttpVersion;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.io.UnsupportedEncodingException;\nimport java.nio.ByteBuffer;\nimport javax.ws.rs.core.HttpHeaders;\n\n/**\n * Utility methods related to HTTP.\n */\npublic class HttpUtil {\n\n    public static final String EMPTY_BODY = \"\";\n    public static final String CLOSE = \"close\";\n    public static final String KEEP_ALIVE = \"keep-alive\";\n\n    /**\n     * Create a CarbonMessage for a specific status code.\n     *\n     * @param status HTTP status code\n     * @param msg message text\n     * @return CarbonMessage representing the status\n     */\n    public static HttpCarbonMessage createTextResponse(int status, String msg) {\n        HttpCarbonMessage response = new HttpCarbonMessage(\n                new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(status)));\n        response.setHttpStatusCode(status);\n        if (msg != null) {\n            response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(msg.length()));\n            byte[] msgArray = null;\n            try {\n                msgArray = msg.getBytes(\"UTF-8\");\n            } catch (UnsupportedEncodingException e) {\n                throw new RuntimeException(\"Failed to get the byte array from responseValue\", e);\n            }\n            ByteBuffer byteBuffer = ByteBuffer.allocate(msgArray.length);\n            byteBuffer.put(msgArray);\n            byteBuffer.flip();\n            response.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(byteBuffer)));\n        } else {\n            response.setHeader(HttpHeaders.CONTENT_LENGTH, \"0\");\n        }\n        return response;\n    }\n\n    /**\n     * Set connection header of the response object according to the\n     * connection header of the request.\n     *\n     * @param request  HTTP request object\n     * @param response HTTP response object\n     */\n    public static void setConnectionHeader(Request request, Response response) {\n        String connection = request.getHeader(HttpHeaderNames.CONNECTION.toString());\n        if (connection != null && CLOSE.equalsIgnoreCase(connection)) {\n            response.setHeader(HttpHeaderNames.CONNECTION.toString(), CLOSE);\n        } else {\n            response.setHeader(HttpHeaderNames.CONNECTION.toString(), KEEP_ALIVE);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/Primitives.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.util;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\n\n/**\n * Contains static utility methods pertaining to primitive types and their corresponding wrapper\n * types.\n *\n */\npublic final class Primitives {\n    private Primitives() {\n    }\n\n    /**\n     * A map from primitive types to their corresponding wrapper types.\n     */\n    private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;\n\n    /**\n     * A map from wrapper types to their corresponding primitive types.\n     */\n    private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;\n\n    // Sad that we can't use a BiMap. :(\n\n    static {\n        Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);\n        Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);\n\n        add(primToWrap, wrapToPrim, boolean.class, Boolean.class);\n        add(primToWrap, wrapToPrim, byte.class, Byte.class);\n        add(primToWrap, wrapToPrim, char.class, Character.class);\n        add(primToWrap, wrapToPrim, double.class, Double.class);\n        add(primToWrap, wrapToPrim, float.class, Float.class);\n        add(primToWrap, wrapToPrim, int.class, Integer.class);\n        add(primToWrap, wrapToPrim, long.class, Long.class);\n        add(primToWrap, wrapToPrim, short.class, Short.class);\n        add(primToWrap, wrapToPrim, void.class, Void.class);\n\n        PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);\n        WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);\n    }\n\n    private static void add(Map<Class<?>, Class<?>> forward, Map<Class<?>, Class<?>> backward, Class<?> key,\n                            Class<?> value) {\n        forward.put(key, value);\n        backward.put(value, key);\n    }\n\n    /**\n     * Returns an immutable set of all nine primitive types (including {@code\n     * void}). Note that a simpler way to test whether a {@code Class} instance is a member of this\n     * set is to call {@link Class#isPrimitive}.\n     *\n     */\n    public static Set<Class<?>> allPrimitiveTypes() {\n        return PRIMITIVE_TO_WRAPPER_TYPE.keySet();\n    }\n\n    /**\n     * Returns an immutable set of all nine primitive-wrapper types (including {@link Void}).\n     *\n     */\n    public static Set<Class<?>> allWrapperTypes() {\n        return WRAPPER_TO_PRIMITIVE_TYPE.keySet();\n    }\n\n    /**\n     * Returns {@code true} if {@code type} is one of the nine primitive-wrapper types, such as\n     * {@link Integer}.\n     *\n     * @see Class#isPrimitive\n     */\n    public static boolean isWrapperType(Class<?> type) {\n        Objects.requireNonNull(type);\n        return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(type);\n    }\n\n    /**\n     * Returns the corresponding wrapper type of {@code type} if it is a primitive type; otherwise\n     * returns {@code type} itself. Idempotent.\n     * <p>\n     * <pre>\n     *     wrap(int.class) == Integer.class\n     *     wrap(Integer.class) == Integer.class\n     *     wrap(String.class) == String.class\n     * </pre>\n     */\n    public static <T> Class<T> wrap(Class<T> type) {\n        Objects.requireNonNull(type);\n        // cast is safe: long.class and Long.class are both of type Class<Long>\n        @SuppressWarnings(\"unchecked\") Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);\n        return (wrapped == null) ? type : wrapped;\n    }\n\n    /**\n     * Returns the corresponding primitive type of {@code type} if it is a wrapper type; otherwise\n     * returns {@code type} itself. Idempotent.\n     * <p>\n     * <pre>\n     *     unwrap(Integer.class) == int.class\n     *     unwrap(int.class) == int.class\n     *     unwrap(String.class) == String.class\n     * </pre>\n     */\n    public static <T> Class<T> unwrap(Class<T> type) {\n        Objects.requireNonNull(type);\n        // cast is safe: long.class and Long.class are both of type Class<Long>\n        @SuppressWarnings(\"unchecked\") Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);\n        return (unwrapped == null) ? type : unwrapped;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/QueryStringDecoderUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.util;\n\nimport java.net.URI;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Splits an HTTP query string into a path string and key-value parameter pairs.\n * This decoder is for one time use only.  Create a new instance for each URI:\n * <pre>\n * {@link QueryStringDecoderUtil} decoder = new {@link QueryStringDecoderUtil}(\"/hello?recipient=world&x=1;y=2\");\n * assert decoder.path().equals(\"/hello\");\n * assert decoder.parameters().get(\"recipient\").get(0).equals(\"world\");\n * assert decoder.parameters().get(\"x\").get(0).equals(\"1\");\n * assert decoder.parameters().get(\"y\").get(0).equals(\"2\");\n * </pre>\n * <p>\n * This decoder can also decode the content of an HTTP POST request whose\n * content type is <tt>application/x-www-form-urlencoded</tt>:\n * <pre>\n * {@link QueryStringDecoderUtil} decoder = new {@link QueryStringDecoderUtil}(\"recipient=world&x=1;y=2\", false);\n * ...\n * </pre>\n *\n * <h3>HashDOS vulnerability fix</h3>\n *\n * As a workaround to the <a href=\"http://netty.io/s/hashdos\">HashDOS</a> vulnerability, the decoder\n * limits the maximum number of decoded key-value parameter pairs, up to {@literal 1024} by\n * default, and you can configure it when you construct the decoder by passing an additional\n * integer parameter.\n */\npublic class QueryStringDecoderUtil {\n\n    private static final int DEFAULT_MAX_PARAMS = 1024;\n\n    private final Charset charset;\n    private final String uri;\n    private final boolean hasPath;\n    private final int maxParams;\n    private String path;\n    private Map<String, List<String>> params;\n    private int nParams;\n\n    /**\n     * Creates a new decoder that decodes the specified URI. The decoder will\n     * assume that the query string is encoded in UTF-8.\n     *\n     * @param uri object to be decoded\n     */\n    public QueryStringDecoderUtil(String uri) {\n        this(uri, Charset.defaultCharset());\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param hasPath whether uri contains path\n     */\n    public QueryStringDecoderUtil(String uri, boolean hasPath) {\n        this(uri, Charset.defaultCharset(), hasPath);\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param charset encoded charset\n     */\n    public QueryStringDecoderUtil(String uri, Charset charset) {\n        this(uri, charset, true);\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param charset encoded charset\n     * @param hasPath whether uri contains path\n     */\n    public QueryStringDecoderUtil(String uri, Charset charset, boolean hasPath) {\n        this(uri, charset, hasPath, DEFAULT_MAX_PARAMS);\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param charset encoded charset\n     * @param hasPath whether uri contains path\n     * @param maxParams maximum no of parameters to decode\n     */\n    public QueryStringDecoderUtil(String uri, Charset charset, boolean hasPath, int maxParams) {\n        if (uri == null) {\n            throw new NullPointerException(\"getUri\");\n        }\n        if (charset == null) {\n            throw new NullPointerException(\"charset\");\n        }\n        if (maxParams <= 0) {\n            throw new IllegalArgumentException(\n                    \"maxParams: \" + maxParams + \" (expected: a positive integer)\");\n        }\n\n        this.uri = uri;\n        this.charset = charset;\n        this.maxParams = maxParams;\n        this.hasPath = hasPath;\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI. The decoder will\n     * assume that the query string is encoded in UTF-8.\n     *\n     * @param uri object to be decoded\n     */\n    public QueryStringDecoderUtil(URI uri) {\n        this(uri, Charset.defaultCharset());\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param charset encoded charset\n     */\n    public QueryStringDecoderUtil(URI uri, Charset charset) {\n        this(uri, charset, DEFAULT_MAX_PARAMS);\n    }\n\n    /**\n     * Creates a new decoder that decodes the specified URI encoded in the\n     * specified charset.\n     *\n     * @param uri object to be decoded\n     * @param charset encoded charset\n     * @param maxParams maximum no of parameters to decode\n     */\n    public QueryStringDecoderUtil(URI uri, Charset charset, int maxParams) {\n        if (uri == null) {\n            throw new NullPointerException(\"getUri\");\n        }\n        if (charset == null) {\n            throw new NullPointerException(\"charset\");\n        }\n        if (maxParams <= 0) {\n            throw new IllegalArgumentException(\n                    \"maxParams: \" + maxParams + \" (expected: a positive integer)\");\n        }\n\n        String rawPath = uri.getRawPath();\n        if (rawPath != null) {\n            hasPath = true;\n        } else {\n            rawPath = \"\";\n            hasPath = false;\n        }\n        // Also take care of cut of things like \"http://localhost\"\n        this.uri = rawPath + (uri.getRawQuery() == null ? \"\" : '?' + uri.getRawQuery());\n\n        this.charset = charset;\n        this.maxParams = maxParams;\n    }\n\n    /**\n     * Returns the uri used to initialize this {@link QueryStringDecoderUtil}.\n     *\n     * @return uri object that initialize decoder\n     */\n    public String uri() {\n        return uri;\n    }\n\n    /**\n     * Returns the decoded path string of the URI.\n     *\n     * @return decoded path string\n     */\n    public String path() {\n        if (path == null) {\n            if (!hasPath) {\n                return path = \"\";\n            }\n\n            int pathEndPos = uri.indexOf('?');\n            if (pathEndPos < 0) {\n                path = uri;\n            } else {\n                return path = uri.substring(0, pathEndPos);\n            }\n        }\n        return path;\n    }\n\n    /**\n     * Returns the decoded key-value parameter pairs of the URI.\n     *\n     * @return the decoded key-value parameter pairs of the URI\n     */\n    public Map<String, List<String>> parameters() {\n        if (params == null) {\n            if (hasPath) {\n                int pathLength = path().length();\n                if (uri.length() == pathLength) {\n                    return Collections.emptyMap();\n                }\n                decodeParams(uri.substring(pathLength + 1));\n            } else {\n                if (uri.isEmpty()) {\n                    return Collections.emptyMap();\n                }\n                decodeParams(uri);\n            }\n        }\n        return params;\n    }\n\n    private void decodeParams(String s) {\n        Map<String, List<String>> params = this.params = new LinkedHashMap<>();\n        nParams = 0;\n        String name = null;\n        int pos = 0; // Beginning of the unprocessed region\n        int i;       // End of the unprocessed region\n        char c;  // Current character\n        for (i = 0; i < s.length(); i++) {\n            c = s.charAt(i);\n            if (c == '=' && name == null) {\n                if (pos != i) {\n                    name = decodeComponent(s.substring(pos, i), charset);\n                }\n                pos = i + 1;\n                // http://www.w3.org/TR/html401/appendix/notes.html#h-B.2.2\n            } else if (c == '&' || c == ';') {\n                if (name == null && pos != i) {\n                    // We haven't seen an `=' so far but moved forward.\n                    // Must be a param of the form '&a&' so add it with\n                    // an empty value.\n                    if (!addParam(params, decodeComponent(s.substring(pos, i), charset), \"\")) {\n                        return;\n                    }\n                } else if (name != null) {\n                    if (!addParam(params, name, decodeComponent(s.substring(pos, i), charset))) {\n                        return;\n                    }\n                    name = null;\n                }\n                pos = i + 1;\n            }\n        }\n\n        if (pos != i) {  // Are there characters we haven't dealt with?\n            if (name == null) {     // Yes and we haven't seen any `='.\n                addParam(params, decodeComponent(s.substring(pos, i), charset), \"\");\n            } else {                // Yes and this must be the last value.\n                addParam(params, name, decodeComponent(s.substring(pos, i), charset));\n            }\n        } else if (name != null) {  // Have we seen a name without value?\n            addParam(params, name, \"\");\n        }\n    }\n\n    private boolean addParam(Map<String, List<String>> params, String name, String value) {\n        if (nParams >= maxParams) {\n            return false;\n        }\n\n        List<String> values = params.get(name);\n        if (values == null) {\n            values = new ArrayList<>(1);  // Often there's only 1 value.\n            params.put(name, values);\n        }\n        values.add(value);\n        nParams++;\n        return true;\n    }\n\n    /**\n     * Decodes a bit of an URL encoded by a browser.\n     * <p>\n     * This is equivalent to calling {@link #decodeComponent(String, Charset)}\n     * with the UTF-8 charset (recommended to comply with RFC 3986, Section 2).\n     *\n     * @param s The string to decode (can be empty).\n     * @return The decoded string, or {@code s} if there's nothing to decode.\n     * If the string to decode is {@code null}, returns an empty string.\n     * @throws IllegalArgumentException if the string contains a malformed\n     *                                  escape sequence.\n     */\n    public static String decodeComponent(final String s) {\n        return decodeComponent(s, Charset.forName(\"UTF-8\"));\n    }\n\n    /**\n     * Decodes a bit of an URL encoded by a browser.\n     * <p>\n     * The string is expected to be encoded as per RFC 3986, Section 2.\n     * This is the encoding used by JavaScript functions {@code encodeURI}\n     * and {@code encodeURIComponent}, but not {@code escape}.  For example\n     * in this encoding, &eacute; (in Unicode {@code U+00E9} or in UTF-8\n     * {@code 0xC3 0xA9}) is encoded as {@code %C3%A9} or {@code %c3%a9}.\n     * <p>\n     * This is essentially equivalent to calling\n     * URLDecoder.decode(s, charset.name())\n     * except that it's over 2x faster and generates less garbage for the GC.\n     * Actually this function doesn't allocate any memory if there's nothing\n     * to decode, the argument itself is returned.\n     *\n     * @param s       The string to decode (can be empty).\n     * @param charset The charset to use to decode the string\n     * @return The decoded string, or {@code s} if there's nothing to decode.\n     * If the string to decode is {@code null}, returns an empty string.\n     * @throws IllegalArgumentException if the string contains a malformed\n     *                                  escape sequence.\n     */\n    public static String decodeComponent(final String s, final Charset charset) {\n        if (s == null) {\n            return \"\";\n        }\n        final int size = s.length();\n        boolean modified = false;\n        for (int i = 0; i < size; i++) {\n            final char c = s.charAt(i);\n            if (c == '%' || c == '+') {\n                modified = true;\n                break;\n            }\n        }\n        if (!modified) {\n            return s;\n        }\n        final byte[] buf = new byte[size];\n        int pos = 0;  // position in `buf'.\n        for (int i = 0; i < size; i++) {\n            char c = s.charAt(i);\n            switch (c) {\n                case '+':\n                    buf[pos++] = ' ';  // \"+\" -> \" \"\n                    break;\n                case '%':\n                    if (i == size - 1) {\n                        throw new IllegalArgumentException(\"unterminated escape\"\n                                + \" sequence at end of string: \" + s);\n                    }\n                    c = s.charAt(++i);\n                    if (c == '%') {\n                        buf[pos++] = '%';  // \"%%\" -> \"%\"\n                        break;\n                    }\n                    if (i == size - 1) {\n                        throw new IllegalArgumentException(\"partial escape\"\n                                + \" sequence at end of string: \" + s);\n                    }\n                    c = decodeHexNibble(c);\n                    final char c2 = decodeHexNibble(s.charAt(++i));\n                    if (c == Character.MAX_VALUE || c2 == Character.MAX_VALUE) {\n                        throw new IllegalArgumentException(\n                                \"invalid escape sequence `%\" + s.charAt(i - 1)\n                                        + s.charAt(i) + \"' at index \" + (i - 2)\n                                        + \" of: \" + s);\n                    }\n                    c = (char) (c * 16 + c2);\n                    // Fall through.\n                default:\n                    buf[pos++] = (byte) c;\n                    break;\n            }\n        }\n        return new String(buf, 0, pos, charset);\n    }\n\n    /**\n     * Helper to decode half of a hexadecimal number from a string.\n     *\n     * @param c The ASCII character of the hexadecimal number to decode.\n     *          Must be in the range {@code [0-9a-fA-F]}.\n     * @return The hexadecimal value represented in the ASCII character\n     * given, or {@link Character#MAX_VALUE} if the character is invalid.\n     */\n    private static char decodeHexNibble(final char c) {\n        if ('0' <= c && c <= '9') {\n            return (char) (c - '0');\n        } else if ('a' <= c && c <= 'f') {\n            return (char) (c - 'a' + 10);\n        } else if ('A' <= c && c <= 'F') {\n            return (char) (c - 'A' + 10);\n        } else {\n            return Character.MAX_VALUE;\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/ReflectionUtils.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.util;\n\nimport org.osgi.framework.Bundle;\nimport org.osgi.framework.FrameworkUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Optional;\n\n/**\n * Util class to do java reflection related activities.\n */\npublic class ReflectionUtils {\n\n    private static final Logger log = LoggerFactory.getLogger(ReflectionUtils.class);\n\n    private ReflectionUtils() {\n    }\n\n    /**\n     * Create a new instance for a given type.\n     *\n     * @param clazz                     type of the expected instance\n     * @param constructorParameterTypes the parameter array\n     * @param constructorArguments      array of objects to be passed as arguments to the constructor call\n     * @param <T>                       Type of the object to be created\n     * @return Object of type T\n     * @throws NoSuchMethodException     when the specified constructor is not available\n     * @throws IllegalAccessException    when the constructor is not visible\n     * @throws InvocationTargetException when invocation target exception\n     * @throws InstantiationException    when error on object creation\n     */\n    public static <T> T createInstanceFromClass(Class<T> clazz, Class<?>[] constructorParameterTypes,\n                                                Object... constructorArguments)\n            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {\n        Constructor<T> constructor = clazz.getConstructor(constructorParameterTypes);\n        return constructor.newInstance(constructorArguments);\n    }\n\n    /**\n     * Load class from bundle (find class from the bundles).\n     * If there is no bundle with the specific class or loading the class from bundle fails, this method\n     * will return Optional.empty()\n     * This method is only sensible to be used in the OSGi environment\n     *\n     * @param clazz class to load\n     * @param <T>   type of the class\n     * @return Optional loaded class\n     */\n    @SuppressWarnings(\"unchecked\")\n    public static <T> Optional<Class<? extends T>> loadClassFromBundle(Class<? extends T> clazz) {\n        String className = clazz.getName();\n        Bundle bundle = FrameworkUtil.getBundle(clazz);\n        if (bundle != null) {\n            try {\n                return Optional.of((Class<? extends T>) bundle.loadClass(className));\n            } catch (ClassNotFoundException e) {\n                log.error(\"Class \" + className + \" do not exist in any bundle\", e);\n            }\n        }\n        return Optional.empty();\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/RuntimeAnnotations.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.util;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.security.AccessController;\nimport java.security.PrivilegedAction;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * Utility class used to change the class annotation at runtime.\n * This class will be removed in future release. Since some of the classes that being used here might cause\n * issues in different JDKs.\n */\n@Deprecated\npublic final class RuntimeAnnotations {\n\n    private static final Constructor<?> annotationInvocationHandlerConstructor;\n    private static final Constructor<?> annotationDataConstructor;\n    private static final Method classAnnotationData;\n    private static final Field classClassRedefinedCount;\n    private static final Field annotationDataAnnotations;\n    private static final Field annotationDataDeclaredAnotations;\n    private static final Method atomicClassAnnotationData;\n    private static final Class<?> atomicClass;\n\n    static {\n        // static initialization of necessary reflection Objects\n        try {\n            Class<?> annotationInvocationHandlerClass =\n                    Class.forName(\"sun.reflect.annotation.AnnotationInvocationHandler\");\n            annotationInvocationHandlerConstructor =\n                    annotationInvocationHandlerClass.getDeclaredConstructor(new Class[] { Class.class, Map.class });\n            annotationInvocationHandlerConstructor.setAccessible(true);\n\n            atomicClass = Class.forName(\"java.lang.Class$Atomic\");\n            Class<?> annotationDataClass = Class.forName(\"java.lang.Class$AnnotationData\");\n\n            annotationDataConstructor =\n                    annotationDataClass.getDeclaredConstructor(new Class[] { Map.class, Map.class, int.class });\n            annotationDataConstructor.setAccessible(true);\n            classAnnotationData = Class.class.getDeclaredMethod(\"annotationData\");\n            AccessController.doPrivileged(new PrivilegedAction<Object>() {\n                @Override\n                public Object run() {\n                    classAnnotationData.setAccessible(true);\n                    return null;\n                }\n            });\n\n            classClassRedefinedCount = Class.class.getDeclaredField(\"classRedefinedCount\");\n\n            AccessController.doPrivileged(new PrivilegedAction<Object>() {\n                @Override\n                public Void run() {\n                    classClassRedefinedCount.setAccessible(true);\n                    return null;\n                }\n            });\n\n            annotationDataAnnotations = annotationDataClass.getDeclaredField(\"annotations\");\n            AccessController.doPrivileged(new PrivilegedAction<Object>() {\n                @Override\n                public Object run() {\n                    annotationDataAnnotations.setAccessible(true);\n                    return null;\n                }\n            });\n            annotationDataDeclaredAnotations = annotationDataClass.getDeclaredField(\"declaredAnnotations\");\n            AccessController.doPrivileged(new PrivilegedAction<Object>() {\n                @Override\n                public Object run() {\n                    annotationDataDeclaredAnotations.setAccessible(true);\n                    return null;\n                }\n            });\n            atomicClassAnnotationData = atomicClass\n                    .getDeclaredMethod(\"casAnnotationData\", Class.class, annotationDataClass, annotationDataClass);\n            AccessController.doPrivileged(new PrivilegedAction<Object>() {\n                @Override\n                public Object run() {\n                    atomicClassAnnotationData.setAccessible(true);\n                    return null;\n                }\n            });\n\n        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | NoSuchFieldException e) {\n            throw new IllegalStateException(e);\n        }\n    }\n\n    /**\n     * Change the given annotation of the given class.\n     *\n     * @param clazz Class need to be change\n     * @param annotationClass Annotation class that need to change\n     * @param valuesMap value map to set\n     * @param <T> Annotation that get change\n     */\n    public static <T extends Annotation> void putAnnotation(Class<?> clazz, Class<T> annotationClass,\n                                                            Map<String, Object> valuesMap) {\n        putAnnotation(clazz, annotationClass, annotationForMap(annotationClass, valuesMap));\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static <T extends Annotation> void putAnnotation(Class<?> c, Class<T> annotationClass, T annotation) {\n        try {\n            while (true) { // retry loop\n                int classRedefinedCount = classClassRedefinedCount.getInt(c);\n                Object annotationData = classAnnotationData.invoke(c);\n                // null or stale annotationData -> optimistically create new instance\n                Object newAnnotationData =\n                        createAnnotationData(c, annotationData, annotationClass, annotation, classRedefinedCount);\n                // try to install it\n                if ((boolean) atomicClassAnnotationData.invoke(atomicClass, c, annotationData, newAnnotationData)) {\n                    // successfully installed new AnnotationData\n                    break;\n                }\n            }\n        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException\n                | InstantiationException e) {\n            throw new IllegalStateException(e);\n        }\n\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static <T extends Annotation> Object createAnnotationData(Class<?> c, Object annotationData,\n                                                                      Class<T> annotationClass, T annotation,\n                                                                      int classRedefinedCount)\n            throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        Map<Class<? extends Annotation>, Annotation> annotations =\n                (Map<Class<? extends Annotation>, Annotation>) annotationDataAnnotations.get(annotationData);\n        Map<Class<? extends Annotation>, Annotation> declaredAnnotations =\n                (Map<Class<? extends Annotation>, Annotation>) annotationDataDeclaredAnotations.get(annotationData);\n\n        Map<Class<? extends Annotation>, Annotation> newDeclaredAnnotations = new LinkedHashMap<>(annotations);\n        newDeclaredAnnotations.put(annotationClass, annotation);\n        Map<Class<? extends Annotation>, Annotation> newAnnotations;\n        if (declaredAnnotations == annotations) {\n            newAnnotations = newDeclaredAnnotations;\n        } else {\n            newAnnotations = new LinkedHashMap<>(annotations);\n            newAnnotations.put(annotationClass, annotation);\n        }\n        return annotationDataConstructor.newInstance(newAnnotations, newDeclaredAnnotations, classRedefinedCount);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static <T extends Annotation> T annotationForMap(final Class<T> annotationClass,\n                                                            final Map<String, Object> valuesMap) {\n        return (T) AccessController.doPrivileged(new PrivilegedAction<Annotation>() {\n            public Annotation run() {\n                InvocationHandler handler;\n                try {\n                    handler = (InvocationHandler) annotationInvocationHandlerConstructor\n                            .newInstance(annotationClass, new HashMap<>(valuesMap));\n                } catch (InstantiationException | IllegalAccessException\n                        | IllegalArgumentException | InvocationTargetException e) {\n                    throw new IllegalStateException(e);\n                }\n                return (Annotation) Proxy\n                        .newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass }, handler);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/SystemVariableUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.util;\n\n\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.stream.Collectors;\n\n/**\n * A utility which allows reading variables from the environment or System properties.\n * If the variable in available in the environment as well as a System property, the System property takes\n * precedence.\n */\npublic class SystemVariableUtil {\n\n    private static final String CUSTOM_VAR_PREFIX = \"CUSTOM_\";\n\n    public static String getValue(String variableName, String defaultValue) {\n        String value;\n        if (System.getProperty(variableName) != null) {\n            value = System.getProperty(variableName);\n        } else if (System.getenv(variableName) != null) {\n            value = System.getenv(variableName);\n        } else {\n            value = defaultValue;\n        }\n        return value;\n    }\n\n    public static Map<String, String> getArbitraryAttributes() {\n\n        Map<String, String> arbitraryAttributes;\n\n        Map<String, String> environmentVariables = System.getenv();\n        arbitraryAttributes = environmentVariables.entrySet()\n                .stream()\n                .filter(entry -> entry.getKey().startsWith(CUSTOM_VAR_PREFIX))\n                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));\n\n        Properties properties = System.getProperties();\n        arbitraryAttributes.putAll(\n                properties.entrySet()\n                        .stream()\n                        .filter(entry -> ((String) entry.getKey()).startsWith(CUSTOM_VAR_PREFIX))\n                        .collect(Collectors.toMap(entry -> (String) entry.getKey(), entry -> (String) entry.getValue()))\n        );\n        return arbitraryAttributes;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/util/Utils.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.msf4j.util;\n\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.transport.http.netty.contract.config.TransportsConfiguration;\nimport org.yaml.snakeyaml.LoaderOptions;\nimport org.yaml.snakeyaml.Yaml;\nimport org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;\nimport org.yaml.snakeyaml.introspector.BeanAccess;\n\nimport java.lang.reflect.Field;\nimport java.security.AccessController;\nimport java.security.PrivilegedAction;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\n/**\n * Utility class.\n */\npublic class Utils {\n\n    /**\n     * Return the String representation of given object.\n     *\n     * @param object Object to be reflected.\n     * @return String representation of given object.\n     */\n    public static String toString(Object object) {\n        Objects.requireNonNull(object);\n        StringBuilder sb = new StringBuilder();\n        try {\n            for (Field field : object.getClass().getFields()) {\n                sb.append(field.getName()).append(\":\").append(field.get(object)).append(\"\\n\");\n            }\n        } catch (IllegalAccessException e) {\n            throw new RuntimeException(\"Error while executing \" + object.getClass() + \".toString()\", e);\n        }\n        return sb.toString();\n    }\n\n    /**\n     * Return the String representation of given object's given fields list.\n     *\n     * @param object Object to be reflected.\n     * @return String representation of given object.\n     */\n    public static String toString(Object object, String[] fields) {\n        Objects.requireNonNull(object);\n        StringBuilder sb = new StringBuilder();\n\n        AccessController.doPrivileged(new PrivilegedAction<Object>() {\n            @Override\n            public Object run() {\n                try {\n                    for (String field : fields) {\n                        Objects.requireNonNull(field);\n                        Field declaredField = object.getClass().getDeclaredField(field);\n                        declaredField.setAccessible(true);\n                        sb.append(field).append(\":\").append(declaredField.get(object)).append(\"\\n\");\n                        declaredField.setAccessible(false);\n                    }\n                    return sb;\n                } catch (IllegalAccessException e) {\n                    throw new RuntimeException(\"Error while executing \" + object.getClass() + \".toString()\", e);\n                } catch (NoSuchFieldException e) {\n                    throw new RuntimeException(\"Error while executing \" + object.getClass() + \".toString()\", e);\n                }\n            }\n        });\n        return sb.toString();\n    }\n\n    /**\n     * Split the given sequence with the given delimiter and return list of values.\n     *\n     * @param sequence  String need to be splitted.\n     * @param delimiter String delimiter\n     * @param omitEmpty boolean need to skip empty values.\n     * @return List of values obtained by splitting.\n     */\n    public static List<String> split(String sequence, String delimiter, boolean omitEmpty) {\n        Objects.requireNonNull(sequence);\n        Objects.requireNonNull(delimiter);\n        String[] splittedValues = sequence.split(delimiter);\n        List<String> values = Arrays.asList(splittedValues);\n        return omitEmpty ? values.stream().filter(value -> !value.isEmpty()).collect(Collectors.toList()) : values;\n    }\n\n    /**\n     * Get the remaining count of intersection between 2 sets.\n     *\n     * @param set1 First set\n     * @param set2 Second set\n     * @return remaining count of intersection between 2 sets\n     */\n    public static int getIntersection(Set set1, Set set2) {\n        HashSet cloneSet1 = new HashSet<>(set1);\n        HashSet cloneSet2 = new HashSet<>(set2);\n        if (cloneSet1.size() > cloneSet2.size()) {\n            cloneSet1.retainAll(cloneSet2);\n            return cloneSet1.size();\n        }\n        cloneSet2.retainAll(cloneSet1);\n        return cloneSet2.size();\n    }\n\n    public static TransportsConfiguration resolveTransportsNSConfiguration(Object transportsConfig)\n            throws ConfigurationException {\n\n        TransportsConfiguration transportsConfiguration;\n\n        if (transportsConfig instanceof Map) {\n            LinkedHashMap httpConfig = ((LinkedHashMap) ((Map) transportsConfig).get(\"http\"));\n            if (httpConfig != null) {\n                String configYaml = new Yaml().dump(httpConfig);\n                Yaml yaml = new Yaml(new CustomClassLoaderConstructor(TransportsConfiguration.class,\n                        TransportsConfiguration.class.getClassLoader(), new LoaderOptions()));\n                yaml.setBeanAccess(BeanAccess.FIELD);\n                transportsConfiguration = yaml.loadAs(configYaml, TransportsConfiguration.class);\n\n            } else {\n                transportsConfiguration = new TransportsConfiguration();\n            }\n        } else {\n            throw new ConfigurationException(\"The first level config under 'transports' namespace should be \" +\n                    \"a map.\");\n        }\n        return transportsConfiguration;\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/websocket/WebSocketEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket;\n\n/**\n * Maker Interface for developers who are developing endpoints in OSGi environment.\n * This should be implemented if developer are creating a WebSocket endpoint\n */\npublic interface WebSocketEndpoint {\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/websocket/WebSocketEndpointsRegistry.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket;\n\n\nimport java.util.Set;\n\n/**\n * Registry interface for WebSocket Endpoints\n */\npublic interface WebSocketEndpointsRegistry {\n    Set<Object> getAllEndpoints();\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/websocket/exception/WebSocketEndpointAnnotationException.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.exception;\n\n/**\n * Throws when an exception occurred in WebSocket Endpoint annotations.\n */\npublic class WebSocketEndpointAnnotationException extends Exception {\n\n    /**\n     * @param message the message which should be shown with the exception.\n     */\n    public WebSocketEndpointAnnotationException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/websocket/exception/WebSocketEndpointMethodReturnTypeException.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.exception;\n\n/**\n * This is thrown when an invalid return type is defined in method.\n */\npublic class WebSocketEndpointMethodReturnTypeException extends Exception {\n\n    /**\n     * @param message The message which should be shown when the exception is thrown.\n     */\n    public WebSocketEndpointMethodReturnTypeException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "core/src/main/java/org/wso2/msf4j/websocket/exception/WebSocketMethodParameterException.java",
    "content": "/*\n *   Copyright (c) ${date}, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.exception;\n\n/**\n * This is thrown when a issue found it WebSocket method parameters.\n */\npublic class WebSocketMethodParameterException extends Exception {\n\n    public WebSocketMethodParameterException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "core/src/main/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "core/src/main/resources/log4j.properties",
    "content": "# Root logger option\nlog4j.rootLogger=INFO, stdout\n# Direct log messages to stdout\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.Target=System.out\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n\n"
  },
  {
    "path": "core/src/main/resources/mime-map.properties",
    "content": "123=application/vnd.lotus-1-2-3\n3dml=text/vnd.in3d.3dml\n3ds=image/x-3ds\n3g2=video/3gpp2\n3gp=video/3gpp\n7z=application/x-7z-compressed\naab=application/x-authorware-bin\naac=audio/x-aac\naam=application/x-authorware-map\naas=application/x-authorware-seg\nabs=audio/x-mpeg\nabw=application/x-abiword\nac=application/pkix-attr-cert\nacc=application/vnd.americandynamics.acc\nace=application/x-ace-compressed\nacu=application/vnd.acucobol\nacutc=application/vnd.acucorp\nadp=audio/adpcm\naep=application/vnd.audiograph\nafm=application/x-font-type1\nafp=application/vnd.ibm.modcap\nahead=application/vnd.ahead.space\nai=application/postscript\naif=audio/x-aiff\naifc=audio/x-aiff\naiff=audio/x-aiff\naim=application/x-aim\nair=application/vnd.adobe.air-application-installer-package+zip\nait=application/vnd.dvb.ait\nami=application/vnd.amiga.ami\nanx=application/annodex\napk=application/vnd.android.package-archive\nappcache=text/cache-manifest\napplication=application/x-ms-application\napr=application/vnd.lotus-approach\narc=application/x-freearc\nart=image/x-jg\nasc=application/pgp-signature\nasf=video/x-ms-asf\nasm=text/x-asm\naso=application/vnd.accpac.simply.aso\nasx=video/x-ms-asf\natc=application/vnd.acucorp\natom=application/atom+xml\natomcat=application/atomcat+xml\natomsvc=application/atomsvc+xml\natx=application/vnd.antix.game-component\nau=audio/basic\navi=video/x-msvideo\navx=video/x-rad-screenplay\naw=application/applixware\naxa=audio/annodex\naxv=video/annodex\nazf=application/vnd.airzip.filesecure.azf\nazs=application/vnd.airzip.filesecure.azs\nazw=application/vnd.amazon.ebook\nbat=application/x-msdownload\nbcpio=application/x-bcpio\nbdf=application/x-font-bdf\nbdm=application/vnd.syncml.dm+wbxml\nbed=application/vnd.realvnc.bed\nbh2=application/vnd.fujitsu.oasysprs\nbin=application/octet-stream\nblb=application/x-blorb\nblorb=application/x-blorb\nbmi=application/vnd.bmi\nbmp=image/bmp\nbody=text/html\nbook=application/vnd.framemaker\nbox=application/vnd.previewsystems.box\nboz=application/x-bzip2\nbpk=application/octet-stream\nbtif=image/prs.btif\nbz=application/x-bzip\nbz2=application/x-bzip2\nc=text/x-c\nc11amc=application/vnd.cluetrust.cartomobile-config\nc11amz=application/vnd.cluetrust.cartomobile-config-pkg\nc4d=application/vnd.clonk.c4group\nc4f=application/vnd.clonk.c4group\nc4g=application/vnd.clonk.c4group\nc4p=application/vnd.clonk.c4group\nc4u=application/vnd.clonk.c4group\ncab=application/vnd.ms-cab-compressed\ncaf=audio/x-caf\ncap=application/vnd.tcpdump.pcap\ncar=application/vnd.curl.car\ncat=application/vnd.ms-pki.seccat\ncb7=application/x-cbr\ncba=application/x-cbr\ncbr=application/x-cbr\ncbt=application/x-cbr\ncbz=application/x-cbr\ncc=text/x-c\ncct=application/x-director\nccxml=application/ccxml+xml\ncdbcmsg=application/vnd.contact.cmsg\ncdf=application/x-cdf\ncdkey=application/vnd.mediastation.cdkey\ncdmia=application/cdmi-capability\ncdmic=application/cdmi-container\ncdmid=application/cdmi-domain\ncdmio=application/cdmi-object\ncdmiq=application/cdmi-queue\ncdx=chemical/x-cdx\ncdxml=application/vnd.chemdraw+xml\ncdy=application/vnd.cinderella\ncer=application/pkix-cert\ncfs=application/x-cfs-compressed\ncgm=image/cgm\nchat=application/x-chat\nchm=application/vnd.ms-htmlhelp\nchrt=application/vnd.kde.kchart\ncif=chemical/x-cif\ncii=application/vnd.anser-web-certificate-issue-initiation\ncil=application/vnd.ms-artgalry\ncla=application/vnd.claymore\nclass=application/java\nclkk=application/vnd.crick.clicker.keyboard\nclkp=application/vnd.crick.clicker.palette\nclkt=application/vnd.crick.clicker.template\nclkw=application/vnd.crick.clicker.wordbank\nclkx=application/vnd.crick.clicker\nclp=application/x-msclip\ncmc=application/vnd.cosmocaller\ncmdf=chemical/x-cmdf\ncml=chemical/x-cml\ncmp=application/vnd.yellowriver-custom-menu\ncmx=image/x-cmx\ncod=application/vnd.rim.cod\ncom=application/x-msdownload\nconf=text/plain\ncpio=application/x-cpio\ncpp=text/x-c\ncpt=application/mac-compactpro\ncrd=application/x-mscardfile\ncrl=application/pkix-crl\ncrt=application/x-x509-ca-cert\ncryptonote=application/vnd.rig.cryptonote\ncsh=application/x-csh\ncsml=chemical/x-csml\ncsp=application/vnd.commonspace\ncss=text/css\ncst=application/x-director\ncsv=text/csv\ncu=application/cu-seeme\ncurl=text/vnd.curl\ncww=application/prs.cww\ncxt=application/x-director\ncxx=text/x-c\ndae=model/vnd.collada+xml\ndaf=application/vnd.mobius.daf\ndart=application/vnd.dart\ndataless=application/vnd.fdsn.seed\ndavmount=application/davmount+xml\ndbk=application/docbook+xml\ndcr=application/x-director\ndcurl=text/vnd.curl.dcurl\ndd2=application/vnd.oma.dd2+xml\nddd=application/vnd.fujixerox.ddd\ndeb=application/x-debian-package\ndef=text/plain\ndeploy=application/octet-stream\nder=application/x-x509-ca-cert\ndfac=application/vnd.dreamfactory\ndgc=application/x-dgc-compressed\ndib=image/bmp\ndic=text/x-c\ndir=application/x-director\ndis=application/vnd.mobius.dis\ndist=application/octet-stream\ndistz=application/octet-stream\ndjv=image/vnd.djvu\ndjvu=image/vnd.djvu\ndll=application/x-msdownload\ndmg=application/x-apple-diskimage\ndmp=application/vnd.tcpdump.pcap\ndms=application/octet-stream\ndna=application/vnd.dna\ndoc=application/msword\ndocm=application/vnd.ms-word.document.macroenabled.12\ndocx=application/vnd.openxmlformats-officedocument.wordprocessingml.document\ndot=application/msword\ndotm=application/vnd.ms-word.template.macroenabled.12\ndotx=application/vnd.openxmlformats-officedocument.wordprocessingml.template\ndp=application/vnd.osgi.dp\ndpg=application/vnd.dpgraph\ndra=audio/vnd.dra\ndsc=text/prs.lines.tag\ndssc=application/dssc+der\ndtb=application/x-dtbook+xml\ndtd=application/xml-dtd\ndts=audio/vnd.dts\ndtshd=audio/vnd.dts.hd\ndump=application/octet-stream\ndv=video/x-dv\ndvb=video/vnd.dvb.file\ndvi=application/x-dvi\ndwf=model/vnd.dwf\ndwg=image/vnd.dwg\ndxf=image/vnd.dxf\ndxp=application/vnd.spotfire.dxp\ndxr=application/x-director\necelp4800=audio/vnd.nuera.ecelp4800\necelp7470=audio/vnd.nuera.ecelp7470\necelp9600=audio/vnd.nuera.ecelp9600\necma=application/ecmascript\nedm=application/vnd.novadigm.edm\nedx=application/vnd.novadigm.edx\nefif=application/vnd.picsel\nei6=application/vnd.pg.osasli\nelc=application/octet-stream\nemf=application/x-msmetafile\neml=message/rfc822\nemma=application/emma+xml\nemz=application/x-msmetafile\neol=audio/vnd.digital-winds\neot=application/vnd.ms-fontobject\neps=application/postscript\nepub=application/epub+zip\nes3=application/vnd.eszigno3+xml\nesa=application/vnd.osgi.subsystem\nesf=application/vnd.epson.esf\net3=application/vnd.eszigno3+xml\netx=text/x-setext\neva=application/x-eva\nevy=application/x-envoy\nexe=application/octet-stream\nexi=application/exi\next=application/vnd.novadigm.ext\nez=application/andrew-inset\nez2=application/vnd.ezpix-album\nez3=application/vnd.ezpix-package\nf=text/x-fortran\nf4v=video/x-f4v\nf77=text/x-fortran\nf90=text/x-fortran\nfbs=image/vnd.fastbidsheet\nfcdt=application/vnd.adobe.formscentral.fcdt\nfcs=application/vnd.isac.fcs\nfdf=application/vnd.fdf\nfe_launch=application/vnd.denovo.fcselayout-link\nfg5=application/vnd.fujitsu.oasysgp\nfgd=application/x-director\nfh=image/x-freehand\nfh4=image/x-freehand\nfh5=image/x-freehand\nfh7=image/x-freehand\nfhc=image/x-freehand\nfig=application/x-xfig\nflac=audio/flac\nfli=video/x-fli\nflo=application/vnd.micrografx.flo\nflv=video/x-flv\nflw=application/vnd.kde.kivio\nflx=text/vnd.fmi.flexstor\nfly=text/vnd.fly\nfm=application/vnd.framemaker\nfnc=application/vnd.frogans.fnc\nfor=text/x-fortran\nfpx=image/vnd.fpx\nframe=application/vnd.framemaker\nfsc=application/vnd.fsc.weblaunch\nfst=image/vnd.fst\nftc=application/vnd.fluxtime.clip\nfti=application/vnd.anser-web-funds-transfer-initiation\nfvt=video/vnd.fvt\nfxp=application/vnd.adobe.fxp\nfxpl=application/vnd.adobe.fxp\nfzs=application/vnd.fuzzysheet\ng2w=application/vnd.geoplan\ng3=image/g3fax\ng3w=application/vnd.geospace\ngac=application/vnd.groove-account\ngam=application/x-tads\ngbr=application/rpki-ghostbusters\ngca=application/x-gca-compressed\ngdl=model/vnd.gdl\ngeo=application/vnd.dynageo\ngex=application/vnd.geometry-explorer\nggb=application/vnd.geogebra.file\nggt=application/vnd.geogebra.tool\nghf=application/vnd.groove-help\ngif=image/gif\ngim=application/vnd.groove-identity-message\ngml=application/gml+xml\ngmx=application/vnd.gmx\ngnumeric=application/x-gnumeric\ngph=application/vnd.flographit\ngpx=application/gpx+xml\ngqf=application/vnd.grafeq\ngqs=application/vnd.grafeq\ngram=application/srgs\ngramps=application/x-gramps-xml\ngre=application/vnd.geometry-explorer\ngrv=application/vnd.groove-injector\ngrxml=application/srgs+xml\ngsf=application/x-font-ghostscript\ngtar=application/x-gtar\ngtm=application/vnd.groove-tool-message\ngtw=model/vnd.gtw\ngv=text/vnd.graphviz\ngxf=application/gxf\ngxt=application/vnd.geonext\ngz=application/x-gzip\nh=text/x-c\nh261=video/h261\nh263=video/h263\nh264=video/h264\nhal=application/vnd.hal+xml\nhbci=application/vnd.hbci\nhdf=application/x-hdf\nhh=text/x-c\nhlp=application/winhlp\nhpgl=application/vnd.hp-hpgl\nhpid=application/vnd.hp-hpid\nhps=application/vnd.hp-hps\nhqx=application/mac-binhex40\nhtc=text/x-component\nhtke=application/vnd.kenameaapp\nhtm=text/html\nhtml=text/html\nhvd=application/vnd.yamaha.hv-dic\nhvp=application/vnd.yamaha.hv-voice\nhvs=application/vnd.yamaha.hv-script\ni2g=application/vnd.intergeo\nicc=application/vnd.iccprofile\nice=x-conference/x-cooltalk\nicm=application/vnd.iccprofile\nico=image/x-icon\nics=text/calendar\nief=image/ief\nifb=text/calendar\nifm=application/vnd.shana.informed.formdata\niges=model/iges\nigl=application/vnd.igloader\nigm=application/vnd.insors.igm\nigs=model/iges\nigx=application/vnd.micrografx.igx\niif=application/vnd.shana.informed.interchange\nimp=application/vnd.accpac.simply.imp\nims=application/vnd.ms-ims\nin=text/plain\nink=application/inkml+xml\ninkml=application/inkml+xml\ninstall=application/x-install-instructions\niota=application/vnd.astraea-software.iota\nipfix=application/ipfix\nipk=application/vnd.shana.informed.package\nirm=application/vnd.ibm.rights-management\nirp=application/vnd.irepository.package+xml\niso=application/x-iso9660-image\nitp=application/vnd.shana.informed.formtemplate\nivp=application/vnd.immervision-ivp\nivu=application/vnd.immervision-ivu\njad=text/vnd.sun.j2me.app-descriptor\njam=application/vnd.jam\njar=application/java-archive\njava=text/x-java-source\njisp=application/vnd.jisp\njlt=application/vnd.hp-jlyt\njnlp=application/x-java-jnlp-file\njoda=application/vnd.joost.joda-archive\njpe=image/jpeg\njpeg=image/jpeg\njpg=image/jpeg\njpgm=video/jpm\njpgv=video/jpeg\njpm=video/jpm\njs=application/javascript\njsf=text/plain\njson=application/json\njsonml=application/jsonml+json\njspf=text/plain\nkar=audio/midi\nkarbon=application/vnd.kde.karbon\nkfo=application/vnd.kde.kformula\nkia=application/vnd.kidspiration\nkml=application/vnd.google-earth.kml+xml\nkmz=application/vnd.google-earth.kmz\nkne=application/vnd.kinar\nknp=application/vnd.kinar\nkon=application/vnd.kde.kontour\nkpr=application/vnd.kde.kpresenter\nkpt=application/vnd.kde.kpresenter\nkpxx=application/vnd.ds-keypoint\nksp=application/vnd.kde.kspread\nktr=application/vnd.kahootz\nktx=image/ktx\nktz=application/vnd.kahootz\nkwd=application/vnd.kde.kword\nkwt=application/vnd.kde.kword\nlasxml=application/vnd.las.las+xml\nlatex=application/x-latex\nlbd=application/vnd.llamagraphics.life-balance.desktop\nlbe=application/vnd.llamagraphics.life-balance.exchange+xml\nles=application/vnd.hhe.lesson-player\nlha=application/x-lzh-compressed\nlink66=application/vnd.route66.link66+xml\nlist=text/plain\nlist3820=application/vnd.ibm.modcap\nlistafp=application/vnd.ibm.modcap\nlnk=application/x-ms-shortcut\nlog=text/plain\nlostxml=application/lost+xml\nlrf=application/octet-stream\nlrm=application/vnd.ms-lrm\nltf=application/vnd.frogans.ltf\nlvp=audio/vnd.lucent.voice\nlwp=application/vnd.lotus-wordpro\nlzh=application/x-lzh-compressed\nm13=application/x-msmediaview\nm14=application/x-msmediaview\nm1v=video/mpeg\nm21=application/mp21\nm2a=audio/mpeg\nm2v=video/mpeg\nm3a=audio/mpeg\nm3u=audio/x-mpegurl\nm3u8=application/vnd.apple.mpegurl\nm4a=audio/mp4\nm4b=audio/mp4\nm4r=audio/mp4\nm4u=video/vnd.mpegurl\nm4v=video/mp4\nma=application/mathematica\nmac=image/x-macpaint\nmads=application/mads+xml\nmag=application/vnd.ecowin.chart\nmaker=application/vnd.framemaker\nman=text/troff\nmar=application/octet-stream\nmathml=application/mathml+xml\nmb=application/mathematica\nmbk=application/vnd.mobius.mbk\nmbox=application/mbox\nmc1=application/vnd.medcalcdata\nmcd=application/vnd.mcd\nmcurl=text/vnd.curl.mcurl\nmdb=application/x-msaccess\nmdi=image/vnd.ms-modi\nme=text/troff\nmesh=model/mesh\nmeta4=application/metalink4+xml\nmetalink=application/metalink+xml\nmets=application/mets+xml\nmfm=application/vnd.mfmp\nmft=application/rpki-manifest\nmgp=application/vnd.osgeo.mapguide.package\nmgz=application/vnd.proteus.magazine\nmid=audio/midi\nmidi=audio/midi\nmie=application/x-mie\nmif=application/x-mif\nmime=message/rfc822\nmj2=video/mj2\nmjp2=video/mj2\nmk3d=video/x-matroska\nmka=audio/x-matroska\nmks=video/x-matroska\nmkv=video/x-matroska\nmlp=application/vnd.dolby.mlp\nmmd=application/vnd.chipnuts.karaoke-mmd\nmmf=application/vnd.smaf\nmmr=image/vnd.fujixerox.edmics-mmr\nmng=video/x-mng\nmny=application/x-msmoney\nmobi=application/x-mobipocket-ebook\nmods=application/mods+xml\nmov=video/quicktime\nmovie=video/x-sgi-movie\nmp1=audio/mpeg\nmp2=audio/mpeg\nmp21=application/mp21\nmp2a=audio/mpeg\nmp3=audio/mpeg\nmp4=video/mp4\nmp4a=audio/mp4\nmp4s=application/mp4\nmp4v=video/mp4\nmpa=audio/mpeg\nmpc=application/vnd.mophun.certificate\nmpe=video/mpeg\nmpeg=video/mpeg\nmpega=audio/x-mpeg\nmpg=video/mpeg\nmpg4=video/mp4\nmpga=audio/mpeg\nmpkg=application/vnd.apple.installer+xml\nmpm=application/vnd.blueice.multipass\nmpn=application/vnd.mophun.application\nmpp=application/vnd.ms-project\nmpt=application/vnd.ms-project\nmpv2=video/mpeg2\nmpy=application/vnd.ibm.minipay\nmqy=application/vnd.mobius.mqy\nmrc=application/marc\nmrcx=application/marcxml+xml\nms=text/troff\nmscml=application/mediaservercontrol+xml\nmseed=application/vnd.fdsn.mseed\nmseq=application/vnd.mseq\nmsf=application/vnd.epson.msf\nmsh=model/mesh\nmsi=application/x-msdownload\nmsl=application/vnd.mobius.msl\nmsty=application/vnd.muvee.style\nmts=model/vnd.mts\nmus=application/vnd.musician\nmusicxml=application/vnd.recordare.musicxml+xml\nmvb=application/x-msmediaview\nmwf=application/vnd.mfer\nmxf=application/mxf\nmxl=application/vnd.recordare.musicxml\nmxml=application/xv+xml\nmxs=application/vnd.triscape.mxs\nmxu=video/vnd.mpegurl\nn-gage=application/vnd.nokia.n-gage.symbian.install\nn3=text/n3\nnb=application/mathematica\nnbp=application/vnd.wolfram.player\nnc=application/x-netcdf\nncx=application/x-dtbncx+xml\nnfo=text/x-nfo\nngdat=application/vnd.nokia.n-gage.data\nnitf=application/vnd.nitf\nnlu=application/vnd.neurolanguage.nlu\nnml=application/vnd.enliven\nnnd=application/vnd.noblenet-directory\nnns=application/vnd.noblenet-sealer\nnnw=application/vnd.noblenet-web\nnpx=image/vnd.net-fpx\nnsc=application/x-conference\nnsf=application/vnd.lotus-notes\nntf=application/vnd.nitf\nnzb=application/x-nzb\noa2=application/vnd.fujitsu.oasys2\noa3=application/vnd.fujitsu.oasys3\noas=application/vnd.fujitsu.oasys\nobd=application/x-msbinder\nobj=application/x-tgif\noda=application/oda\nodb=application/vnd.oasis.opendocument.database\nodc=application/vnd.oasis.opendocument.chart\nodf=application/vnd.oasis.opendocument.formula\nodft=application/vnd.oasis.opendocument.formula-template\nodg=application/vnd.oasis.opendocument.graphics\nodi=application/vnd.oasis.opendocument.image\nodm=application/vnd.oasis.opendocument.text-master\nodp=application/vnd.oasis.opendocument.presentation\nods=application/vnd.oasis.opendocument.spreadsheet\nodt=application/vnd.oasis.opendocument.text\noga=audio/ogg\nogg=audio/ogg\nogv=video/ogg\nogx=application/ogg\nomdoc=application/omdoc+xml\nonepkg=application/onenote\nonetmp=application/onenote\nonetoc=application/onenote\nonetoc2=application/onenote\nopf=application/oebps-package+xml\nopml=text/x-opml\noprc=application/vnd.palm\norg=application/vnd.lotus-organizer\nosf=application/vnd.yamaha.openscoreformat\nosfpvg=application/vnd.yamaha.openscoreformat.osfpvg+xml\notc=application/vnd.oasis.opendocument.chart-template\notf=application/x-font-otf\notg=application/vnd.oasis.opendocument.graphics-template\noth=application/vnd.oasis.opendocument.text-web\noti=application/vnd.oasis.opendocument.image-template\notp=application/vnd.oasis.opendocument.presentation-template\nots=application/vnd.oasis.opendocument.spreadsheet-template\nott=application/vnd.oasis.opendocument.text-template\noxps=application/oxps\noxt=application/vnd.openofficeorg.extension\np=text/x-pascal\np10=application/pkcs10\np12=application/x-pkcs12\np7b=application/x-pkcs7-certificates\np7c=application/pkcs7-mime\np7m=application/pkcs7-mime\np7r=application/x-pkcs7-certreqresp\np7s=application/pkcs7-signature\np8=application/pkcs8\npas=text/x-pascal\npaw=application/vnd.pawaafile\npbd=application/vnd.powerbuilder6\npbm=image/x-portable-bitmap\npcap=application/vnd.tcpdump.pcap\npcf=application/x-font-pcf\npcl=application/vnd.hp-pcl\npclxl=application/vnd.hp-pclxl\npct=image/pict\npcurl=application/vnd.curl.pcurl\npcx=image/x-pcx\npdb=application/vnd.palm\npdf=application/pdf\npfa=application/x-font-type1\npfb=application/x-font-type1\npfm=application/x-font-type1\npfr=application/font-tdpfr\npfx=application/x-pkcs12\npgm=image/x-portable-graymap\npgn=application/x-chess-pgn\npgp=application/pgp-encrypted\npic=image/pict\npict=image/pict\npkg=application/octet-stream\npki=application/pkixcmp\npkipath=application/pkix-pkipath\nplb=application/vnd.3gpp.pic-bw-large\nplc=application/vnd.mobius.plc\nplf=application/vnd.pocketlearn\npls=audio/x-scpls\npml=application/vnd.ctc-posml\npng=image/png\npnm=image/x-portable-anymap\npnt=image/x-macpaint\nportpkg=application/vnd.macports.portpkg\npot=application/vnd.ms-powerpoint\npotm=application/vnd.ms-powerpoint.template.macroenabled.12\npotx=application/vnd.openxmlformats-officedocument.presentationml.template\nppam=application/vnd.ms-powerpoint.addin.macroenabled.12\nppd=application/vnd.cups-ppd\nppm=image/x-portable-pixmap\npps=application/vnd.ms-powerpoint\nppsm=application/vnd.ms-powerpoint.slideshow.macroenabled.12\nppsx=application/vnd.openxmlformats-officedocument.presentationml.slideshow\nppt=application/vnd.ms-powerpoint\npptm=application/vnd.ms-powerpoint.presentation.macroenabled.12\npptx=application/vnd.openxmlformats-officedocument.presentationml.presentation\npqa=application/vnd.palm\nprc=application/x-mobipocket-ebook\npre=application/vnd.lotus-freelance\nprf=application/pics-rules\nps=application/postscript\npsb=application/vnd.3gpp.pic-bw-small\npsd=image/vnd.adobe.photoshop\npsf=application/x-font-linux-psf\npskcxml=application/pskc+xml\nptid=application/vnd.pvi.ptid1\npub=application/x-mspublisher\npvb=application/vnd.3gpp.pic-bw-var\npwn=application/vnd.3m.post-it-notes\npya=audio/vnd.ms-playready.media.pya\npyv=video/vnd.ms-playready.media.pyv\nqam=application/vnd.epson.quickanime\nqbo=application/vnd.intu.qbo\nqfx=application/vnd.intu.qfx\nqps=application/vnd.publishare-delta-tree\nqt=video/quicktime\nqti=image/x-quicktime\nqtif=image/x-quicktime\nqwd=application/vnd.quark.quarkxpress\nqwt=application/vnd.quark.quarkxpress\nqxb=application/vnd.quark.quarkxpress\nqxd=application/vnd.quark.quarkxpress\nqxl=application/vnd.quark.quarkxpress\nqxt=application/vnd.quark.quarkxpress\nra=audio/x-pn-realaudio\nram=audio/x-pn-realaudio\nrar=application/x-rar-compressed\nras=image/x-cmu-raster\nrcprofile=application/vnd.ipunplugged.rcprofile\nrdf=application/rdf+xml\nrdz=application/vnd.data-vision.rdz\nrep=application/vnd.businessobjects\nres=application/x-dtbresource+xml\nrgb=image/x-rgb\nrif=application/reginfo+xml\nrip=audio/vnd.rip\nris=application/x-research-info-systems\nrl=application/resource-lists+xml\nrlc=image/vnd.fujixerox.edmics-rlc\nrld=application/resource-lists-diff+xml\nrm=application/vnd.rn-realmedia\nrmi=audio/midi\nrmp=audio/x-pn-realaudio-plugin\nrms=application/vnd.jcp.javame.midlet-rms\nrmvb=application/vnd.rn-realmedia-vbr\nrnc=application/relax-ng-compact-syntax\nroa=application/rpki-roa\nroff=text/troff\nrp9=application/vnd.cloanto.rp9\nrpss=application/vnd.nokia.radio-presets\nrpst=application/vnd.nokia.radio-preset\nrq=application/sparql-query\nrs=application/rls-services+xml\nrsd=application/rsd+xml\nrss=application/rss+xml\nrtf=application/rtf\nrtx=text/richtext\ns=text/x-asm\ns3m=audio/s3m\nsaf=application/vnd.yamaha.smaf-audio\nsbml=application/sbml+xml\nsc=application/vnd.ibm.secure-container\nscd=application/x-msschedule\nscm=application/vnd.lotus-screencam\nscq=application/scvp-cv-request\nscs=application/scvp-cv-response\nscurl=text/vnd.curl.scurl\nsda=application/vnd.stardivision.draw\nsdc=application/vnd.stardivision.calc\nsdd=application/vnd.stardivision.impress\nsdkd=application/vnd.solent.sdkm+xml\nsdkm=application/vnd.solent.sdkm+xml\nsdp=application/sdp\nsdw=application/vnd.stardivision.writer\nsee=application/vnd.seemail\nseed=application/vnd.fdsn.seed\nsema=application/vnd.sema\nsemd=application/vnd.semd\nsemf=application/vnd.semf\nser=application/java-serialized-object\nsetpay=application/set-payment-initiation\nsetreg=application/set-registration-initiation\nsfd-hdstx=application/vnd.hydrostatix.sof-data\nsfs=application/vnd.spotfire.sfs\nsfv=text/x-sfv\nsgi=image/sgi\nsgl=application/vnd.stardivision.writer-global\nsgm=text/sgml\nsgml=text/sgml\nsh=application/x-sh\nshar=application/x-shar\nshf=application/shf+xml\nsid=image/x-mrsid-image\nsig=application/pgp-signature\nsil=audio/silk\nsilo=model/mesh\nsis=application/vnd.symbian.install\nsisx=application/vnd.symbian.install\nsit=application/x-stuffit\nsitx=application/x-stuffitx\nskd=application/vnd.koan\nskm=application/vnd.koan\nskp=application/vnd.koan\nskt=application/vnd.koan\nsldm=application/vnd.ms-powerpoint.slide.macroenabled.12\nsldx=application/vnd.openxmlformats-officedocument.presentationml.slide\nslt=application/vnd.epson.salt\nsm=application/vnd.stepmania.stepchart\nsmf=application/vnd.stardivision.math\nsmi=application/smil+xml\nsmil=application/smil+xml\nsmv=video/x-smv\nsmzip=application/vnd.stepmania.package\nsnd=audio/basic\nsnf=application/x-font-snf\nso=application/octet-stream\nspc=application/x-pkcs7-certificates\nspf=application/vnd.yamaha.smaf-phrase\nspl=application/x-futuresplash\nspot=text/vnd.in3d.spot\nspp=application/scvp-vp-response\nspq=application/scvp-vp-request\nspx=audio/ogg\nsql=application/x-sql\nsrc=application/x-wais-source\nsrt=application/x-subrip\nsru=application/sru+xml\nsrx=application/sparql-results+xml\nssdl=application/ssdl+xml\nsse=application/vnd.kodak-descriptor\nssf=application/vnd.epson.ssf\nssml=application/ssml+xml\nst=application/vnd.sailingtracker.track\nstc=application/vnd.sun.xml.calc.template\nstd=application/vnd.sun.xml.draw.template\nstf=application/vnd.wt.stf\nsti=application/vnd.sun.xml.impress.template\nstk=application/hyperstudio\nstl=application/vnd.ms-pki.stl\nstr=application/vnd.pg.format\nstw=application/vnd.sun.xml.writer.template\nsub=text/vnd.dvb.subtitle\nsus=application/vnd.sus-calendar\nsusp=application/vnd.sus-calendar\nsv4cpio=application/x-sv4cpio\nsv4crc=application/x-sv4crc\nsvc=application/vnd.dvb.service\nsvd=application/vnd.svd\nsvg=image/svg+xml\nsvgz=image/svg+xml\nswa=application/x-director\nswf=application/x-shockwave-flash\nswi=application/vnd.aristanetworks.swi\nsxc=application/vnd.sun.xml.calc\nsxd=application/vnd.sun.xml.draw\nsxg=application/vnd.sun.xml.writer.global\nsxi=application/vnd.sun.xml.impress\nsxm=application/vnd.sun.xml.math\nsxw=application/vnd.sun.xml.writer\nt=text/troff\nt3=application/x-t3vm-image\ntaglet=application/vnd.mynfc\ntao=application/vnd.tao.intent-module-archive\ntar=application/x-tar\ntcap=application/vnd.3gpp2.tcap\ntcl=application/x-tcl\nteacher=application/vnd.smart.teacher\ntei=application/tei+xml\nteicorpus=application/tei+xml\ntex=application/x-tex\ntexi=application/x-texinfo\ntexinfo=application/x-texinfo\ntext=text/plain\ntfi=application/thraud+xml\ntfm=application/x-tex-tfm\ntga=image/x-tga\nthmx=application/vnd.ms-officetheme\ntif=image/tiff\ntiff=image/tiff\ntmo=application/vnd.tmobile-livetv\ntorrent=application/x-bittorrent\ntpl=application/vnd.groove-tool-template\ntpt=application/vnd.trid.tpt\ntr=text/troff\ntra=application/vnd.trueapp\ntrm=application/x-msterminal\ntsd=application/timestamped-data\ntsv=text/tab-separated-values\nttc=application/x-font-ttf\nttf=application/x-font-ttf\nttl=text/turtle\ntwd=application/vnd.simtech-mindmapper\ntwds=application/vnd.simtech-mindmapper\ntxd=application/vnd.genomatix.tuxedo\ntxf=application/vnd.mobius.txf\ntxt=text/plain\nu32=application/x-authorware-bin\nudeb=application/x-debian-package\nufd=application/vnd.ufdl\nufdl=application/vnd.ufdl\nulw=audio/basic\nulx=application/x-glulx\numj=application/vnd.umajin\nunityweb=application/vnd.unity\nuoml=application/vnd.uoml+xml\nuri=text/uri-list\nuris=text/uri-list\nurls=text/uri-list\nustar=application/x-ustar\nutz=application/vnd.uiq.theme\nuu=text/x-uuencode\nuva=audio/vnd.dece.audio\nuvd=application/vnd.dece.data\nuvf=application/vnd.dece.data\nuvg=image/vnd.dece.graphic\nuvh=video/vnd.dece.hd\nuvi=image/vnd.dece.graphic\nuvm=video/vnd.dece.mobile\nuvp=video/vnd.dece.pd\nuvs=video/vnd.dece.sd\nuvt=application/vnd.dece.ttml+xml\nuvu=video/vnd.uvvu.mp4\nuvv=video/vnd.dece.video\nuvva=audio/vnd.dece.audio\nuvvd=application/vnd.dece.data\nuvvf=application/vnd.dece.data\nuvvg=image/vnd.dece.graphic\nuvvh=video/vnd.dece.hd\nuvvi=image/vnd.dece.graphic\nuvvm=video/vnd.dece.mobile\nuvvp=video/vnd.dece.pd\nuvvs=video/vnd.dece.sd\nuvvt=application/vnd.dece.ttml+xml\nuvvu=video/vnd.uvvu.mp4\nuvvv=video/vnd.dece.video\nuvvx=application/vnd.dece.unspecified\nuvvz=application/vnd.dece.zip\nuvx=application/vnd.dece.unspecified\nuvz=application/vnd.dece.zip\nvcard=text/vcard\nvcd=application/x-cdlink\nvcf=text/x-vcard\nvcg=application/vnd.groove-vcard\nvcs=text/x-vcalendar\nvcx=application/vnd.vcx\nvis=application/vnd.visionary\nviv=video/vnd.vivo\nvob=video/x-ms-vob\nvor=application/vnd.stardivision.writer\nvox=application/x-authorware-bin\nvrml=model/vrml\nvsd=application/vnd.visio\nvsf=application/vnd.vsf\nvss=application/vnd.visio\nvst=application/vnd.visio\nvsw=application/vnd.visio\nvtu=model/vnd.vtu\nvxml=application/voicexml+xml\nw3d=application/x-director\nwad=application/x-doom\nwav=audio/x-wav\nwax=audio/x-ms-wax\nwbmp=image/vnd.wap.wbmp\nwbs=application/vnd.criticaltools.wbs+xml\nwbxml=application/vnd.wap.wbxml\nwcm=application/vnd.ms-works\nwdb=application/vnd.ms-works\nwdp=image/vnd.ms-photo\nweba=audio/webm\nwebm=video/webm\nwebp=image/webp\nwg=application/vnd.pmi.widget\nwgt=application/widget\nwks=application/vnd.ms-works\nwm=video/x-ms-wm\nwma=audio/x-ms-wma\nwmd=application/x-ms-wmd\nwmf=application/x-msmetafile\nwml=text/vnd.wap.wml\nwmlc=application/vnd.wap.wmlc\nwmls=text/vnd.wap.wmlscript\nwmlsc=application/vnd.wap.wmlscriptc\nwmv=video/x-ms-wmv\nwmx=video/x-ms-wmx\nwmz=application/x-msmetafile\nwoff=application/x-font-woff\nwpd=application/vnd.wordperfect\nwpl=application/vnd.ms-wpl\nwps=application/vnd.ms-works\nwqd=application/vnd.wqd\nwri=application/x-mswrite\nwrl=model/vrml\nwsdl=application/wsdl+xml\nwspolicy=application/wspolicy+xml\nwtb=application/vnd.webturbo\nwvx=video/x-ms-wvx\nx32=application/x-authorware-bin\nx3d=model/x3d+xml\nx3db=model/x3d+binary\nx3dbz=model/x3d+binary\nx3dv=model/x3d+vrml\nx3dvz=model/x3d+vrml\nx3dz=model/x3d+xml\nxaml=application/xaml+xml\nxap=application/x-silverlight-app\nxar=application/vnd.xara\nxbap=application/x-ms-xbap\nxbd=application/vnd.fujixerox.docuworks.binder\nxbm=image/x-xbitmap\nxdf=application/xcap-diff+xml\nxdm=application/vnd.syncml.dm+xml\nxdp=application/vnd.adobe.xdp+xml\nxdssc=application/dssc+xml\nxdw=application/vnd.fujixerox.docuworks\nxenc=application/xenc+xml\nxer=application/patch-ops-error+xml\nxfdf=application/vnd.adobe.xfdf\nxfdl=application/vnd.xfdl\nxht=application/xhtml+xml\nxhtml=application/xhtml+xml\nxhvml=application/xv+xml\nxif=image/vnd.xiff\nxla=application/vnd.ms-excel\nxlam=application/vnd.ms-excel.addin.macroenabled.12\nxlc=application/vnd.ms-excel\nxlf=application/x-xliff+xml\nxlm=application/vnd.ms-excel\nxls=application/vnd.ms-excel\nxlsb=application/vnd.ms-excel.sheet.binary.macroenabled.12\nxlsm=application/vnd.ms-excel.sheet.macroenabled.12\nxlsx=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\nxlt=application/vnd.ms-excel\nxltm=application/vnd.ms-excel.template.macroenabled.12\nxltx=application/vnd.openxmlformats-officedocument.spreadsheetml.template\nxlw=application/vnd.ms-excel\nxm=audio/xm\nxml=application/xml\nxo=application/vnd.olpc-sugar\nxop=application/xop+xml\nxpi=application/x-xpinstall\nxpl=application/xproc+xml\nxpm=image/x-xpixmap\nxpr=application/vnd.is-xpr\nxps=application/vnd.ms-xpsdocument\nxpw=application/vnd.intercon.formnet\nxpx=application/vnd.intercon.formnet\nxsl=application/xml\nxslt=application/xslt+xml\nxsm=application/vnd.syncml+xml\nxspf=application/xspf+xml\nxul=application/vnd.mozilla.xul+xml\nxvm=application/xv+xml\nxvml=application/xv+xml\nxwd=image/x-xwindowdump\nxyz=chemical/x-xyz\nxz=application/x-xz\nyang=application/yang\nyin=application/yin+xml\nz=application/x-compress\nZ=application/x-compress\nz1=application/x-zmachine\nz2=application/x-zmachine\nz3=application/x-zmachine\nz4=application/x-zmachine\nz5=application/x-zmachine\nz6=application/x-zmachine\nz7=application/x-zmachine\nz8=application/x-zmachine\nzaz=application/vnd.zzazz.deck+xml\nzip=application/zip\nzir=application/vnd.zul\nzirz=application/vnd.zul\nzmm=application/vnd.handheld-entertainment+xml\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/DeprecatedInterceptorTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.interceptor.TestInterceptor;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.net.URI;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\nimport javax.ws.rs.core.Response;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Tests handler interceptor.\n */\npublic class DeprecatedInterceptorTest extends InterceptorTestBase {\n    private final TestInterceptor interceptor1 = new TestInterceptor();\n    private final TestInterceptor interceptor2 = new TestInterceptor();\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private static final int port = Constants.PORT + 7;\n    private MicroservicesRunner microservicesRunner;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        microservicesRunner = new MicroservicesRunner(port);\n        microservicesRunner\n                .deploy(testMicroservice)\n                .addInterceptor(interceptor1, interceptor2)\n                .start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n        baseURI = URI.create(\"http://\" + Constants.HOSTNAME + \":\" + port);\n        Thread.sleep(100);\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n    }\n\n    @BeforeMethod\n    public void reset() {\n        interceptor1.reset();\n        interceptor2.reset();\n    }\n\n    @Test\n    public void testPreInterceptorReject() throws Exception {\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"X-Request-Type\", \"Reject\");\n        int status = doGetAndGetStatusCode(\"/test/v1/resource\", false, headers);\n        assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), status);\n\n        // Wait for any post handlers to be called\n        TimeUnit.MILLISECONDS.sleep(100);\n        assertEquals(1, interceptor1.getNumPreCalls());\n\n        // The second pre-call should not have happened due to rejection by the first pre-call\n        // None of the post calls should have happened.\n        assertEquals(0, interceptor1.getNumPostCalls());\n        assertEquals(0, interceptor2.getNumPreCalls());\n        assertEquals(0, interceptor2.getNumPostCalls());\n    }\n\n    @Test\n    public void testPreException() throws Exception {\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"X-Request-Type\", \"PreException\");\n        int status = doGetAndGetStatusCode(\"/test/v1/resource\", false, headers);\n        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), status);\n\n        // Wait for any post handlers to be called\n        TimeUnit.MILLISECONDS.sleep(100);\n        assertEquals(1, interceptor1.getNumPreCalls());\n\n        // The second pre-call should not have happened due to exception in the first pre-call\n        // None of the post calls should have happened.\n        assertEquals(0, interceptor1.getNumPostCalls());\n        assertEquals(0, interceptor2.getNumPreCalls());\n        assertEquals(0, interceptor2.getNumPostCalls());\n    }\n\n    @Test\n    public void testPostException() throws Exception {\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"X-Request-Type\", \"PostException\");\n        int status = doGetAndGetStatusCode(\"/test/v1/resource\", false, headers);\n        assertEquals(Response.Status.OK.getStatusCode(), status);\n\n        assertEquals(1, interceptor1.getNumPreCalls());\n        assertEquals(1, interceptor1.getNumPostCalls());\n\n        assertEquals(1, interceptor2.getNumPreCalls());\n        assertEquals(1, interceptor2.getNumPostCalls());\n    }\n\n    @Test\n    public void testUnknownPath() throws Exception {\n        int status = doGetAndGetStatusCode(\"/unknown/path/test/v1/resource\", false,\n                Collections.unmodifiableMap(Collections.emptyMap()));\n        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), status);\n\n        // Wait for any post handlers to be called\n        TimeUnit.MILLISECONDS.sleep(100);\n        assertEquals(0, interceptor1.getNumPreCalls());\n        assertEquals(0, interceptor1.getNumPostCalls());\n\n        assertEquals(0, interceptor2.getNumPreCalls());\n        assertEquals(0, interceptor2.getNumPostCalls());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/ExtendedServiceTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport com.google.gson.Gson;\nimport com.google.gson.reflect.TypeToken;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.Charsets;\nimport org.apache.commons.io.IOUtils;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.service.ExtendedTestMicroservice;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport java.util.Map;\nimport javax.ws.rs.HttpMethod;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Test for extended (inherited) microservices.\n */\npublic class ExtendedServiceTest {\n\n    public static final String HEADER_VAL_CLOSE = \"CLOSE\";\n    protected static final Type STRING_MAP_TYPE = new TypeToken<Map<String, String>>() {\n    }.getType();\n    protected static final Gson GSON = new Gson();\n\n    private final TestMicroservice testMicroservice = new ExtendedTestMicroservice();\n\n    private static final int port = Constants.PORT + 39;\n    protected static URI baseURI;\n\n    private MicroservicesRunner microservicesRunner;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"http://%s:%d\", Constants.HOSTNAME, port));\n        microservicesRunner = new MicroservicesRunner(port);\n        microservicesRunner\n                .deploy(testMicroservice)\n                .start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n        Thread.sleep(1000);\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n    }\n\n    /**\n     * Tests that an overridden method gets invoked.\n     *\n     * @throws IOException\n     */\n    @Test\n    public void testValidEndPoints() throws IOException {\n        HttpURLConnection urlConn = request(\"/ext-test/v1/resource?num=10\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled extended get in resource end-point\", map.get(\"status\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testPutWithData() throws IOException {\n        HttpURLConnection urlConn = request(\"/ext-test/v1/facebook/1/message\", HttpMethod.PUT);\n        writeContent(urlConn, \"Hello, World\");\n        assertEquals(200, urlConn.getResponseCode());\n\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled put in tweets end-point, id: 1. Content: Hello, World\", map.get(\"result\"));\n        urlConn.disconnect();\n    }\n\n    private HttpURLConnection request(String path, String method) throws IOException {\n        return request(path, method, false);\n    }\n\n    private HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n    private String getContent(HttpURLConnection urlConn) throws IOException {\n        return new String(IOUtils.toByteArray(urlConn.getInputStream()), Charsets.UTF_8);\n    }\n\n    protected void writeContent(HttpURLConnection urlConn, String content) throws IOException {\n        urlConn.getOutputStream().write(content.getBytes(Charsets.UTF_8));\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/HostBindingTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.testng.Assert;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.InetSocketAddress;\nimport java.net.NetworkInterface;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.util.Enumeration;\n\n/**\n * Testing the \"msf4j.host\" environment variable.\n */\npublic class HostBindingTest {\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    \n    /**\n     * Testing happy path.\n     */\n    @Test\n    public void testHostForMicroserviceRunner() throws InterruptedException {\n        MicroservicesRunner microservicesRunner = new MicroservicesRunner(3333);\n        microservicesRunner.deploy(testMicroservice);\n        microservicesRunner.start();\n        Thread.sleep(100);\n        Assert.assertTrue(this.isHostPortAvailable(\"127.0.0.1\", 3333),\n                                                                \"Unable to connect to service started on 127.0.0.1\");\n        Assert.assertTrue(this.isHostPortAvailable(\"localhost\", 3333),\n                                                                \"Unable to connect to service started on localhost\");\n        microservicesRunner.stop();\n    }\n    \n    /**\n     * Hosting a test microservice on 127.0.0.1 and check if it can be accessed with 127.0.0.1 and that it cannot be\n     * accessed through any other network ip.\n     */\n    @Test\n    public void testDifferentHostForMicroserviceRunner() throws SocketException, InterruptedException {\n        System.setProperty(\"msf4j.host\", \"127.0.0.1\");\n        MicroservicesRunner microservicesRunner = new MicroservicesRunner(4444);\n        microservicesRunner.deploy(testMicroservice);\n        microservicesRunner.start();\n        Thread.sleep(100);\n        Assert.assertTrue(this.isHostPortAvailable(\"127.0.0.1\", 4444),\n                                                                \"Unable to connect to service started on 127.0.0.1\");\n        Assert.assertTrue(this.isHostPortAvailable(\"localhost\", 4444),\n                                                                \"Unable to connect to service started on localhost\");\n        Enumeration e = NetworkInterface.getNetworkInterfaces();\n        while (e.hasMoreElements()) {\n            NetworkInterface n = (NetworkInterface) e.nextElement();\n            Enumeration ee = n.getInetAddresses();\n            while (ee.hasMoreElements()) {\n                InetAddress i = (InetAddress) ee.nextElement();\n                String networkHost = i.getHostAddress();\n                if (!networkHost.equals(\"127.0.0.1\") && !networkHost.equals(\"localhost\")) {\n                    Assert.assertFalse(this.isHostPortAvailable(networkHost, 4444),\n                                                                    \"Should not be able to connect on \" + networkHost);\n                }\n            }\n        }\n        System.clearProperty(\"msf4j.host\");\n        microservicesRunner.stop();\n    }\n    \n    /**\n     * Check if a port is open with a given host. An SO timeout of 3000 milliseconds is used.\n     * @param host The host to be checked.\n     * @param port The port to be checked.\n     * @return True if available, else false.\n     */\n    private boolean isHostPortAvailable(String host, int port) {\n        try {\n            boolean isConnected;\n            Socket client = new Socket();\n            client.connect(new InetSocketAddress(host, port), 3000);\n            isConnected = client.isConnected();\n            client.close();\n            return isConnected;\n        } catch (IOException ignored) {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/HttpResourceModelTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.router.HttpResourceModel;\n\nimport static org.testng.AssertJUnit.assertTrue;\n\n/**\n * Tests functionality fo HttpResourceModel.\n */\npublic class HttpResourceModelTest {\n\n    @Test\n    public void testStreamingReqSupportedCheckWhenStreamingSupported() throws NoSuchMethodException {\n        TestClass testObj = new TestClass();\n        HttpResourceModel httpResourceModel = new HttpResourceModel(\"\", testObj.getClass()\n                .getMethod(\"methodWithHttpStreaming\", HttpStreamer.class),\n                testObj, false);\n        assertTrue(httpResourceModel.isStreamingReqSupported());\n        assertTrue(httpResourceModel.isStreamingReqSupported());\n    }\n\n    @Test\n    public void testStreamingReqSupportedCheckWhenStreamingUnsupported() throws NoSuchMethodException {\n        TestClass testObj = new TestClass();\n        HttpResourceModel httpResourceModel = new HttpResourceModel(\"\", testObj.getClass()\n                .getMethod(\"methodWithNoHttpStreaming\", Object.class),\n                testObj, false);\n        assertTrue(!httpResourceModel.isStreamingReqSupported());\n        assertTrue(!httpResourceModel.isStreamingReqSupported());\n    }\n\n    /**\n     * Test class used for testing HttpResourceMethod functionality.\n     */\n    private static class TestClass {\n\n        public void methodWithHttpStreaming(HttpStreamer httpStreamer) {\n        }\n\n        public void methodWithNoHttpStreaming(Object object) {\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/HttpServerTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonObject;\nimport com.google.gson.reflect.TypeToken;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.Charsets;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.entity.ContentType;\nimport org.apache.http.entity.mime.MultipartEntityBuilder;\nimport org.apache.http.entity.mime.content.FileBody;\nimport org.apache.http.entity.mime.content.StringBody;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.beanconversion.BeanConversionException;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\nimport org.wso2.msf4j.internal.beanconversion.BeanConverter;\nimport org.wso2.msf4j.pojo.Category;\nimport org.wso2.msf4j.pojo.Pet;\nimport org.wso2.msf4j.pojo.TextBean;\nimport org.wso2.msf4j.pojo.XmlBean;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\nimport org.wso2.msf4j.service.sub.Player;\nimport org.wso2.msf4j.service.sub.Team;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\nimport java.io.PrintStream;\nimport java.io.RandomAccessFile;\nimport java.lang.reflect.Type;\nimport java.net.HttpURLConnection;\nimport java.net.Socket;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.core.HttpHeaders;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\n\nimport static org.testng.AssertJUnit.assertEquals;\nimport static org.testng.AssertJUnit.assertNotNull;\nimport static org.testng.AssertJUnit.assertNull;\nimport static org.testng.AssertJUnit.assertTrue;\nimport static org.testng.AssertJUnit.fail;\n\n/**\n * Test the HttpServer.\n */\npublic class HttpServerTest {\n    public static final String HEADER_VAL_CLOSE = \"CLOSE\";\n    protected static final Type STRING_MAP_TYPE = new TypeToken<Map<String, String>>() {\n    }.getType();\n    protected static final Gson GSON = new Gson();\n\n    public static File tmpFolder;\n\n    static {\n        try {\n            tmpFolder = Files.createTempDirectory(\"msf4j\").toFile();\n        } catch (IOException e) {\n            throw new RuntimeException(\"Error while creating tenp directory\", e);\n        }\n    }\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private final SecondService secondService = new SecondService();\n\n    private static final int port = Constants.PORT + 1;\n    protected static URI baseURI;\n\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"http://%s:%d\", Constants.HOSTNAME, port));\n        microservicesRunner = new MicroservicesRunner(port);\n        microservicesRunner\n                .addExceptionMapper(new TestExceptionMapper(), new TestExceptionMapper2())\n                .deploy(testMicroservice)\n                .start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n    }\n\n    @Test\n    public void testMultipleMicroServiceRunners() throws IOException {\n        HttpURLConnection urlConn =\n                request(\"/SecondService/addNumbers/9/25\", HttpMethod.GET, false, baseURI.getPort() + 1);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n\n        assertEquals(34, Integer.parseInt(content));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testDynamicMicroserviceRegistration() throws IOException {\n        HttpURLConnection urlConn = request(\"/DynamicPath/hello/MSF4J\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n        assertEquals(\"Hello MSF4J\", content);\n        urlConn.disconnect();\n\n        urlConn = request(\"/DynamicPath2/hello/MSF4J\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        content = getContent(urlConn);\n        assertEquals(\"Hello MSF4J\", content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testValidEndPoints() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/resource?num=10\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled get in resource end-point\", map.get(\"status\"));\n        urlConn.disconnect();\n\n        urlConn = request(\"/test/v1/tweets/1\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        content = getContent(urlConn);\n        map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled get in tweets end-point, id: 1\", map.get(\"status\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testSmallFileUpload() throws IOException {\n        testStreamUpload(10, \"testSmallFileUpload.txt\");\n    }\n\n    @Test\n    public void testLargeFileUpload() throws IOException {\n        testStreamUpload(1000000, \"testLargeFileUpload.txt\");\n    }\n\n    protected void testStreamUpload(int size, String filename) throws IOException {\n        //create a random file to be uploaded.\n        File fname = new File(tmpFolder, filename);\n        fname.createNewFile();\n        RandomAccessFile randf = new RandomAccessFile(fname, \"rw\");\n        String contentStr = IntStream.range(0, size)\n                .mapToObj(value -> String.valueOf((int) (Math.random() * 1000)))\n                .collect(Collectors.joining(\"\"));\n        randf.write(contentStr.getBytes(Charsets.UTF_8));\n        randf.close();\n\n        //test stream upload\n        HttpURLConnection urlConn = request(\"/test/v1/stream/upload\", HttpMethod.PUT);\n        Files.copy(Paths.get(fname.toURI()), urlConn.getOutputStream());\n        assertEquals(200, urlConn.getResponseCode());\n        String contentFromServer = getContent(urlConn);\n        assertEquals(contentStr, contentFromServer);\n        urlConn.disconnect();\n        fname.delete();\n    }\n\n    //    @Test\n    public void testStreamUploadFailure() throws IOException {\n        //create a random file to be uploaded.\n        int size = 20 * 1024;\n        File fname = new File(tmpFolder, \"testStreamUploadFailure.txt\");\n        fname.createNewFile();\n        RandomAccessFile randf = new RandomAccessFile(fname, \"rw\");\n        randf.setLength(size);\n        randf.close();\n\n        HttpURLConnection urlConn = request(\"/test/v1/stream/upload/fail\", HttpMethod.PUT);\n        Files.copy(Paths.get(fname.toURI()), urlConn.getOutputStream());\n        assertEquals(500, urlConn.getResponseCode());\n        urlConn.disconnect();\n        fname.delete();\n    }\n\n    @Test\n    public void testChunkAggregatedUpload() throws IOException {\n        //create a random file to be uploaded.\n        int size = 69 * 1024;\n        File fname = new File(tmpFolder, \"testChunkAggregatedUpload.txt\");\n        fname.createNewFile();\n        RandomAccessFile randf = new RandomAccessFile(fname, \"rw\");\n        randf.setLength(size);\n        randf.close();\n\n        //test chunked upload\n        HttpURLConnection urlConn = request(\"/test/v1/aggregate/upload\", HttpMethod.PUT);\n        urlConn.setChunkedStreamingMode(1024);\n        Files.copy(Paths.get(fname.toURI()), urlConn.getOutputStream());\n        assertEquals(200, urlConn.getResponseCode());\n\n        assertEquals(size, Integer.parseInt(getContent(urlConn).split(\":\")[1].trim()));\n        urlConn.disconnect();\n        fname.delete();\n    }\n\n    //    @Test\n    public void testChunkAggregatedUploadFailure() throws IOException {\n        //create a random file to be uploaded.\n        int size = 78 * 1024;\n        File fname = new File(tmpFolder, \"testChunkAggregatedUploadFailure.txt\");\n        fname.createNewFile();\n        RandomAccessFile randf = new RandomAccessFile(fname, \"rw\");\n        randf.setLength(size);\n        randf.close();\n\n        //test chunked upload\n        HttpURLConnection urlConn = request(\"/test/v1/aggregate/upload\", HttpMethod.PUT);\n        urlConn.setChunkedStreamingMode(1024);\n        Files.copy(Paths.get(fname.toURI()), urlConn.getOutputStream());\n        assertEquals(500, urlConn.getResponseCode());\n        urlConn.disconnect();\n        fname.delete();\n    }\n\n    @Test\n    public void testPathWithMultipleMethods() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/tweets/1\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        urlConn.disconnect();\n\n        urlConn = request(\"/test/v1/tweets/1\", HttpMethod.PUT);\n        writeContent(urlConn, \"data\");\n        assertEquals(200, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n\n    @Test\n    public void testNonExistingEndPoints() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/users\", HttpMethod.POST);\n        writeContent(urlConn, \"data\");\n        assertEquals(404, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testPutWithData() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/facebook/1/message\", HttpMethod.PUT);\n        writeContent(urlConn, \"Hello, World\");\n        assertEquals(200, urlConn.getResponseCode());\n\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled put in tweets end-point, id: 1. Content: Hello, World\", map.get(\"result\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testPostWithData() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/facebook/1/message\", HttpMethod.POST);\n        writeContent(urlConn, \"Hello, World\");\n        assertEquals(200, urlConn.getResponseCode());\n\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled post in tweets end-point, id: 1. Content: Hello, World\", map.get(\"result\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNonExistingMethods() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/facebook/1/message\", HttpMethod.GET);\n        assertEquals(405, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testMultiplePathParameters() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/user/sree/message/12\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled multiple path parameters sree 12\", map.get(\"result\"));\n        urlConn.disconnect();\n    }\n\n    //Test the end point where the parameter in path and order of declaration in method signature are different\n    @Test\n    public void testMultiplePathParametersWithParamterInDifferentOrder() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/message/21/user/sree\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(1, map.size());\n        assertEquals(\"Handled multiple path parameters sree 21\", map.get(\"result\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNotRoutablePathParamMismatch() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/NotRoutable/sree\", HttpMethod.GET);\n        assertEquals(500, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testMultiMatchParamPut() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/multi-match/bar\", HttpMethod.PUT);\n        assertEquals(405, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testHandlerException() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/uexception\", HttpMethod.GET);\n        assertEquals(500, urlConn.getResponseCode());\n        // assertEquals(\"Exception encountered while processing request : User Exception\",\n        //         new String(ByteStreams.toByteArray(urlConn.getErrorStream()), Charsets.UTF_8));\n        urlConn.disconnect();\n    }\n\n    /**\n     * Test that the TestChannelHandler that was added using the builder adds the correct header field and value.\n     *\n     * @throws Exception\n     */\n    /*@Test\n    public void testChannelPipelineModification() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/tweets/1\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        assertEquals(urlConn.getHeaderField(TestChannelHandler.HEADER_FIELD), TestChannelHandler.HEADER_VALUE);\n    }*/\n    @Test\n    public void testMultiMatchFoo() throws Exception {\n        testContent(\"/test/v1/multi-match/foo\", \"multi-match-get-actual-foo\");\n    }\n\n    @Test\n    public void testMultiMatchAll() throws Exception {\n        testContent(\"/test/v1/multi-match/foo/baz/id\", \"multi-match-*\");\n    }\n\n    @Test\n    public void testMultiMatchParam() throws Exception {\n        testContent(\"/test/v1/multi-match/bar\", \"multi-match-param-bar\");\n    }\n\n    @Test\n    public void testMultiMatchParamBar() throws Exception {\n        testContent(\"/test/v1/multi-match/id/bar\", \"multi-match-param-bar-id\");\n    }\n\n    @Test\n    public void testMultiMatchFooParamBar() throws Exception {\n        testContent(\"/test/v1/multi-match/foo/id/bar\", \"multi-match-foo-param-bar-id\");\n    }\n\n    @Test\n    public void testMultiMatchFooBarParam() throws Exception {\n        testContent(\"/test/v1/multi-match/foo/bar/id\", \"multi-match-foo-bar-param-id\");\n    }\n\n    @Test\n    public void testMultiMatchFooBarParamId() throws Exception {\n        testContent(\"/test/v1/multi-match/foo/bar/bar/bar\", \"multi-match-foo-bar-param-bar-id-bar\");\n    }\n\n    @Test\n    public void testMultiMatchFooPut() throws Exception {\n        testContent(\"/test/v1/multi-match/foo\", \"multi-match-put-actual-foo\", HttpMethod.PUT);\n    }\n\n    //@Test\n    public void testChunkResponse() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/chunk\", HttpMethod.POST);\n        try {\n            writeContent(urlConn, \"Testing message\");\n            String response = getContent(urlConn);\n            assertEquals(\"Testing message\", response);\n        } finally {\n            urlConn.disconnect();\n        }\n    }\n\n    @Test\n    public void testStringQueryParam() throws IOException {\n        // First send without query, for String type, should get defaulted to null.\n        testContent(\"/test/v1/stringQueryParam/mypath\", \"mypath:null\", HttpMethod.GET);\n\n        // Then send with query, should response with the given name.\n        testContent(\"/test/v1/stringQueryParam/mypath?name=netty\", \"mypath:netty\", HttpMethod.GET);\n    }\n\n    @Test\n    public void testPrimitiveQueryParam() throws IOException {\n        // For primitive type, if missing parameter, should get defaulted to Java primitive default value.\n        testContent(\"/test/v1/primitiveQueryParam\", \"0\", HttpMethod.GET);\n\n        testContent(\"/test/v1/primitiveQueryParam?age=20\", \"20\", HttpMethod.GET);\n    }\n\n    @Test\n    public void testSortedSetQueryParam() throws IOException {\n        // For collection, if missing parameter, should get defaulted to empty collection\n        testContent(\"/test/v1/sortedSetQueryParam\", \"\", HttpMethod.GET);\n\n        // Try different way of passing the ids, they should end up de-dup and sorted.\n        testContent(\"/test/v1/sortedSetQueryParam?id=30&id=10&id=20&id=30\", \"10,20,30\", HttpMethod.GET);\n        testContent(\"/test/v1/sortedSetQueryParam?id=10&id=30&id=20&id=20\", \"10,20,30\", HttpMethod.GET);\n        testContent(\"/test/v1/sortedSetQueryParam?id=20&id=30&id=20&id=10\", \"10,20,30\", HttpMethod.GET);\n    }\n\n    @Test\n    public void testListHeaderParam() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/listHeaderParam\", HttpMethod.GET);\n        urlConn.addRequestProperty(\"name\", \"name1,name3,name2,name1\");\n        assertEquals(200, urlConn.getResponseCode());\n        assertEquals(\"name1,name3,name2,name1\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testHeaderResponse() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/headerResponse\", HttpMethod.GET);\n        urlConn.addRequestProperty(\"name\", \"name1\");\n\n        assertEquals(200, urlConn.getResponseCode());\n        assertEquals(\"name1\", urlConn.getHeaderField(\"name\"));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testDefaultQueryParam() throws IOException {\n        // Submit with no parameters. Each should get the default values.\n        HttpURLConnection urlConn = request(\"/test/v1/defaultValue\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        JsonObject json = GSON.fromJson(getContent(urlConn), JsonObject.class);\n\n        Type hobbyType = new TypeToken<List<String>>() {\n        }.getType();\n\n        assertEquals(30, json.get(\"age\").getAsLong());\n        assertEquals(\"hello\", json.get(\"name\").getAsString());\n        assertEquals(Collections.singletonList(\"casking\"),\n                     GSON.fromJson(json.get(\"hobby\").getAsJsonArray(), hobbyType));\n\n        urlConn.disconnect();\n    }\n\n    @Test(timeOut = 5000)\n    public void testConnectionClose() throws Exception {\n        URL url = baseURI.resolve(\"/test/v1/connectionClose\").toURL();\n\n        // Fire http request using raw socket so that we can verify the connection get closed by the server\n        // after the response.\n        Socket socket = createRawSocket(url);\n        try {\n            PrintStream printer = new PrintStream(socket.getOutputStream(), false, \"UTF-8\");\n            printer.printf(\"GET %s HTTP/1.1\\r\\n\", url.getPath());\n            printer.printf(\"Host: %s:%d\\r\\n\", url.getHost(), url.getPort());\n            printer.printf (\"%s: close\\r\\n\", HttpHeaderNames.CONNECTION.toString());\n            printer.print(\"\\r\\n\");\n            printer.flush();\n\n            // Just read everything from the response. Since the server will close the connection, the read loop should\n            // end with an EOF. Otherwise there will be timeout of this test case\n            String response = IOUtils.toString(new InputStreamReader(socket.getInputStream(), Charsets.UTF_8));\n            assertTrue(response.startsWith(\"HTTP/1.1 200 OK\"));\n        } finally {\n            socket.close();\n        }\n    }\n\n    @Test\n    public void testUploadReject() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/uploadReject\", HttpMethod.POST, true);\n        try {\n            urlConn.setChunkedStreamingMode(1024);\n            urlConn.getOutputStream().write(\"Rejected Content\".getBytes(Charsets.UTF_8));\n            try {\n                urlConn.getInputStream();\n                fail();\n            } catch (IOException e) {\n                // Expect to get exception since server response with 400. Just drain the error stream.\n                IOUtils.toByteArray(urlConn.getErrorStream());\n                assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), urlConn.getResponseCode());\n            }\n        } finally {\n            urlConn.disconnect();\n        }\n    }\n\n    @Test\n    public void testNoPathGetMethod() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1\", HttpMethod.GET);\n        assertEquals(\"no-@Path-GET\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNoPathPostMethod() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1\", HttpMethod.POST);\n        assertEquals(\"no-@Path-POST\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNoPathPutMethod() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1\", HttpMethod.PUT);\n        assertEquals(\"no-@Path-PUT\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNoPathDeleteMethod() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1\", HttpMethod.DELETE);\n        assertEquals(\"no-@Path-DELETE\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testSleep() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/sleep/10\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testWrongMethod() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/customException\", HttpMethod.GET);\n        assertEquals(Response.Status.METHOD_NOT_ALLOWED.getStatusCode(), urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testExceptionHandler() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/customException\", HttpMethod.POST);\n        assertEquals(TestMicroservice.CustomException.HTTP_RESPONSE_STATUS, urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testConsumeJsonProduceString() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/jsonConsumeStringProduce\", HttpMethod.POST);\n        urlConn.setRequestProperty(HttpHeaders.CONTENT_TYPE, \"text/json\");\n        Gson gson = new Gson();\n        Pet pet = petInstance();\n        writeContent(urlConn, gson.toJson(pet));\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(pet.getDetails(), getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testConsumeStringProduceJson() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/textConsumeJsonProduce\", HttpMethod.POST);\n        urlConn.setRequestProperty(HttpHeaders.CONTENT_TYPE, \"text/plain\");\n        String str = \"send-something\";\n        writeContent(urlConn, str);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        Gson gson = new Gson();\n        String content = getContent(urlConn);\n        TextBean textBean = gson.fromJson(content, TextBean.class);\n        assertEquals(str, textBean.getText());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testConsumeStringProduceString() throws IOException {\n        HttpURLConnection urlConn = request(\"/test/v1/textConsumeTextProduce\", HttpMethod.POST);\n        urlConn.setRequestProperty(HttpHeaders.CONTENT_TYPE, \"text/plain\");\n        String str = \"send-something\";\n        writeContent(urlConn, str);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(str + \"-processed\", getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testConsumeXmlProduceXml() throws IOException, BeanConversionException {\n        HttpURLConnection urlConn = request(\"/test/v1/textConsumeTextProduceXml\", HttpMethod.POST);\n        urlConn.setRequestProperty(HttpHeaders.CONTENT_TYPE, \"text/xml\");\n        XmlBean xmlBean = new XmlBean();\n        xmlBean.setName(\"send-something\");\n        xmlBean.setId(10);\n        xmlBean.setValue(15);\n        writeContent(urlConn, Charset.defaultCharset()\n                .decode(BeanConverter.getConverter(\"text/xml\").convertToMedia(xmlBean)).toString());\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String respBody = getContent(urlConn);\n        XmlBean xmlBean2 = (XmlBean) BeanConverter.getConverter(\"text/xml\").convertToObject(\n                ByteBuffer.wrap(respBody.getBytes(Charset.defaultCharset())), XmlBean.class);\n        assertEquals(xmlBean.getName(), xmlBean2.getName());\n        assertEquals(xmlBean.getId(), xmlBean2.getId());\n        assertEquals(xmlBean.getValue(), xmlBean2.getValue());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testDownloadPngFile() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/png\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"image/png\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n    @Test\n    public void testDownloadPngFileFromInputStream() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/ip/png\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"image/png\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n\n    @Test\n    public void testDownloadJpgFile() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/jpg\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(\"wso2\", urlConn.getHeaderField(\"X-Custom-Header\"));\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"image/jpeg\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n    @Test\n    public void testDownloadJpgFileFromInputStream() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/ip/jpg\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(\"wso2\", urlConn.getHeaderField(\"X-Custom-Header\"));\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"image/jpeg\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n    @Test\n    public void testDownloadTxtFile() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/txt\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"text/plain\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n    @Test\n    public void testDownloadTxtFileFromInputStream() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/fileserver/ip/txt\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(\"text/plain\".equalsIgnoreCase(contentType));\n        InputStream downStream = urlConn.getInputStream();\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI());\n        assertTrue(isStreamEqual(downStream, new FileInputStream(file)));\n    }\n\n    @Test\n    public void testGzipCompressionWithNoGzipAccept() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/gzipfile\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentEncoding = urlConn.getHeaderField(HttpHeaders.CONTENT_ENCODING);\n        assertTrue(contentEncoding == null || !contentEncoding.contains(\"gzip\"));\n        InputStream downStream = urlConn.getInputStream();\n        assertTrue(IOUtils.toByteArray(downStream).length == IOUtils.toByteArray(\n                Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").openStream()).length);\n    }\n\n    @Test\n    public void testGzipCompressionWithGzipAccept() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/gzipfile\", HttpMethod.GET);\n        urlConn.addRequestProperty(HttpHeaders.ACCEPT_ENCODING, \"gzip\");\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentEncoding = urlConn.getHeaderField(HttpHeaders.CONTENT_ENCODING);\n        assertTrue(\"gzip\".equalsIgnoreCase(contentEncoding));\n        InputStream downStream = urlConn.getInputStream();\n        assertTrue(IOUtils.toByteArray(downStream).length < IOUtils.toByteArray(\n                Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").openStream()).length);\n    }\n\n    @Test\n    public void testContentTypeSetting0() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/response/typehtml\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(contentType.equalsIgnoreCase(MediaType.TEXT_HTML));\n        String content = getContent(urlConn);\n        assertEquals(\"Hello\", content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testContentTypeSetting1() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/response/typehtml/str\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        String contentType = urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE);\n        assertTrue(contentType.equalsIgnoreCase(MediaType.TEXT_HTML));\n        String content = getContent(urlConn);\n        assertEquals(\"Hello\", content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testExceptionMapper() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/mappedException\", HttpMethod.GET);\n        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(MediaType.TEXT_PLAIN, urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testExceptionMapper2() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/mappedException2\", HttpMethod.GET);\n        assertEquals(Response.Status.EXPECTATION_FAILED.getStatusCode(), urlConn.getResponseCode());\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void tesFormParamWithURLEncoded() throws IOException {\n        HttpURLConnection connection = request(\"/test/v1/formParam\", HttpMethod.POST);\n        String rawData = \"name=wso2&age=10\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"wso2:10\");\n    }\n\n    @Test\n    public void testFormParamWithMultipart() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/formParam\", HttpMethod.POST);\n        MultipartEntityBuilder builder = MultipartEntityBuilder.create();\n        builder.addPart(\"name\", new StringBody(\"wso2\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"age\", new StringBody(\"10\", ContentType.TEXT_PLAIN));\n        HttpEntity build = builder.build();\n        connection.setRequestProperty(\"Content-Type\", build.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            build.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"wso2:10\");\n    }\n\n    @Test\n    public void testFormDataParamWithSimpleRequest() throws IOException, URISyntaxException {\n        // Send x-form-url-encoded request\n        HttpURLConnection connection = request(\"/test/v1/formDataParam\", HttpMethod.POST);\n        String rawData = \"name=wso2&age=10\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"wso2:10\");\n\n        // Send multipart/form-data request\n        connection = request(\"/test/v1/formDataParam\", HttpMethod.POST);\n        MultipartEntityBuilder builder = MultipartEntityBuilder.create();\n        builder.addPart(\"name\", new StringBody(\"wso2\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"age\", new StringBody(\"10\", ContentType.TEXT_PLAIN));\n        HttpEntity build = builder.build();\n        connection.setRequestProperty(\"Content-Type\", build.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            build.writeTo(out);\n        }\n\n        inputStream = connection.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"wso2:10\");\n    }\n\n    @Test\n    public void tesFormParamWithCollection() throws IOException {\n        // Send x-form-url-encoded request\n        HttpURLConnection connection = request(\"/test/v1/formParamWithList\", HttpMethod.POST);\n        String rawData = \"names=WSO2&names=IBM\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"2\");\n\n        // Send multipart/form-data request\n        connection = request(\"/test/v1/formParamWithList\", HttpMethod.POST);\n        MultipartEntityBuilder builder = MultipartEntityBuilder.create();\n        builder.addPart(\"names\", new StringBody(\"WSO2\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"names\", new StringBody(\"IBM\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"names\", new StringBody(\"Oracle\", ContentType.TEXT_PLAIN));\n        HttpEntity build = builder.build();\n        connection.setRequestProperty(\"Content-Type\", build.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            build.writeTo(out);\n        }\n\n        inputStream = connection.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"3\");\n\n        // Send x-form-url-encoded request\n        connection = request(\"/test/v1/formParamWithSet\", HttpMethod.POST);\n        rawData = \"names=WSO2&names=IBM&names=IBM\";\n        encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        inputStream = connection.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"2\");\n\n        // Send multipart/form-data request\n        connection = request(\"/test/v1/formParamWithSet\", HttpMethod.POST);\n        builder = MultipartEntityBuilder.create();\n        builder.addPart(\"names\", new StringBody(\"WSO2\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"names\", new StringBody(\"IBM\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"names\", new StringBody(\"IBM\", ContentType.TEXT_PLAIN));\n        builder.addPart(\"names\", new StringBody(\"Oracle\", ContentType.TEXT_PLAIN));\n        build = builder.build();\n        connection.setRequestProperty(\"Content-Type\", build.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            build.writeTo(out);\n        }\n\n        inputStream = connection.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"3\");\n    }\n\n    @Test\n    public void testFormParamWithFile() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/testFormParamWithFile\", HttpMethod.POST);\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI());\n        MultipartEntityBuilder builder = MultipartEntityBuilder.create();\n        FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);\n        builder.addPart(\"form\", fileBody);\n        HttpEntity build = builder.build();\n        connection.setRequestProperty(\"Content-Type\", build.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            build.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, file.getName());\n    }\n\n    @Test\n    public void testFormDataParamWithComplexForm() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/complexForm\", HttpMethod.POST);\n        StringBody companyText = new StringBody(\"{\\\"type\\\": \\\"Open Source\\\"}\", ContentType.APPLICATION_JSON);\n        StringBody personList = new StringBody(\n                \"[{\\\"name\\\":\\\"Richard Stallman\\\",\\\"age\\\":63}, {\\\"name\\\":\\\"Linus Torvalds\\\",\\\"age\\\":46}]\",\n                ContentType.APPLICATION_JSON);\n        HttpEntity reqEntity = MultipartEntityBuilder.create()\n                .addTextBody(\"id\", \"1\")\n                .addPart(\"company\", companyText)\n                .addPart(\"people\", personList)\n                .addBinaryBody(\"file\",\n                        new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI()),\n                               ContentType.DEFAULT_BINARY, \"testTxtFile.txt\").build();\n\n        connection.setRequestProperty(\"Content-Type\", reqEntity.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            reqEntity.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"testTxtFile.txt:1:2:Open Source\");\n    }\n\n    @Test\n    public void testFormDataParamWithMultipleFiles() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/multipleFiles\", HttpMethod.POST);\n        File file1 = new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI());\n        File file2 = new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI());\n        HttpEntity reqEntity = MultipartEntityBuilder.create().\n                addBinaryBody(\"files\", file1, ContentType.DEFAULT_BINARY, file1.getName())\n                .addBinaryBody(\"files\", file2, ContentType.DEFAULT_BINARY,\n                        file2.getName()).build();\n\n        connection.setRequestProperty(\"Content-Type\", reqEntity.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            reqEntity.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(response, \"2\");\n    }\n\n    @Test\n    public void testFormDataParamWithFileStream() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/streamFile\", HttpMethod.POST);\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI());\n        HttpEntity reqEntity = MultipartEntityBuilder.create().\n                addBinaryBody(\"file\", file, ContentType.DEFAULT_BINARY, file.getName()).build();\n\n        connection.setRequestProperty(\"Content-Type\", reqEntity.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            reqEntity.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        StringBuilder stringBuilder = new StringBuilder();\n        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {\n            while (bufferedReader.ready()) {\n                stringBuilder.append(bufferedReader.readLine());\n            }\n        }\n        assertEquals(response, stringBuilder.toString() + \"-\" + file.getName());\n    }\n\n    @Test\n    public void testGetAllFormItemsWithURLEncoded() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/getAllFormItemsURLEncoded\", HttpMethod.POST);\n        String rawData = \"names=WSO2&names=IBM&age=10&type=Software\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(\"No of Companies-2 type-Software\", response);\n    }\n\n    @Test\n    public void getAllFormItemsMultipart() throws IOException, URISyntaxException {\n        HttpURLConnection connection = request(\"/test/v1/getAllFormItemsMultipart\", HttpMethod.POST);\n        StringBody companyText = new StringBody(\"{\\\"type\\\": \\\"Open Source\\\"}\", ContentType.APPLICATION_JSON);\n        StringBody personList = new StringBody(\n                \"[{\\\"name\\\":\\\"Richard Stallman\\\",\\\"age\\\":63}, {\\\"name\\\":\\\"Linus Torvalds\\\",\\\"age\\\":46}]\",\n                ContentType.APPLICATION_JSON);\n        HttpEntity reqEntity = MultipartEntityBuilder.create()\n                .addTextBody(\"id\", \"1\")\n                .addPart(\"company\", companyText)\n                .addPart(\"people\", personList)\n                .addBinaryBody(\"file\",\n                        new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI()),\n                        ContentType.DEFAULT_BINARY, \"testTxtFile.txt\")\n                .addBinaryBody(\"file\",\n                        new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI()),\n                        ContentType.DEFAULT_BINARY, \"testPngFile.png\")\n                .build();\n\n        connection.setRequestProperty(\"Content-Type\", reqEntity.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            reqEntity.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(\"FileCount-2 SecondFileName-testPngFile.png FirstPerson-Richard Stallman\", response);\n\n        connection = request(\"/test/v1/getAllFormItemsXFormUrlEncoded\", HttpMethod.POST);\n        String rawData = \"names=WSO2&names=IBM&type=Software\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = connection.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n\n        inputStream = connection.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        assertEquals(\"Type = Software No of names = 2 First name = IBM\", response);\n    }\n\n    @Test\n    public void testPathParamWithRegexOne() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/WSDL/12/states\", HttpMethod.GET);\n\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(response, \"Asset Type = WSDL, Asset Id = 12\");\n    }\n\n    @Test\n    public void testPathParamWithRegexTwo() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/endpoints/WADL/10\", HttpMethod.GET);\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(response, \"Asset Type = WADL, Asset Id = 10\");\n    }\n\n    @Test\n    public void testDualInvocation() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/testDualInvocation1\", HttpMethod.GET);\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"1\", response);\n\n        urlConn = request(\"/test/v1/testDualInvocation2\", HttpMethod.GET);\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"2\", response);\n    }\n\n    @Test\n    public void testJsonProduceWithStringJsonArrayAndJsonObject() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/testJsonProduceWithString\", HttpMethod.GET);\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"{\\\"abc\\\":[{\\\"name\\\":\\\"Richard Stallman\\\",\\\"age\\\":63}, {\\\"name\\\":\\\"Linus Torvalds\\\",\\\"age\\\":46}]}\",\n                response);\n\n        urlConn = request(\"/test/v1/testJsonProduceWithJsonArray\", HttpMethod.GET);\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"[\\\"12\\\",\\\"15\\\",\\\"15\\\"]\", response);\n\n        urlConn = request(\"/test/v1/testJsonProduceWithJsonObject\", HttpMethod.GET);\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"{\\\"name\\\":\\\"WSO2\\\",\\\"products\\\":[\\\"APIM\\\",\\\"IS\\\",\\\"MSF4J\\\"]}\", response);\n    }\n\n    @Test\n    public void testSetAndGetFromSession() throws Exception {\n        long value = System.currentTimeMillis();\n\n        // Request to first operation\n        HttpURLConnection urlConn = request(\"/test/v1/set-session/\" + value, HttpMethod.GET);\n        assertEquals(204, urlConn.getResponseCode());\n        String setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(setCookieHeader);\n        urlConn.disconnect();\n\n        // Request to 2nd operation\n        urlConn = request(\"/test/v1/get-session/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", setCookieHeader);\n        assertEquals(200, urlConn.getResponseCode());\n        setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNull(setCookieHeader);\n        String content = getContent(urlConn); // content retrieved & returned from session\n        assertEquals(String.valueOf(value), content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testSetAndGetFromSession2() throws Exception {\n        long value = System.currentTimeMillis();\n\n        // Request to first operation\n        HttpURLConnection urlConn = request(\"/test/v1/set-session2/\" + value, HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(setCookieHeader);\n        String content = getContent(urlConn);\n        assertEquals(String.valueOf(value), content);\n        urlConn.disconnect();\n\n        // Request to 2nd operation\n        urlConn = request(\"/test/v1/get-session/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", setCookieHeader);\n        assertEquals(200, urlConn.getResponseCode());\n        setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNull(setCookieHeader);\n        content = getContent(urlConn);  // content retrieved & returned from session\n        assertEquals(String.valueOf(value), content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testSessionExpiry() throws Exception {\n        long value = System.currentTimeMillis();\n\n        // Request to first operation\n        HttpURLConnection urlConn = request(\"/test/v1/set-session2/\" + value, HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(setCookieHeader);\n        String content = getContent(urlConn);\n        assertEquals(String.valueOf(value), content);\n        urlConn.disconnect();\n\n        // Request to 2nd operation\n        urlConn = request(\"/test/v1/get-session/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", setCookieHeader);\n        assertEquals(200, urlConn.getResponseCode());\n        setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNull(setCookieHeader);\n        content = getContent(urlConn);  // content retrieved & returned from session\n        assertEquals(String.valueOf(value), content);\n        urlConn.disconnect();\n\n        // Expire the session\n        urlConn = request(\"/test/v1/expire-session/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", setCookieHeader);\n        assertEquals(204, urlConn.getResponseCode());\n        setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNull(setCookieHeader);\n        urlConn.disconnect();\n\n        // Try to retrieve the object stored in the expired session\n        urlConn = request(\"/test/v1/get-session/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", setCookieHeader);\n        assertEquals(204, urlConn.getResponseCode());\n        setCookieHeader = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(setCookieHeader);\n        content = getContent(urlConn);  // content retrieved & returned from session\n        assertEquals(\"\", content);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testCookieParam() throws Exception {\n        String value = \"wso2\";\n\n        HttpURLConnection urlConn = request(\"/test/v1/cookie/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", \"name=\" + value);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n        assertEquals(value, content);\n        String cookie = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(cookie);\n        assertEquals(\"test-cookie=\" + value + \";Path=/cookie;Domain=wso2.com;MaxAge=10;Comment=Cookie Test;\" +\n                \"Expires=Sat, 31 Dec 2016 18:30:00 GMT;Secure;HttpOnly\", cookie);\n        urlConn.disconnect();\n\n        value = \"Apache\";\n        urlConn = request(\"/test/v1/cookie/\", HttpMethod.GET);\n        urlConn.setRequestProperty(\"Cookie\", \"name=\" + value);\n        assertEquals(200, urlConn.getResponseCode());\n        content = getContent(urlConn);\n        assertEquals(value, content);\n        cookie = urlConn.getHeaderField(\"Set-Cookie\");\n        assertNotNull(cookie);\n        assertEquals(\"test-cookie=\" + value, cookie);\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testSubResources() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/SL/team\", HttpMethod.GET);\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        Team team = GSON.fromJson(response, Team.class);\n        assertEquals(\"Cricket\", team.getTeamType());\n        assertEquals(\"SL\", team.getCountryId());\n\n\n        urlConn = request(\"/test/v1/SL/team\", HttpMethod.POST);\n        String rawData = \"countryName=SriLanka\";\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        urlConn.setRequestMethod(\"POST\");\n        urlConn.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        urlConn.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = urlConn.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        team = GSON.fromJson(response, Team.class);\n        assertEquals(\"Cricket\", team.getTeamType());\n        assertEquals(\"SL\", team.getCountryId());\n        assertEquals(\"SriLanka\", team.getCountryName());\n\n\n        urlConn = request(\"/test/v1/SL/team/123\", HttpMethod.POST);\n        rawData = \"countryName=SriLanka&type=Batsman\";\n        encodedData = Charset.defaultCharset().encode(rawData);\n        urlConn.setRequestMethod(\"POST\");\n        urlConn.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        urlConn.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = urlConn.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        Player player = GSON.fromJson(response, Player.class);\n        assertEquals(\"player_1\", player.getName());\n        assertEquals(123, player.getPlayerId());\n        assertEquals(\"SL\", player.getCountryId());\n        assertEquals(\"SriLanka\", player.getCountryName());\n        assertEquals(30, player.getAge());\n        assertEquals(\"Batsman\", player.getType());\n\n\n        urlConn = request(\"/test/v1/SL/team/123/details/name\", HttpMethod.POST);\n        rawData = \"countryName=SriLanka&type=Batsman\";\n        encodedData = Charset.defaultCharset().encode(rawData);\n        urlConn.setRequestMethod(\"POST\");\n        urlConn.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        urlConn.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = urlConn.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n        inputStream = urlConn.getInputStream();\n        response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        urlConn.disconnect();\n        assertEquals(\"SL_123_name_Batsman_SriLanka\", response);\n    }\n\n    @Test\n    public void testLocation() throws Exception {\n        HttpURLConnection urlConn = request(\"/test/v1/locationRealtiveUriTest\", HttpMethod.GET);\n        assertEquals(201, urlConn.getResponseCode());\n        String location = urlConn.getHeaderField(\"Location\");\n        assertEquals(\"http://\" + baseURI.getHost() + \":\" + baseURI.getPort() + \"/entity/1\", location);\n        urlConn.disconnect();\n\n        urlConn = request(\"/test/v1/locationAbsoluteUriTest\", HttpMethod.GET);\n        assertEquals(201, urlConn.getResponseCode());\n        location = urlConn.getHeaderField(\"Location\");\n        assertEquals(\"http://localhost:8080/products/entity/2\", location);\n        urlConn.disconnect();\n    }\n\n    protected Socket createRawSocket(URL url) throws IOException {\n        return new Socket(url.getHost(), url.getPort());\n    }\n\n    protected void testContent(String path, String content) throws IOException {\n        testContent(path, content, HttpMethod.GET);\n    }\n\n    protected void testContent(String path, String content, String method) throws IOException {\n        HttpURLConnection urlConn = request(path, method);\n        assertEquals(200, urlConn.getResponseCode());\n        assertEquals(content, getContent(urlConn));\n        urlConn.disconnect();\n    }\n\n    protected HttpURLConnection request(String path, String method) throws IOException {\n        return request(path, method, false);\n    }\n\n    protected HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n    protected HttpURLConnection request(String path, String method, boolean keepAlive, int port) throws IOException {\n        URL url = URI.create(String.format(\"http://%s:%d\", Constants.HOSTNAME, port)).resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n    protected String getContent(HttpURLConnection urlConn) throws IOException {\n        return new String(IOUtils.toByteArray(urlConn.getInputStream()), Charsets.UTF_8);\n    }\n\n    protected void writeContent(HttpURLConnection urlConn, String content) throws IOException {\n        urlConn.getOutputStream().write(content.getBytes(Charsets.UTF_8));\n    }\n\n    protected boolean isStreamEqual(InputStream input1, InputStream input2) throws IOException {\n        if (!(input1 instanceof BufferedInputStream)) {\n            input1 = new BufferedInputStream(input1);\n        }\n        if (!(input2 instanceof BufferedInputStream)) {\n            input2 = new BufferedInputStream(input2);\n        }\n        int ch = input1.read();\n        while (-1 != ch) {\n            int ch2 = input2.read();\n            if (ch != ch2) {\n                return false;\n            }\n            ch = input1.read();\n        }\n        int ch2 = input2.read();\n        return (ch2 == -1);\n    }\n\n    protected Pet petInstance() {\n        Pet pet = new Pet();\n        pet.setCategory(new Category(\"dog\"));\n        pet.setAgeMonths(3);\n        pet.setDetails(\"small-cat\");\n        pet.setPrice(10.5f);\n        pet.setImage(\"cat.png\");\n        return pet;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/HttpsServerTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.conf.SSLClientContext;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.Socket;\nimport java.net.URI;\nimport java.net.URL;\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.ws.rs.HttpMethod;\n\n/**\n * Test the HttpsServer.\n */\npublic class HttpsServerTest extends HttpServerTest {\n\n    private static SSLClientContext sslClientContext;\n\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private final SecondService secondService = new SecondService();\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n\n    private static final int port = Constants.PORT + 4;\n\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"https://%s:%d\", Constants.HOSTNAME, port));\n        System.setProperty(\"transports.netty.conf\",\n                           Thread.currentThread().getContextClassLoader().getResource(\"netty-transports-1.yaml\")\n                                 .getPath());\n        microservicesRunner = new MicroservicesRunner();\n        sslClientContext = new SSLClientContext();\n        microservicesRunner\n                .addExceptionMapper(new TestExceptionMapper(), new TestExceptionMapper2())\n                .deploy(testMicroservice)\n                .start();\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n    }\n\n    @Override\n    protected HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpsURLConnection.setDefaultSSLSocketFactory(sslClientContext.getClientContext().getSocketFactory());\n        HostnameVerifier allHostsValid = (hostname1, session) -> true;\n\n        // Install the all-trusting host verifier\n        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);\n        HttpURLConnection urlConn = (HttpsURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n        return urlConn;\n    }\n\n    @Override\n    protected Socket createRawSocket(URL url) throws IOException {\n        return sslClientContext.getClientContext().getSocketFactory().createSocket(url.getHost(), url.getPort());\n    }\n\n    static void setSslClientContext(SSLClientContext sslClientContext) {\n        HttpsServerTest.sslClientContext = sslClientContext;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/InterceptorTest.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j;\n\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.interceptor.HighPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.TestBreakRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestBreakResponseInterceptor;\nimport org.wso2.msf4j.interceptor.TestExceptionBreakRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestInterceptorDeprecated;\nimport org.wso2.msf4j.interceptor.TestRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestResponseInterceptor;\nimport org.wso2.msf4j.service.InterceptorTestMicroService;\nimport org.wso2.msf4j.service.PriorityInterceptorTestMicroService;\nimport org.wso2.msf4j.service.sub.Player;\nimport org.wso2.msf4j.service.sub.Team;\n\nimport java.net.URI;\nimport java.net.URL;\nimport java.util.Collections;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Class for testing interceptors.\n * <p>\n * Please note that the deprecated interceptors are also tested along the way.\n */\npublic class InterceptorTest extends InterceptorTestBase {\n\n    private static final int port = Constants.PORT + 6;\n    private final String microServiceBaseUrl = \"/test/interceptorTest/\";\n    private MicroservicesRunner microservicesRunner;\n    private final InterceptorTestMicroService interceptorTestMicroService = new InterceptorTestMicroService();\n    private final PriorityInterceptorTestMicroService priorityInterceptorTestMicroService =\n            new PriorityInterceptorTestMicroService();\n\n    @BeforeClass\n    public void setup() throws Exception {\n        URL resource = Thread.currentThread().getContextClassLoader().getResource(\"netty-transports-3.yaml\");\n        if (resource == null) {\n            Assert.fail(\"netty-transports-3.yaml not found\");\n        }\n        System.setProperty(\"transports.netty.conf\", resource.getPath());\n        microservicesRunner = new MicroservicesRunner(port);\n\n        // Global request interceptors are registered in the priority order of new interceptors -> old interceptors\n        // Global response interceptors are registered in the priority order of old interceptors -> new interceptors\n        microservicesRunner\n                .deploy(interceptorTestMicroService)\n                .deploy(priorityInterceptorTestMicroService)\n                .addGlobalRequestInterceptor(new HighPriorityGlobalRequestInterceptor(),\n                        new MediumPriorityGlobalRequestInterceptor(), new LowPriorityGlobalRequestInterceptor())\n                .addInterceptor(new TestInterceptorDeprecated())\n                .addGlobalResponseInterceptor(new HighPriorityGlobalResponseInterceptor(),\n                        new MediumPriorityGlobalResponseInterceptor(), new LowPriorityGlobalResponseInterceptor())\n                .start();\n        baseURI = URI.create(\"http://\" + Constants.HOSTNAME + \":\" + port);\n        Thread.sleep(1000);\n    }\n\n    @AfterClass\n    public void tearDown() throws Exception {\n        microservicesRunner.stop();\n    }\n\n    @BeforeMethod\n    public void reset() {\n        PriorityDataHolder.setPriorityOrder(\"\");\n\n        // Reset request interceptors\n        TestRequestInterceptor.reset();\n\n        // Reset response interceptors\n        TestResponseInterceptor.reset();\n\n        // Reset global request interceptors\n        HighPriorityGlobalRequestInterceptor.reset();\n        MediumPriorityGlobalRequestInterceptor.reset();\n        LowPriorityGlobalRequestInterceptor.reset();\n\n        // Reset global response interceptors\n        HighPriorityGlobalResponseInterceptor.reset();\n        MediumPriorityGlobalResponseInterceptor.reset();\n        LowPriorityGlobalResponseInterceptor.reset();\n\n        // Reset deprecated interceptor\n        TestInterceptorDeprecated.reset();\n    }\n\n    /**\n     * Test whether resource interceptors are called.\n     *\n     * @throws Exception on any exception\n     */\n    @Test\n    public void interceptionTest() throws Exception {\n        // No sub resource\n        Team team = doGetAndGetResponseObject(microServiceBaseUrl + \"subResourceLocatorTest/SL/\",\n                false, Team.class, Collections.unmodifiableMap(Collections.emptyMap()));\n\n        // Assert response\n        assertEquals(\"Cricket\", team.getTeamType());\n        assertEquals(\"SL\", team.getCountryId());\n\n        // Assert interceptor calls\n        // Request interceptors\n        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors\n\n        assertEquals(2, TestRequestInterceptor.getFilterCalls()); // Resource level interceptor\n\n        // Response interceptors\n        assertEquals(1, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors\n\n        assertEquals(2, TestResponseInterceptor.getFilterCalls()); // Resource level interceptor\n    }\n\n    /**\n     * Test whether sub-resource interceptors are called.\n     *\n     * @throws Exception on any exception\n     */\n    @Test\n    public void subResourceInterceptionTest() throws Exception {\n        // 1 sub resource\n        String rawData = \"countryName=SriLanka&type=Batsman\";\n        Player player = doPostAndGetResponseObject(microServiceBaseUrl + \"subResourceLocatorTest/SL/\" +\n                        \"interceptorTest/99/\", rawData, false, Player.class,\n                Collections.unmodifiableMap(Collections.emptyMap()));\n\n        // Assert response\n        assertEquals(\"player_1\", player.getName());\n        assertEquals(99, player.getPlayerId());\n        assertEquals(\"SriLanka\", player.getCountryName());\n        assertEquals(30, player.getAge());\n        assertEquals(\"Batsman\", player.getType());\n\n        // Assert interceptor calls\n        // Request interceptors\n        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors\n\n        assertEquals(3, TestRequestInterceptor.getFilterCalls()); // Resource level interceptor\n\n        // Response interceptors\n        assertEquals(1, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors\n\n        assertEquals(3, TestResponseInterceptor.getFilterCalls()); // Resource level interceptor\n\n        String executionOrderString = \"HighPriorityGlobalRequestInterceptor\" +\n                \"MediumPriorityGlobalRequestInterceptor\" +\n                \"LowPriorityGlobalRequestInterceptor\" +\n                \"TestInterceptorDeprecated - [PRE CALL]\" +\n                \"TestRequestInterceptor\" +\n                \"TestRequestInterceptor\" +\n                \"[HTTP RESOURCE METHOD]\" +\n                \"TestRequestInterceptor\" +\n                \"[HTTP SUB RESOURCE METHOD]\" +\n                \"TestResponseInterceptor\" +\n                \"TestResponseInterceptor\" +\n                \"TestResponseInterceptor\" +\n                \"TestInterceptorDeprecated - [POST CALL]\" +\n                \"HighPriorityGlobalResponseInterceptor\" +\n                \"MediumPriorityGlobalResponseInterceptor\" +\n                \"LowPriorityGlobalResponseInterceptor\";\n        assertEquals(executionOrderString, PriorityDataHolder.getPriorityOrder());\n    }\n\n    /**\n     * Test the order of the filters.\n     * Order of the execution should be\n     * <p>\n     * 1) Global request interceptors according to the priority order (way developer writes them)\n     * HighPriorityGlobalRequestInterceptor -> MediumPriorityGlobalRequestInterceptor ->\n     * LowPriorityGlobalRequestInterceptor -> TestInterceptorDeprecated - [PRE CALL]\n     * <p>\n     * 2) Resource level request interceptors according to the priority order (way developer writes them)\n     * HighPriorityRRequestInterceptor -> MediumPriorityRRequestInterceptor -> LowPriorityRRequestInterceptor\n     * <p>\n     * 3) Sub-resource level request interceptors according to the priority order (way developer writes them)\n     * HighPrioritySRRequestInterceptor -> MediumPrioritySRRequestInterceptor -> LowPrioritySRRequestInterceptor\n     * <p>\n     * 4) HTTP method\n     * <p>\n     * 5) Sub-resource level response interceptors according to the priority order (way developer writes them)\n     * HighPrioritySRResponseInterceptor -> MediumPrioritySRResponseInterceptor -> LowPrioritySRResponseInterceptor\n     * <p>\n     * 6) Resource level response interceptors according to the priority order (way developer writes them)\n     * HighPriorityRResponseInterceptor -> MediumPriorityRResponseInterceptor -> LowPriorityRResponseInterceptor\n     * <p>\n     * 7) Global response interceptors according to the priority order (way developer writes them)\n     * TestInterceptorDeprecated - [POST CALL] -> HighPriorityGlobalResponseInterceptor ->\n     * MediumPriorityGlobalResponseInterceptor -> LowPriorityGlobalResponseInterceptor\n     *\n     * @throws Exception on any exception\n     */\n    @Test\n    public void priorityTest() throws Exception {\n        String response = doGetAndGetResponseString(\"/test/priorityInterceptorTest/priorityTest\", false,\n                Collections.unmodifiableMap(Collections.emptyMap()));\n        assertEquals(\"Priority interceptor test\", response);\n        String executionOrderString = \"HighPriorityGlobalRequestInterceptor\" +\n                \"MediumPriorityGlobalRequestInterceptor\" +\n                \"LowPriorityGlobalRequestInterceptor\" +\n                \"TestInterceptorDeprecated - [PRE CALL]\" +\n                \"HighPriorityClassRequestInterceptor\" +\n                \"MediumPriorityClassRequestInterceptor\" +\n                \"LowPriorityClassRequestInterceptor\" +\n                \"HighPriorityMethodRequestInterceptor\" +\n                \"MediumPriorityMethodRequestInterceptor\" +\n                \"LowPriorityMethodRequestInterceptor\" +\n                \"[HTTP METHOD]\" +\n                \"HighPriorityMethodResponseInterceptor\" +\n                \"MediumPriorityMethodResponseInterceptor\" +\n                \"LowPriorityMethodResponseInterceptor\" +\n                \"HighPriorityClassResponseInterceptor\" +\n                \"MediumPriorityClassResponseInterceptor\" +\n                \"LowPriorityClassResponseInterceptor\" +\n                \"TestInterceptorDeprecated - [POST CALL]\" +\n                \"HighPriorityGlobalResponseInterceptor\" +\n                \"MediumPriorityGlobalResponseInterceptor\" +\n                \"LowPriorityGlobalResponseInterceptor\";\n        assertEquals(executionOrderString, PriorityDataHolder.getPriorityOrder());\n    }\n\n    /**\n     * Test for interception break on exception.\n     */\n    @Test\n    public void interceptorFlowBreakOnExceptionTest() {\n        try {\n            doGetAndGetResponseString(microServiceBaseUrl + \"interceptorBreakOnExceptionTest\", false,\n                    Collections.unmodifiableMap(Collections.emptyMap()));\n            Assert.fail(); // Fail test if exception is not thrown\n        } catch (Exception e) {\n            assertEquals(e.getClass().getName(), \"java.io.IOException\");\n            assertEquals(e.getMessage(), \"Server returned HTTP response code: 500 for URL: \" +\n                    \"http://localhost:8096/test/interceptorTest/interceptorBreakOnExceptionTest\");\n\n            assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n            assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n            assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n            assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors\n            assertEquals(1, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n            assertEquals(1, TestExceptionBreakRequestInterceptor.getFilterCalls()); // Faulty interceptor\n\n            // Response interceptors\n            assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n            assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors\n            assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n            assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n            assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        }\n    }\n\n    /**\n     * Test for interception break manually by user.\n     */\n    @Test\n    public void requestInterceptorFlowBreakByUserTest() throws Exception {\n        String response =\n                doGetAndGetResponseString(microServiceBaseUrl + \"requestInterceptorBreakByUserTest\",\n                        false, Collections.unmodifiableMap(Collections.emptyMap()));\n        assertEquals(response, \"\");\n        // Request interceptors\n        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors\n        assertEquals(1, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n        assertEquals(1, TestBreakRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n\n        // Response interceptors\n        assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n        assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors\n        assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n\n    }\n\n    /**\n     * Test for interception break manually by user.\n     *\n     * @throws Exception on any exception\n     */\n    @Test\n    public void responseInterceptorFlowBreakByUserTest() throws Exception {\n        String response =\n                doGetAndGetResponseString(microServiceBaseUrl + \"responseInterceptorBreakByUserTest\",\n                        false, Collections.unmodifiableMap(Collections.emptyMap()));\n        assertEquals(response, \"\");\n\n        // Request interceptors\n        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors\n        assertEquals(2, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n\n        // Response interceptors\n        assertEquals(1, TestBreakResponseInterceptor.getFilterCalls()); // Break interception flow interceptor\n        assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors\n        assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors\n        assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n        assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/InterceptorTestBase.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j;\n\nimport com.google.gson.Gson;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.IOUtils;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.util.Arrays;\nimport java.util.Map;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Base class for testing interceptors.\n */\npublic abstract class InterceptorTestBase {\n\n    private final Gson gson = new Gson();\n    protected static URI baseURI;\n\n    /**\n     * @param path      http path\n     * @param keepAlive should the connection be kept alive\n     * @param headers   createHttpUrlConnection headers\n     * @return object from response\n     * @throws IOException on any exception\n     */\n    protected int doGetAndGetStatusCode(String path, boolean keepAlive, Map<String, String> headers)\n            throws IOException {\n        HttpURLConnection urlConn = createHttpUrlConnection(path, HttpMethod.GET, keepAlive, headers);\n        return urlConn.getResponseCode();\n    }\n\n    /**\n     * @param path      http path\n     * @param keepAlive should the connection be kept alive\n     * @param tClass    type of the expected object\n     * @param headers   createHttpUrlConnection headers\n     * @param <T>       type of the expected object\n     * @return object from response\n     * @throws IOException on any exception\n     */\n    protected <T> T doGetAndGetResponseObject(String path, boolean keepAlive, Class<T> tClass,\n                                              Map<String, String> headers) throws IOException {\n        HttpURLConnection urlConn = createHttpUrlConnection(path, HttpMethod.GET, keepAlive, headers);\n        return getResponseObject(urlConn, tClass);\n    }\n\n    /**\n     * @param path      http path\n     * @param keepAlive should the connection be kept alive\n     * @param headers   createHttpUrlConnection headers\n     * @return object from response\n     * @throws IOException on any exception\n     */\n    protected String doGetAndGetResponseString(String path, boolean keepAlive, Map<String, String> headers)\n            throws IOException {\n        HttpURLConnection urlConn = createHttpUrlConnection(path, HttpMethod.GET, keepAlive, headers);\n        return getResponseString(urlConn);\n    }\n\n    /**\n     * @param path      http path\n     * @param rawData   data to post\n     * @param keepAlive should the connection be kept alive\n     * @param tClass    type of the expected object\n     * @param headers   createHttpUrlConnection headers\n     * @param <T>       type of the expected object\n     * @return object from response\n     * @throws IOException on any exception\n     */\n    protected <T> T doPostAndGetResponseObject(String path, String rawData, boolean keepAlive, Class<T> tClass,\n                                               Map<String, String> headers) throws IOException {\n        HttpURLConnection urlConn = createHttpUrlConnection(path, HttpMethod.POST, keepAlive, headers);\n        ByteBuffer encodedData = Charset.defaultCharset().encode(rawData);\n        urlConn.setRequestMethod(\"POST\");\n        urlConn.setRequestProperty(\"Content-Type\", MediaType.APPLICATION_FORM_URLENCODED);\n        urlConn.setRequestProperty(\"Content-Length\", String.valueOf(encodedData.array().length));\n        try (OutputStream os = urlConn.getOutputStream()) {\n            os.write(Arrays.copyOf(encodedData.array(), encodedData.limit()));\n        }\n        return getResponseObject(urlConn, tClass);\n    }\n\n    /**\n     * Get java object from http url connection.\n     *\n     * @param urlConn http url connection\n     * @param tClass  type of the expected object\n     * @param <T>     type of the expected object\n     * @return object from response\n     * @throws IOException on any exception\n     */\n    protected <T> T getResponseObject(HttpURLConnection urlConn, Class<T> tClass) throws IOException {\n        return gson.fromJson(getResponseString(urlConn), tClass);\n    }\n\n    /**\n     * Get java object from http url connection.\n     *\n     * @param urlConn http url connection\n     * @return string from response\n     * @throws IOException on any exception\n     */\n    protected String getResponseString(HttpURLConnection urlConn) throws IOException {\n        InputStream inputStream = urlConn.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        return response;\n    }\n\n    /**\n     * Get http url connection for the path and method specified.\n     *\n     * @param path      http path\n     * @param method    http method\n     * @param keepAlive should the connection be kept alive\n     * @param headers   createHttpUrlConnection headers\n     * @return http url connection instance\n     * @throws IOException on error creating http url connection\n     */\n    protected HttpURLConnection createHttpUrlConnection(String path, String method, boolean keepAlive,\n                                                      Map<String, String> headers) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (headers != null) {\n            headers.entrySet().forEach(header -> urlConn.setRequestProperty(header.getKey(), header.getValue()));\n        }\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), \"CLOSE\");\n        }\n        return urlConn;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/MSF4JResponseTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n\nimport org.testng.annotations.Test;\n\nimport java.util.Arrays;\nimport javax.ws.rs.core.Response;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Test MSF4JResponse and MSF4J ResponseBuilder.\n */\npublic class MSF4JResponseTest {\n\n    @Test\n    public void testStatusOk() {\n        Response response = Response\n                .status(Response.Status.OK.getStatusCode())\n                .build();\n        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());\n    }\n\n    @Test\n    public void testStatusNotFound() {\n        Response response = Response\n                .status(Response.Status.NOT_FOUND.getStatusCode())\n                .build();\n        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());\n    }\n\n    @Test\n    public void testEntity() {\n        Response response = Response\n                .status(Response.Status.OK.getStatusCode())\n                .entity(\"Entity\")\n                .build();\n        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());\n        assertEquals(response.getEntity(), \"Entity\");\n    }\n\n    @Test\n    public void testSingleHeaderSingleVal() {\n        Response response = Response\n                .status(Response.Status.OK.getStatusCode())\n                .header(\"key1\", \"val1\")\n                .build();\n        assertEquals(\"val1\", response.getStringHeaders().getFirst(\"key1\"));\n    }\n\n    @Test\n    public void testMultipleHeaderSingleVal() {\n        Response response = Response\n                .status(Response.Status.OK.getStatusCode())\n                .header(\"key1\", \"val1\")\n                .header(\"key2\", \"val2\")\n                .build();\n        assertEquals(\"val1\", response.getStringHeaders().getFirst(\"key1\"));\n        assertEquals(\"val2\", response.getStringHeaders().getFirst(\"key2\"));\n    }\n\n    @Test\n    public void testSingleHeaderRepeatedSingleVal() {\n        Response response = Response\n                .status(Response.Status.OK.getStatusCode())\n                .header(\"key1\", \"val1\")\n                .header(\"key1\", \"val2\")\n                .build();\n        assertEquals(\"val1\", response.getStringHeaders().get(\"key1\").get(0));\n        assertEquals(\"val2\", response.getStringHeaders().get(\"key1\").get(1));\n    }\n\n    @Test\n    public void testSingleHeaderListVal() {\n        Response response =\n                Response.\n                        status(Response.Status.OK.getStatusCode()).\n                        header(\"key1\", Arrays.asList(\"val1\", \"val2\")).build();\n        assertEquals(\"val1\", response.getStringHeaders().get(\"key1\").get(0));\n        assertEquals(\"val2\", response.getStringHeaders().get(\"key1\").get(1));\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/MimeMapperTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\n\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.mime.MimeMapper;\nimport org.wso2.msf4j.internal.mime.MimeMappingException;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Test the functionality of MimeMapper.\n */\npublic class MimeMapperTest {\n\n    @Test\n    public void testMimeMappingForKnownExtension() throws MimeMappingException {\n        String mimeType = MimeMapper.getMimeType(\"png\");\n        assertEquals(\"image/png\", mimeType);\n    }\n\n    @Test(expectedExceptions = MimeMappingException.class)\n    public void testMimeMappingForUnknownExtension() throws MimeMappingException {\n        MimeMapper.getMimeType(\"unknownext\");\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/MutualAuthServerTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j;\n\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.conf.SSLClientContext;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.File;\nimport java.net.URI;\nimport java.nio.file.Files;\nimport java.nio.file.StandardCopyOption;\n\n/**\n * Test the HttpsServer with mutual authentication.\n */\npublic class MutualAuthServerTest extends HttpsServerTest {\n\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private final SecondService secondService = new SecondService();\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n\n    private static String hostname = Constants.HOSTNAME;\n    private static final int port = Constants.PORT + 5;\n    private static File trustKeyStore;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"https://%s:%d\", hostname, port));\n        trustKeyStore = new File(tmpFolder, \"MutualAuthServerTest.jks\");\n        trustKeyStore.createNewFile();\n        Files.copy(Thread.currentThread().getContextClassLoader().getResource(\"client.jks\").openStream(),\n                   trustKeyStore.toPath(), StandardCopyOption.REPLACE_EXISTING);\n        String trustKeyStorePassword = \"password\";\n        setSslClientContext(new SSLClientContext(trustKeyStore, trustKeyStorePassword));\n\n        System.setProperty(\"transports.netty.conf\",\n                           Thread.currentThread().getContextClassLoader().getResource(\"netty-transports-2.yaml\")\n                                 .getPath());\n        microservicesRunner = new MicroservicesRunner();\n        microservicesRunner.addExceptionMapper(new TestExceptionMapper(), new TestExceptionMapper2())\n                           .deploy(testMicroservice).start();\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n        trustKeyStore.delete();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/PathRouterTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.router.PatternPathRouter;\n\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport static org.testng.AssertJUnit.assertEquals;\nimport static org.testng.AssertJUnit.assertTrue;\n\n/**\n * Test the routing logic using String as the destination.\n */\npublic class PathRouterTest {\n\n    @Test\n    public void testPathRoutings() {\n\n        PatternPathRouter<String> pathRouter = PatternPathRouter.create();\n        pathRouter.add(\"/\", \"root\");\n        pathRouter.add(\"/foo/{baz}/b\", \"foobarb\");\n        pathRouter.add(\"/foo/bar/baz\", \"foobarbaz\");\n        pathRouter.add(\"/baz/bar\", \"bazbar\");\n        pathRouter.add(\"/bar\", \"bar\");\n        pathRouter.add(\"/foo/bar\", \"foobar\");\n        pathRouter.add(\"//multiple/slash//route\", \"multipleslashroute\");\n\n        pathRouter.add(\"/multi/match/**\", \"multi-match-*\");\n        pathRouter.add(\"/multi/match/def\", \"multi-match-def\");\n\n        pathRouter.add(\"/multi/maxmatch/**\", \"multi-max-match-*\");\n        pathRouter.add(\"/multi/maxmatch/{id}\", \"multi-max-match-id\");\n        pathRouter.add(\"/multi/maxmatch/foo\", \"multi-max-match-foo\");\n\n        pathRouter.add(\"**/wildcard/{id}\", \"wildcard-id\");\n        pathRouter.add(\"/**/wildcard/{id}\", \"slash-wildcard-id\");\n\n        pathRouter.add(\"**/wildcard/**/foo/{id}\", \"wildcard-foo-id\");\n        pathRouter.add(\"/**/wildcard/**/foo/{id}\", \"slash-wildcard-foo-id\");\n\n        pathRouter.add(\"**/wildcard/**/foo/{id}/**\", \"wildcard-foo-id-2\");\n        pathRouter.add(\"/**/wildcard/**/foo/{id}/**\", \"slash-wildcard-foo-id-2\");\n\n        List<PatternPathRouter.RoutableDestination<String>> routes;\n\n        routes = pathRouter.getDestinations(\"\");\n        assertEquals(1, routes.size());\n        assertEquals(\"root\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/\");\n        assertEquals(1, routes.size());\n        assertEquals(\"root\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/foo/bar/baz\");\n        assertEquals(1, routes.size());\n        assertEquals(\"foobarbaz\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/baz/bar\");\n        assertEquals(1, routes.size());\n        assertEquals(\"bazbar\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/foo/bar/baz/moo\");\n        assertTrue(routes.isEmpty());\n\n        routes = pathRouter.getDestinations(\"/bar/121\");\n        assertTrue(routes.isEmpty());\n\n        routes = pathRouter.getDestinations(\"/foo/bar/b\");\n        assertEquals(1, routes.size());\n        assertEquals(\"foobarb\", routes.get(0).getDestination());\n        assertEquals(1, routes.get(0).getGroupNameValues().size());\n        assertEquals(\"bar\", routes.get(0).getGroupNameValues().get(\"baz\"));\n\n        routes = pathRouter.getDestinations(\"/foo/bar\");\n        assertEquals(1, routes.size());\n        assertEquals(\"foobar\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/multiple/slash/route\");\n        assertEquals(1, routes.size());\n        assertEquals(\"multipleslashroute\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/foo/bar/bazooka\");\n        assertTrue(routes.isEmpty());\n\n        routes = pathRouter.getDestinations(\"/multi/match/def\");\n        assertEquals(2, routes.size());\n        Set<String> set1 = new HashSet<>();\n        set1.add(\"multi-match-def\");\n        set1.add(\"multi-match-*\");\n        Set<String> set2 = new HashSet<>();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        assertEquals(set1, set2);\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n        assertTrue(routes.get(1).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/multi/match/ghi\");\n        assertEquals(1, routes.size());\n        assertEquals(\"multi-match-*\", routes.get(0).getDestination());\n        assertTrue(routes.get(0).getGroupNameValues().isEmpty());\n\n        routes = pathRouter.getDestinations(\"/multi/maxmatch/id1\");\n        assertEquals(2, routes.size());\n        set1.clear();\n        set1.add(\"multi-max-match-id\");\n        set1.add(\"multi-max-match-*\");\n        set2.clear();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        assertEquals(set1, set2);\n        //noinspection assertEqualsBetweenInconvertibleTypes\n        Set<Map<String, String>> set11 = new HashSet<>();\n        Set<Map<String, String>> set12 = new HashSet<>();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set11.add(Collections.emptyMap());\n        set12.add(routes.get(0).getGroupNameValues());\n        set12.add(routes.get(1).getGroupNameValues());\n        assertEquals(set11, set12);\n\n        routes = pathRouter.getDestinations(\"/multi/maxmatch/foo\");\n        assertEquals(3, routes.size());\n        set1.clear();\n        set1.add(\"multi-max-match-id\");\n        set1.add(\"multi-max-match-*\");\n        set1.add(\"multi-max-match-foo\");\n        set2.clear();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        set2.add(routes.get(2).getDestination());\n        assertEquals(set1, set2);\n        //noinspection assertEqualsBetweenInconvertibleTypes\n\n        set11.clear();\n        set12.clear();\n        set11.add(Collections.singletonMap(\"id\", \"foo\"));\n        set11.add(Collections.emptyMap());\n        set12.add(routes.get(0).getGroupNameValues());\n        set12.add(routes.get(1).getGroupNameValues());\n        assertEquals(set11, set12);\n\n        routes = pathRouter.getDestinations(\"/foo/bar/wildcard/id1\");\n        assertEquals(2, routes.size());\n        set1.clear();\n        set1.add(\"wildcard-id\");\n        set1.add(\"slash-wildcard-id\");\n        set2.clear();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        assertEquals(set1, set2);\n        //noinspection assertEqualsBetweenInconvertibleTypes\n        set11.clear();\n        set12.clear();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set12.add(routes.get(0).getGroupNameValues());\n        set12.add(routes.get(1).getGroupNameValues());\n        assertEquals(set11, set12);\n\n        routes = pathRouter.getDestinations(\"/wildcard/id1\");\n        assertEquals(1, routes.size());\n        assertEquals(\"wildcard-id\", routes.get(0).getDestination());\n        set11.clear();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        assertEquals(Collections.singletonMap(\"id\", \"id1\"), routes.get(0).getGroupNameValues());\n\n        routes = pathRouter.getDestinations(\"/foo/bar/wildcard/bar/foo/id1\");\n        assertEquals(2, routes.size());\n        set1.clear();\n        set1.add(\"wildcard-foo-id\");\n        set1.add(\"slash-wildcard-foo-id\");\n        set2.clear();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        assertEquals(set1, set2);\n        //noinspection assertEqualsBetweenInconvertibleTypes\n        set11.clear();\n        set12.clear();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set12.add(routes.get(0).getGroupNameValues());\n        set12.add(routes.get(1).getGroupNameValues());\n        assertEquals(set11, set12);\n\n        routes = pathRouter.getDestinations(\"/foo/bar/wildcard/bar/foo/id1/baz/bar\");\n        assertEquals(2, routes.size());\n        set1.clear();\n        set1.add(\"wildcard-foo-id-2\");\n        set1.add(\"slash-wildcard-foo-id-2\");\n        set2.clear();\n        set2.add(routes.get(0).getDestination());\n        set2.add(routes.get(1).getDestination());\n        assertEquals(set1, set2);\n        //noinspection assertEqualsBetweenInconvertibleTypes\n        set11.clear();\n        set12.clear();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        set12.add(routes.get(0).getGroupNameValues());\n        set12.add(routes.get(1).getGroupNameValues());\n        assertEquals(set11, set12);\n\n        routes = pathRouter.getDestinations(\"/wildcard/bar/foo/id1/baz/bar\");\n        assertEquals(1, routes.size());\n        assertEquals(\"wildcard-foo-id-2\", routes.get(0).getDestination());\n        set11.clear();\n        set11.add(Collections.singletonMap(\"id\", \"id1\"));\n        assertEquals(Collections.singletonMap(\"id\", \"id1\"), routes.get(0).getGroupNameValues());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/SSLKeyStoreTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j;\n\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.conf.SSLConfig;\nimport org.wso2.msf4j.conf.SSLHandlerFactory;\n\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.StandardCopyOption;\n\n/**\n * Tests SSL KeyStore behaviour.\n */\npublic class SSLKeyStoreTest {\n\n    public static File tmpFolder;\n    private static File keyStore;\n\n    @BeforeClass\n    public static void setup() throws Exception {\n        keyStore = new File(tmpFolder, \"KeyStore.jks\");\n        keyStore.createNewFile();\n        Files.copy(Thread.currentThread().getContextClassLoader().getResource(\"cert.jks\").openStream(),\n                   keyStore.toPath(), StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    @AfterClass\n    public static void cleanup() {\n        keyStore.delete();\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testSslCertPathConfiguration1() throws IllegalArgumentException {\n        //Bad Certificate Path\n        new SSLHandlerFactory(SSLConfig.builder(new File(\"badCertificate\"), \"secret\").setCertificatePassword(\"secret\")\n                .build());\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testSslCertPathConfiguration2() throws IllegalArgumentException {\n        //Null Certificate Path\n        new SSLHandlerFactory(SSLConfig.builder(null, \"secret\").setCertificatePassword(\"secret\").build());\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testSslKeyStorePassConfiguration2() throws IllegalArgumentException {\n        //Missing Key Pass\n        new SSLHandlerFactory(SSLConfig.builder(keyStore, null).setCertificatePassword(\"secret\").build());\n    }\n\n    @Test\n    public void testSslCertPassConfiguration() throws IllegalArgumentException {\n        //Bad Cert Pass\n        new SSLHandlerFactory(SSLConfig.builder(keyStore, \"secret\").build());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/TransportConfigurationTest.java",
    "content": "/*\n * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.wso2.carbon.config.ConfigProviderFactory;\nimport org.wso2.carbon.config.ConfigurationException;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.conf.SSLClientContext;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\nimport org.wso2.transport.http.netty.contract.config.TransportsConfiguration;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.Socket;\nimport java.net.URI;\nimport java.net.URL;\nimport java.nio.file.Paths;\n\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.ws.rs.HttpMethod;\n\nimport static org.wso2.msf4j.internal.MSF4JConstants.WSO2_TRANSPORT_HTTP_CONFIG_NAMESPACE;\n\n/**\n * Test the HttpsServer.\n */\npublic class TransportConfigurationTest extends HttpServerTest {\n\n    private static SSLClientContext sslClientContext;\n\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private final SecondService secondService = new SecondService();\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n\n    private static final int port = Constants.PORT + 4;\n\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"https://%s:%d\", Constants.HOSTNAME, port));\n        TransportsConfiguration transportsConfiguration = getConfiguration(Thread.currentThread().\n                getContextClassLoader().getResource(\"netty-transports-1.yaml\").getPath());\n        microservicesRunner = new MicroservicesRunner(transportsConfiguration);\n        sslClientContext = new SSLClientContext();\n        microservicesRunner\n                .addExceptionMapper(new TestExceptionMapper(), new TestExceptionMapper2())\n                .deploy(testMicroservice)\n                .start();\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n    }\n\n    /**\n     * Get the {@code TransportsConfiguration} represented by a particular configuration file\n     *\n     * @param configFileLocation configuration file location\n     * @return TransportsConfiguration represented by a particular configuration file\n     */\n    public TransportsConfiguration getConfiguration(String configFileLocation) {\n        TransportsConfiguration transportsConfiguration;\n\n        File file = new File(configFileLocation);\n        if (file.exists()) {\n            try {\n            transportsConfiguration =\n                    ConfigProviderFactory.getConfigProvider(Paths.get(configFileLocation), null)\n                    .getConfigurationObject(WSO2_TRANSPORT_HTTP_CONFIG_NAMESPACE, TransportsConfiguration.class);\n            } catch (ConfigurationException e) {\n                throw new RuntimeException(\n                        \"Error while loading \" + configFileLocation + \" configuration file\", e);\n            }\n        } else { // return a default config\n            transportsConfiguration = new TransportsConfiguration();\n        }\n\n        return transportsConfiguration;\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n    }\n\n    @Override\n    protected HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpsURLConnection.setDefaultSSLSocketFactory(sslClientContext.getClientContext().getSocketFactory());\n        HostnameVerifier allHostsValid = (hostname1, session) -> true;\n\n        // Install the all-trusting host verifier\n        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);\n        HttpURLConnection urlConn = (HttpsURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n        return urlConn;\n    }\n\n    @Override\n    protected Socket createRawSocket(URL url) throws IOException {\n        return sslClientContext.getClientContext().getSocketFactory().createSocket(url.getHost(), url.getPort());\n    }\n\n    static void setSslClientContext(SSLClientContext sslClientContext) {\n        TransportConfigurationTest.sslClientContext = sslClientContext;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/TransportConfigurationTest2.java",
    "content": "/*\n * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.conf.SSLClientContext;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroServiceWithDynamicPath;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.Socket;\nimport java.net.URI;\nimport java.net.URL;\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.ws.rs.HttpMethod;\n\n/**\n * Test the HttpsServer.\n */\npublic class TransportConfigurationTest2 extends HttpServerTest {\n\n    private static SSLClientContext sslClientContext;\n\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private final SecondService secondService = new SecondService();\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n\n    private static final int port = Constants.PORT + 4;\n\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"https://%s:%d\", Constants.HOSTNAME, port));\n\n        System.setProperty(\"transports.netty.conf\", Thread.currentThread().\n                getContextClassLoader().getResource(\"netty-transports-4.yaml\").getPath());\n\n        microservicesRunner = new MicroservicesRunner();\n        sslClientContext = new SSLClientContext();\n        microservicesRunner\n                .addExceptionMapper(new TestExceptionMapper(), new TestExceptionMapper2())\n                .deploy(testMicroservice)\n                .start();\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n        microservicesRunner.deploy(\"/DynamicPath\", new TestMicroServiceWithDynamicPath());\n        microservicesRunner.deploy(\"/DynamicPath2\", new TestMicroServiceWithDynamicPath());\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n    }\n\n    @Override\n    protected HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpsURLConnection.setDefaultSSLSocketFactory(sslClientContext.getClientContext().getSocketFactory());\n        HostnameVerifier allHostsValid = (hostname1, session) -> true;\n\n        // Install the all-trusting host verifier\n        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);\n        HttpURLConnection urlConn = (HttpsURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n        return urlConn;\n    }\n\n    @Override\n    protected Socket createRawSocket(URL url) throws IOException {\n        return sslClientContext.getClientContext().getSocketFactory().createSocket(url.getHost(), url.getPort());\n    }\n\n    static void setSslClientContext(SSLClientContext sslClientContext) {\n        TransportConfigurationTest2.sslClientContext = sslClientContext;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/beanconversion/BeanConverterTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.beanconversion;\n\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.beanconversion.BeanConverter;\nimport org.wso2.msf4j.pojo.Category;\nimport org.wso2.msf4j.pojo.Pet;\nimport org.wso2.msf4j.pojo.XmlBean;\n\nimport java.nio.ByteBuffer;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * Tests the functionality of BeanConverter.\n */\npublic class BeanConverterTest {\n\n    @Test\n    public void testJsonBeanConversionTextJson() throws BeanConversionException {\n        Pet pet = makePet();\n        ByteBuffer json = BeanConverter.getConverter(\"text/json\").toMedia(pet);\n        Pet pet1 = (Pet) BeanConverter.getConverter(\"text/json\").toObject(json, Pet.class);\n        assertEquals(pet.getId(), pet1.getId());\n        assertEquals(pet.getDetails(), pet1.getDetails());\n        assertEquals(pet.getImage(), pet1.getImage());\n        assertEquals(pet.getCategory().getName(), pet1.getCategory().getName());\n        assertEquals(pet.getAgeMonths(), pet1.getAgeMonths());\n        assertEquals(pet.getPrice(), pet1.getPrice(), 0);\n        assertEquals(pet.getDateAdded(), pet1.getDateAdded());\n    }\n\n    @Test\n    public void testJsonBeanConversionApplicationJson() throws BeanConversionException {\n        Pet original = makePet();\n        ByteBuffer json = BeanConverter.getConverter(\"application/json\").toMedia(original);\n        Pet result = (Pet) BeanConverter.getConverter(\"application/json\").toObject(json, Pet.class);\n        assertEquals(original.getId(), result.getId());\n        assertEquals(original.getDetails(), result.getDetails());\n        assertEquals(original.getImage(), result.getImage());\n        assertEquals(original.getCategory().getName(), result.getCategory().getName());\n        assertEquals(original.getAgeMonths(), result.getAgeMonths());\n        assertEquals(original.getPrice(), result.getPrice(), 0);\n        assertEquals(original.getDateAdded(), result.getDateAdded());\n    }\n\n    @Test\n    public void testTextPlainBeanConversion() throws BeanConversionException {\n        String val = \"Test_String\";\n        ByteBuffer media = BeanConverter.getConverter(\"text/plain\").toMedia(val);\n        Object obj1 = BeanConverter.getConverter(\"text/plain\").toObject(media, null);\n        assertEquals(obj1, val);\n    }\n\n    @Test\n    public void testAnyBeanConversion() throws BeanConversionException {\n        String original = \"Test_String\";\n        ByteBuffer media = BeanConverter.getConverter(\"*/*\").toMedia(original);\n        Object result = BeanConverter.getConverter(\"*/*\").toObject(media, null);\n        assertEquals(original, result);\n    }\n\n    @Test\n    public void testXmlBeanConversion() throws BeanConversionException {\n        XmlBean original = makeXmlBan();\n        ByteBuffer xml = BeanConverter.getConverter(\"text/xml\").toMedia(original);\n        XmlBean result = (XmlBean) BeanConverter.getConverter(\"text/xml\").toObject(xml, XmlBean.class);\n        assertEquals(original.getName(), result.getName());\n        assertEquals(original.getId(), result.getId());\n        assertEquals(original.getValue(), result.getValue());\n    }\n\n    private XmlBean makeXmlBan() {\n        XmlBean xmlBean = new XmlBean();\n        xmlBean.setId(12);\n        xmlBean.setName(\"xml-bean-name\");\n        xmlBean.setValue(457);\n        return xmlBean;\n    }\n\n    private Pet makePet() {\n        Pet pet = new Pet();\n        pet.setCategory(new Category(\"dog\"));\n        pet.setAgeMonths(3);\n        pet.setDetails(\"small-cat\");\n        pet.setPrice(10.5f);\n        pet.setImage(\"cat.png\");\n        return pet;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/conf/Constants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.conf;\n\n/**\n * Constants related to tests.\n */\npublic class Constants {\n\n    public static final String HOSTNAME = \"localhost\";\n    public static final int PORT = 8090;\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/conf/SSLClientContext.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.conf;\n\nimport org.apache.commons.io.IOUtils;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.KeyStore;\nimport javax.net.ssl.KeyManagerFactory;\nimport javax.net.ssl.SSLContext;\n\n/**\n * Provides Client Context.\n * Used by HttpsServerTest\n */\npublic class SSLClientContext {\n\n    private SSLContext clientContext;\n    private String protocol = \"TLS\";\n\n    public SSLClientContext() {\n        this(null, null);\n    }\n\n    public SSLClientContext(File keyStore, String keyStorePassword) {\n\n        try {\n            KeyManagerFactory kmf = null;\n            if (keyStore != null && keyStorePassword != null) {\n                KeyStore ks = getKeyStore(keyStore, keyStorePassword);\n                kmf = KeyManagerFactory.getInstance(\"SunX509\");\n                kmf.init(ks, keyStorePassword.toCharArray());\n            }\n            clientContext = SSLContext.getInstance(protocol);\n            clientContext.init(kmf == null ? null : kmf.getKeyManagers(), TrustManagerFactory.getTrustManagers(), null);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to initialize the client-side SSLContext\", e);\n        }\n    }\n\n    private static KeyStore getKeyStore(File keyStore, String keyStorePassword) throws IOException {\n        KeyStore ks = null;\n        InputStream is = new FileInputStream(keyStore);\n        try {\n            ks = KeyStore.getInstance(\"JKS\");\n            ks.load(is, keyStorePassword.toCharArray());\n        } catch (Exception ex) {\n            if (ex instanceof RuntimeException) {\n                throw ((RuntimeException) ex);\n            }\n            throw new IOException(ex);\n        } finally {\n            IOUtils.closeQuietly(is);\n        }\n        return ks;\n    }\n\n    public SSLContext getClientContext() {\n        return clientContext;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/conf/SSLConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.conf;\n\nimport java.io.File;\n\n/**\n * A class that encapsulates SSLContext configuration.\n */\npublic class SSLConfig {\n    private final File keyStore;\n    private final String keyStorePassword;\n    private final String certificatePassword;\n    private final File trustKeyStore;\n    private final String trustKeyStorePassword;\n\n    private SSLConfig(File keyStore, String keyStorePassword,\n                      String certificatePassword, File trustKeyStore, String trustKeyStorePassword) {\n        this.keyStore = keyStore;\n        this.keyStorePassword = keyStorePassword;\n        this.certificatePassword = certificatePassword;\n        this.trustKeyStore = trustKeyStore;\n        this.trustKeyStorePassword = trustKeyStorePassword;\n    }\n\n    /**\n     *\n     * @param keyStore Key store\n     * @param keyStorePassword password for accessing the key store\n     * @return instance of {@code Builder}\n     */\n    public static Builder builder(File keyStore, String keyStorePassword) {\n        return new Builder(keyStore, keyStorePassword);\n    }\n\n    /**\n     * @return KeyStore file\n     */\n    public File getKeyStore() {\n        return keyStore;\n    }\n\n    /**\n     * @return KeyStore password.\n     */\n    public String getKeyStorePassword() {\n        return keyStorePassword;\n    }\n\n    /**\n     * @return certificate password\n     */\n    public String getCertificatePassword() {\n        return certificatePassword;\n    }\n\n    /**\n     * @return trust KeyStore file\n     */\n    public File getTrustKeyStore() {\n        return trustKeyStore;\n    }\n\n    /**\n     * @return trust KeyStore password.\n     */\n    public String getTrustKeyStorePassword() {\n        return trustKeyStorePassword;\n    }\n\n    /**\n     * Builder to help create the SSLConfig.\n     */\n    public static class Builder {\n        private final File keyStore;\n        private final String keyStorePassword;\n        private String certificatePassword;\n        private File trustKeyStore;\n        private String trustKeyStorePassword;\n\n        private Builder(File keyStore, String keyStorePassword) {\n            this.keyStore = keyStore;\n            this.keyStorePassword = keyStorePassword;\n        }\n\n        /**\n         * Set the certificate password for KeyStore.\n         *\n         * @param certificatePassword certificate password\n         * @return instance of {@code Builder}.\n         */\n        public Builder setCertificatePassword(String certificatePassword) {\n            this.certificatePassword = certificatePassword;\n            return this;\n        }\n\n        /**\n         * Set trust KeyStore file.\n         *\n         * @param trustKeyStore trust KeyStore file.\n         * @return an instance of {@code Builder}.\n         */\n        public Builder setTrustKeyStore(File trustKeyStore) {\n            this.trustKeyStore = trustKeyStore;\n            return this;\n        }\n\n        /**\n         * Set trust KeyStore password.\n         *\n         * @param trustKeyStorePassword trust KeyStore password.\n         * @return an instance of {@code Builder}.\n         */\n        public Builder setTrustKeyStorePassword(String trustKeyStorePassword) {\n            if (trustKeyStorePassword == null) {\n                throw new IllegalArgumentException(\"KeyStore Password Not Configured\");\n            }\n            this.trustKeyStorePassword = trustKeyStorePassword;\n            return this;\n        }\n\n        /**\n         * @return instance of {@code SSLConfig}\n         */\n        public SSLConfig build() {\n            if (keyStore == null) {\n                throw new IllegalArgumentException(\"Certificate File Not Configured\");\n            }\n            if (keyStorePassword == null) {\n                throw new IllegalArgumentException(\"KeyStore Password Not Configured\");\n            }\n            return new SSLConfig(keyStore, keyStorePassword, certificatePassword, trustKeyStore, trustKeyStorePassword);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/conf/SSLHandlerFactory.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.conf;\n\nimport org.apache.commons.io.IOUtils;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.KeyManagementException;\nimport java.security.KeyStore;\nimport java.security.KeyStoreException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.Security;\nimport java.security.UnrecoverableKeyException;\nimport javax.net.ssl.KeyManager;\nimport javax.net.ssl.KeyManagerFactory;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.TrustManagerFactory;\n\n/**\n * A class that encapsulates SSL Certificate Information.\n */\npublic class SSLHandlerFactory {\n\n    private static final String protocol = \"TLS\";\n    private final SSLContext serverContext;\n    private boolean needClientAuth;\n\n    public SSLHandlerFactory(SSLConfig sslConfig) {\n        String algorithm = Security.getProperty(\"ssl.KeyManagerFactory.algorithm\");\n        if (algorithm == null) {\n            algorithm = \"SunX509\";\n        }\n        try {\n            KeyStore ks = getKeyStore(sslConfig.getKeyStore(), sslConfig.getKeyStorePassword());\n            // Set up key manager factory to use our key store\n            KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);\n            kmf.init(ks, sslConfig.getCertificatePassword() != null ? sslConfig.getCertificatePassword().toCharArray()\n                    : sslConfig.getKeyStorePassword().toCharArray());\n            KeyManager[] keyManagers = kmf.getKeyManagers();\n            TrustManager[] trustManagers = null;\n            if (sslConfig.getTrustKeyStore() != null) {\n                this.needClientAuth = true;\n                KeyStore tks = getKeyStore(sslConfig.getTrustKeyStore(), sslConfig.getTrustKeyStorePassword());\n                TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);\n                tmf.init(tks);\n                trustManagers = tmf.getTrustManagers();\n            }\n            serverContext = SSLContext.getInstance(protocol);\n            serverContext.init(keyManagers, trustManagers, null);\n        } catch (UnrecoverableKeyException | KeyManagementException |\n                NoSuchAlgorithmException | KeyStoreException | IOException e) {\n            throw new IllegalArgumentException(\"Failed to initialize the server-side SSLContext\", e);\n        }\n    }\n\n    private static KeyStore getKeyStore(File keyStore, String keyStorePassword) throws IOException {\n        KeyStore ks = null;\n        InputStream is = new FileInputStream(keyStore);\n        try {\n            ks = KeyStore.getInstance(\"JKS\");\n            ks.load(is, keyStorePassword.toCharArray());\n        } catch (Exception ex) {\n            if (ex instanceof RuntimeException) {\n                throw (RuntimeException) ex;\n            }\n            throw new IOException(ex);\n        } finally {\n            IOUtils.closeQuietly(is);\n        }\n        return ks;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/conf/TrustManagerFactory.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.conf;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.security.InvalidAlgorithmParameterException;\nimport java.security.KeyStore;\nimport java.security.KeyStoreException;\nimport java.security.cert.X509Certificate;\nimport javax.net.ssl.ManagerFactoryParameters;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.TrustManagerFactorySpi;\nimport javax.net.ssl.X509TrustManager;\n\n/**\n * Dummy TrustManager {@link TrustManagerFactorySpi} that accepts any certificate.\n */\npublic class TrustManagerFactory extends TrustManagerFactorySpi {\n    private static final Logger log = LoggerFactory.getLogger(TrustManagerFactory.class);\n\n    private static final TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() {\n        public X509Certificate[] getAcceptedIssuers() {\n            return new X509Certificate[0];\n        }\n\n        public void checkClientTrusted(X509Certificate[] chain, String authType) {\n            // This example always trusts the incoming certificate.\n            // Perform certificate inspection and invalid certificate check here\n            log.error(\"UNKNOWN CLIENT CERTIFICATE: \" + chain[0].getSubjectDN());\n        }\n\n        public void checkServerTrusted(X509Certificate[] chain, String authType) {\n            // Always trust - it is an example.\n            // You should do something in the real world.\n            log.error(\"UNKNOWN SERVER CERTIFICATE: \" + chain[0].getSubjectDN());\n        }\n    };\n\n    public static TrustManager[] getTrustManagers() {\n        return new TrustManager[]{DUMMY_TRUST_MANAGER};\n    }\n\n    @Override\n    protected TrustManager[] engineGetTrustManagers() {\n        return getTrustManagers();\n    }\n\n    @Override\n    protected void engineInit(KeyStore keystore) throws KeyStoreException {\n        // Unused\n    }\n\n    @Override\n    protected void engineInit(ManagerFactoryParameters managerFactoryParameters)\n            throws InvalidAlgorithmParameterException {\n        // Unused\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/exception/MappedException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.exception;\n\n/**\n * Test exception for testing ExceptionMapper.\n */\npublic class MappedException extends Exception {\n    public MappedException() {\n        super();\n    }\n\n    public MappedException(String message) {\n        super(message);\n    }\n\n    public MappedException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public MappedException(Throwable cause) {\n        super(cause);\n    }\n\n    protected MappedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/exception/MappedException2.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.exception;\n\n/**\n * Test exception for testing ExceptionMapper.\n */\npublic class MappedException2 extends Exception {\n    public MappedException2() {\n        super();\n    }\n\n    public MappedException2(String message) {\n        super(message);\n    }\n\n    public MappedException2(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public MappedException2(Throwable cause) {\n        super(cause);\n    }\n\n    protected MappedException2(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/exception/TestExceptionMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * Test exception mapper used for testing ExceptionMapper feature.\n */\npublic class TestExceptionMapper implements ExceptionMapper<MappedException> {\n\n    @Override\n    public Response toResponse(MappedException e) {\n        return Response.status(404).\n                entity(e.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/exception/TestExceptionMapper2.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * Test exception mapper used for testing ExceptionMapper feature.\n */\npublic class TestExceptionMapper2 implements ExceptionMapper<MappedException2> {\n\n    @Override\n    public Response toResponse(MappedException2 e) {\n        return Response.status(Response.Status.EXPECTATION_FAILED).\n                entity(e.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityClassRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * High priority request interceptor.\n */\npublic class HighPriorityClassRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityClassResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * High priority response interceptor.\n */\npublic class HighPriorityClassResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityGlobalRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * High priority global request interceptor.\n */\npublic class HighPriorityGlobalRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityGlobalResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * High priority global response interceptor.\n */\npublic class HighPriorityGlobalResponseInterceptor implements ResponseInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityMethodRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * High priority request interceptor.\n */\npublic class HighPriorityMethodRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/HighPriorityMethodResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * High priority response interceptor.\n */\npublic class HighPriorityMethodResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityClassRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Low priority request interceptor.\n */\npublic class LowPriorityClassRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityClassResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Low priority response interceptor.\n */\npublic class LowPriorityClassResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityGlobalRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Low priority global request interceptor.\n */\npublic class LowPriorityGlobalRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityGlobalResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Low priority global request interceptor.\n */\npublic class LowPriorityGlobalResponseInterceptor implements ResponseInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityMethodRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Low priority request interceptor.\n */\npublic class LowPriorityMethodRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/LowPriorityMethodResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Low priority response interceptor.\n */\npublic class LowPriorityMethodResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityClassRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Medium priority request interceptor.\n */\npublic class MediumPriorityClassRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityClassResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Medium priority response interceptor.\n */\npublic class MediumPriorityClassResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityGlobalRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Medium priority global request interceptor.\n */\npublic class MediumPriorityGlobalRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityGlobalResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Medium priority global request interceptor.\n */\npublic class MediumPriorityGlobalResponseInterceptor implements ResponseInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityMethodRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Medium priority request interceptor.\n */\npublic class MediumPriorityMethodRequestInterceptor implements RequestInterceptor {\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/MediumPriorityMethodResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\n/**\n * Medium priority response interceptor.\n */\npublic class MediumPriorityMethodResponseInterceptor implements ResponseInterceptor {\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/PriorityDataHolder.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\n/**\n * Note down the interceptor execution order.\n */\npublic class PriorityDataHolder {\n\n    private static String priorityOrder = \"\";\n\n    /**\n     * Get the executed priority order.\n     *\n     * @return executed priority order.\n     */\n    public static String getPriorityOrder() {\n        return priorityOrder;\n    }\n\n    /**\n     * Set the executed priority order.\n     *\n     * @param priorityOrder executed priority order.\n     */\n    public static void setPriorityOrder(String priorityOrder) {\n        PriorityDataHolder.priorityOrder = priorityOrder;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestBreakRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Test request interceptor.\n */\npublic class TestBreakRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        return false;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestBreakResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Test response interceptor for fat jar mode.\n */\npublic class TestBreakResponseInterceptor implements ResponseInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        return false;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestExceptionBreakRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Test request interceptor.\n */\npublic class TestExceptionBreakRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        throw new Exception(\"Test exception\");\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Interceptor used in test.\n */\npublic class TestInterceptor implements Interceptor {\n    private volatile AtomicInteger numPreCalls = new AtomicInteger(0);\n    private volatile AtomicInteger numPostCalls = new AtomicInteger(0);\n\n    public int getNumPreCalls() {\n        return numPreCalls.get();\n    }\n\n    public int getNumPostCalls() {\n        return numPostCalls.get();\n    }\n\n    public void reset() {\n        numPreCalls.set(0);\n        numPostCalls.set(0);\n    }\n\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo)\n            throws Exception {\n        numPreCalls.incrementAndGet();\n\n        String header = request.getHeader(\"X-Request-Type\");\n        if (header != null && header.equals(\"Reject\")) {\n            responder.setStatus(javax.ws.rs.core.Response.Status.NOT_ACCEPTABLE.getStatusCode());\n            responder.send();\n            return false;\n        }\n\n        if (header != null && header.equals(\"PreException\")) {\n            throw new IllegalArgumentException(\"PreException\");\n        }\n\n        return true;\n    }\n\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) {\n        numPostCalls.incrementAndGet();\n        String header = request.getHeader(\"X-Request-Type\");\n        if (header != null && header.equals(\"PostException\")) {\n            throw new IllegalArgumentException(\"PostException\");\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestInterceptorDeprecated.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Interceptor;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.ServiceMethodInfo;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Interceptor class using deprecated interceptor.\n */\npublic class TestInterceptorDeprecated implements Interceptor {\n\n    private static AtomicInteger preCallInterceptorCalls = new AtomicInteger(0);\n    private static AtomicInteger postCallInterceptorCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        preCallInterceptorCalls.set(0);\n        postCallInterceptorCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor pre calls.\n     *\n     * @return number of pre calls\n     */\n    public static int getPreCallInterceptorCallsCount() {\n        return preCallInterceptorCalls.get();\n    }\n\n    /**\n     * Get the number of interceptor post calls.\n     *\n     * @return number of post calls\n     */\n    public static int getPostCallInterceptorCallsCount() {\n        return postCallInterceptorCalls.get();\n    }\n\n    @Override\n    public boolean preCall(Request request, Response responder, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        preCallInterceptorCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName()\n                + \" - [PRE CALL]\");\n        return true;\n    }\n\n    @Override\n    public void postCall(Request request, int status, ServiceMethodInfo serviceMethodInfo) throws Exception {\n        postCallInterceptorCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName()\n                + \" - [POST CALL]\");\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Test request interceptor.\n */\npublic class TestRequestInterceptor implements RequestInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/interceptor/TestResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.interceptor;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Test response interceptor for fat jar mode.\n */\npublic class TestResponseInterceptor implements ResponseInterceptor {\n\n    private static AtomicInteger filterCalls = new AtomicInteger(0);\n\n    /**\n     * Reset interceptor call count.\n     */\n    public static void reset() {\n        filterCalls.set(0);\n    }\n\n    /**\n     * Get the number of interceptor calls.\n     *\n     * @return number of calls\n     */\n    public static int getFilterCalls() {\n        return filterCalls.get();\n    }\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        filterCalls.incrementAndGet();\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + this.getClass().getSimpleName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/internal/HttpHeadersImplTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.internal;\n\nimport io.netty.handler.codec.http.DefaultHttpRequest;\nimport io.netty.handler.codec.http.HttpVersion;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\nimport org.wso2.transport.http.netty.message.HttpCarbonMessage;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport javax.ws.rs.core.Cookie;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.MultivaluedMap;\n\nimport static org.testng.Assert.assertEquals;\nimport static org.testng.Assert.assertNotNull;\nimport static org.testng.Assert.assertNull;\nimport static org.testng.Assert.assertTrue;\n\npublic class HttpHeadersImplTest {\n    private javax.ws.rs.core.HttpHeaders httpHeaders1;\n    private javax.ws.rs.core.HttpHeaders httpHeaders2;\n\n    @BeforeMethod\n    public void setUp() throws Exception {\n        HttpCarbonMessage httpCarbonMessage = new HttpCarbonMessage(\n                new DefaultHttpRequest(HttpVersion.HTTP_1_1, io.netty.handler.codec.http.HttpMethod.GET, \"msf4j\"));\n        httpCarbonMessage.getHeaders().add(\"testA\", \"test1\");\n        httpCarbonMessage.getHeaders().add(\"testA\", \"test2\");\n        httpCarbonMessage.setHeader(\"Accept\", \"application/json\");\n        httpCarbonMessage.setHeader(\"Content-Type\", \"text/html\");\n        httpCarbonMessage.setHeader(\"Content-Language\", \"en\");\n        httpCarbonMessage.setHeader(\"Content-Length\", \"1024\");\n        httpCarbonMessage.setHeader(\"Date\", \"Sun, 06 Nov 1994 08:49:37 GMT\");\n        httpCarbonMessage.getHeaders().add(\"Accept-Language\", \"da\");\n        httpCarbonMessage.getHeaders().add(\"Accept-Language\", \"en-gb;q=0.8\");\n        httpCarbonMessage.getHeaders().add(\"Accept-Language\", \"en;q=0.7\");\n        httpCarbonMessage.getHeaders().add(\"Cookie\", \"JSESSIONID=3508015E4EF0ECA8C4B761FCC4BC1718\");\n        httpHeaders1 = new HttpHeadersImpl(httpCarbonMessage.getHeaders());\n\n        HttpCarbonMessage httpCarbonMessage2 = new HttpCarbonMessage(\n                new DefaultHttpRequest(HttpVersion.HTTP_1_1, io.netty.handler.codec.http.HttpMethod.GET, \"msf4j\"));\n        httpHeaders2 = new HttpHeadersImpl(httpCarbonMessage2.getHeaders());\n    }\n\n    @Test\n    public void testGetRequestHeader() throws Exception {\n        List<String> headerValues = httpHeaders1.getRequestHeader(\"testA\");\n        assertEquals(headerValues.size(), 2);\n        assertTrue(headerValues.contains(\"test1\"));\n        assertTrue(headerValues.contains(\"test2\"));\n    }\n\n    @Test\n    public void testGetHeaderString() throws Exception {\n        String headerValue = httpHeaders1.getHeaderString(\"testA\");\n        assertEquals(headerValue, \"test1,test2\");\n\n        headerValue = httpHeaders1.getHeaderString(\"Accept\");\n        assertEquals(headerValue, \"application/json\");\n    }\n\n    @Test\n    public void testGetRequestHeaders() throws Exception {\n        MultivaluedMap<String, String> headersMap = httpHeaders1.getRequestHeaders();\n        List<String> headerValues = headersMap.get(\"testA\");\n        assertEquals(headerValues.size(), 2);\n        assertTrue(headerValues.contains(\"test1\"));\n        assertTrue(headerValues.contains(\"test2\"));\n\n        headerValues = headersMap.get(\"Accept\");\n        assertEquals(headerValues.size(), 1);\n        assertTrue(headerValues.contains(\"application/json\"));\n    }\n\n    @Test\n    public void testGetAcceptableMediaTypes() throws Exception {\n        List<MediaType> mediaTypes = httpHeaders1.getAcceptableMediaTypes();\n        assertEquals(mediaTypes.size(), 1);\n        assertEquals(mediaTypes.get(0).getType(), \"application\");\n        assertEquals(mediaTypes.get(0).getSubtype(), \"json\");\n        assertEquals(mediaTypes.get(0).toString(), \"application/json\");\n\n        mediaTypes = httpHeaders2.getAcceptableMediaTypes();\n        assertEquals(mediaTypes.size(), 1);\n        assertEquals(mediaTypes.get(0).getType(), \"*\");\n        assertEquals(mediaTypes.get(0).getSubtype(), \"*\");\n        assertEquals(mediaTypes.get(0).toString(), \"*/*\");\n    }\n\n    @Test\n    public void testGetAcceptableLanguages() throws Exception {\n        List<Locale> locales = httpHeaders1.getAcceptableLanguages();\n        assertEquals(locales.size(), 3);\n        assertEquals(locales.get(0).getLanguage(), \"da\");\n        assertEquals(locales.get(1).getLanguage(), \"en-gb\");\n        assertEquals(locales.get(2).getLanguage(), \"en\");\n\n        locales = httpHeaders2.getAcceptableLanguages();\n        assertEquals(locales.size(), 1);\n        assertEquals(locales.get(0).getLanguage(), \"*\");\n    }\n\n    @Test\n    public void testGetMediaType() throws Exception {\n        MediaType mediaType = httpHeaders1.getMediaType();\n        assertNotNull(mediaType);\n        assertEquals(mediaType.getType(), \"text\");\n        assertEquals(mediaType.getSubtype(), \"html\");\n        assertEquals(mediaType.toString(), \"text/html\");\n\n        MediaType mediaType2 = httpHeaders2.getMediaType();\n        assertNull(mediaType2);\n    }\n\n    @Test\n    public void testGetLanguage() throws Exception {\n        Locale locale = httpHeaders1.getLanguage();\n        assertNotNull(locale);\n        assertEquals(locale.getLanguage(), \"en\");\n\n        Locale locale2 = httpHeaders2.getLanguage();\n        assertNull(locale2);\n    }\n\n    @Test\n    public void testGetCookies() throws Exception {\n        Map<String, Cookie> cookieMap = httpHeaders1.getCookies();\n        assertNotNull(cookieMap);\n        assertEquals(cookieMap.size(), 1);\n        assertTrue(cookieMap.containsKey(\"JSESSIONID\"));\n        assertEquals(cookieMap.get(\"JSESSIONID\").getValue(), \"3508015E4EF0ECA8C4B761FCC4BC1718\");\n\n        Map<String, Cookie> cookieMap2 = httpHeaders2.getCookies();\n        assertEquals(cookieMap2.size(), 0);\n    }\n\n    @Test\n    public void testGetDate() throws Exception {\n        Date date = httpHeaders1.getDate();\n        assertNotNull(date);\n        assertEquals(date.getTime(), 784111777000L);\n\n        Date date2 = httpHeaders2.getDate();\n        assertNull(date2);\n    }\n\n    @Test\n    public void testGetLength() throws Exception {\n        int length = httpHeaders1.getLength();\n        assertEquals(length, 1024);\n\n        int length2 = httpHeaders2.getLength();\n        assertEquals(length2, -1);\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/internal/MicroservicesRegistryTest.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.internal;\n\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.exception.MappedException;\nimport org.wso2.msf4j.exception.MappedException2;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\nimport org.wso2.msf4j.interceptor.TestInterceptor;\nimport org.wso2.msf4j.interceptor.TestInterceptorDeprecated;\nimport org.wso2.msf4j.service.SecondService;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\n\nimport static org.testng.Assert.assertEquals;\nimport static org.testng.Assert.assertFalse;\nimport static org.testng.Assert.assertTrue;\n\n/**\n * Test class to validate the MicroservicesRegistry.\n */\npublic class MicroservicesRegistryTest {\n\n    private MicroservicesRunner microservicesRunner = new MicroservicesRunner();\n    private SecondService service = new SecondService();\n    private TestExceptionMapper exceptionMapper1 = new TestExceptionMapper();\n    private TestExceptionMapper2 exceptionMapper2 = new TestExceptionMapper2();\n    private TestInterceptor interceptor1 = new TestInterceptor();\n    private TestInterceptorDeprecated interceptor2 = new TestInterceptorDeprecated();\n\n    @BeforeClass\n    public void setup() {\n        microservicesRunner.getMsRegistry().addService(service);\n        microservicesRunner.getMsRegistry().addInterceptor(interceptor1, interceptor2);\n        microservicesRunner.getMsRegistry().addExceptionMapper(exceptionMapper1, exceptionMapper2);\n    }\n\n    /**\n     * Test the basic functionality of MicroservicesRegistry.\n     */\n    @Test\n    public void testMicroservicesRegistry() {\n        MicroservicesRegistryImpl msRegistry = microservicesRunner.getMsRegistry();\n        Optional<Map.Entry<String, Object>> serviceWithBasePath = msRegistry.getServiceWithBasePath(\"/SecondService\");\n        assertTrue(serviceWithBasePath.isPresent());\n        assertEquals(msRegistry.getHttpServices().size(), 1);\n        assertEquals(msRegistry.getServiceCount(), 1);\n        assertTrue(msRegistry.getHttpServices().contains(service));\n        msRegistry.removeService(service);\n        serviceWithBasePath = msRegistry.getServiceWithBasePath(\"/SecondService\");\n        assertFalse(serviceWithBasePath.isPresent());\n\n        List<RequestInterceptor> globalRequestInterceptorList = msRegistry.getGlobalRequestInterceptorList();\n        assertEquals(globalRequestInterceptorList.size(), 2);\n        assertEquals(globalRequestInterceptorList.get(0), interceptor1);\n        List<ResponseInterceptor> globalResponseInterceptorList = msRegistry.getGlobalResponseInterceptorList();\n        assertEquals(globalResponseInterceptorList.size(), 2);\n        assertEquals(globalResponseInterceptorList.get(0), interceptor1);\n        msRegistry.removeInterceptor(interceptor1);\n        assertEquals(msRegistry.getGlobalRequestInterceptorList().size(), 1);\n        assertEquals(msRegistry.getGlobalResponseInterceptorList().size(), 1);\n        msRegistry.removeGlobalRequestInterceptor(interceptor2);\n        assertEquals(msRegistry.getGlobalRequestInterceptorList().size(), 0);\n        assertEquals(msRegistry.getGlobalResponseInterceptorList().size(), 1);\n        msRegistry.removeGlobalResponseInterceptor(interceptor2);\n        assertEquals(msRegistry.getGlobalRequestInterceptorList().size(), 0);\n        assertEquals(msRegistry.getGlobalResponseInterceptorList().size(), 0);\n\n        assertTrue(msRegistry.getExceptionMapper(new MappedException()).isPresent());\n        assertTrue(msRegistry.getExceptionMapper(new MappedException2()).isPresent());\n        msRegistry.removeExceptionMapper(exceptionMapper1);\n        //TODO this assertion get fail when enable coverage. Need to check why\n        assertFalse(msRegistry.getExceptionMapper(new MappedException()).isPresent());\n        assertTrue(msRegistry.getExceptionMapper(new MappedException2()).isPresent());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/Category.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.pojo;\n\n/**\n * The pet category; such as dog, cat, bird, reptile, fish etc.\n */\npublic class Category {\n\n    private String name;\n\n    public Category(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/Company.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.pojo;\n\n/**\n * Simple bean class for a company.\n */\npublic class Company {\n    private String type;\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    @Override\n    public String toString() {\n        return \"Company {\" +\n               \"type='\" + type + '\\'' +\n               '}';\n    }\n\n    /*public Company(String type) {\n        this.type = type;\n    }*/\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/Person.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.pojo;\n\n/**\n * Simple Bean class for a Person.\n */\npublic class Person {\n    private String name;\n    private int age;\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String toString() {\n        return \"Person{\" +\n               \"name='\" + name + '\\'' +\n               \", age=\" + age +\n               '}';\n    }\n\n    /*public Person(String name) {\n        this.name = name;\n    }*/\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/Pet.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.pojo;\n\nimport java.util.UUID;\n\n/**\n * Bean class used for testing JAX-RS bean conversions.\n */\npublic class Pet {\n\n    private String id = UUID.randomUUID().toString();\n    private Category category;\n    private int ageMonths;\n    private String details;\n    private float price;\n    private long dateAdded  = System.currentTimeMillis();\n    private String image;\n\n    public Pet() {\n    }\n\n    public int getAgeMonths() {\n        return ageMonths;\n    }\n\n    public void setAgeMonths(int ageMonths) {\n        this.ageMonths = ageMonths;\n    }\n\n    public Category getCategory() {\n        return category;\n    }\n\n    public void setCategory(Category category) {\n        this.category = category;\n    }\n\n    public long getDateAdded() {\n        return dateAdded;\n    }\n\n    public String getDetails() {\n        return details;\n    }\n\n    public void setDetails(String details) {\n        this.details = details;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getImage() {\n        return image;\n    }\n\n    public void setImage(String image) {\n        this.image = image;\n    }\n\n    public float getPrice() {\n        return price;\n    }\n\n    public void setPrice(float price) {\n        this.price = price;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/TextBean.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.pojo;\n\n/**\n * Bean class used for testing JAX-RS bean conversions.\n */\npublic class TextBean {\n    private String text;\n\n    public String getText() {\n        return text;\n    }\n\n    public void setText(String text) {\n        this.text = text;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/pojo/XmlBean.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.pojo;\n\nimport javax.xml.bind.annotation.XmlAttribute;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Xml bean conversion test bean.\n */\n@XmlRootElement\npublic class XmlBean {\n\n    String name;\n    int value;\n    int id;\n\n    public String getName() {\n        return name;\n    }\n\n    @XmlElement\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getValue() {\n        return value;\n    }\n\n    @XmlElement\n    public void setValue(int value) {\n        this.value = value;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    @XmlAttribute\n    public void setId(int id) {\n        this.id = id;\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/ExtendedTestMicroservice.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.service;\n\nimport com.google.gson.JsonObject;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Response;\n\n/**\n * Service for testing inheritance.\n */\n@Path(\"/ext-test/v1\")\npublic class ExtendedTestMicroservice extends TestMicroservice {\n\n    @Path(\"resource\")\n    @GET\n    public Response testExtendendGet() {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"status\", \"Handled extended get in resource end-point\");\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/InterceptorTestMicroService.java",
    "content": "/*\n*  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied.  See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\npackage org.wso2.msf4j.service;\n\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.TestBreakRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestBreakResponseInterceptor;\nimport org.wso2.msf4j.interceptor.TestExceptionBreakRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestResponseInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\nimport org.wso2.msf4j.service.sub.Team;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Micro Service to test interceptors.\n */\n@Path(\"/test/interceptorTest\")\n@RequestInterceptor(TestRequestInterceptor.class)\n@ResponseInterceptor(TestResponseInterceptor.class)\npublic class InterceptorTestMicroService implements Microservice {\n\n    @GET\n    @Path(\"/interceptorBreakOnExceptionTest\")\n    @RequestInterceptor({TestExceptionBreakRequestInterceptor.class, TestRequestInterceptor.class})\n    public String interceptorBreakOnExceptionTest() {\n        return \"Exception break interceptor test\";\n    }\n\n    @GET\n    @Path(\"/requestInterceptorBreakByUserTest\")\n    @RequestInterceptor({TestBreakRequestInterceptor.class, TestRequestInterceptor.class})\n    public String requestInterceptorBreakByUserTest() {\n        return \"Manual break request interceptor test\";\n    }\n\n    @GET\n    @Path(\"/responseInterceptorBreakByUserTest\")\n    @RequestInterceptor(TestRequestInterceptor.class)\n    @ResponseInterceptor({TestBreakResponseInterceptor.class, TestResponseInterceptor.class})\n    public String responseInterceptorBreakByUserTest() {\n        return \"Manual break response interceptor test\";\n    }\n\n    @Produces(MediaType.APPLICATION_JSON)\n    @Path(\"/subResourceLocatorTest/{countryId}\")\n    @RequestInterceptor(TestRequestInterceptor.class)\n    @ResponseInterceptor(TestResponseInterceptor.class)\n    public Team subResourceLocatorTest(@PathParam(\"countryId\") String countryId) {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + \"[HTTP RESOURCE METHOD]\");\n        return new Team(countryId);\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/PriorityInterceptorTestMicroService.java",
    "content": "/*\n*  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n*\n*  WSO2 Inc. licenses this file to you under the Apache License,\n*  Version 2.0 (the \"License\"); you may not use this file except\n*  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,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied.  See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\npackage org.wso2.msf4j.service;\n\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.interceptor.HighPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n/**\n * Micro Service to test priority of interceptors.\n */\n@Path(\"/test/priorityInterceptorTest\")\n@RequestInterceptor({\n        HighPriorityClassRequestInterceptor.class,\n        MediumPriorityClassRequestInterceptor.class,\n        LowPriorityClassRequestInterceptor.class\n})\n@ResponseInterceptor({\n        HighPriorityClassResponseInterceptor.class,\n        MediumPriorityClassResponseInterceptor.class,\n        LowPriorityClassResponseInterceptor.class\n})\npublic class PriorityInterceptorTestMicroService implements Microservice {\n\n    @GET\n    @Path(\"/priorityTest\")\n    @RequestInterceptor({\n            HighPriorityMethodRequestInterceptor.class,\n            MediumPriorityMethodRequestInterceptor.class,\n            LowPriorityMethodRequestInterceptor.class\n    })\n    @ResponseInterceptor({\n            HighPriorityMethodResponseInterceptor.class,\n            MediumPriorityMethodResponseInterceptor.class,\n            LowPriorityMethodResponseInterceptor.class\n    })\n    public String priorityInterceptorTest() {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + \"[HTTP METHOD]\");\n        return \"Priority interceptor test\";\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/SecondService.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.service;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Simple RESTful web service.\n */\n@Path(\"/SecondService\")\npublic class SecondService {\n\n    @GET\n    @Path(\"/addNumbers/{no1}/{no2}\")\n    public int add(@PathParam(\"no1\") int no1, @PathParam(\"no2\") int no2) {\n        return no1 + no2;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/TestMicroServiceWithDynamicPath.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.service;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\npublic class TestMicroServiceWithDynamicPath {\n\n    @GET\n    @Path(\"/hello/{name}\")\n    public String sayHello(@PathParam(\"name\") String name) {\n        return \"Hello \" + name;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/TestMicroservice.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.service;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\nimport com.google.gson.JsonPrimitive;\nimport com.google.gson.reflect.TypeToken;\nimport org.apache.commons.io.IOUtils;\nimport org.wso2.msf4j.HttpStreamHandler;\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.exception.MappedException;\nimport org.wso2.msf4j.exception.MappedException2;\nimport org.wso2.msf4j.formparam.FileInfo;\nimport org.wso2.msf4j.formparam.FormDataParam;\nimport org.wso2.msf4j.formparam.FormItem;\nimport org.wso2.msf4j.formparam.FormParamIterator;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.pojo.Company;\nimport org.wso2.msf4j.pojo.Person;\nimport org.wso2.msf4j.pojo.Pet;\nimport org.wso2.msf4j.pojo.TextBean;\nimport org.wso2.msf4j.pojo.XmlBean;\nimport org.wso2.msf4j.service.sub.Team;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedReader;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TimeZone;\nimport java.util.concurrent.TimeUnit;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.CookieParam;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.DefaultValue;\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HeaderParam;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.QueryParam;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.MultivaluedMap;\nimport javax.ws.rs.core.NewCookie;\nimport javax.ws.rs.core.Response;\n\nimport static org.testng.AssertJUnit.fail;\n\n/**\n * Test service.\n */\n@SuppressWarnings(\"UnusedParameters\")\n@Path(\"/test/v1\")\npublic class TestMicroservice implements Microservice {\n    private static final String SAMPLE_STRING = \"foo\";\n\n    private static final Gson GSON = new Gson();\n\n    @GET\n    public String noMethodPathGet() {\n        return \"no-@Path-GET\";\n    }\n\n    @POST\n    public String noMethodPathPost() {\n        return \"no-@Path-POST\";\n    }\n\n    @PUT\n    public String noMethodPathPut() {\n        return \"no-@Path-PUT\";\n    }\n\n    @DELETE\n    public String noMethodPathDelete() {\n        return \"no-@Path-DELETE\";\n    }\n\n    @Path(\"jsonConsumeStringProduce\")\n    @POST\n    @Consumes(\"text/json\")\n    @Produces(\"text/plain\")\n    public String jsonConsume01(Pet input) {\n        return input.getDetails();\n    }\n\n    @Path(\"textConsumeJsonProduce\")\n    @POST\n    @Produces(\"text/json\")\n    @Consumes(\"text/plain\")\n    public TextBean textConsume01(String input) {\n        TextBean textBean = new TextBean();\n        textBean.setText(input);\n        return textBean;\n    }\n\n    @Path(\"textConsumeTextProduce\")\n    @POST\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String textConsume02(String input) {\n        return input + \"-processed\";\n    }\n\n    @Path(\"textConsumeTextProduceXml\")\n    @POST\n    @Consumes(\"text/xml\")\n    @Produces(\"text/xml\")\n    public XmlBean textConsume03(XmlBean input) {\n        return input;\n    }\n\n    @Path(\"sleep/{seconds}\")\n    @GET\n    public Response testSleep(@PathParam(\"seconds\") int seconds) {\n        try {\n            TimeUnit.SECONDS.sleep(seconds);\n            return Response.status(Response.Status.OK).entity(\"slept: \" + seconds + \"s\").build();\n        } catch (InterruptedException e) {\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();\n        }\n    }\n\n    @Path(\"response/typehtml\")\n    @GET\n    public Response produceHtmlContent0() {\n        return Response.ok()\n                .type(MediaType.TEXT_HTML_TYPE)\n                .entity(\"Hello\")\n                .build();\n    }\n\n    @Path(\"response/typehtml/str\")\n    @GET\n    public Response produceHtmlContent1() {\n        return Response.ok()\n                .type(MediaType.TEXT_HTML)\n                .entity(\"Hello\")\n                .build();\n    }\n\n    @Path(\"resource\")\n    @GET\n    public Response testGet() {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"status\", \"Handled get in resource end-point\");\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"tweets/{id}\")\n    @GET\n    public Response testGetTweet(@PathParam(\"id\") String id) {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"status\", String.format(\"Handled get in tweets end-point, id: %s\", id));\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"tweets/{id}\")\n    @PUT\n    public Response testPutTweet(@PathParam(\"id\") String id) {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"status\", String.format(\"Handled put in tweets end-point, id: %s\", id));\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"facebook/{id}/message\")\n    @DELETE\n    public void testNoMethodRoute(@PathParam(\"id\") String id) {\n\n    }\n\n    @Path(\"facebook/{id}/message\")\n    @PUT\n    public Response testPutMessage(@PathParam(\"id\") String id, @Context Request request) {\n        String message = String.format(\"Handled put in tweets end-point, id: %s. \", id);\n        try {\n            String data = getStringContent(request);\n            message = message.concat(String.format(\"Content: %s\", data));\n        } catch (IOException e) {\n            //This condition should never occur\n            fail();\n        }\n        JsonObject object = new JsonObject();\n        object.addProperty(\"result\", message);\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"facebook/{id}/message\")\n    @POST\n    public Response testPostMessage(@PathParam(\"id\") String id, @Context Request request) {\n        String message = String.format(\"Handled post in tweets end-point, id: %s. \", id);\n        try {\n            String data = getStringContent(request);\n            message = message.concat(String.format(\"Content: %s\", data));\n        } catch (IOException e) {\n            //This condition should never occur\n            fail();\n        }\n        JsonObject object = new JsonObject();\n        object.addProperty(\"result\", message);\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"/user/{userId}/message/{messageId}\")\n    @GET\n    public Response testMultipleParametersInPath(@PathParam(\"userId\") String userId,\n                                                 @PathParam(\"messageId\") int messageId) {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"result\", String.format(\"Handled multiple path parameters %s %d\", userId, messageId));\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"/message/{messageId}/user/{userId}\")\n    @GET\n    public Response testMultipleParametersInDifferentParameterDeclarationOrder(@PathParam(\"userId\") String userId,\n                                                                               @PathParam(\"messageId\") int messageId) {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"result\", String.format(\"Handled multiple path parameters %s %d\", userId, messageId));\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"/NotRoutable/{id}\")\n    @GET\n    public Response notRoutableParameterMismatch(@PathParam(\"userid\") String userId) {\n        JsonObject object = new JsonObject();\n        object.addProperty(\"result\", String.format(\"Handled Not routable path %s \", userId));\n        return Response.status(Response.Status.OK).entity(object).build();\n    }\n\n    @Path(\"/exception\")\n    @GET\n    public void exception() {\n        throw new IllegalArgumentException(\"Illegal argument\");\n    }\n\n    private String getStringContent(Request request) throws IOException {\n        return getStringFromInputStream(request.getMessageContentStream());\n    }\n\n    /**\n     * Convert input stream to String.\n     *\n     * @param in Input stream to be converted to string\n     * @return Converted string\n     */\n    private static String getStringFromInputStream(InputStream in) {\n        BufferedInputStream bis = new BufferedInputStream(in);\n        ByteArrayOutputStream bos = new ByteArrayOutputStream();\n        String result;\n        try {\n            int data;\n            while ((data = bis.read()) != -1) {\n                bos.write(data);\n            }\n            result = bos.toString();\n        } catch (IOException ioe) {\n            return \"\";\n        } finally {\n            try {\n                bos.close();\n            } catch (IOException ignored) {\n\n            }\n        }\n        return result;\n    }\n\n    @Path(\"/multi-match/**\")\n    @GET\n    public String multiMatchAll() {\n        return \"multi-match-*\";\n    }\n\n    @Path(\"/multi-match/{param}\")\n    @GET\n    public String multiMatchParam(@PathParam(\"param\") String param) {\n        return \"multi-match-param-\" + param;\n    }\n\n    @Path(\"/multi-match/foo\")\n    @GET\n    public String multiMatchFoo() {\n        return \"multi-match-get-actual-foo\";\n    }\n\n    @Path(\"/multi-match/foo\")\n    @PUT\n    public String multiMatchParamPut() {\n        return \"multi-match-put-actual-foo\";\n    }\n\n    @Path(\"/multi-match/{param}/bar\")\n    @GET\n    public String multiMatchParamBar(@PathParam(\"param\") String param) {\n        return \"multi-match-param-bar-\" + param;\n    }\n\n    @Path(\"/multi-match/foo/{param}\")\n    @GET\n    public String multiMatchFooParam(@PathParam(\"param\") String param) {\n        return \"multi-match-get-foo-param-\" + param;\n    }\n\n    @Path(\"/multi-match/foo/{param}/bar\")\n    @GET\n    public String multiMatchFooParamBar(@PathParam(\"param\") String param) {\n        return \"multi-match-foo-param-bar-\" + param;\n    }\n\n    @Path(\"/multi-match/foo/bar/{param}\")\n    @GET\n    public String multiMatchFooBarParam(@PathParam(\"param\") String param) {\n        return \"multi-match-foo-bar-param-\" + param;\n    }\n\n    @Path(\"/multi-match/foo/{param}/bar/baz\")\n    @GET\n    public String multiMatchFooParamBarBaz(@PathParam(\"param\") String param) {\n        return \"multi-match-foo-param-bar-baz-\" + param;\n    }\n\n    @Path(\"/multi-match/foo/bar/{param}/{id}\")\n    @GET\n    public String multiMatchFooBarParamId(@PathParam(\"param\") String param, @PathParam(\"id\") String id) {\n        return \"multi-match-foo-bar-param-\" + param + \"-id-\" + id;\n    }\n\n    @Path(\"/fileserver/{fileType}\")\n    @GET\n    public Response serveFile(@PathParam(\"fileType\") String fileType) throws Exception {\n        File file;\n        if (\"png\".equals(fileType)) {\n            file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI());\n            return Response.ok(file).build();\n        } else if (\"jpg\".equals(fileType)) {\n            file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI());\n            return Response.ok(file).header(\"X-Custom-Header\", \"wso2\").build();\n        } else if (\"txt\".equals(fileType)) {\n            file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI());\n            return Response.ok(file).build();\n        }\n        return Response.noContent().build();\n    }\n\n    @Path(\"/fileserver/ip/{fileType}\")\n    @GET\n    public Response serveInputStream(@PathParam(\"fileType\") String fileType) throws Exception {\n        if (\"png\".equals(fileType)) {\n            InputStream ipStream = new FileInputStream(\n                    new File(Thread.currentThread().getContextClassLoader().getResource(\"testPngFile.png\").toURI()));\n            return Response.ok(ipStream).type(\"image/png\").build();\n        } else if (\"jpg\".equals(fileType)) {\n            InputStream ipStream = new FileInputStream(\n                    new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI()));\n            return Response.ok(ipStream).type(\"image/jpeg\").header(\"X-Custom-Header\", \"wso2\").build();\n        } else if (\"txt\".equals(fileType)) {\n            InputStream ipStream = new FileInputStream(\n                    new File(Thread.currentThread().getContextClassLoader().getResource(\"testTxtFile.txt\").toURI()));\n            return Response.ok(ipStream).type(\"text/plain\").build();\n        }\n        return Response.noContent().build();\n    }\n\n    @Path(\"/stream/upload\")\n    @PUT\n    public void streamUpload(@Context HttpStreamer httpStreamer) throws Exception {\n        final StringBuffer sb = new StringBuffer();\n        httpStreamer.callback(new HttpStreamHandler() {\n\n            private org.wso2.msf4j.Response response;\n\n            @Override\n            public void init(org.wso2.msf4j.Response response) {\n\n                this.response = response;\n            }\n\n            @Override\n            public void chunk(ByteBuffer content) throws Exception {\n                sb.append(Charset.defaultCharset().decode(content).toString());\n            }\n\n            @Override\n            public void end() throws Exception {\n                response.setStatus(Response.Status.OK.getStatusCode());\n                response.setEntity(sb.toString());\n                response.send();\n            }\n\n            @Override\n            public void error(Throwable cause) {\n                sb.delete(0, sb.length());\n            }\n        });\n    }\n\n    @Path(\"/stream/upload/fail\")\n    @PUT\n    public HttpStreamHandler streamUploadFailure() {\n        final int fileSize = 30 * 1024 * 1024;\n\n        return new HttpStreamHandler() {\n            private org.wso2.msf4j.Response response;\n            ByteBuffer offHeapBuffer = ByteBuffer.allocateDirect(fileSize);\n\n            @Override\n            public void init(org.wso2.msf4j.Response response) {\n                this.response = response;\n            }\n\n            @Override\n            public void chunk(ByteBuffer content) throws Exception {\n                offHeapBuffer.put(content.array());\n            }\n\n            @Override\n            public void end() throws Exception {\n                int bytesUploaded = offHeapBuffer.position();\n                response.setStatus(Response.Status.OK.getStatusCode());\n                response.setEntity(\"Uploaded:\" + bytesUploaded);\n                response.send();\n            }\n\n            @Override\n            public void error(Throwable cause) {\n                offHeapBuffer = null;\n            }\n        };\n    }\n\n    @Path(\"/aggregate/upload\")\n    @PUT\n    public String aggregatedUpload(@Context Request request) {\n        ByteBuffer content = ByteBuffer.wrap(getStringFromInputStream(request.getMessageContentStream()).\n                getBytes(Charset.defaultCharset()));\n        int bytesUploaded = content.capacity();\n        return \"Uploaded:\" + bytesUploaded;\n    }\n\n    @Path(\"/gzipfile\")\n    @GET\n    public Response gzipFile() throws IOException, URISyntaxException {\n        File file = new File(Thread.currentThread().getContextClassLoader().getResource(\"testJpgFile.jpg\").toURI());\n        return Response.ok().entity(file).build();\n    }\n\n    @Path(\"/uexception\")\n    @GET\n    public void testException() {\n        throw new RuntimeException(\"User Exception\");\n    }\n\n    @Path(\"/noresponse\")\n    @GET\n    public void testNoResponse() {\n    }\n\n    @Path(\"/stringQueryParam/{path}\")\n    @GET\n    public String testStringQueryParam(@PathParam(\"path\") String path, @QueryParam(\"name\") String name) {\n        return path + \":\" + name;\n    }\n\n    @Path(\"/primitiveQueryParam\")\n    @GET\n    public String testPrimitiveQueryParam(@QueryParam(\"age\") int age) {\n        return Integer.toString(age);\n    }\n\n    @Path(\"/sortedSetQueryParam\")\n    @GET\n    public String testSortedSetQueryParam(@QueryParam(\"id\") SortedSet<Integer> ids) {\n        StringBuilder response = new StringBuilder();\n        ids.forEach(id -> response.append(id).append(\",\"));\n        if (response.length() > 0) {\n            response.setLength(response.length() - 1);\n        }\n        return response.toString();\n    }\n\n    @Path(\"/listHeaderParam\")\n    @GET\n    public String testListHeaderParam(@HeaderParam(\"name\") List<String> names) {\n        StringBuilder response = new StringBuilder();\n        names.forEach(name -> response.append(name).append(\",\"));\n        response.setLength(response.length() - 1);\n        return response.toString();\n    }\n\n    @Path(\"/headerResponse\")\n    @GET\n    public Response testHeaderResponse(@HeaderParam(\"name\") String name) {\n        return Response.status(Response.Status.OK.getStatusCode()).entity(\"Entity\").header(\"name\", name).build();\n    }\n\n    @Path(\"/defaultValue\")\n    @GET\n    public Object testDefaultValue(@DefaultValue(\"30\") @QueryParam(\"age\") Integer age,\n                                   @DefaultValue(\"hello\") @QueryParam(\"name\") String name,\n                                   @DefaultValue(\"casking\") @HeaderParam(\"hobby\") List<String> hobbies) {\n        JsonObject response = new JsonObject();\n        response.addProperty(\"age\", age);\n        response.addProperty(\"name\", name);\n        response.add(\"hobby\", GSON.toJsonTree(hobbies, new TypeToken<List<String>>() {\n        }.getType()));\n\n        return response;\n    }\n\n    @Path(\"/connectionClose\")\n    @GET\n    public Response testConnectionClose() {\n        return Response.status(Response.Status.OK).entity(\"Close connection\").header(\"Connection\", \"close\").build();\n    }\n\n    @Path(\"/uploadReject\")\n    @POST\n    public Response testUploadReject() {\n        return Response.status(Response.Status.BAD_REQUEST).entity(\"Rejected\").header(\"Connection\", \"close\").build();\n    }\n\n    @Path(\"/customException\")\n    @POST\n    public void testCustomException() throws CustomException {\n        throw new CustomException();\n    }\n\n    @Path(\"/mappedException\")\n    @GET\n    public void testExceptionMapping() throws MappedException {\n        throw new MappedException(\"Mapped exception thrown\");\n    }\n\n    @Path(\"/mappedException2\")\n    @GET\n    public void testExceptionMapping2() throws MappedException2 {\n        throw new MappedException2(\"Mapped exception 2 thrown\");\n    }\n\n    @Path(\"/formParam\")\n    @POST\n    @Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})\n    public Response tesFormParamWithURLEncoded(@FormParam(\"name\") String name, @FormParam(\"age\") int age) {\n        return Response.ok().entity(name + \":\" + age).build();\n    }\n\n    @Path(\"/formDataParam\")\n    @POST\n    @Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})\n    public Response tesFormDataParam(@FormDataParam(\"name\") String name, @FormDataParam(\"age\") int age) {\n        return Response.ok().entity(name + \":\" + age).build();\n    }\n\n    @Path(\"/formParamWithList\")\n    @POST\n    @Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})\n    public Response tesFormParamList(@FormParam(\"names\") List<String> names) {\n        return Response.ok().entity(names.size()).build();\n    }\n\n    @Path(\"/formParamWithSet\")\n    @POST\n    @Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})\n    public Response tesFormParamSet(@FormParam(\"names\") Set<String> names) {\n        return Response.ok().entity(names.size()).build();\n    }\n\n    @POST\n    @Path(\"/testFormParamWithFile\")\n    public Response testFormParamWithFile(@Context FormParamIterator formParamIterator) {\n        String response = \"\";\n        try {\n            while (formParamIterator.hasNext()) {\n                FormItem item = formParamIterator.next();\n                response = item.getName();\n            }\n        } catch (FormUploadException e) {\n            response = e.getMessage();\n        }\n        return Response.ok().entity(response).build();\n    }\n\n    @POST\n    @Path(\"/complexForm\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response complexForm(@FormDataParam(\"file\") File file,\n                                @FormDataParam(\"id\") int id,\n                                @FormDataParam(\"people\") List<Person> personList,\n                                @FormDataParam(\"company\") Company company) {\n        return Response.ok().entity(file.getName() + \":\" + id + \":\" + personList.size() + \":\" + company.getType())\n                .build();\n    }\n\n\n    @POST\n    @Path(\"/multipleFiles\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response multipleFiles(@FormDataParam(\"files\") List<File> files) {\n        return Response.ok().entity(files.size()).build();\n    }\n\n    @POST\n    @Path(\"/streamFile\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response multipleFiles(@FormDataParam(\"file\") FileInfo fileInfo,\n                                  @FormDataParam(\"file\") InputStream inputStream) {\n        StringBuilder stringBuilder = new StringBuilder();\n        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {\n            while (bufferedReader.ready()) {\n                stringBuilder.append(bufferedReader.readLine());\n            }\n        } catch (IOException e) {\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();\n        } finally {\n            IOUtils.closeQuietly(inputStream);\n        }\n        return Response.ok().entity(stringBuilder.toString() + \"-\" + fileInfo.getFileName()).build();\n    }\n\n    @POST\n    @Path(\"/getAllFormItemsURLEncoded\")\n    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n    public Response getAllFormItemsURLEncoded(@Context MultivaluedMap formItemMultivaluedMap) {\n        int noOfCompanies = ((ArrayList) formItemMultivaluedMap.get(\"names\")).size();\n        String type = formItemMultivaluedMap.getFirst(\"type\").toString();\n        String response = \"No of Companies-\" + noOfCompanies + \" type-\" + type;\n        return Response.ok().entity(response).build();\n    }\n\n    @POST\n    @Path(\"/getAllFormItemsMultipart\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response getAllFormItemsMultipart(@Context MultivaluedMap formItemMultivaluedMap) {\n        ArrayList files = (ArrayList) formItemMultivaluedMap.get(\"file\");\n        String person = formItemMultivaluedMap.getFirst(\"people\").toString();\n        JsonParser parser = new JsonParser();\n        String name = parser.parse(person).getAsJsonArray().get(0).getAsJsonObject().get(\"name\").getAsString();\n        String response =\n                \"FileCount-\" + files.size() + \" SecondFileName-\" + ((File) files.get(1)).getName() + \" FirstPerson-\" +\n                        name;\n        return Response.ok().entity(response).build();\n    }\n\n    @POST\n    @Path(\"/getAllFormItemsXFormUrlEncoded\")\n    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n    public Response getAllFormItemsXFormUrlEncoded(@Context MultivaluedMap formItemMultivaluedMap) {\n        ArrayList names = (ArrayList) formItemMultivaluedMap.get(\"names\");\n        String type = formItemMultivaluedMap.getFirst(\"type\").toString();\n        String response = \"Type = \" + type + \" No of names = \" + names.size() + \" First name = \" + names.get(1);\n        return Response.ok().entity(response).build();\n    }\n\n    @GET\n    @Path(\"{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/states\")\n    public Response testPathParamWithRegexOne(@PathParam(\"assetType\") String assetType, @PathParam(\"id\") String id) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"Asset Type = \").append(assetType).append(\", Asset Id = \").append(id);\n        return Response.ok().entity(sb.toString()).build();\n    }\n\n    @GET\n    @Path(\"/endpoints/{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}\")\n    public Response testPathParamWithRegexTwo(@PathParam(\"assetType\") String assetType, @PathParam(\"id\") String id) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"Asset Type = \").append(assetType).append(\", Asset Id = \").append(id);\n        return Response.ok().entity(sb.toString()).build();\n    }\n\n    private static int initialValue = 0;\n\n    @GET\n    @Path(\"/testDualInvocation1\")\n    public Response testDualInvocation1() {\n        initialValue++;\n        return Response.ok().entity(initialValue).build();\n    }\n\n    @GET\n    @Path(\"/testDualInvocation2\")\n    public Response testDualInvocation2() {\n        int returnVal = initialValue + 1;\n        initialValue = 0;\n        return Response.ok().entity(returnVal).build();\n    }\n\n    @GET\n    @Path(\"/testJsonProduceWithString\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Response testJsonProduceWithString() {\n        String res = \"{\\\"abc\\\":[{\\\"name\\\":\\\"Richard Stallman\\\",\\\"age\\\":63}, {\\\"name\\\":\\\"Linus Torvalds\\\",\\\"age\\\":46}]}\";\n        return Response.ok().entity(res).build();\n    }\n\n    @GET\n    @Path(\"/testJsonProduceWithJsonArray\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Response testJsonProduceWithJsonArray() {\n        JsonArray jsonArray = new JsonArray();\n        jsonArray.add(new JsonPrimitive(\"12\"));\n        jsonArray.add(new JsonPrimitive(\"15\"));\n        jsonArray.add(new JsonPrimitive(\"15\"));\n        return Response.ok().entity(jsonArray).build();\n    }\n\n    @GET\n    @Path(\"/testJsonProduceWithJsonObject\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Response testJsonProduceWithJJsonObject() {\n        JsonObject jsonObject = new JsonObject();\n        jsonObject.add(\"name\", new JsonPrimitive(\"WSO2\"));\n        JsonArray jsonArray = new JsonArray();\n        jsonArray.add(new JsonPrimitive(\"APIM\"));\n        jsonArray.add(new JsonPrimitive(\"IS\"));\n        jsonArray.add(new JsonPrimitive(\"MSF4J\"));\n        jsonObject.add(\"products\", jsonArray);\n        return Response.ok().entity(jsonObject).build();\n    }\n\n    /**\n     * Operation with no content in the response and sets a value in the session.\n     */\n    @GET\n    @Path(\"/set-session/{value}\")\n    public void setObjectInSession(@Context Request request, @PathParam(\"value\") String value) {\n        request.getSession().setAttribute(SAMPLE_STRING, value);\n    }\n\n    /**\n     * Operation which returns content in the response and sets a value in the session.\n     */\n    @GET\n    @Path(\"/set-session2/{value}\")\n    public String setObjectInSession2(@Context Request request, @PathParam(\"value\") String value) {\n        request.getSession().setAttribute(SAMPLE_STRING, value);\n        return value;\n    }\n\n    /**\n     * Operation which retrieves value set in the session in the {@link #setObjectInSession} &\n     * {@link #setObjectInSession2} methods.\n     */\n    @GET\n    @Path(\"/get-session\")\n    public String getObjectFromSession(@Context Request request) {\n        return (String) request.getSession().getAttribute(SAMPLE_STRING);\n    }\n\n    @GET\n    @Path(\"/expire-session\")\n    public void expireSession(@Context Request request) {\n        request.getSession().invalidate();\n    }\n\n    @GET\n    @Path(\"/cookie\")\n    public Response echoCookieValue(@CookieParam(\"name\") String name) {\n        NewCookie newCookie;\n        if (\"wso2\".equalsIgnoreCase(name)) {\n            TimeZone.setDefault(TimeZone.getTimeZone(\"IST\"));\n            Calendar instance = Calendar.getInstance();\n            instance.set(2017, 0, 1, 0, 0, 0);\n            newCookie =\n                    new NewCookie(\"test-cookie\", name, \"/cookie\", \"wso2.com\", 1, \"Cookie Test\", 10, instance.getTime(),\n                                  true, true);\n        } else {\n            newCookie = new NewCookie(\"test-cookie\", name);\n        }\n        return Response.ok().entity(name).cookie(newCookie).build();\n    }\n\n\n    @Produces(MediaType.APPLICATION_JSON)\n    @Path(\"/{countryId}/team\")\n    public Team getCountryTeam(@PathParam(\"countryId\") String countryId) {\n        return new Team(countryId);\n    }\n\n    @GET\n    @Path(\"/locationRealtiveUriTest\")\n    public Response locationRealtiveUriTest() {\n        return Response.status(Response.Status.CREATED).location(URI.create(\"/entity/1\")).build();\n    }\n\n    @GET\n    @Path(\"/locationAbsoluteUriTest\")\n    public Response locationAbsoluteUriTest() {\n        return Response.status(Response.Status.CREATED).location(URI.create(\"http://localhost:8080/products/entity/2\"))\n                       .build();\n    }\n\n    /**\n     * Custom exception class for testing exception handler.\n     */\n    public static final class CustomException extends Exception {\n        public static final int HTTP_RESPONSE_STATUS = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/sub/Player.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.service.sub;\n\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Simple RESTful web service for Player.\n */\n@Path(\"/\")\npublic class Player {\n\n    private String name;\n    private int playerId;\n    private String countryId;\n    private String countryName;\n    private byte age;\n    private String type;\n\n    public Player(String countryId, int playerId) {\n        this.countryId = countryId;\n        this.playerId = playerId;\n        age = 30;\n        name = \"player_1\";\n    }\n\n    public Player() {\n        name = \"Sanath Jayasuriya\";\n        age = 27;\n    }\n\n    @POST\n    @Path(\"/details/{filed}\")\n    public String getPlayerProfileFiled(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId,\n                                        @PathParam(\"filed\") String field, @FormParam(\"type\") String type,\n                                        @FormParam(\"countryName\") String countryName) {\n        return countryId + \"_\" + playerId + \"_\" + field + \"_\" + type + \"_\" + countryName;\n    }\n\n    @POST\n    @Path(\"\")\n    public Player getPlayerProfile(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId,\n                                        @FormParam(\"type\") String type, @FormParam(\"countryName\") String countryName) {\n        Player player = new Player(countryId, playerId);\n        player.setType(type);\n        player.setCountryName(countryName);\n        return player;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public void setAge(byte age) {\n        this.age = age;\n    }\n\n    public void setCountryId(String countryId) {\n        this.countryId = countryId;\n    }\n\n    public void setPlayerId(int playerId) {\n        this.playerId = playerId;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public void setCountryName(String countryName) {\n        this.countryName = countryName;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getPlayerId() {\n        return playerId;\n    }\n\n    public String getCountryId() {\n        return countryId;\n    }\n\n    public String getCountryName() {\n        return countryName;\n    }\n\n    public byte getAge() {\n        return age;\n    }\n\n    public String getType() {\n        return type;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/service/sub/Team.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.service.sub;\n\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.TestRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestResponseInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\n\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Simple RESTful web service for Team.\n */\n@Path(\"/\")\npublic class Team {\n\n    private String teamType;\n    private String countryName;\n\n    public String getCountryId() {\n        return countryId;\n    }\n\n    public String getCountryName() {\n        return countryName;\n    }\n\n    public void setCountryName(String countryName) {\n        this.countryName = countryName;\n    }\n\n    public String getTeamType() {\n        return teamType;\n    }\n\n    public void setTeamType(String teamType) {\n        this.teamType = teamType;\n    }\n\n    private String countryId;\n\n    public void setCountryId(String countryId) {\n        this.countryId = countryId;\n    }\n\n    public Team(String countryId) {\n        this.countryId = countryId;\n        teamType = \"Cricket\";\n    }\n\n    public Team(String countryId, String countryName) {\n        this.countryName = countryName;\n        this.countryId = countryId;\n        teamType = \"Cricket\";\n    }\n\n    @Path(\"/{playerId}\")\n    public Player getPlayerObj(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId) {\n        return new Player(countryId, playerId);\n    }\n\n    @Path(\"/interceptorTest/{playerId}\")\n    @RequestInterceptor(TestRequestInterceptor.class)\n    @ResponseInterceptor(TestResponseInterceptor.class)\n    public Player getPlayer(@PathParam(\"playerId\") int playerId) {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + \"[HTTP SUB RESOURCE METHOD]\");\n        return new Player(countryId, playerId);\n    }\n\n    @GET\n    @Path(\"\")\n    public Team getCountryTeam(@PathParam(\"countryId\") String countryId) {\n        return new Team(countryId);\n    }\n\n    @POST\n    @Path(\"\")\n    public Team getCountryTeamFromPost(@PathParam(\"countryId\") String countryId,\n                                       @FormParam(\"countryName\") String countryName) {\n        return new Team(countryId, countryName);\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/session/SessionIdGeneratorTest.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.session;\n\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.session.SessionIdGenerator;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.testng.Assert.fail;\n\n/**\n * Tests SessionIdGenerator.\n */\npublic class SessionIdGeneratorTest {\n\n    @Test\n    public void test() {\n        List<String> sessions = new ArrayList<>();\n        for (int i = 0; i < 10000; i++) {\n            String id = new SessionIdGenerator().generateSessionId(\"foo:\");\n            if (sessions.contains(id)) {\n                fail(\"Duplicate session found \" + id);\n            }\n            sessions.add(id);\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/util/QueryStringDecoderUtilTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.util;\n\n\nimport org.testng.annotations.Test;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.charset.Charset;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport static org.testng.AssertJUnit.assertEquals;\nimport static org.testng.AssertJUnit.assertFalse;\nimport static org.testng.AssertJUnit.assertNotNull;\nimport static org.testng.AssertJUnit.assertTrue;\n\n/**\n * Tests for QueryStringDecoderUtil.\n */\npublic class QueryStringDecoderUtilTest {\n\n    @Test\n    public void testBasicUris() throws URISyntaxException {\n        QueryStringDecoderUtil d = new QueryStringDecoderUtil(new URI(\"http://localhost/path\"));\n        assertEquals(0, d.parameters().size());\n    }\n\n    @Test\n    public void testBasic() throws Exception {\n        QueryStringDecoderUtil d;\n\n        d = new QueryStringDecoderUtil(\"/foo?a=b=c\");\n        assertEquals(\"/foo\", d.path());\n        assertEquals(1, d.parameters().size());\n        assertEquals(1, d.parameters().get(\"a\").size());\n        assertEquals(\"b=c\", d.parameters().get(\"a\").get(0));\n\n        d = new QueryStringDecoderUtil(\"/foo?a=1&a=2\");\n        assertEquals(\"/foo\", d.path());\n        assertEquals(1, d.parameters().size());\n        assertEquals(2, d.parameters().get(\"a\").size());\n        assertEquals(\"1\", d.parameters().get(\"a\").get(0));\n        assertEquals(\"2\", d.parameters().get(\"a\").get(1));\n\n        d = new QueryStringDecoderUtil(\"/foo?a=&a=2\");\n        assertEquals(\"/foo\", d.path());\n        assertEquals(1, d.parameters().size());\n        assertEquals(2, d.parameters().get(\"a\").size());\n        assertEquals(\"\", d.parameters().get(\"a\").get(0));\n        assertEquals(\"2\", d.parameters().get(\"a\").get(1));\n\n        d = new QueryStringDecoderUtil(\"/foo?a=1&a=\");\n        assertEquals(\"/foo\", d.path());\n        assertEquals(1, d.parameters().size());\n        assertEquals(2, d.parameters().get(\"a\").size());\n        assertEquals(\"1\", d.parameters().get(\"a\").get(0));\n        assertEquals(\"\", d.parameters().get(\"a\").get(1));\n\n        d = new QueryStringDecoderUtil(\"/foo?a=1&a=&a=\");\n        assertEquals(d.path(), \"/foo\");\n        assertEquals(d.parameters().size(), 1);\n        assertEquals(3, d.parameters().get(\"a\").size());\n        assertEquals(\"1\", d.parameters().get(\"a\").get(0));\n        assertEquals(\"\", d.parameters().get(\"a\").get(1));\n        assertEquals(\"\", d.parameters().get(\"a\").get(2));\n\n        d = new QueryStringDecoderUtil(\"/foo?a=1=&a==2\");\n        assertEquals(\"/foo\", d.path());\n        assertEquals(1, d.parameters().size());\n        assertEquals(2, d.parameters().get(\"a\").size());\n        assertEquals(\"1=\", d.parameters().get(\"a\").get(0));\n        assertEquals(\"=2\", d.parameters().get(\"a\").get(1));\n    }\n\n    @Test\n    public void testExotic() throws Exception {\n        assertQueryString(\"\", \"\");\n        assertQueryString(\"foo\", \"foo\");\n        assertQueryString(\"/foo\", \"/foo\");\n        assertQueryString(\"?a=\", \"?a\");\n        assertQueryString(\"foo?a=\", \"foo?a\");\n        assertQueryString(\"/foo?a=\", \"/foo?a\");\n        assertQueryString(\"/foo?a=\", \"/foo?a&\");\n        assertQueryString(\"/foo?a=\", \"/foo?&a\");\n        assertQueryString(\"/foo?a=\", \"/foo?&a&\");\n        assertQueryString(\"/foo?a=\", \"/foo?&=a\");\n        assertQueryString(\"/foo?a=\", \"/foo?=a&\");\n        assertQueryString(\"/foo?a=\", \"/foo?a=&\");\n        assertQueryString(\"/foo?a=b&c=d\", \"/foo?a=b&&c=d\");\n        assertQueryString(\"/foo?a=b&c=d\", \"/foo?a=b&=&c=d\");\n        assertQueryString(\"/foo?a=b&c=d\", \"/foo?a=b&==&c=d\");\n        assertQueryString(\"/foo?a=b&c=&x=y\", \"/foo?a=b&c&x=y\");\n        assertQueryString(\"/foo?a=\", \"/foo?a=\");\n        assertQueryString(\"/foo?a=\", \"/foo?&a=\");\n        assertQueryString(\"/foo?a=b&c=d\", \"/foo?a=b&c=d\");\n        assertQueryString(\"/foo?a=1&a=&a=\", \"/foo?a=1&a&a=\");\n    }\n\n    @Test\n    public void testHashDos() throws Exception {\n        StringBuilder buf = new StringBuilder();\n        buf.append('?');\n        for (int i = 0; i < 65536; i++) {\n            buf.append('k');\n            buf.append(i);\n            buf.append(\"=v\");\n            buf.append(i);\n            buf.append('&');\n        }\n        assertEquals(1024, new QueryStringDecoderUtil(buf.toString()).parameters().size());\n    }\n\n    @Test\n    public void testHasPath() throws Exception {\n        QueryStringDecoderUtil decoder = new QueryStringDecoderUtil(\"1=2\", false);\n        assertEquals(\"\", decoder.path());\n        Map<String, List<String>> params = decoder.parameters();\n        assertEquals(1, params.size());\n        assertTrue(params.containsKey(\"1\"));\n        List<String> param = params.get(\"1\");\n        assertNotNull(param);\n        assertEquals(1, param.size());\n        assertEquals(\"2\", param.get(0));\n    }\n\n    @Test\n    public void testUrlDecoding() throws Exception {\n        final String caffe = new String(\n                // \"Caffé\" but instead of putting the literal E-acute in the\n                // source file, we directly use the UTF-8 encoding so as to\n                // not rely on the platform's default encoding (not portable).\n                new byte[]{'C', 'a', 'f', 'f', (byte) 0xC3, (byte) 0xA9},\n                \"UTF-8\");\n        final String[] tests = {\n                // Encoded   ->   Decoded or error message substring\n                \"\", \"\",\n                \"foo\", \"foo\",\n                \"f%%b\", \"f%b\",\n                \"f+o\", \"f o\",\n                \"f++\", \"f  \",\n                \"fo%\", \"unterminated escape sequence\",\n                \"%42\", \"B\",\n                \"%5f\", \"_\",\n                \"f%4\", \"partial escape sequence\",\n                \"%x2\", \"invalid escape sequence `%x2' at index 0 of: %x2\",\n                \"%4x\", \"invalid escape sequence `%4x' at index 0 of: %4x\",\n                \"Caff%C3%A9\", caffe,\n        };\n        for (int i = 0; i < tests.length; i += 2) {\n            final String encoded = tests[i];\n            final String expected = tests[i + 1];\n            try {\n                final String decoded = QueryStringDecoderUtil.decodeComponent(encoded);\n                assertEquals(expected, decoded);\n            } catch (IllegalArgumentException e) {\n                assertTrue(\"String \" + e.getMessage() + \"\\\" does not contain \\\"\" + expected + '\"',\n                        e.getMessage().contains(expected));\n            }\n        }\n    }\n\n    private static void assertQueryString(String expected, String actual) {\n        QueryStringDecoderUtil ed = new QueryStringDecoderUtil(expected, Charset.defaultCharset());\n        QueryStringDecoderUtil ad = new QueryStringDecoderUtil(actual, Charset.defaultCharset());\n        assertEquals(ed.path(), ad.path());\n        assertEquals(ed.parameters(), ad.parameters());\n    }\n\n    // See #189\n    @Test\n    public void testURI() {\n        URI uri = URI.create(\"http://localhost:8080/foo?param1=value1&param2=value2&param3=value3\");\n        QueryStringDecoderUtil decoder = new QueryStringDecoderUtil(uri);\n        assertEquals(\"/foo\", decoder.path());\n        Map<String, List<String>> params = decoder.parameters();\n        assertEquals(3, params.size());\n        Iterator<Entry<String, List<String>>> entries = params.entrySet().iterator();\n\n        Entry<String, List<String>> entry = entries.next();\n        assertEquals(\"param1\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value1\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param2\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value2\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param3\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value3\", entry.getValue().get(0));\n\n        assertFalse(entries.hasNext());\n    }\n\n    // See #189\n    @Test\n    public void testURISlashPath() {\n        URI uri = URI.create(\"http://localhost:8080/?param1=value1&param2=value2&param3=value3\");\n        QueryStringDecoderUtil decoder = new QueryStringDecoderUtil(uri);\n        assertEquals(\"/\", decoder.path());\n        Map<String, List<String>> params = decoder.parameters();\n        assertEquals(3, params.size());\n        Iterator<Entry<String, List<String>>> entries = params.entrySet().iterator();\n\n        Entry<String, List<String>> entry = entries.next();\n        assertEquals(\"param1\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value1\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param2\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value2\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param3\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value3\", entry.getValue().get(0));\n\n        assertFalse(entries.hasNext());\n    }\n\n    // See #189\n    @Test\n    public void testURINoPath() {\n        URI uri = URI.create(\"http://localhost:8080?param1=value1&param2=value2&param3=value3\");\n        QueryStringDecoderUtil decoder = new QueryStringDecoderUtil(uri);\n        assertEquals(\"\", decoder.path());\n        Map<String, List<String>> params = decoder.parameters();\n        assertEquals(3, params.size());\n        Iterator<Entry<String, List<String>>> entries = params.entrySet().iterator();\n\n        Entry<String, List<String>> entry = entries.next();\n        assertEquals(\"param1\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value1\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param2\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value2\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"param3\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"value3\", entry.getValue().get(0));\n\n        assertFalse(entries.hasNext());\n    }\n\n    // See https://github.com/netty/netty/issues/1833\n    @Test\n    public void testURI2() {\n        URI uri = URI.create(\"http://foo.com/images;num=10?query=name;value=123\");\n        QueryStringDecoderUtil decoder = new QueryStringDecoderUtil(uri);\n        assertEquals(\"/images;num=10\", decoder.path());\n        Map<String, List<String>> params = decoder.parameters();\n        assertEquals(2, params.size());\n        Iterator<Entry<String, List<String>>> entries = params.entrySet().iterator();\n\n        Entry<String, List<String>> entry = entries.next();\n        assertEquals(\"query\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"name\", entry.getValue().get(0));\n\n        entry = entries.next();\n        assertEquals(\"value\", entry.getKey());\n        assertEquals(1, entry.getValue().size());\n        assertEquals(\"123\", entry.getValue().get(0));\n\n        assertFalse(entries.hasNext());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/util/client/websocket/WebSocketClient.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\n\npackage org.wso2.msf4j.util.client.websocket;\n\nimport io.netty.bootstrap.Bootstrap;\nimport io.netty.buffer.Unpooled;\nimport io.netty.channel.Channel;\nimport io.netty.channel.ChannelInitializer;\nimport io.netty.channel.ChannelPipeline;\nimport io.netty.channel.EventLoopGroup;\nimport io.netty.channel.nio.NioEventLoopGroup;\nimport io.netty.channel.socket.SocketChannel;\nimport io.netty.channel.socket.nio.NioSocketChannel;\nimport io.netty.handler.codec.http.DefaultHttpHeaders;\nimport io.netty.handler.codec.http.HttpClientCodec;\nimport io.netty.handler.codec.http.HttpHeaders;\nimport io.netty.handler.codec.http.HttpObjectAggregator;\nimport io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.PingWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.TextWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;\nimport io.netty.handler.codec.http.websocketx.WebSocketVersion;\nimport io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;\nimport io.netty.handler.ssl.SslContext;\nimport io.netty.handler.ssl.SslContextBuilder;\nimport io.netty.handler.ssl.util.InsecureTrustManagerFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.ByteBuffer;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.net.ssl.SSLException;\n\n/**\n * WebSocket client class for test\n */\npublic class WebSocketClient {\n\n    private static final Logger logger = LoggerFactory.getLogger(WebSocketClient.class);\n\n    private final String url;\n    private final String subProtocol;\n    private Map<String, String> customHeaders = new HashMap<>();\n\n    private Channel channel = null;\n    private WebSocketClientHandler handler;\n    private EventLoopGroup group;\n    private boolean isHandshakeSuccessful = false;\n\n\n\n    public WebSocketClient(String url) {\n        this.subProtocol = null;\n        this.url = url;\n    }\n\n    public WebSocketClient(String url, String subProtocol, Map<String, String> customHeaders) {\n        this.url = url;\n        this.subProtocol = subProtocol;\n        if (customHeaders != null) {\n            this.customHeaders = customHeaders;\n        }\n    }\n\n    /**\n     * @return true if the handshake is done properly.\n     * @throws URISyntaxException throws if there is an error in the URI syntax.\n     * @throws InterruptedException throws if the connecting the server is interrupted.\n     */\n    public boolean handhshake() throws InterruptedException, URISyntaxException, SSLException {\n        boolean isDone;\n        URI uri = new URI(url);\n        String scheme = uri.getScheme() == null ? \"ws\" : uri.getScheme();\n        final String host = uri.getHost() == null ? \"127.0.0.1\" : uri.getHost();\n        final int port;\n        if (uri.getPort() == -1) {\n            if (\"ws\".equalsIgnoreCase(scheme)) {\n                port = 80;\n            } else if (\"wss\".equalsIgnoreCase(scheme)) {\n                port = 443;\n            } else {\n                port = -1;\n            }\n        } else {\n            port = uri.getPort();\n        }\n\n        if (!\"ws\".equalsIgnoreCase(scheme) && !\"wss\".equalsIgnoreCase(scheme)) {\n            logger.error(\"Only WS(S) is supported.\");\n            return false;\n        }\n\n        final boolean ssl = \"wss\".equalsIgnoreCase(scheme);\n        final SslContext sslCtx;\n        if (ssl) {\n            sslCtx = SslContextBuilder.forClient()\n                                      .trustManager(InsecureTrustManagerFactory.INSTANCE).build();\n        } else {\n            sslCtx = null;\n        }\n\n        group = new NioEventLoopGroup();\n\n        HttpHeaders headers = new DefaultHttpHeaders();\n        customHeaders.entrySet().forEach(\n                header -> headers.add(header.getKey(), header.getValue())\n        );\n        try {\n            // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.\n            // If you change it to V00, ping is not supported and remember to change\n            // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.\n            handler =\n                    new WebSocketClientHandler(\n                            WebSocketClientHandshakerFactory.newHandshaker(\n                                    uri, WebSocketVersion.V13, subProtocol,\n                                    true, headers));\n\n            Bootstrap b = new Bootstrap();\n            b.group(group)\n             .channel(NioSocketChannel.class)\n             .handler(new ChannelInitializer<SocketChannel>() {\n                 @Override\n                 protected void initChannel(SocketChannel ch) {\n                     ChannelPipeline p = ch.pipeline();\n                     if (sslCtx != null) {\n                         p.addLast(sslCtx.newHandler(ch.alloc(), host, port));\n                     }\n                     p.addLast(\n                             new HttpClientCodec(),\n                             new HttpObjectAggregator(8192),\n                             WebSocketClientCompressionHandler.INSTANCE,\n                             handler);\n                 }\n             });\n\n            channel = b.connect(uri.getHost(), port).sync().channel();\n            isDone = handler.handshakeFuture().sync().isSuccess();\n            logger.debug(\"WebSocket Handshake successful : \" + isDone);\n            return isDone;\n        } catch (Exception e) {\n            logger.error(\"Handshake unsuccessful : \" + e.getMessage(), e);\n            return false;\n        }\n    }\n\n    /**\n     * Send text to the server.\n     * @param text text need to be sent.\n     */\n    public void sendText(String text) throws InterruptedException {\n        if (channel == null) {\n            logger.error(\"Channel is null. Cannot send text.\");\n            throw new IllegalArgumentException(\"Cannot find the channel to write\");\n        }\n        channel.writeAndFlush(new TextWebSocketFrame(text)).sync();\n    }\n\n    /**\n     * Send binary data to server.\n     * @param buf buffer containing the data need to be sent.\n     */\n    public void sendBinary(ByteBuffer buf) throws IOException, InterruptedException {\n        if (channel == null) {\n            logger.error(\"Channel is null. Cannot send text.\");\n            throw new IllegalArgumentException(\"Cannot find the channel to write\");\n        }\n        channel.writeAndFlush(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(buf))).sync();\n    }\n\n    /**\n     * Send a ping message to the server.\n     * @param buf content of the ping message to be sent.\n     */\n    public void sendPing(ByteBuffer buf) throws IOException, InterruptedException {\n        if (channel == null) {\n            logger.error(\"Channel is null. Cannot send text.\");\n            throw new IllegalArgumentException(\"Cannot find the channel to write\");\n        }\n        channel.writeAndFlush(new PingWebSocketFrame(Unpooled.wrappedBuffer(buf))).sync();\n    }\n\n    /**\n     * @return the text received from the server.\n     */\n    public String getTextReceived() {\n        return handler.getTextReceived();\n    }\n\n    /**\n     * @return the binary data received from the server.\n     */\n    public ByteBuffer getBufferReceived() {\n        return handler.getBufferReceived();\n    }\n\n    /**\n     * Shutdown the WebSocket Client.\n     */\n    public void shutDown() throws InterruptedException {\n        handler.shutDown();\n        group.shutdownGracefully();\n    }\n\n    /**\n     * Check whether the handshake is successful of not.\n     *\n     * @return true if the handshake is successful.\n     */\n    public boolean isHandshakeSuccessful() {\n        return isHandshakeSuccessful;\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/util/client/websocket/WebSocketClientHandler.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.util.client.websocket;\n\nimport io.netty.channel.Channel;\nimport io.netty.channel.ChannelFuture;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelPromise;\nimport io.netty.channel.SimpleChannelInboundHandler;\nimport io.netty.handler.codec.http.FullHttpResponse;\nimport io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.PongWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.TextWebSocketFrame;\nimport io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;\nimport io.netty.handler.codec.http.websocketx.WebSocketFrame;\nimport io.netty.util.CharsetUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.nio.ByteBuffer;\n\n/**\n * WebSocket Client Handler for Testing.\n */\npublic class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {\n\n    private static final Logger logger = LoggerFactory.getLogger(WebSocketClient.class);\n\n    private final WebSocketClientHandshaker handshaker;\n    private ChannelPromise handshakeFuture;\n    private ChannelHandlerContext ctx;\n\n    private String textReceived = \"\";\n    private ByteBuffer bufferReceived = null;\n    private boolean isOpen = false;\n\n    public WebSocketClientHandler(WebSocketClientHandshaker handshaker) {\n        this.handshaker = handshaker;\n    }\n\n    public ChannelFuture handshakeFuture() {\n        return handshakeFuture;\n    }\n\n    @Override\n    public void handlerAdded(ChannelHandlerContext ctx) {\n        handshakeFuture = ctx.newPromise();\n        this.ctx = ctx;\n    }\n\n    @Override\n    public void channelActive(ChannelHandlerContext ctx) {\n        handshaker.handshake(ctx.channel());\n        isOpen = true;\n    }\n\n    @Override\n    public void channelInactive(ChannelHandlerContext ctx) throws InterruptedException {\n        logger.debug(\"WebSocket Client disconnected!\");\n        ctx.channel().close().sync();\n        isOpen = false;\n    }\n\n    @Override\n    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {\n        Channel ch = ctx.channel();\n        if (!handshaker.isHandshakeComplete()) {\n            handshaker.finishHandshake(ch, (FullHttpResponse) msg);\n            logger.debug(\"WebSocket Client connected!\");\n            handshakeFuture.setSuccess();\n            return;\n        }\n\n        if (msg instanceof FullHttpResponse) {\n            FullHttpResponse response = (FullHttpResponse) msg;\n            throw new IllegalStateException(\n                    \"Unexpected FullHttpResponse (getStatus=\" + response.status() +\n                    \", content=\" + response.content().toString(CharsetUtil.UTF_8) + ')');\n        }\n\n        WebSocketFrame frame = (WebSocketFrame) msg;\n        if (frame instanceof TextWebSocketFrame) {\n            TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;\n            logger.debug(\"WebSocket Client received text message: \" + textFrame.text());\n            textReceived = textFrame.text();\n        } else if (frame instanceof BinaryWebSocketFrame) {\n            BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame;\n            bufferReceived = binaryFrame.content().nioBuffer();\n            logger.debug(\"WebSocket Client received  binary message: \" + bufferReceived.toString());\n        } else if (frame instanceof PongWebSocketFrame) {\n            logger.debug(\"WebSocket Client received pong\");\n            PongWebSocketFrame pongFrame = (PongWebSocketFrame) frame;\n            bufferReceived = pongFrame.content().nioBuffer();\n        } else if (frame instanceof CloseWebSocketFrame) {\n            logger.debug(\"WebSocket Client received closing\");\n            ch.close();\n        }\n    }\n\n    /**\n     * @return the text received from the server.\n     */\n    public String getTextReceived() {\n        return textReceived;\n    }\n\n    /**\n     * @return the binary data received from the server.\n     */\n    public ByteBuffer getBufferReceived() {\n        return bufferReceived;\n    }\n\n    @Override\n    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {\n        if (!handshakeFuture.isDone()) {\n            logger.error(\"Handshake failed : \" + cause.getMessage(), cause);\n            handshakeFuture.setFailure(cause);\n        }\n        ctx.close();\n    }\n\n    public void shutDown() throws InterruptedException {\n        ctx.channel().writeAndFlush(new CloseWebSocketFrame());\n        ctx.channel().closeFuture().sync();\n    }\n\n    public boolean isOpen() {\n        return isOpen;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/DeploymentTest.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.util.client.websocket.WebSocketClient;\nimport org.wso2.msf4j.websocket.endpoint.ChatAppEndpoint;\nimport org.wso2.msf4j.websocket.endpoint.EchoEndpoint;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointAnnotationException;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.nio.ByteBuffer;\nimport javax.net.ssl.SSLException;\n\n/**\n * Test the WebSocket endpoint deployment.\n * Check all the methods of the endpoint.\n */\npublic class DeploymentTest {\n\n    private static final Logger log = LoggerFactory.getLogger(DeploymentTest.class);\n    private final String host = \"localhost\";\n    private final String port = \"9090\";\n    private final int sleepTime = 1000;\n\n    private String echoUrl = \"ws://\" + host + \":\" + port + \"/echo\";\n    private String chatUrl = \"ws://\" + host + \":\" + port + \"/chat/\";\n\n    private MicroservicesRunner microservicesRunner = new MicroservicesRunner();\n\n    @BeforeClass\n    public void setup() throws WebSocketEndpointAnnotationException {\n        log.info(System.lineSeparator() +\n                         \"--------------------------------WebSocket Deployment Test--------------------------------\");\n        microservicesRunner.deployWebSocketEndpoint(new EchoEndpoint());\n        microservicesRunner.deployWebSocketEndpoint(new ChatAppEndpoint());\n        microservicesRunner.start();\n    }\n\n    @Test(description = \"Testing the echoing the message sent by client for text, binary and pong messages.\")\n    public void testReply() throws InterruptedException, IOException, URISyntaxException {\n        WebSocketClient echoClient = new WebSocketClient(echoUrl);\n        //Test handshake\n        Assert.assertTrue(echoClient.handhshake());\n\n        //Test Echo String\n        String textSent = \"test\";\n        echoClient.sendText(textSent);\n        Thread.sleep(sleepTime);\n        String textReceived = echoClient.getTextReceived();\n        Assert.assertEquals(textReceived, textSent);\n\n        //Test echo binaryMessage\n        byte[] bytes = {1, 2, 3, 4, 5};\n        ByteBuffer bufferSent = ByteBuffer.wrap(bytes);\n        echoClient.sendBinary(bufferSent);\n        Thread.sleep(sleepTime);\n        ByteBuffer bufferReceived = echoClient.getBufferReceived();\n        Assert.assertEquals(bufferReceived, bufferSent);\n\n        //Test the Pong Message\n        byte[] pingBytes = {6, 7, 8, 9, 10};\n        ByteBuffer pingBufferSent = ByteBuffer.wrap(pingBytes);\n        echoClient.sendPing(pingBufferSent);\n        Thread.sleep(sleepTime);\n        ByteBuffer pongBufferReceived = echoClient.getBufferReceived();\n        Assert.assertEquals(pongBufferReceived, pingBufferSent);\n\n        //Closing the connection\n        echoClient.shutDown();\n    }\n\n    @Test(description = \"Testing broadcasting messages for text, binary and pong using two clients.\")\n    public void testBroadcast() throws InterruptedException, SSLException, URISyntaxException {\n        //Initializing local variables\n        String textReceived;\n        String client1Name = \"abc\";\n        String client2Name = \"xyz\";\n\n        WebSocketClient chatClient1 = new WebSocketClient(chatUrl + client1Name);\n        Assert.assertTrue(chatClient1.handhshake());\n        Thread.sleep(sleepTime);\n\n        WebSocketClient chatClient2 = new WebSocketClient(chatUrl + client2Name);\n        Assert.assertTrue(chatClient2.handhshake());\n        Thread.sleep(sleepTime);\n\n        textReceived = chatClient1.getTextReceived();\n        Assert.assertEquals(textReceived, client2Name + \" connected to chat\");\n\n        //Check the broadcast text\n        String textSent = \"test\";\n        chatClient1.sendText(textSent);\n        Thread.sleep(sleepTime);\n        Assert.assertEquals(chatClient1.getTextReceived(), client1Name + \":\" + textSent);\n        Assert.assertEquals(chatClient2.getTextReceived(), client1Name + \":\" + textSent);\n\n        //Check close connection\n        chatClient2.shutDown();\n        Thread.sleep(sleepTime);\n        Assert.assertEquals(chatClient1.getTextReceived(), client2Name + \" left the chat\");\n        chatClient1.shutDown();\n    }\n\n    @AfterClass\n    public void cleanUp() {\n        microservicesRunner.stop();\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/EndpointRegistryTest.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.router.PatternPathRouter;\nimport org.wso2.msf4j.internal.websocket.EndpointDispatcher;\nimport org.wso2.msf4j.internal.websocket.EndpointsRegistryImpl;\nimport org.wso2.msf4j.websocket.endpoint.TestEndpoint;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.URISyntaxException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Optional;\n\n/**\n * Test Class for WebSocket Endpoint Registry\n */\npublic class EndpointRegistryTest {\n\n    private static final Logger log = LoggerFactory.getLogger(EndpointRegistryTest.class);\n\n    private final String testText = \"test\";\n    private TestEndpoint testEndpoint = new TestEndpoint();\n    private EndpointsRegistryImpl endpointsRegistry = EndpointsRegistryImpl.getInstance();\n    private final String uri = \"/test\";\n\n    public EndpointRegistryTest() {\n    }\n\n    @BeforeClass\n    public void onRegister() throws URISyntaxException {\n        log.info(System.lineSeparator() +\n                 \"--------------------------------WebSocket Registry Test--------------------------------\");\n    }\n\n    @Test(description = \"Testing the adding a correct endpoint to the registry.\")\n    public void addEndpoint() throws InvocationTargetException, IllegalAccessException, URISyntaxException {\n        log.info(\"Testing the adding a correct endpoint to the registry.\");\n        endpointsRegistry.addEndpoint(testEndpoint);\n        PatternPathRouter.RoutableDestination<Object> routableEndpoint =\n                endpointsRegistry.getRoutableEndpoint(uri);\n        Object webSocketEndpoint = routableEndpoint.getDestination();\n        List<Object> paralist = new LinkedList<>();\n        paralist.add(testText);\n        paralist.add(null);\n        Optional<Method> methodOptional = new EndpointDispatcher().getOnStringMessageMethod(webSocketEndpoint);\n        if (methodOptional.isPresent()) {\n            String returnValue = (String) methodOptional.get().invoke(webSocketEndpoint, paralist.toArray());\n            Assert.assertEquals(returnValue, testText);\n        } else {\n            Assert.assertTrue(false);\n        }\n    }\n\n    @Test(description = \"Testing the removing of an endpoint from the registry.\")\n    public void removeEndpoint() {\n        log.info(\"Testing the removing of an endpoint from the registry.\");\n        endpointsRegistry.removeEndpoint(testEndpoint);\n        PatternPathRouter.RoutableDestination<Object> endPoint = endpointsRegistry.\n                getRoutableEndpoint(uri);\n        Assert.assertTrue(endPoint == null);\n\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/ValidatorTest.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.internal.websocket.EndpointValidator;\nimport org.wso2.msf4j.websocket.endpoint.TestEndpointWithAllCorrect;\nimport org.wso2.msf4j.websocket.endpoint.TestEndpointWithMandatoryParameters;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpoinWithOnTextError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithMandatoryParametersMissing;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithOnBinaryError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithOnCloseError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithOnError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithOnOpenError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithOnPongError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithReturnTypeError;\nimport org.wso2.msf4j.websocket.endpoint.error.TestEndpointWithServerEndpointError;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointAnnotationException;\nimport org.wso2.msf4j.websocket.exception.WebSocketEndpointMethodReturnTypeException;\nimport org.wso2.msf4j.websocket.exception.WebSocketMethodParameterException;\n\n/**\n * Test the Exceptions which can be occurred when deploying and running WebSocket.\n */\npublic class ValidatorTest {\n\n    private static final Logger log = LoggerFactory.getLogger(ValidatorTest.class);\n    private EndpointValidator validator = new EndpointValidator();\n\n    @BeforeClass\n    public void setup() {\n        log.info(System.lineSeparator() +\n                         \"--------------------------------WebSocket Validator Test--------------------------------\");\n    }\n\n    @Test(description = \"Test endpoint with all necessary methods and all correct parameters\")\n    public void testCorretEndpoint() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                            WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test endpoint with all necessary methods and all correct parameters\");\n        Assert.assertTrue(validator.validate(new TestEndpointWithAllCorrect()));\n    }\n\n    @Test(description = \"Test endpoint with all necessary methods with mandatory parameters\")\n    public void testMandatoryParametersEndpoint() throws WebSocketMethodParameterException,\n                                                         WebSocketEndpointAnnotationException,\n                                                         WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test endpoint with all necessary methods with mandatory parameters\");\n        Assert.assertTrue(validator.validate(new TestEndpointWithMandatoryParameters()));\n    }\n\n    @Test(description = \"Check the mandatory parameters missing\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testMandatoryParameterMissing()\n            throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                   WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Check the mandatory parameters missing\");\n        validator.validate(new TestEndpointWithMandatoryParametersMissing());\n    }\n\n    @Test(description = \"Test the expected exceptions for not defining server endpoint\",\n          expectedExceptions = WebSocketEndpointAnnotationException.class)\n    public void testerverEndpoint() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                           WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for not defining server endpoint\");\n        validator.validate(new TestEndpointWithServerEndpointError());\n\n    }\n\n    @Test(description = \"Test the expected exceptions for onOpen\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnOpen() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                    WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onOpen\");\n        validator.validate(new TestEndpointWithOnOpenError());\n    }\n\n    @Test(description = \"Test the expected exceptions for onClose\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnClose() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                     WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onClose\");\n        validator.validate(new TestEndpointWithOnCloseError());\n    }\n\n    @Test(description = \"Test the expected exceptions for onTextMessage\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnTextMessage() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                           WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onTextMessage\");\n        validator.validate(new TestEndpoinWithOnTextError());\n    }\n\n    @Test(description = \"Test the expected exceptions for onBinaryMessage\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnBinaryMessage() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                             WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onBinaryMessage\");\n        validator.validate(new TestEndpointWithOnBinaryError());\n    }\n\n    @Test(description = \"Test the expected exceptions for onPongMessage\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnPongMessage() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                           WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onPongMessage\");\n        validator.validate(new TestEndpointWithOnPongError());\n    }\n\n    @Test(description = \"Test the expected exceptions for onError\",\n          expectedExceptions = WebSocketMethodParameterException.class)\n    public void testOnError() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                     WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for onError\");\n        validator.validate(new TestEndpointWithOnError());\n    }\n\n    @Test(description = \"Test the expected exceptions for invalid return type\",\n          expectedExceptions = WebSocketEndpointMethodReturnTypeException.class)\n    public void testReturnTypeError() throws WebSocketMethodParameterException, WebSocketEndpointAnnotationException,\n                                     WebSocketEndpointMethodReturnTypeException {\n        log.info(\"Test the expected exceptions for invalid return type\");\n        validator.validate(new TestEndpointWithReturnTypeError());\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/ChatAppEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@SuppressWarnings(\"ALL\")\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class ChatAppEndpoint {\n    private static final Logger log = LoggerFactory.getLogger(ChatAppEndpoint.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        String msg = name + \" connected to chat\";\n        log.info(msg);\n        sendMessageToAll(msg);\n        webSocketConnections.add(webSocketConnection);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        log.info(\"Received Text: \" + text + \" from  \" + name + \" \" + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onBinaryMessage(ByteBuffer buffer, boolean isFinal, WebSocketConnection webSocketConnection) {\n\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        log.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        log.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> {\n                    log.info(\"Send message '\" + message + \"' to id '\" + webSocketConnection.getChannelId() + \"'.\");\n                    webSocketConnection.pushText(message);\n                }\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/EchoEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.websocket.WebSocketEndpoint;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n */\n@ServerEndpoint(\"/echo\")\npublic class EchoEndpoint implements WebSocketEndpoint {\n    private static final Logger log = LoggerFactory.getLogger(EchoEndpoint.class);\n\n    @OnOpen\n    public void onOpen(WebSocketConnection webSocketConnection) {\n        log.info(webSocketConnection.getChannelId() + \" connected to repeat-app\");\n    }\n\n    /**\n     * Echo the same {@link String} to user.\n     */\n    @OnMessage\n    public String onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        log.info(\"Received Text : \" + text + \" from  \" + webSocketConnection.getChannelId());\n        return text;\n    }\n\n    /**\n     * Echo the same ByteBuffer to user.\n     */\n    @OnMessage\n    public byte[] onBinaryMessage(byte[] buffer, WebSocketConnection webSocketConnection) {\n        String values = \"\";\n        int bufferLength = buffer.length;\n        byte[] bytes = new byte[buffer.length];\n        for (int i = 0; i < buffer.length; i++) {\n            byte b = buffer[i];\n            values = values.concat(\" \" + b);\n        }\n        log.info(\"Binary message values received from \" + webSocketConnection.getChannelId() + System.lineSeparator() +\n                \"buffer length: \" + bufferLength + System.lineSeparator() + \"values : \" + values);\n        return buffer;\n    }\n\n    @OnMessage\n    public PongMessage onPongMessage(PongMessage pongMessage, WebSocketConnection webSocketConnection) {\n        log.info(\"Received a pong message.\");\n        return pongMessage;\n    }\n\n    @OnClose\n    public void onClose(CloseReason closeReason, WebSocketConnection webSocketConnection) {\n        log.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                            + \" On reason \" + closeReason.getReasonPhrase());\n    }\n\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/TestEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.ServerEndpoint;\n\n@ServerEndpoint(\"/test\")\npublic class TestEndpoint {\n    Logger log = LoggerFactory.getLogger(TestEndpoint.class);\n\n    @OnOpen\n    public void onOpen(WebSocketConnection webSocketConnection) {\n        log.info(webSocketConnection.getChannelId());\n    }\n\n    @OnMessage\n    public String onStringMessage(String str, WebSocketConnection webSocketConnection) {\n        log.info(\"Test str is : \" + str);\n        return str;\n    }\n\n    @OnClose\n    public void onClose(CloseReason closeReason, WebSocketConnection webSocketConnection) {\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/TestEndpointWithAllCorrect.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint;\n\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.nio.ByteBuffer;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This endpoint include all necessary methods and all the acceptable parameters of those methods according to\n * JSR-356 specification\n */\n@ServerEndpoint(\"/allCorrect/{param1}/{param2}\")\npublic class TestEndpointWithAllCorrect {\n\n    @OnOpen\n    public void onOpen(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2,\n                       WebSocketConnection webSocketConnection) {\n    }\n\n    @OnMessage\n    public byte[] onString(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2, String text,\n                           WebSocketConnection webSocketConnection) {\n        return new byte[4];\n    }\n\n    @OnMessage\n    public String onBinary(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2, ByteBuffer buffer,\n                           WebSocketConnection webSocketConnection) {\n        return \"test\";\n    }\n\n    @OnMessage\n    public PongMessage onPong(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2,\n                              PongMessage pongMessage, WebSocketConnection webSocketConnection) {\n        return pongMessage;\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n\n    }\n\n    @OnError\n    public void onError(@PathParam(\"param1\") String param1, @PathParam(\"param2\") String param2, Throwable throwable,\n                        WebSocketConnection webSocketConnection) {\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/TestEndpointWithMandatoryParameters.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint;\n\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n *This test class include all the methods of WebSocket with only mandatory parameters according to JSR-356\n * specification\n */\n@ServerEndpoint(\"/test-with-mandatory-params\")\npublic class TestEndpointWithMandatoryParameters {\n\n    @OnOpen\n    public void onOpen() {\n    }\n\n    @OnMessage\n    public byte[] onString(String text) {\n        return new byte[4];\n    }\n\n    @OnMessage\n    public String onBinary(byte[] bytes) {\n        return \"test\";\n    }\n\n    @OnMessage\n    public PongMessage onPong(PongMessage pongMessage) {\n        return pongMessage;\n    }\n\n    @OnClose\n    public void onClose() {\n\n    }\n\n    @OnError\n    public void onError(Throwable throwable) {\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpoinWithOnTextError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class TestEndpoinWithOnTextError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpoinWithOnTextError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection,\n                              ByteBuffer buffer)\n            throws IOException {\n        String msg = name + \":\" + text + buffer;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithMandatoryParametersMissing.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\n\nimport javax.websocket.OnError;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * Test class with mandatory parameters for a given javax.websocket annotation is missing according to JSR-356\n * specification.\n */\n@ServerEndpoint(\"/test-mandatory-parameters-missing\")\npublic class TestEndpointWithMandatoryParametersMissing {\n\n    @OnError\n    public void onError() {\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithOnBinaryError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class TestEndpointWithOnBinaryError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpointWithOnBinaryError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onBinaryMessage(@PathParam(\"name\") String name, ByteBuffer buffer, String text,\n                                WebSocketConnection webSocketConnection) throws IOException {\n        String msg = name + \":\" + text + buffer;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithOnCloseError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class TestEndpointWithOnCloseError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpointWithOnCloseError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection, String errorValue) {\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + errorValue;\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithOnError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class TestEndpointWithOnError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpointWithOnError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection, String errorValue) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithOnOpenError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/test-error\")\npublic class TestEndpointWithOnOpenError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpointWithOnOpenError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection, String errorValue) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + errorValue;\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithOnPongError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.PongMessage;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class TestEndpointWithOnPongError {\n    private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpointWithOnPongError.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \":\" + text;\n        LOGGER.info(\"Received Text: \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(PongMessage pongMessage, WebSocketConnection webSocketConnection, String errorText)\n            throws IOException {\n\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code: \" + closeReason.getCloseCode().getCode()\n                + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method: \" + throwable.toString());\n    }\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithReturnTypeError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport javax.websocket.OnMessage;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * Test class which include method with wrong return type.\n */\n@ServerEndpoint(\"/test-with-false-return\")\npublic class TestEndpointWithReturnTypeError {\n\n    @OnMessage\n    public int onText(String text, WebSocketConnection webSocketConnection) {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "core/src/test/java/org/wso2/msf4j/websocket/endpoint/error/TestEndpointWithServerEndpointError.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.websocket.endpoint.error;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.websocket.WebSocketEndpoint;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport javax.websocket.OnClose;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\n\npublic class TestEndpointWithServerEndpointError implements WebSocketEndpoint {\n    Logger log = LoggerFactory.getLogger(TestEndpointWithServerEndpointError.class);\n\n    @OnOpen\n    public void onOpen(WebSocketConnection webSocketConnection) {\n        log.info(webSocketConnection.getChannelId());\n    }\n\n    @OnMessage\n    public String onStringMessage(String str, WebSocketConnection webSocketConnection) {\n        log.info(\"Test str is: \" + str);\n        return str;\n    }\n\n    @OnClose\n    public void onClose(String reasonText, int statusCode) {\n    }\n}\n"
  },
  {
    "path": "core/src/test/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "core/src/test/resources/netty-transports-1.yaml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\nwso2.transport.http:\n  transportProperties:\n   -\n    name: \"latency.metrics.enabled\"\n    value: true\n   -\n    name: \"server.bootstrap.boss.group.size\"\n    value: 4\n   -\n    name: \"server.bootstrap.worker.group.size\"\n    value: 8\n  listenerConfigurations:\n  -\n    id: \"msf4j-http\"\n    host: \"127.0.0.1\"\n    port: 8080\n  -\n    id: \"jaxrs-http\"\n    host: \"0.0.0.0\"\n    port: 8094\n    scheme: https\n    sslConfig:\n      keyStore: \"src/test/resources/cert.jks\"\n      keyStorePass: secret\n  senderConfigurations:\n   -\n    id: \"netty-gw\""
  },
  {
    "path": "core/src/test/resources/netty-transports-2.yaml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\nwso2.transport.http:\n  transportProperties:\n   -\n    name: \"latency.metrics.enabled\"\n    value: true\n   -\n    name: \"server.bootstrap.boss.group.size\"\n    value: 4\n   -\n    name: \"server.bootstrap.worker.group.size\"\n    value: 8\n  listenerConfigurations:\n  -\n    id: \"jaxrs-http\"\n    host: \"0.0.0.0\"\n    port: 8095\n    scheme: https\n    sslConfig:\n      keyStore: \"src/test/resources/cert.jks\"\n      keyStorePass: secret\n  senderConfigurations:\n   -\n    id: \"netty-gw\""
  },
  {
    "path": "core/src/test/resources/netty-transports-3.yaml",
    "content": "################################################################################\n#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\nwso2.transport.http:\n  listenerConfigurations:\n    -\n      certPass: secret\n      host: \"0.0.0.0\"\n      id: jaxrs-http\n      sslConfig:\n        keyStore: \"src/test/resources/cert.jks\"\n        keyStorePass: secret\n      port: 8096\n      scheme: https\n  senderConfigurations:\n    -\n      id: netty-gw\n  transportProperties:\n    -\n      name: latency.metrics.enabled\n      value: true\n    -\n      name: server.bootstrap.boss.group.size\n      value: 4\n    -\n      name: server.bootstrap.worker.group.size\n      value: 8\n\n"
  },
  {
    "path": "core/src/test/resources/netty-transports-4.yaml",
    "content": "################################################################################\n#   Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransports:\n  http:\n    transportProperties:\n     -\n      name: \"latency.metrics.enabled\"\n      value: true\n     -\n      name: \"server.bootstrap.boss.group.size\"\n      value: 4\n     -\n      name: \"server.bootstrap.worker.group.size\"\n      value: 8\n    listenerConfigurations:\n    -\n      id: \"msf4j-http\"\n      host: \"127.0.0.1\"\n      port: 8080\n    -\n      id: \"jaxrs-http\"\n      host: \"0.0.0.0\"\n      port: 8094\n      scheme: https\n      sslConfig:\n        keyStore: \"src/test/resources/cert.jks\"\n        keyStorePass: secret\n    senderConfigurations:\n     -\n      id: \"netty-gw\""
  },
  {
    "path": "core/src/test/resources/testTxtFile.txt",
    "content": "9X54cMfpjnTiMTkIwlO/l8wxEn8GhoGbPxmwpEAfCaRDqqc/x8IhihSpapPLVeXZXjCTHmtzPh2e\nXkQqxZ9+WbOYJ8fJBMqdsOY6/yL/2a3k1gZxxItKfsztQnVd+kVnjL2Vb5oxZiueogAAO12Op4yt\n9yykdeJruOE5JnVUWWnG+DA4z/km883uLrO3y0Pgp9X3FuPJvFENE0uUIZresMBeHR6FbhpSNAbj\nOH1p6PCgRfEBrHWEp6oVAjvUpESvquxSouebvUok8FnjabrBgTazxCSMnsZqOYOs76h47hEJdjGq\ndtnLs3FTJ1ibdGqK5Af9U4wJV6uA/O62flu9/Fe6QJnok3gmF86SFRYuL2LpatmfbT1tQt8Q9A2C\n7cmZPSv8lEs9UrweHlaWfrTZbfBfpGiPBgv963tY9ov6nxAgdJQIEL2pGhJhysg/cDKYR2CGaeVd\n+nZ1+ByhHLQgmy/jitLYCXXNKYuoJ9ITd851EjDad1gY/oB7qzlZCEt+CZBf6T5SjWVwAW1JOTNS\nrLEkmb4UWYPucm9Mjhdv7KaoJGBRH1Y4pgyojab0B9duC3rQziyH58iC1tW9Utw8EhzwVg7PgtEc\ngEsLUFT4kN9T9H/n1LM2zpoItXoSAKwFOJcuuROF7ufohVEIrjRpRMjDGPwg40Y3a8BUsVtaGnoo\nffkNOwCVekm9tFjbA+2hqPvZTgZvBuQx2vnUUkZKxX97aIaBclKiAvGCs4Qo2RZVf5WIVRTcTi3m\n8Drfp0Dq7BCOlnk+vyKhMZ/K2C61DaNUpvV/u3rG3Aq9Q1oqPAdqzFmmTspAByLmqXitLwLPDyjd\nBf03cKKSusE21i7+HGhe2p7MLMbRL/a6z/frNHLP0lpxTri9dVhxdeSSIi9odMnVsS1JdTY+nseN\ndKopMsQu9Z+mSx7SjORj8BzFOF+bwAqyECmuJ0v+91kRM9/kVkPMQDdmxVA4l9vDxh8CES+LIKlx"
  },
  {
    "path": "core/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"MSF4J_Test-Suite\">\n\n    <test name=\"interceptor-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.InterceptorTest\"/>\n            <!-- TODO Fix  WMS-82-->\n            <!--class name=\"org.wso2.msf4j.HandlerInterceptorTest\" /-->\n        </classes>\n    </test>\n\n    <test name=\"bean-conversion-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.beanconversion.BeanConverterTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"query-string-decoder-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.util.QueryStringDecoderUtilTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"mime-mapper-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.MimeMapperTest\"/>\n        </classes>\n    </test>\n\n    <!-- TODO Need to Fix the test case -->\n    <!--<test name=\"deployer-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.MSF4JDeployerTest\"/>\n        </classes>\n    </test>-->\n\n    <test name=\"http-server-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.HttpResourceModelTest\"/>\n            <class name=\"org.wso2.msf4j.HttpServerTest\"/>\n            <class name=\"org.wso2.msf4j.HttpsServerTest\"/>\n            <class name=\"org.wso2.msf4j.MSF4JResponseTest\"/>\n            <class name=\"org.wso2.msf4j.MutualAuthServerTest\"/>\n            <class name=\"org.wso2.msf4j.PathRouterTest\"/>\n            <class name=\"org.wso2.msf4j.SSLKeyStoreTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"extended-microservice-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.ExtendedServiceTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"session-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.websocket.ValidatorTest\"/>\n            <class name=\"org.wso2.msf4j.websocket.EndpointRegistryTest\"/>\n            <class name=\"org.wso2.msf4j.websocket.DeploymentTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"deprecated-interceptor-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.DeprecatedInterceptorTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"new unit tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.internal.MicroservicesRegistryTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"host-binding-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.HostBindingTest\"/>\n        </classes>\n    </test>\n\n    <test name=\"configurations-test\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.TransportConfigurationTest\"/>\n            <class name=\"org.wso2.msf4j.TransportConfigurationTest2\"/>\n        </classes>\n    </test>\n\n</suite>\n"
  },
  {
    "path": "deployer/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>msf4j-deployer</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J Deployer</name>\n    <description>WSO2 MSF4J Deployer</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi.services</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.deployment</groupId>\n            <artifactId>org.wso2.carbon.deployment.engine</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-spring</artifactId>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.maven.shared</groupId>\n            <artifactId>maven-invoker</artifactId>\n            <version>2.2</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                    <systemPropertyVariables>\n                        <maven.home>${maven.home}</maven.home>\n                        <project.filepath>${project.basedir}</project.filepath>\n                    </systemPropertyVariables>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <private.package>org.wso2.msf4j.deployer.internal</private.package>\n        <export.package>\n            !org.wso2.msf4j.deployer.internal,\n            org.wso2.msf4j.deployer;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            org.wso2.msf4j.*;version=\"${msf4j.version}\",\n            javax.annotation.*,\n            javax.ws.rs.*,\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.wso2.carbon.kernel.startupresolver.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.deployment.engine.*;version=\"${carbon.deployment.version.range}\",\n        </import.package>\n        <carbon.component>\n            startup.listener;componentName=\"wso2-microservices-deployer\";requiredService=\"org.wso2.msf4j.MicroservicesRegistry\",\n            osgi.service; objectClass=\"org.wso2.carbon.deployment.engine.Deployer\"\n        </carbon.component>\n        <!-- This require DynamicImports in order to support swagger annotations-->\n        <dynamic.import.package>*</dynamic.import.package>\n    </properties>\n</project>\n"
  },
  {
    "path": "deployer/src/main/java/org/wso2/msf4j/deployer/MicroserviceDeploymentException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.deployer;\n\n/**\n * Exception that is thrown when processing jar files\n * by MicroserviceProcessor.\n */\npublic class MicroserviceDeploymentException extends Exception {\n    public MicroserviceDeploymentException(String message) {\n        super(message);\n    }\n\n    public MicroserviceDeploymentException(String message, Exception e) {\n        super(message, e);\n    }\n}\n"
  },
  {
    "path": "deployer/src/main/java/org/wso2/msf4j/deployer/MicroserviceDeploymentUtils.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.deployer;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.security.AccessController;\nimport java.security.PrivilegedActionException;\nimport java.security.PrivilegedExceptionAction;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\n\n/**\n * Dynamically initialising a set of objects from a given jar\n * according to the manifest entry 'microservices'.\n */\npublic class MicroserviceDeploymentUtils {\n    private static final Logger logger = LoggerFactory.getLogger(MicroserviceDeploymentUtils.class);\n    private static final String MICROSERVICES_MANIFEST_KEY = \"Microservices\";\n\n    /**\n     * Initialize a list of objects from the jar for the specified\n     * classes in the jar's manifest file under 'microservices' key.\n     *\n     * @return micro services object list\n     * @throws MicroserviceDeploymentException if an error occurs while processing the jar file\n     */\n    public static List<Object> getRourceInstances(File artifactFile) throws MicroserviceDeploymentException {\n        String jarPath = artifactFile.getAbsolutePath();\n        final String[] serviceClassNames = readManifestEntry(jarPath);\n        List<Object> resourceInstances = new ArrayList<>();\n\n        //Parent class loader is required to provide classes that are outside of the jar\n        try {\n            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {\n                public Void run() throws MicroserviceDeploymentException {\n                    try {\n                        URLClassLoader classLoader =\n                                new URLClassLoader(new URL[]{artifactFile.toURI().toURL()},\n                                        this.getClass().getClassLoader());\n                        for (String className : serviceClassNames) {\n                            try {\n                                Class classToLoad = classLoader.loadClass(className);\n                                resourceInstances.add(classToLoad.newInstance());\n                            } catch (ClassNotFoundException e) {\n                                throw new MicroserviceDeploymentException(\"Class: \" + className + \" not found\", e);\n                            } catch (InstantiationException e) {\n                                throw new MicroserviceDeploymentException(\"Failed to initialize class: \"\n                                        + className, e);\n                            } catch (IllegalAccessException e) {\n                                throw new MicroserviceDeploymentException(\"Failed to access class: \" + className, e);\n                            }\n                        }\n                    } catch (MalformedURLException e) {\n                        throw new MicroserviceDeploymentException(\"Path to jar is invalid\", e);\n                    }\n                    return null;\n                }\n            });\n        } catch (PrivilegedActionException e) {\n            //This assignment is required to fix unchecked/unconfirmed cast findbugs issue\n            Exception e1 = e.getException();\n            if (e1 instanceof MicroserviceDeploymentException) {\n                throw (MicroserviceDeploymentException) e1;\n            }\n        }\n        return resourceInstances;\n    }\n\n    /**\n     * Extracts the comma separated list of fully qualified class\n     * names of the 'microservices' key of the jar's maifest file.\n     *\n     * @param jarPath absolute path to the jar file\n     * @return String array of fully qualified class names\n     */\n    private static String[] readManifestEntry(String jarPath) throws MicroserviceDeploymentException {\n        try (JarFile jarFile = new JarFile(jarPath)) {\n            Manifest manifest = jarFile.getManifest();\n            if (manifest == null) {\n                throw new MicroserviceDeploymentException(\"Error retrieving manifest: \" + jarPath);\n            }\n            Attributes mainAttributes = manifest.getMainAttributes();\n            String serviceEntry = mainAttributes.getValue(MICROSERVICES_MANIFEST_KEY);\n            if (serviceEntry == null) {\n                throw new MicroserviceDeploymentException(\"Manifest entry 'microservices' not found: \" + jarPath);\n            }\n            return serviceEntry.split(\"\\\\s*,\\\\s*\");\n        } catch (IOException e) {\n            throw new MicroserviceDeploymentException(\"Error retrieving manifest: \" + jarPath, e);\n        }\n    }\n}\n"
  },
  {
    "path": "deployer/src/main/java/org/wso2/msf4j/deployer/internal/DataHolder.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.msf4j.deployer.internal;\n\nimport org.wso2.msf4j.MicroservicesRegistry;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * DataHolder for Swagger component.\n *\n * @since 2.4.0\n */\npublic class DataHolder {\n\n    private static final DataHolder instance = new DataHolder();\n\n    private Map<String, MicroservicesRegistry> microserviceRegistries = new HashMap<>();\n\n    private DataHolder() {\n    }\n\n    /**\n     * Get DataHolder object.\n     *\n     * @return DataHolder instance.\n     */\n    public static DataHolder getInstance() {\n        return instance;\n    }\n\n    /**\n     * Get available MicroservicesRegistries.\n     *\n     * @return Map of available MicroservicesRegistries.\n     */\n    public Map<String, MicroservicesRegistry> getMicroservicesRegistries() {\n        return microserviceRegistries;\n    }\n\n    /**\n     * Get available MicroservicesRegistry for the gievn registry Id.\n     *\n     * @param registryId of the registry need to be pick\n     * @return MicroservicesRegistry object if the given Id.\n     */\n    public MicroservicesRegistry getMicroserviceRegistry(String registryId) {\n        return microserviceRegistries.get(registryId);\n    }\n\n    /**\n     * Add MicroservicesRegistry with the given registry Id.\n     *\n     * @param registryId id of the registry.\n     * @param microservicesRegistry instance.\n     */\n    public void addMicroserviceRegistry(String registryId, MicroservicesRegistry microservicesRegistry) {\n        microserviceRegistries.put(registryId, microservicesRegistry);\n    }\n\n    /**\n     * Get all the MicroservicesRegistries\n     * @return Map of MicroservicesRegistries and there IDs\n     *\n     */\n    public Map<String, MicroservicesRegistry> getMicroserviceRegistries() {\n        return microserviceRegistries;\n    }\n\n}\n"
  },
  {
    "path": "deployer/src/main/java/org/wso2/msf4j/deployer/internal/MSF4JDeployerSC.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.deployer.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.framework.FrameworkUtil;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Deactivate;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.deployment.engine.Deployer;\nimport org.wso2.carbon.kernel.startupresolver.RequiredCapabilityListener;\nimport org.wso2.carbon.kernel.startupresolver.StartupServiceUtils;\nimport org.wso2.msf4j.MicroservicesRegistry;\n\nimport java.util.Map;\n\n/**\n * Service component for Microservices Deployer.\n *\n * @since 2.4.0\n */\n@Component(\n        name = \"org.wso2.msf4j.deployer.internal.MSF4JDeployerSC\",\n        immediate = true,\n        property = {\n                \"componentName=wso2-microservices-deployer\"\n        }\n)\npublic class MSF4JDeployerSC implements RequiredCapabilityListener {\n\n    private static final Logger log = LoggerFactory.getLogger(MSF4JDeployerSC.class);\n    private static final String CHANNEL_ID = \"LISTENER_INTERFACE_ID\";\n\n    @Activate\n    protected void start(BundleContext bundleContext) {\n    }\n\n    @Deactivate\n    protected void stop() {\n    }\n\n    @Override\n    public void onAllRequiredCapabilitiesAvailable() {\n        FrameworkUtil.getBundle(MSF4JDeployerSC.class).getBundleContext()\n                     .registerService(Deployer.class, new MicroservicesDeployer(), null);\n        log.debug(\"MicroservicesDeployer service is available\");\n    }\n\n    /**\n     * To deploy micro services, we need to have at least one micro service registry in the system.\n     * Since microservice registry is added when microservice server is active, added the reference to wait till\n     * microservices server is active.\n     * Otherwise if deployer registered before at least one registry is added, Deployer will start to deploy services\n     * and will fail deployment.\n     */\n    @Reference(\n            name = \"microservices-regitry\",\n            service = MicroservicesRegistry.class,\n            cardinality = ReferenceCardinality.AT_LEAST_ONE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeMicroservicesRegistry\"\n    )\n    protected void addMicroservicesRegitry(MicroservicesRegistry registry, Map properties) {\n        log.debug(\"MicroservicesRegistry get registered successfully.\");\n        DataHolder.getInstance().addMicroserviceRegistry(properties.get(CHANNEL_ID).toString(), registry);\n        StartupServiceUtils.updateServiceCache(\"wso2-microservices-deployer\", MicroservicesRegistry.class);\n    }\n\n    protected void removeMicroservicesRegistry(MicroservicesRegistry microservicesRegistry, Map properties) {\n        log.debug(\"MicroservicesRegistry get unregistered successfully.\");\n        DataHolder.getInstance().getMicroserviceRegistries().remove(properties.get(CHANNEL_ID).toString());\n    }\n}\n"
  },
  {
    "path": "deployer/src/main/java/org/wso2/msf4j/deployer/internal/MicroservicesDeployer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.deployer.internal;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.deployment.engine.Artifact;\nimport org.wso2.carbon.deployment.engine.ArtifactType;\nimport org.wso2.carbon.deployment.engine.Deployer;\nimport org.wso2.carbon.deployment.engine.exception.CarbonDeploymentException;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.deployer.MicroserviceDeploymentException;\nimport org.wso2.msf4j.deployer.MicroserviceDeploymentUtils;\n\nimport java.io.File;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Implementation of the micro service deployer.\n * This will be picked by the DeploymentEngine service according to the whiteboard pattern to deploy\n * micro service POJO artifacts.\n */\npublic class MicroservicesDeployer implements Deployer {\n\n    private static final Logger log = LoggerFactory.getLogger(MicroservicesDeployer.class);\n    private static final String DEPLOYMENT_PATH = \"file:microservices\";\n    private static final String SUPPORTED_EXTENSIONS[] = {\"jar\", \"zip\"};\n    private static final String MICROSERVICE_ARTIFACT_TYPE = \"microservices\";\n    private URL deploymentLocation;\n    private ArtifactType artifactType;\n    private Map<Object, List<Object>> deployedArtifacts = new HashMap<>();\n\n    public void init() {\n        if (log.isDebugEnabled()) {\n            log.debug(\"microservice deployer initializing\");\n        }\n        artifactType = new ArtifactType<>(MICROSERVICE_ARTIFACT_TYPE);\n        try {\n            deploymentLocation = new URL(DEPLOYMENT_PATH);\n        } catch (MalformedURLException e) {\n            log.error(\"microservices deployer location error | location: \" + DEPLOYMENT_PATH , e);\n        }\n    }\n\n    /**\n     * Deploy and artifact in the netty-http service.\n     *\n     * @param artifact the artifact to be deployed\n     * @return A key to identify the deployed artifact\n     * @throws CarbonDeploymentException If deployment fails\n     */\n    public Object deploy(Artifact artifact) throws CarbonDeploymentException {\n        if (artifact == null || artifact.getFile() == null) {\n            throw new CarbonDeploymentException(\"Deployment artifact cannot be null\");\n        }\n\n        File artifactFile = artifact.getFile();\n        String artifactPath = artifactFile.getAbsolutePath();\n        if (isSupportedFile(artifactFile)) {\n            log.info(\"Deploying microservice artifact: {}\", artifactPath);\n            List<Object> resourcesList;\n            try {\n                resourcesList = MicroserviceDeploymentUtils.getRourceInstances(artifactFile);\n            } catch (MicroserviceDeploymentException e) {\n                throw new CarbonDeploymentException(\"Error while processing the artifact: \" + artifactPath, e);\n            }\n            if (resourcesList.size() == 0) {\n                throw new CarbonDeploymentException(\"No classes to initialize in artifact: \" + artifactPath);\n            }\n\n            boolean deployed = resourcesList.stream()\n                    .filter(resource -> resource instanceof Microservice)\n                    .map(resource -> addService((Microservice) resource))\n                    .anyMatch(Boolean.FALSE::equals);\n\n            if (!deployed) {\n                // If one service not deployed correctly, process should retry later.\n                artifact.setKey(artifactPath);\n                deployedArtifacts.put(artifactPath, resourcesList);\n                return artifactPath;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Undeploy the artifact with the key from the netty-http service.\n     *\n     * @param key Key to identify the artifact\n     * @throws CarbonDeploymentException If an error occurs while undeploying\n     */\n    public void undeploy(Object key) throws CarbonDeploymentException {\n        log.info(\"Undeploying artifact: {}\", key);\n        List<Object> resourcesList = deployedArtifacts.get(key);\n        if (resourcesList != null) {\n            resourcesList.forEach(resource -> {\n                if (resource instanceof Microservice) {\n                    removeService((Microservice) resource);\n                }\n            });\n        }\n    }\n\n    /**\n     * Update the artifact from the netty-http service.\n     * @param artifact the artifact to be deployed\n     * @return A key to identify the deployed artifact\n     * @throws CarbonDeploymentException If update fails\n     */\n    public Object update(Artifact artifact) throws CarbonDeploymentException {\n        File artifactFile = artifact.getFile();\n        String artifactPath = artifactFile.getAbsolutePath();\n        if (isSupportedFile(artifactFile)) {\n            log.info(\"Updating artifact: {}\", artifactPath);\n            undeploy(artifact.getKey());\n            deploy(artifact);\n        }\n        return artifactPath;\n    }\n\n    /**\n     * @return Artifact deployment location relative to the\n     * server dir in repository\n     */\n    public URL getLocation() {\n        return deploymentLocation;\n    }\n\n    /**\n     * @return Artifact deployment location\n     */\n    public ArtifactType getArtifactType() {\n        return artifactType;\n    }\n\n\n    /**\n     * Checks whether the artifact file type is supported in Microservices Deployer.\n     * @param file artifact file\n     * @return true, if file type is supported, false, if not\n     */\n    private boolean isSupportedFile(File file) {\n        return Arrays\n                .stream(SUPPORTED_EXTENSIONS)\n                .filter(\n                        s -> s.equalsIgnoreCase(getFileExtension(file))\n                ).findAny().isPresent();\n    }\n\n    /**\n     * Returns the extension of the artifact file.\n     * @param file artifact file\n     * @return file extension\n     */\n    private String getFileExtension(File file) {\n        String extension = \"\";\n        if (file == null) {\n            return extension;\n        }\n\n        String fileName = file.getName();\n        if (file.isFile()) {\n            int i = fileName.lastIndexOf('.');\n            if (i > 0) {\n                extension = fileName.substring(i + 1);\n            }\n        }\n        return extension;\n    }\n\n    /**\n     * Add micro services instance to micro services registry.\n     * @param service object to be added to registry\n     */\n    private boolean addService(Microservice service) {\n        Map<String, MicroservicesRegistry> microservicesRegistries =\n                DataHolder.getInstance().getMicroserviceRegistries();\n        if (microservicesRegistries.isEmpty()) {\n            log.error(\"Microservice deployment failed. Microservices Registry doesn't exist to register microservice.\");\n            return false;\n        }\n        microservicesRegistries.values().forEach(registry -> registry.addService(service));\n        log.info(\"Microservice {} deployed successfully\", service.getClass().getName());\n        return true;\n    }\n\n    /**\n     * Remove micro services instance to micro services registry.\n     * @param service object to be removed from registry,\n     */\n    private boolean removeService(Microservice service) {\n        Map<String, MicroservicesRegistry> microservicesRegistries =\n                DataHolder.getInstance().getMicroserviceRegistries();\n        if (microservicesRegistries.isEmpty()) {\n            log.error(\"Microservice removal failed. Microservices Registry doesn't exist to register microservice.\");\n            return false;\n        }\n\n        microservicesRegistries.values().forEach(registry -> {\n            registry.removeService(service);\n            registry.preDestroyService(service);\n        });\n        log.info(\"Microservice {} undeployed successfully\", service.getClass().getName());\n        return true;\n    }\n}\n"
  },
  {
    "path": "deployer/src/test/java/org/wso2/msf4j/deployer/MSF4JDeployerTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.deployer;\n\nimport com.google.gson.Gson;\nimport com.google.gson.reflect.TypeToken;\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.Charsets;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.maven.shared.invoker.DefaultInvocationRequest;\nimport org.apache.maven.shared.invoker.DefaultInvoker;\nimport org.apache.maven.shared.invoker.InvocationRequest;\nimport org.apache.maven.shared.invoker.Invoker;\nimport org.apache.maven.shared.invoker.MavenInvocationException;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.carbon.deployment.engine.Artifact;\nimport org.wso2.carbon.deployment.engine.exception.CarbonDeploymentException;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.deployer.internal.DataHolder;\nimport org.wso2.msf4j.deployer.internal.MicroservicesDeployer;\nimport org.wso2.msf4j.internal.MicroservicesRegistryImpl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.stream.Stream;\nimport javax.ws.rs.HttpMethod;\n\nimport static org.testng.AssertJUnit.assertEquals;\nimport static org.testng.AssertJUnit.assertTrue;\n\n/**\n * Tests microservice deployer.\n */\npublic class MSF4JDeployerTest {\n\n    private static final String HOSTNAME = \"localhost\";\n    private static final int PORT = 8090;\n    private MicroservicesDeployer deployer;\n    private static final String HEADER_VAL_CLOSE = \"CLOSE\";\n    private static final Gson GSON = new Gson();\n    private static final Type STRING_MAP_TYPE = new TypeToken<Map<String, String>>() {\n    }.getType();\n    protected static URI baseURI;\n    private String stockqoutesSamplesFile;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        MicroservicesRunner microservicesRunner = new MicroservicesRunner(PORT);\n        microservicesRunner.start();\n        Map<String, MicroservicesRegistry> microservicesRegistries =\n                DataHolder.getInstance().getMicroservicesRegistries();\n        microservicesRegistries.put(\"test\", microservicesRunner.getMsRegistry());\n        deployer = new MicroservicesDeployer();\n        baseURI = URI.create(String.format(\"http://%s:%d\", HOSTNAME, 8090));\n        // get the stockquote sample project path. sample.filepath property is added to surefire plugins configuration\n        String rootDirectory = Paths.get(System.getProperty(\"project.filepath\")).getParent().toString();\n        stockqoutesSamplesFile = Paths.get(rootDirectory, \"samples\", \"stockquote\").toString();\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistries =\n                org.wso2.msf4j.internal.DataHolder.getInstance().getMicroservicesRegistries();\n        microservicesRegistries.remove(\"test\");\n    }\n\n    @Test\n    public void testJarArtifactDeployment() throws Exception {\n        // compile the stockqoute deployable-jar sample\n        compileTestSamples(Paths.get(stockqoutesSamplesFile, \"deployable-jar\", \"pom.xml\").toFile());\n        // get the jar file path\n        Optional<Path> path = getSampleJarFile(Paths.get(stockqoutesSamplesFile, \"deployable-jar\", \"target\"));\n        assertTrue(\"Sample artifact doesn't found in output directory : \"\n                + Paths.get(stockqoutesSamplesFile, \"deployable-jar\", \"target\"), path.isPresent());\n        File file = path.get().toFile();\n        Artifact artifact = new Artifact(file);\n        deployer.deploy(artifact);\n\n        HttpURLConnection urlConn = request(\"/stockquote/IBM\", HttpMethod.GET);\n        assertEquals(HttpURLConnection.HTTP_OK, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n\n        Map<String, String> map = GSON.fromJson(content, STRING_MAP_TYPE);\n        assertEquals(5, map.size());\n        assertEquals(\"IBM\", map.get(\"symbol\"));\n        assertEquals(\"International Business Machines\", map.get(\"name\"));\n        urlConn.disconnect();\n    }\n\n    @Test(dependsOnMethods = \"testJarArtifactDeployment\")\n    public void testJarArtifactUndeployment() throws Exception {\n        Optional<Path> path = getSampleJarFile(Paths.get(stockqoutesSamplesFile, \"deployable-jar\", \"target\"));\n        assertTrue(\"Sample artifact doesn't found in output directory : \"\n                + Paths.get(stockqoutesSamplesFile, \"deployable-jar\", \"target\"), path.isPresent());\n        File file = path.get().toFile();\n        deployer.undeploy(file.getAbsolutePath());\n        HttpURLConnection urlConn = request(\"/stockquote/IBM\", HttpMethod.GET);\n        assertEquals(HttpURLConnection.HTTP_NOT_FOUND, urlConn.getResponseCode());\n    }\n\n    @Test(expectedExceptions = CarbonDeploymentException.class,\n            expectedExceptionsMessageRegExp = \"Error while processing the artifact.*\")\n    public void testFatJarArtifactDeployment() throws Exception {\n        // compile the stockqoute fatjar sample\n        compileTestSamples(Paths.get(stockqoutesSamplesFile, \"fatjar\", \"pom.xml\").toFile());\n        Optional<Path> path = getSampleJarFile(Paths.get(stockqoutesSamplesFile, \"fatjar\", \"target\"));\n        assertTrue(\"Sample artifact doesn't found in output directory : \"\n                + Paths.get(stockqoutesSamplesFile, \"fatjar\", \"target\"), path.isPresent());\n        File file = path.get().toFile();\n        Artifact artifact = new Artifact(file);\n        deployer.deploy(artifact);\n    }\n\n    @Test(expectedExceptions = CarbonDeploymentException.class,\n            expectedExceptionsMessageRegExp = \"Error while processing the artifact.*\")\n    public void testBundleArtifactDeployment() throws Exception {\n        // compile the stockqoute bundle sample\n        compileTestSamples(Paths.get(stockqoutesSamplesFile, \"bundle\", \"pom.xml\").toFile());\n        Optional<Path> path = getSampleJarFile(Paths.get(stockqoutesSamplesFile, \"bundle\", \"target\"));\n        assertTrue(\"Sample artifact doesn't found in output directory : \"\n                + Paths.get(stockqoutesSamplesFile, \"bundle\", \"target\"), path.isPresent());\n        File file = path.get().toFile();\n        Artifact artifact = new Artifact(file);\n        deployer.deploy(artifact);\n    }\n\n    private HttpURLConnection request(String path, String method) throws IOException {\n        return request(path, method, false);\n    }\n\n    private HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n    private String getContent(HttpURLConnection urlConn) throws IOException {\n        return new String(IOUtils.toByteArray(urlConn.getInputStream()), Charsets.UTF_8);\n    }\n\n    /**\n     * compile the sample project in the given filepath.\n     * @param projectFile sample project pom file location\n     * @throws MavenInvocationException\n     */\n    private void compileTestSamples(File projectFile) throws MavenInvocationException {\n        InvocationRequest request = new DefaultInvocationRequest();\n        request.setPomFile(projectFile);\n        request.setGoals(Collections.singletonList(\"install\"));\n\n        Invoker invoker = new DefaultInvoker();\n        String mavenLocalRepo = System.getProperty(\"maven.repo.local\");\n        if (mavenLocalRepo != null && !mavenLocalRepo.isEmpty()) {\n            invoker.setLocalRepositoryDirectory(new File(mavenLocalRepo));\n        }\n        invoker.execute(request);\n    }\n\n    /**\n     * Returns the jar file in the given project target directory location.\n     * @param targetDirectory target file path\n     * @return\n     * @throws IOException\n     */\n    private Optional<Path> getSampleJarFile(Path targetDirectory) throws IOException {\n        try (Stream<Path> paths = Files.walk(targetDirectory)) {\n            return paths.filter(filePath -> Files.isRegularFile(filePath) && filePath.toString().endsWith(\".jar\"))\n                    .findFirst();\n        }\n    }\n}\n"
  },
  {
    "path": "deployer/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"MSF4J_Deployer_Test_Suite\">\n    <test name=\"deployer-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.deployer.MSF4JDeployerTest\"/>\n        </classes>\n    </test>\n\n</suite>\n"
  },
  {
    "path": "distribution/binary/LICENSE.txt",
    "content": "\nThis product is licensed by WSO2 Inc. under Apache License 2.0. The license\ncan be downloaded from the following locations:\n    http://www.apache.org/licenses/LICENSE-2.0.html\n    http://www.apache.org/licenses/LICENSE-2.0.txt\n\nThis product also contains software under different licenses. This table below\nall the contained libraries (jar files) and the license under which they are\nprovided to you.\n\nAt the bottom of this file is a table that shows what each license indicated\nbelow is and where the actual text of the license can be found.\n\nName                                                                            Type           License\n---------------------------------------------------------------------------------------------------------\nguava_20.0.jar                                                                  bundle         apache2\ncommons-io_2.4.0.wso2v1.jar                                                     bundle         apache2\ncommons-pool_1.5.6.wso2v1.jar                                                   bundle         apache2\nmetrics-core_3.2.4.jar                                                          bundle         apache2\nmetrics-jvm_3.2.4.jar                                                           bundle         apache2\nswagger-annotations_1.5.16.jar                                                   bundle         apache2\nswagger-core_1.5.16.jar                                                          bundle         apache2\nswagger-jaxrs_1.5.16.jar                                                         bundle         apache2\nswagger-models_1.5.16.jar                                                        bundle         apache2\nvalidation-api_1.1.0.Final.jar                                                  jar            apache2\nlibthrift_0.9.2.wso2v1.jar                                                      bundle         apache2\njavassist_3.19.0-GA.jar                                                         bundle         mpl+lgpl+apache2\njson_20140107.jar                                                               jar            apache2\njson_3.0.0.wso2v1.jar                                                           bundle         apache2\nreflections_0.9.11.jar                                                          jar            wtfpl+bsd\ndisruptor_3.3.2.wso2v2.jar                                                      bundle\nhttpclient_4.3.1.wso2v2.jar                                                     bundle         apache2\nsnakeyaml_1.17.jar                                                              bundle         apache2\nlog4j_1.2.17.wso2v1.jar                                                         jar            apache2\njackson-annotations_2.8.9.jar                                                   bundle         apache2\njackson-core_2.8.9.jar                                                          bundle         apache2\njackson-databind_2.8.9.jar                                                      bundle         apache2\njackson-dataformat-yaml_2.8.9.jar                                               bundle         apache2\njackson-jaxrs-base_2.4.5.jar                                                    bundle         apache2\njackson-jaxrs-json-provider_2.4.5.jar                                           bundle         apache2\njackson-module-jaxb-annotations_2.4.5.jar                                       bundle         apache2\ngson_2.2.4.jar                                                                  jar            apache2\njavax.websocket-api_1.1.jar                                                     bundle\njavax.ws.rs-api_2.0.jar                                                         jar\norg.osgi.core_6.0.0.jar                                                         jar            apache2\nslf4j-api_1.7.5.jar                                                             jar            mit\nslf4j-log4j12_1.6.0.jar                                                         jar            mit\ncommons-codec_1.9.jar                                                           jar            apache2\ncommons-logging_1.1.1.jar                                                       jar            apache2\ncommons-pool_1.5.6.jar                                                          jar            apache2\ncommons-lang3_3.4.jar                                                           jar            apache2\nhttpclient_4.5.2.jar                                                            jar            apache2\nhttpcore_4.4.4.jar                                                              jar            apache2\norg.apache.servicemix.bundles.commons-beanutils_1.8.3_2.jar                     bundle         apache2\nnetty-buffer_4.1.16.Final.jar                                                   jar            apache2\nnetty-codec_4.1.16.Final.jar                                                    jar            apache2\nnetty-codec-http_4.1.16.Final.jar                                              jar            apache2\nnetty-codec-http2_4.1.16.Final.jar                                              jar            apache2\nnetty-common_4.1.16.Final.jar                                                   jar            apache2\nnetty-handler_4.1.16.Final.jar                                                  jar            apache2\nnetty-resolver_4.1.16.Final.jar                                                 jar            apache2\nnetty-transport_4.1.16.Final.jar                                                jar            apache2\norg.wso2.carbon.config_2.1.5.jar                                                bundle         apache2\norg.wso2.carbon.core_5.2.0.jar                                                  bundle         apache2\norg.wso2.carbon.launcher_5.2.0.jar                                              jar            apache2\norg.wso2.carbon.databridge.agent_6.0.0.jar                                      bundle         apache2\norg.wso2.carbon.databridge.commons_6.0.0.jar                                    bundle         apache2\norg.wso2.carbon.databridge.commons.binary_6.0.0.jar                             bundle         apache2\norg.wso2.carbon.databridge.commons.thrift_6.0.0.jar                             bundle         apache2\norg.wso2.carbon.deployment.engine_5.1.9.jar                                     bundle         apache2\norg.wso2.carbon.messaging_3.0.2.jar                                             bundle         apache2\norg.wso2.carbon.metrics.core_2.3.2.jar                                          bundle         apache2\norg.wso2.carbon.metrics.das.core_2.3.2.jar                                      bundle         apache2\norg.wso2.carbon.metrics.das.reporter_2.3.2.jar                                  bundle         apache2\norg.wso2.carbon.metrics.jdbc.core_2.3.2.jar                                     bundle         apache2\norg.wso2.carbon.metrics.jdbc.reporter_2.3.2.jar                                 bundle         apache2\norg.wso2.carbon.secvault_5.0.8.jar                                              bundle         apache2\norg.wso2.transport.http.netty_6.0.163.jar                                       bundle         apache2\norg.wso2.carbon.utils_2.0.2.jar                                                 bundle         apache2\njaxrs-delegates_2.6.1.jar                                                       bundle         apache2\nmsf4j-analytics_2.6.1.jar                                                       bundle         apache2\nmsf4j-analytics-common_2.6.1.jar                                                bundle         apache2\nmsf4j-core_2.6.1.jar                                                            bundle         apache2\nmsf4j-swagger_2.6.1.jar                                                         bundle         apache2\nHikariCP_2.6.3.jar                                                              bundle         apache2\n\nThe license types used by the above libraries and their information is given below:\n\napache2        Apache License Version 2.0\n               http://www.apache.org/licenses/LICENSE-2.0.html\ncddl+gpl       CDDL + GPLv2\n               https://glassfish.dev.java.net/public/CDDL+GPL.html\nepl1           Eclipse Public License\n               http://www.eclipse.org/legal/epl-v10.html\n"
  },
  {
    "path": "distribution/binary/README.md",
    "content": "# WSO2 Microservice Framework for Java (MSF4J) Distribution\n\nWSO2 MSF4J is a lightweight high performance framework for implementing microservices in Java. MSF4J \ndistribution contains the [msf4j-all.jar](../msf4j-all) file and the samples.\n\n\n## Running & Installation\n\nPrerequisites: JDK 1.8 and Maven 3.1.x.\n\nYou can simply add the msf4j-all-*.jar file in this distribution to your classpath and start writing your\nmicroservice. If you have Maven installed, you could navigate to the relevant samples in this distribution and\nrun 'mvn clean package' to build the samples. Please follow the instructions in the README files for detailed\ninstructions about the samples.\n\nWe also have a Maven archetype called msf4j-microservice, and you can create your project using that archetype.\nPlease see https://github.com/wso2/msf4j/tree/master/archetypes for more details.\n\nFor key concepts, see https://docs.wso2.com/display/MSF4J100/Key+Concepts#KeyConcepts\n\n\n## Support\n\nWSO2 Inc. offers a variety of development and production support\nprograms, ranging from Web-based support up through normal business\nhours, to premium 24x7 phone support.\n\nFor additional support information please refer to http://wso2.com/support\n\nFor more information on WSO2 Microservices Framework for Java (MSF4J),\nvisit project Home Page (http://wso2.com/products/microservices-framework-for-java/)\n\n\n## Contact Us\n\nWSO2 MSF4J developers can be contacted via the following mailing lists.\n    - Development:  dev@wso2.org\n    - Architecture: architecture@wso2.org\n\nAlternatively, questions can also be raised in the stackoverflow forum\nhttp://stackoverflow.com/questions/tagged/wso2\n\n\n## How To Contribute\n\nYou can find comprehensive instructions on how to contribute from the Getting Involved guide\nhttp://docs.wso2.com/microservices-framework-for-java/Get+Involved\n\n\n## For Further Details\n\n- http://docs.wso2.org/microservices-framework-for-java\n- https://github.com/wso2/msf4j\n\n\n---------------------------------------------------------------------------\n(c) Copyright 2017 WSO2 Inc.\n"
  },
  {
    "path": "distribution/binary/bin.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<assembly>\n    <includeBaseDirectory>true</includeBaseDirectory>\n    <baseDirectory>wso2msf4j-dist-${project.version}</baseDirectory>\n    <id>msf4j</id>\n    <formats>\n        <format>zip</format>\n    </formats>\n\n    <dependencySets>\n        <dependencySet>\n            <outputDirectory>.</outputDirectory>\n            <includes>\n                <include>org.wso2.msf4j:msf4j-all:jar</include>\n            </includes>\n        </dependencySet>\n    </dependencySets>\n\n    <fileSets>\n\n        <fileSet>\n            <directory>conf</directory>\n            <outputDirectory>.</outputDirectory>\n            <fileMode>644</fileMode>\n        </fileSet>\n\n        <!-- Copy the samples -->\n        <fileSet>\n            <directory>../../samples/</directory>\n            <outputDirectory>samples</outputDirectory>\n            <excludes>\n                <exclude>**/target/**</exclude>\n                <exclude>**/.vagrant.d/**</exclude>\n                <exclude>**/.vagrant/**</exclude>\n                <exclude>**/kubernetes-vagrant-coreos-cluster/docker/**</exclude>\n                <exclude>**/VirtualBox VMs/**</exclude>\n                <exclude>**/dependency-reduced-pom.xml</exclude>\n                <exclude>**/*.iml</exclude>\n                <exclude>**/*.ipr</exclude>\n                <exclude>**/*.iwr</exclude>\n                <exclude>**/*.eclipse</exclude>\n            </excludes>\n        </fileSet>\n\n        <!-- Copy the analytics setup -->\n        <fileSet>\n            <directory>../../analytics/das-setup</directory>\n            <outputDirectory>analytics/das-setup</outputDirectory>\n            <excludes>\n                <exclude>**/target/**</exclude>\n                <exclude>**/*.iml</exclude>\n                <exclude>**/*.ipr</exclude>\n                <exclude>**/*.iwr</exclude>\n                <exclude>**/*.eclipse</exclude>\n            </excludes>\n        </fileSet>\n    </fileSets>\n\n    <files>\n        <file>\n            <source>LICENSE.txt</source>\n            <outputDirectory>.</outputDirectory>\n            <fileMode>644</fileMode>\n            <filtered>false</filtered>\n        </file>\n\n        <file>\n            <source>README.md</source>\n            <outputDirectory>.</outputDirectory>\n            <fileMode>644</fileMode>\n            <filtered>false</filtered>\n        </file>\n    </files>\n</assembly>\n"
  },
  {
    "path": "distribution/binary/conf/netty-transports.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransportProperties:\n -\n  name: \"latency.metrics.enabled\"\n  value: true\n -\n  name: \"server.bootstrap.boss.group.size\"\n  value: 4\n -\n  name: \"server.bootstrap.worker.group.size\"\n  value: 8\nlistenerConfigurations:\n-\n  id: \"msf4j-http\"\n  host: \"0.0.0.0\"\n  port: 8080\n-\n  id: \"msf4j-https\"\n  host: \"0.0.0.0\"\n  port: 8443\n  scheme: https\n  sslConfig:\n    keyStore: \"src/test/resources/cert.jks\"\n    keyStorePass: secret\nsenderConfigurations:\n -\n  id: \"netty-gw\"\n"
  },
  {
    "path": "distribution/binary/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>wso2msf4j-dist</artifactId>\n    <packaging>pom</packaging>\n    <name>WSO2 MSF4J Server - Distribution Pack</name>\n    <description>WSO2 MSF4J Server - Distribution Pack</description>\n    <url>http://wso2.org</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-all</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <id>distribution</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>single</goal>\n                        </goals>\n                        <configuration>\n                            <descriptors>\n                                <descriptor>${basedir}/bin.xml</descriptor>\n                            </descriptors>\n                            <appendAssemblyId>false</appendAssemblyId>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "distribution/msf4j-all/README.md",
    "content": "# WSO2 Microservice Framework for Java (MSF4J) - All in one jar file\n\nA single jar file which packs MSF4J and all its dependencies."
  },
  {
    "path": "distribution/msf4j-all/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-all</artifactId>\n    <packaging>jar</packaging>\n\n    <name>MSF4J - All in one jar file</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>com.nimbusds</groupId>\n                    <artifactId>nimbus-jose-jwt</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi.services</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.google.code.findbugs</groupId>\n                    <artifactId>jsr305</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-swagger</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <filters>\n                                <filter>\n                                    <artifact>*:*</artifact>\n                                    <excludes>\n                                        <exclude>META-INF/*.SF</exclude>\n                                        <exclude>META-INF/*.DSA</exclude>\n                                        <exclude>META-INF/*.RSA</exclude>\n                                    </excludes>\n                                </filter>\n                            </filters>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "features/etc/feature.properties",
    "content": "################################################################################\n#  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n#  WSO2 Inc. licenses this file to you under the Apache License,\n#  Version 2.0 (the \"License\"); you may not use this file except\n#  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,\n#  software distributed under the License is distributed on an\n#  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n#  specific language governing permissions and limitations\n#  under the License.\n#\n################################################################################\n\nproviderName=WSO2 Inc.\n\n########################## license properties ##################################\nlicenseURL=http://www.apache.org/licenses/LICENSE-2.0\n\nlicense=\\\n                                 Apache License\\n\\\n                           Version 2.0, January 2004\\n\\\n                        http://www.apache.org/licenses/\\n\\\n\\n\\\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\\n\\\n\\n\\\n   1. Definitions.\\n\\\n\\n\\\n      \"License\" shall mean the terms and conditions for use, reproduction,\\n\\\n      and distribution as defined by Sections 1 through 9 of this document.\\n\\\n\\n\\\n      \"Licensor\" shall mean the copyright owner or entity authorized by\\n\\\n      the copyright owner that is granting the License.\\n\\\n\\n\\\n      \"Legal Entity\" shall mean the union of the acting entity and all\\n\\\n      other entities that control, are controlled by, or are under common\\n\\\n      control with that entity. For the purposes of this definition,\\n\\\n      \"control\" means (i) the power, direct or indirect, to cause the\\n\\\n      direction or management of such entity, whether by contract or\\n\\\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\\n\\\n      outstanding shares, or (iii) beneficial ownership of such entity.\\n\\\n\\n\\\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\\n\\\n      exercising permissions granted by this License.\\n\\\n\\n\\\n      \"Source\" form shall mean the preferred form for making modifications,\\n\\\n      including but not limited to software source code, documentation\\n\\\n      source, and configuration files.\\n\\\n\\n\\\n      \"Object\" form shall mean any form resulting from mechanical\\n\\\n      transformation or translation of a Source form, including but\\n\\\n      not limited to compiled object code, generated documentation,\\n\\\n      and conversions to other media types.\\n\\\n\\n\\\n      \"Work\" shall mean the work of authorship, whether in Source or\\n\\\n      Object form, made available under the License, as indicated by a\\n\\\n      copyright notice that is included in or attached to the work\\n\\\n      (an example is provided in the Appendix below).\\n\\\n\\n\\\n      \"Derivative Works\" shall mean any work, whether in Source or Object\\n\\\n      form, that is based on (or derived from) the Work and for which the\\n\\\n      editorial revisions, annotations, elaborations, or other modifications\\n\\\n      represent, as a whole, an original work of authorship. For the purposes\\n\\\n      of this License, Derivative Works shall not include works that remain\\n\\\n      separable from, or merely link (or bind by name) to the interfaces of,\\n\\\n      the Work and Derivative Works thereof.\\n\\\n\\n\\\n      \"Contribution\" shall mean any work of authorship, including\\n\\\n      the original version of the Work and any modifications or additions\\n\\\n      to that Work or Derivative Works thereof, that is intentionally\\n\\\n      submitted to Licensor for inclusion in the Work by the copyright owner\\n\\\n      or by an individual or Legal Entity authorized to submit on behalf of\\n\\\n      the copyright owner. For the purposes of this definition, \"submitted\"\\n\\\n      means any form of electronic, verbal, or written communication sent\\n\\\n      to the Licensor or its representatives, including but not limited to\\n\\\n      communication on electronic mailing lists, source code control systems,\\n\\\n      and issue tracking systems that are managed by, or on behalf of, the\\n\\\n      Licensor for the purpose of discussing and improving the Work, but\\n\\\n      excluding communication that is conspicuously marked or otherwise\\n\\\n      designated in writing by the copyright owner as \"Not a Contribution.\"\\n\\\n\\n\\\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\\n\\\n      on behalf of whom a Contribution has been received by Licensor and\\n\\\n      subsequently incorporated within the Work.\\n\\\n\\n\\\n   2. Grant of Copyright License. Subject to the terms and conditions of\\n\\\n      this License, each Contributor hereby grants to You a perpetual,\\n\\\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\\n\\\n      copyright license to reproduce, prepare Derivative Works of,\\n\\\n      publicly display, publicly perform, sublicense, and distribute the\\n\\\n      Work and such Derivative Works in Source or Object form.\\n\\\n\\n\\\n   3. Grant of Patent License. Subject to the terms and conditions of\\n\\\n      this License, each Contributor hereby grants to You a perpetual,\\n\\\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\\n\\\n      (except as stated in this section) patent license to make, have made,\\n\\\n      use, offer to sell, sell, import, and otherwise transfer the Work,\\n\\\n      where such license applies only to those patent claims licensable\\n\\\n      by such Contributor that are necessarily infringed by their\\n\\\n      Contribution(s) alone or by combination of their Contribution(s)\\n\\\n      with the Work to which such Contribution(s) was submitted. If You\\n\\\n      institute patent litigation against any entity (including a\\n\\\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\\n\\\n      or a Contribution incorporated within the Work constitutes direct\\n\\\n      or contributory patent infringement, then any patent licenses\\n\\\n      granted to You under this License for that Work shall terminate\\n\\\n      as of the date such litigation is filed.\\n\\\n\\n\\\n   4. Redistribution. You may reproduce and distribute copies of the\\n\\\n      Work or Derivative Works thereof in any medium, with or without\\n\\\n      modifications, and in Source or Object form, provided that You\\n\\\n      meet the following conditions:\\n\\\n\\n\\\n      (a) You must give any other recipients of the Work or\\n\\\n          Derivative Works a copy of this License; and\\n\\\n\\n\\\n      (b) You must cause any modified files to carry prominent notices\\n\\\n          stating that You changed the files; and\\n\\\n\\n\\\n      (c) You must retain, in the Source form of any Derivative Works\\n\\\n          that You distribute, all copyright, patent, trademark, and\\n\\\n          attribution notices from the Source form of the Work,\\n\\\n          excluding those notices that do not pertain to any part of\\n\\\n          the Derivative Works; and\\n\\\n\\n\\\n      (d) If the Work includes a \"NOTICE\" text file as part of its\\n\\\n          distribution, then any Derivative Works that You distribute must\\n\\\n          include a readable copy of the attribution notices contained\\n\\\n          within such NOTICE file, excluding those notices that do not\\n\\\n          pertain to any part of the Derivative Works, in at least one\\n\\\n          of the following places: within a NOTICE text file distributed\\n\\\n          as part of the Derivative Works; within the Source form or\\n\\\n          documentation, if provided along with the Derivative Works; or,\\n\\\n          within a display generated by the Derivative Works, if and\\n\\\n          wherever such third-party notices normally appear. The contents\\n\\\n          of the NOTICE file are for informational purposes only and\\n\\\n          do not modify the License. You may add Your own attribution\\n\\\n          notices within Derivative Works that You distribute, alongside\\n\\\n          or as an addendum to the NOTICE text from the Work, provided\\n\\\n          that such additional attribution notices cannot be construed\\n\\\n          as modifying the License.\\n\\\n\\n\\\n      You may add Your own copyright statement to Your modifications and\\n\\\n      may provide additional or different license terms and conditions\\n\\\n      for use, reproduction, or distribution of Your modifications, or\\n\\\n      for any such Derivative Works as a whole, provided Your use,\\n\\\n      reproduction, and distribution of the Work otherwise complies with\\n\\\n      the conditions stated in this License.\\n\\\n\\n\\\n   5. Submission of Contributions. Unless You explicitly state otherwise,\\n\\\n      any Contribution intentionally submitted for inclusion in the Work\\n\\\n      by You to the Licensor shall be under the terms and conditions of\\n\\\n      this License, without any additional terms or conditions.\\n\\\n      Notwithstanding the above, nothing herein shall supersede or modify\\n\\\n      the terms of any separate license agreement you may have executed\\n\\\n      with Licensor regarding such Contributions.\\n\\\n\\n\\\n   6. Trademarks. This License does not grant permission to use the trade\\n\\\n      names, trademarks, service marks, or product names of the Licensor,\\n\\\n      except as required for reasonable and customary use in describing the\\n\\\n      origin of the Work and reproducing the content of the NOTICE file.\\n\\\n\\n\\\n   7. Disclaimer of Warranty. Unless required by applicable law or\\n\\\n      agreed to in writing, Licensor provides the Work (and each\\n\\\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\\n\\\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\\n\\\n      implied, including, without limitation, any warranties or conditions\\n\\\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\\n\\\n      PARTICULAR PURPOSE. You are solely responsible for determining the\\n\\\n      appropriateness of using or redistributing the Work and assume any\\n\\\n      risks associated with Your exercise of permissions under this License.\\n\\\n\\n\\\n   8. Limitation of Liability. In no event and under no legal theory,\\n\\\n      whether in tort (including negligence), contract, or otherwise,\\n\\\n      unless required by applicable law (such as deliberate and grossly\\n\\\n      negligent acts) or agreed to in writing, shall any Contributor be\\n\\\n      liable to You for damages, including any direct, indirect, special,\\n\\\n      incidental, or consequential damages of any character arising as a\\n\\\n      result of this License or out of the use or inability to use the\\n\\\n      Work (including but not limited to damages for loss of goodwill,\\n\\\n      work stoppage, computer failure or malfunction, or any and all\\n\\\n      other commercial damages or losses), even if such Contributor\\n\\\n      has been advised of the possibility of such damages.\\n\\\n\\n\\\n   9. Accepting Warranty or Additional Liability. While redistributing\\n\\\n      the Work or Derivative Works thereof, You may choose to offer,\\n\\\n      and charge a fee for, acceptance of support, warranty, indemnity,\\n\\\n      or other liability obligations and/or rights consistent with this\\n\\\n      License. However, in accepting such obligations, You may act only\\n\\\n      on Your own behalf and on Your sole responsibility, not on behalf\\n\\\n      of any other Contributor, and only if You agree to indemnify,\\n\\\n      defend, and hold each Contributor harmless for any liability\\n\\\n      incurred by, or claims asserted against, such Contributor by reason\\n\\\n      of your accepting any such warranty or additional liability.\\n\\\n\\n\\\n   END OF TERMS AND CONDITIONS\\n\\\n"
  },
  {
    "path": "features/feature-test/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.3.0-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-osgi-test</artifactId>\n    <packaging>jar</packaging>\n\n    <name>WSO2 MSF4J OSGi tests</name>\n    <description>WSO2 MSF4J core</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <!--<dependency>\n            <groupId>org.wso2.carbon.transport</groupId>\n            <artifactId>org.wso2.carbon.transport.http.netty</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi.services</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>jaxrs-delegates</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-log4j12</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>guava</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.findbugs</groupId>\n            <artifactId>jsr305</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicemix.bundles</groupId>\n            <artifactId>org.apache.servicemix.bundles.commons-beanutils</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.slf4j</groupId>\n                    <artifactId>slf4j-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.yaml</groupId>\n                    <artifactId>snakeyaml</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-jaxrs</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>javax.ws.rs</groupId>\n                    <artifactId>jsr311-api</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-annotations</artifactId>\n        </dependency>-->\n\n        <!-- Pax Exam Dependencies-->\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-inject</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-extender-service</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.osgi</groupId>\n            <artifactId>org.osgi.compendium</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.base</groupId>\n            <artifactId>ops4j-base</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.geronimo.specs</groupId>\n            <artifactId>geronimo-atinject_1.0_spec</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-container-native</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-link-mvn</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.url</groupId>\n            <artifactId>pax-url-aether</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ow2.spec.ee</groupId>\n            <artifactId>ow2-jta-1.1-spec</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.jacoco</groupId>\n            <artifactId>org.jacoco.ant</artifactId>\n            <scope>test</scope>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <!--<dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-core</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n            <scope>test</scope>\n        </dependency>-->\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <!--<argLine>-Dmsf4jTestRunning</argLine>-->\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <profile>\n            <id>with-tests</id>\n            <activation>\n                <property>\n                    <name>!maven.test.skip</name>\n                </property>\n            </activation>\n            <build>\n                <plugins>\n                    <plugin>\n                        <artifactId>maven-resources-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <!--copying distribution/carbon-home directory to the target folder-->\n                                <id>copy-resources</id>\n                                <phase>generate-resources</phase>\n                                <goals>\n                                    <goal>copy-resources</goal>\n                                </goals>\n                                <configuration>\n                                    <outputDirectory>${project.build.directory}/carbon-home</outputDirectory>\n                                    <overwrite>true</overwrite>\n                                    <resources>\n                                        <resource>\n                                            <directory>src/test/resources/carbon-home</directory>\n                                        </resource>\n                                    </resources>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-dependency-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <id>copy-jacoco-dependencies</id>\n                                <phase>compile</phase>\n                                <goals>\n                                    <goal>copy-dependencies</goal>\n                                </goals>\n                                <configuration>\n                                    <outputDirectory>${project.build.directory}</outputDirectory>\n                                    <includeTypes>jar</includeTypes>\n                                    <includeArtifactIds>org.jacoco.ant</includeArtifactIds>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-surefire-plugin</artifactId>\n                        <configuration>\n                            <systemPropertyVariables>\n                                <org.ops4j.pax.url.mvn.localRepository>${settings.localRepository}\n                                </org.ops4j.pax.url.mvn.localRepository>\n                                <jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>\n                                <pax.exam.system>default</pax.exam.system>\n                            </systemPropertyVariables>\n                            <systemProperties>\n                                <property>\n                                    <name>carbon.home</name>\n                                    <value>${basedir}/target/carbon-home</value>\n                                </property>\n                            </systemProperties>\n                            <suiteXmlFiles>\n                                <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                            </suiteXmlFiles>\n                        </configuration>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                        <version>${jacoco.version}</version>\n                        <executions>\n                            <execution>\n                                <id>default-prepare-agent</id>\n                                <goals>\n                                    <goal>prepare-agent</goal>\n                                </goals>\n                                <configuration>\n                                    <includes>\n                                        <include>org.wso2.carbon*</include>\n                                    </includes>\n                                </configuration>\n                            </execution>\n                            <execution>\n                                <id>default-check</id>\n                                <goals>\n                                    <goal>check</goal>\n                                </goals>\n                                <configuration>\n                                    <rules>\n                                        <rule>\n                                        </rule>\n                                    </rules>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-antrun-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <phase>prepare-package</phase>\n                                <configuration>\n                                    <target xmlns:jacoco=\"antlib:org.jacoco.ant\">\n                                        //this task is to provide class/src files locations for jacoco report generation\n                                        <taskdef uri=\"antlib:org.jacoco.ant\" resource=\"org/jacoco/ant/antlib.xml\">\n                                            <classpath path=\"${project.build.directory}\" />\n                                        </taskdef>\n                                        <jacoco:report>\n                                            <executiondata>\n                                                <file file=\"${project.build.directory}/jacoco.exec\" />\n                                            </executiondata>\n                                            <structure name=\"MSF4J OSGi Tests\">\n                                                <classfiles>\n                                                    <fileset dir=\"../../core/target/classes\" />\n                                                </classfiles>\n                                                <sourcefiles encoding=\"UTF-8\">\n                                                    <fileset dir=\"../../core/src\" />\n                                                </sourcefiles>\n                                            </structure>\n                                            <html destdir=\"${project.build.directory}/site/jacoco\" />\n                                        </jacoco:report>\n                                    </target>\n                                </configuration>\n                                <goals>\n                                    <goal>run</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                        <dependencies>\n                            <dependency>\n                                <groupId>org.jacoco</groupId>\n                                <artifactId>org.jacoco.ant</artifactId>\n                                <version>${org.jacoco.ant.version}</version>\n                            </dependency>\n                        </dependencies>\n                    </plugin>\n\n                    <plugin>\n                        <groupId>org.ops4j.pax.exam</groupId>\n                        <artifactId>maven-paxexam-plugin</artifactId>\n                        <version>${maven.paxexam.plugin.version}</version>\n                        <executions>\n                            <execution>\n                                <id>generate-config</id>\n                                <goals>\n                                    <goal>generate-depends-file</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <!--<bundle.activator>org.wso2.msf4j.internal.MicroservicesServerActivator</bundle.activator>\n        <private.package>org.wso2.msf4j.internal.*,</private.package>\n        <export.package>\n            !org.wso2.msf4j.internal.*,\n            !org.wso2.msf4j.delegates.*,\n            org.wso2.msf4j.*;version=\"1.1.0\",\n        </export.package>\n        <import.package>\n            com.google.gson.*;version=\"${gson.version.range}\",\n            com.google.common.*;version=\"${guava.version.range}\",\n            javax.annotation.*,\n            javax.ws.rs.*,\n            javax.xml.bind;resolution:=optional,\n            javax.xml.bind.annotation;resolution:=optional,\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            javax.net.ssl.*,\n            org.apache.commons.beanutils.*;version=\"${beanutils.version.range}\",\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.osgi.util.tracker; version=\"${osgi.service.tracker.import.version.range}\",\n            org.wso2.carbon.kernel.transports.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.kernel.startupresolver.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.kernel.utils.*;version=\"${carbon.kernel.version.range}\",\n            org.wso2.carbon.messaging.*\n        </import.package>\n        <provide.capability>\n            osgi.service;effective:=active;objectClass=\"org.wso2.msf4j.internal.MicroservicesServerSC\";\n            dependent-component-key=\"carbon-transport-mgt\"\n        </provide.capability>\n        <startup.component>\n            wso2-microservices-server;required-service=\"org.wso2.msf4j.Microservice,org.wso2.msf4j.Interceptor\"\n        </startup.component>-->\n    </properties>\n</project>\n"
  },
  {
    "path": "features/feature-test/src/test/java/org/wso2/msf4j/osgi/test/MSF4JStartupTest.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.osgi.test;\n\n\nimport org.ops4j.pax.exam.Configuration;\nimport org.ops4j.pax.exam.Option;\nimport org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;\nimport org.ops4j.pax.exam.spi.reactors.PerClass;\nimport org.ops4j.pax.exam.testng.listener.PaxExam;\nimport org.osgi.framework.BundleContext;\nimport org.testng.Assert;\nimport org.testng.annotations.Listeners;\nimport org.testng.annotations.Test;\nimport org.wso2.carbon.kernel.CarbonServerInfo;\nimport org.wso2.carbon.osgi.test.util.CarbonSysPropConfiguration;\nimport org.wso2.carbon.osgi.test.util.OSGiTestConfigurationUtils;\n\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.inject.Inject;\n\n/**\n * OSGi tests class to test MSF4J startup.\n *\n * @since 5.0.0\n */\n@Listeners(PaxExam.class)\n@ExamReactorStrategy(PerClass.class)\npublic class MSF4JStartupTest {\n    private static final String TRANSPORT_ID = \"DummyTransport\";\n\n//    @Inject\n//    private TransportManager transportManager;\n\n//    @Inject\n//    private CommandProvider transportCommandProvider;\n\n    @Inject\n    private CarbonServerInfo carbonServerInfo;\n\n    @Inject\n    BundleContext bundleContext;\n\n    @Configuration\n    public Option[] createConfiguration() {\n\n        List<Option> optionList = new ArrayList<>();\n        //TODO: add MSF4J specific bundles\n\n        /*optionList.add(mavenBundle().artifactId(\"org.wso2.carbon.sample.deployer.mgt\").groupId(\"org.wso2.carbon\")\n                .versionAsInProject());\n        optionList.add(mavenBundle().artifactId(\"org.wso2.carbon.sample.order.resolver\").groupId(\"org.wso2.carbon\")\n                .versionAsInProject());*/\n\n        /*optionList.add(\n                mavenBundle().groupId(\"org.wso2.msf4j\").artifactId(\"msf4j-core\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"javax.ws.rs\").artifactId(\"javax.ws.rs-api\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"com.google.code.gson\").artifactId(\"gson\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"com.google.guava\").artifactId(\"guava\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.apache.servicemix.bundles\").\n                        artifactId(\"org.apache.servicemix.bundles.commons-beanutils\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.msf4j\").artifactId(\"msf4j-analytics\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.msf4j\").artifactId(\"jaxrs-delegates\").versionAsInProject());\n\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.metrics\").\n                        artifactId(\"org.wso2.carbon.metrics.annotation\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.metrics\").\n                        artifactId(\"org.wso2.carbon.metrics.common\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.metrics\").\n                        artifactId(\"org.wso2.carbon.metrics.manager\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.metrics\").\n                        artifactId(\"org.wso2.carbon.metrics.impl\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.metrics\").\n                        artifactId(\"org.wso2.carbon.metrics.das.reporter\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.analytics-common\").\n                        artifactId(\"org.wso2.carbon.databridge.agent\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.analytics-common\").\n                        artifactId(\"org.wso2.carbon.databridge.commons\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.carbon.analytics-common\").\n                        artifactId(\"org.wso2.carbon.databridge.commons.thrift\").versionAsInProject());\n\n        optionList.add(\n                mavenBundle().groupId(\"org.wso2.orbit.com.lmax\").artifactId(\"disruptor\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"io.dropwizard.metrics\").artifactId(\"metrics-core\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"commons-io.wso2\").artifactId(\"commons-io\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"libthrift.wso2\").artifactId(\"libthrift\").versionAsInProject());\n        optionList.add(\n                mavenBundle().groupId(\"commons-pool.wso2\").artifactId(\"commons-pool\").versionAsInProject());*/\n\n\n        String currentDir = Paths.get(\"\").toAbsolutePath().toString();\n        Path carbonHome = Paths.get(currentDir, \"target\", \"carbon-home\");\n\n        CarbonSysPropConfiguration sysPropConfiguration = new CarbonSysPropConfiguration();\n        sysPropConfiguration.setCarbonHome(carbonHome.toString());\n        sysPropConfiguration.setServerKey(\"carbon-jndi\");\n        sysPropConfiguration.setServerName(\"WSO2 MSF4J Server\");\n        sysPropConfiguration.setServerVersion(\"1.1.0\");\n\n        optionList = OSGiTestConfigurationUtils.getConfiguration(optionList, null);\n        return optionList.toArray(new Option[optionList.size()]);\n    }\n\n    @Test\n    public void testServerStarup() {\n        Assert.assertNotNull(carbonServerInfo, \"CarbonServerInfo Service is null\");\n    }\n\n//    @Test(dependsOnMethods = {\"testTransportManagerExistence\"})\n//    public void testUnsuccessfulStartTransport() {\n//\n//    }\n}\n"
  },
  {
    "path": "features/feature-test/src/test/resources/carbon-home/conf/carbon.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\nid: carbon-kernel\nname: WSO2 Carbon Kernel\nversion: 5.0.0\ntenant: default\n\n# Ports used by this server\nports:\n# Ports offset. This entry will set the value of the ports defined below to\n# the define value + Offset.\n# e.g. Offset=2 and HTTPS port=9443 will set the effective HTTPS port to 9445\n offset: 0\n# Deployment Engine related configurations\ndeployment:\n# Currently there can be two modes\n#  1. Scheduled Mode - (enable below property to \"scheduled\") - where the task runs periodically and trigger deployment\n#  2. Triggered Mode - (enable below property to \"triggered\") - the deployment has to be triggered externally,\n#   eg : in a worker node we don't need the task to run, but rather when we receive a\n#        cluster msg,  the deployment has to be triggered manually\n mode: scheduled\n\n# Location of the artifact repository\n repositoryLocation: ${carbon.home}/deployment/\n\n# Deployment update interval in seconds. This is the interval between repository listener\n# executions.\n updateInterval: 15\n\n\n# StartupOrderResolver related configurations\nstartupResolver:\n# Configuration for the timer task which checks for satisfiable RequiredCapabilityListeners periodically\n capabilityListenerTimer:\n  delay: 200\n  period: 200\n\n# Configuration for the timer task which checks for pending Capabilities\n pendingCapabilityTimer:\n  delay: 60000\n  period: 30000\n\n# JMX Configuration\njmx:\n enabled: false\n hostName: \"127.0.0.1\"\n rmiServerPort: 11111\n rmiRegistryPort: 9999\n"
  },
  {
    "path": "features/feature-test/src/test/resources/carbon-home/conf/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright 2015 WSO2, Inc. (http://wso2.com)\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<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"debug\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n\n"
  },
  {
    "path": "features/feature-test/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Carbon-Kernel-Core_OSGI-Test-Suite\">\n    <test name=\"carbon-core-osgi-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.osgi.test.MSF4JStartupTest\"/>\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "features/org.wso2.msf4j.deployer.feature/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>org.wso2.msf4j.deployer.feature</artifactId>\n    <packaging>carbon-feature</packaging>\n    <name>WSO2 MSF4J Deployer Feature</name>\n    <url>http://wso2.org</url>\n    <description>This feature contains the core bundles required by the MSF4J Deployer</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-deployer</artifactId>\n        </dependency>\n    </dependencies>\n    <build>\n        <resources>\n            <resource>\n                <directory>resources</directory>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.wso2.carbon.maven</groupId>\n                <artifactId>carbon-feature-plugin</artifactId>\n                <version>${carbon.feature.plugin.version}</version>\n                <extensions>true</extensions>\n                <executions>\n                    <execution>\n                        <id>1-p2-feature-generation</id>\n                        <goals>\n                            <goal>generate</goal>\n                        </goals>\n                        <configuration>\n                            <propertyFile>../etc/feature.properties</propertyFile>\n                            <adviceFileContents>\n                                <advice>\n                                    <name>org.wso2.carbon.p2.category.type</name>\n                                    <value>server</value>\n                                </advice>\n                                <advice>\n                                    <name>org.eclipse.equinox.p2.type.group</name>\n                                    <value>false</value>\n                                </advice>\n                            </adviceFileContents>\n                            <bundles>\n                                <bundle>\n                                    <symbolicName>msf4j-deployer</symbolicName>\n                                    <version>${msf4j.version}</version>\n                                </bundle>\n                            </bundles>\n                            <importFeatures>\n                                <feature>\n                                    <id>org.wso2.msf4j.feature</id>\n                                    <version>${msf4j.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.deployment.engine.feature</id>\n                                    <version>${carbon.deployment.version}</version>\n                                </feature>\n                            </importFeatures>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "features/org.wso2.msf4j.deployer.feature/resources/p2.inf",
    "content": "instructions.configure = \\\norg.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../deployment); \\\norg.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../deployment/microservices); \\"
  },
  {
    "path": "features/org.wso2.msf4j.feature/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>org.wso2.msf4j.feature</artifactId>\n    <packaging>carbon-feature</packaging>\n    <name>WSO2 MSF4J Feature</name>\n    <url>http://wso2.org</url>\n    <description>This feature contains the core bundles required by the MSF4J feature\n    </description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicemix.bundles</groupId>\n            <artifactId>org.apache.servicemix.bundles.commons-beanutils</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>jaxrs-delegates</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-swagger</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>guava</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>failureaccess</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.io.swagger.core</groupId>\n            <artifactId>swagger-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.core</groupId>\n                    <artifactId>jackson-annotations</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.core</groupId>\n                    <artifactId>jackson-databind</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.io.swagger.jaxrs</groupId>\n            <artifactId>swagger-jaxrs</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>javax.ws.rs</groupId>\n                    <artifactId>jsr311-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.core</groupId>\n                    <artifactId>jackson-annotations</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-annotations</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-databind</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.core</groupId>\n                    <artifactId>jackson-annotations</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-annotations</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.dataformat</groupId>\n            <artifactId>jackson-dataformat-yaml</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.validation</groupId>\n            <artifactId>validation-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.org.apache.commons</groupId>\n            <artifactId>commons-lang3</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.org.reflections</groupId>\n            <artifactId>reflections</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.javassist</groupId>\n            <artifactId>javassist</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.websocket</groupId>\n            <artifactId>javax.websocket-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.transport.http</groupId>\n            <artifactId>org.wso2.transport.http.netty</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-buffer</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-transport</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-handler</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-codec</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-codec-http</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-codec-http2</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-resolver</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>commons-pool.wso2</groupId>\n            <artifactId>commons-pool</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-handler-proxy</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-codec-socks</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.netty</groupId>\n            <artifactId>netty-transport-native-unix-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.messaging</groupId>\n            <artifactId>org.wso2.carbon.messaging</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.annotation</groupId>\n            <artifactId>javax.annotation-api</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <resources>\n            <resource>\n                <directory>resources</directory>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.wso2.carbon.maven</groupId>\n                <artifactId>carbon-feature-plugin</artifactId>\n                <version>${carbon.feature.plugin.version}</version>\n                <extensions>true</extensions>\n                <executions>\n                    <execution>\n                        <id>1-p2-feature-generation</id>\n                        <goals>\n                            <goal>generate</goal>\n                        </goals>\n                        <configuration>\n                            <propertyFile>../etc/feature.properties</propertyFile>\n                            <adviceFileContents>\n                                <advice>\n                                    <name>org.wso2.carbon.p2.category.type</name>\n                                    <value>server</value>\n                                </advice>\n                                <advice>\n                                    <name>org.eclipse.equinox.p2.type.group</name>\n                                    <value>false</value>\n                                </advice>\n                            </adviceFileContents>\n                            <bundles>\n                                <bundle>\n                                    <symbolicName>msf4j-core</symbolicName>\n                                    <version>${msf4j.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>msf4j-analytics</symbolicName>\n                                    <version>${msf4j.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>jaxrs-delegates</symbolicName>\n                                    <version>${msf4j.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javax.annotation-api</symbolicName>\n                                    <version>${javax.annotation.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>msf4j-swagger</symbolicName>\n                                    <version>${msf4j.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.google.guava</symbolicName>\n                                    <version>${guava.bundle.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.google.guava.failureaccess</symbolicName>\n                                    <version>${guava.failureaccess.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javax.ws.rs-api</symbolicName>\n                                    <version>${rs-api.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.google.gson</symbolicName>\n                                    <version>${gson.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>org.apache.servicemix.bundles.commons-beanutils</symbolicName>\n                                    <version>${beanutils.osgi.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>swagger-core</symbolicName>\n                                    <version>${swagger.orbit.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.swagger.annotations</symbolicName>\n                                    <version>${io.swagger.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>swagger-jaxrs</symbolicName>\n                                    <version>${swagger.orbit.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.fasterxml.jackson.core.jackson-databind</symbolicName>\n                                    <version>${com.fasterxml.jackson.databind.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.fasterxml.jackson.core.jackson-annotations</symbolicName>\n                                    <version>${com.fasterxml.jackson.annotations.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.fasterxml.jackson.core.jackson-core</symbolicName>\n                                    <version>${com.fasterxml.jackson.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>com.fasterxml.jackson.dataformat.jackson-dataformat-yaml\n                                    </symbolicName>\n                                    <version>${com.fasterxml.jackson.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>org.yaml.snakeyaml</symbolicName>\n                                    <version>${org.snakeyaml.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javax.validation.api</symbolicName>\n                                    <version>${javax.validation.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>commons-lang3</symbolicName>\n                                    <version>${apache.commons.lang3.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javax.servlet-api</symbolicName>\n                                    <version>${javax.servlet-api.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>reflections</symbolicName>\n                                    <version>${reflections.orbit.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javassist</symbolicName>\n                                    <version>${javassist.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>commons-io</symbolicName>\n                                    <version>${commons-io.wso2.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>javax.websocket-api</symbolicName>\n                                    <version>${javax.websocket.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.common</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.transport</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.codec</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.codec-http</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.tcnative-boringssl-static</symbolicName>\n                                    <version>${netty-tcnative.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.tcnative-classes</symbolicName>\n                                    <version>${netty-tcnative.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.handler</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.buffer</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.codec-http2</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.resolver</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.transport-native-unix-common</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n\n                                <bundle>\n                                    <symbolicName>commons-pool</symbolicName>\n                                    <version>${commons.pool.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>org.wso2.transport.http.netty</symbolicName>\n                                    <version>${org.wso2.transport.http.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.handler-proxy</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>io.netty.codec-socks</symbolicName>\n                                    <version>${netty.version}</version>\n                                </bundle>\n                                <bundle>\n                                    <symbolicName>org.wso2.carbon.messaging</symbolicName>\n                                    <version>${carbon.messaging.version}</version>\n                                </bundle>\n                            </bundles>\n                            <importFeatures>\n                                <feature>\n                                    <id>org.wso2.carbon.metrics.jdbc.core.feature</id>\n                                    <version>${carbon.metrics.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.metrics.das.core.feature</id>\n                                    <version>${carbon.metrics.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.deployment.engine.feature</id>\n                                    <version>${carbon.deployment.version}</version>\n                                </feature>\n                            </importFeatures>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "features/org.wso2.msf4j.feature/resources/netty-transports.yml",
    "content": "################################################################################\n#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransportProperties:\n -\n  name: \"latency.metrics.enabled\"\n  value: true\n -\n  name: \"server.bootstrap.socket.timeout\"\n  value: 60\n -\n  name: \"client.bootstrap.socket.timeout\"\n  value: 60\n\nlistenerConfigurations:\n -\n  id: \"default\"\n  host: \"0.0.0.0\"\n  port: 9090\nsenderConfigurations:\n -\n  id: \"http-sender\""
  },
  {
    "path": "issue_template.md",
    "content": "**Description:**\r\n<!-- Give a brief description of the issue -->\r\n\r\n**Suggested Labels:**\r\n<!-- Optional comma separated list of suggested labels. Non committers can’t assign labels to issues, so this will help issue creators who are not a committer to suggest possible labels-->\r\n\r\n**Suggested Assignees:**\r\n<!--Optional comma separated list of suggested team members who should attend the issue. Non committers can’t assign issues to assignees, so this will help issue creators who are not a committer to suggest possible assignees-->\r\n\r\n**Affected Product Version:**\r\n\r\n**OS, DB, other environment details and versions:**    \r\n\r\n**Steps to reproduce:**\r\n\r\n\r\n**Related Issues:**\r\n<!-- Any related issues such as sub tasks, issues reported in other repositories (e.g component repositories), similar problems, etc. -->"
  },
  {
    "path": "jaxrs-delegates/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n ~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <name>JAX-RS Delegates</name>\n    <description>This fragment bundle contains MSF4J implementations of jax-rs API classes.</description>\n    <url>http://wso2.org</url>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>jaxrs-delegates</artifactId>\n    <packaging>bundle</packaging>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <!-- TODO: Remove this dependency when carbon-transport client is integrated -->\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpclient</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <export.package>org.wso2.msf4j.delegates.*;version=\"${msf4j.version}\"</export.package>\n        <import.package>org.slf4j.*;version=\"${slf4j.version.range}\"</import.package>\n        <fragment.host>javax.ws.rs-api</fragment.host>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "jaxrs-delegates/src/main/java/org/wso2/msf4j/delegates/CookieHeaderProvider.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.delegates;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\nimport java.util.TimeZone;\nimport javax.ws.rs.core.Cookie;\nimport javax.ws.rs.core.NewCookie;\nimport javax.ws.rs.ext.RuntimeDelegate;\n\n/**\n * Provides conversions from Cookie to String and String to Cookie.\n */\npublic class CookieHeaderProvider implements RuntimeDelegate.HeaderDelegate<Cookie> {\n\n    private static final String DATE_FORMAT_PATTERN = \"EEE, dd MMM yyyy HH:mm:ss zzz\";\n    private static final String GMT_TIMEZONE = \"GMT\";\n    private static final String VERSION = \"Version\";\n    private static final String PATH = \"Path\";\n    private static final String DOMAIN = \"Domain\";\n    private static final String SECURE = \"Secure\";\n    private static final String EXPIRES = \"Expires\";\n    private static final String COMMENT = \"Comment\";\n    private static final String HTTP_ONLY = \"HttpOnly\";\n    private static final String MAX_AGE = \"MaxAge\";\n    private static final Logger log = LoggerFactory.getLogger(CookieHeaderProvider.class);\n    // Preferred date format in internet standard is Sun, 06 Nov 1994 08:49:37 GMT\n    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_PATTERN, Locale.ENGLISH);\n\n    @Override\n    public Cookie fromString(String cookieValue) {\n        if (cookieValue == null) {\n            throw new IllegalArgumentException(\"Cookie value can not be null\");\n        }\n\n        int version = NewCookie.DEFAULT_VERSION;\n        int maxAge = NewCookie.DEFAULT_MAX_AGE;\n        String name = null;\n        String value = null;\n        String path = null;\n        String domain = null;\n        String comment = null;\n        Date expiry = null;\n        boolean secure = false;\n        boolean httpOnly = false;\n\n        String[] parts = cookieValue.split(\";\");\n        for (String part : parts) {\n            String token = part.trim();\n            if (token.startsWith(VERSION)) {\n                version = Integer.parseInt(token.substring(VERSION.length() + 1));\n            } else if (token.startsWith(PATH)) {\n                path = token.substring(PATH.length() + 1);\n            } else if (token.startsWith(DOMAIN)) {\n                domain = token.substring(DOMAIN.length() + 1);\n            } else if (token.startsWith(SECURE)) {\n                secure = Boolean.TRUE;\n            } else if (token.startsWith(HTTP_ONLY)) {\n                httpOnly = Boolean.TRUE;\n            } else if (token.startsWith(COMMENT)) {\n                comment = token.substring(COMMENT.length() + 1);\n            } else if (token.startsWith(MAX_AGE)) {\n                maxAge = Integer.parseInt(token.substring(MAX_AGE.length() + 1));\n            } else if (token.startsWith(EXPIRES)) {\n                try {\n                    //All HTTP date/time stamps MUST be represented in Greenwich Mean Time (GMT)\n                    dateFormat.setTimeZone(TimeZone.getTimeZone(GMT_TIMEZONE));\n                    expiry = dateFormat.parse(token.substring(EXPIRES.length() + 1));\n                } catch (ParseException e) {\n                    log.error(\"Error while parsing the Date value. Hence return null\", e);\n                }\n            } else {\n                int i = token.indexOf('=');\n                if (i != -1) {\n                    name = token.substring(0, i);\n                    value = i == token.length()  + 1 ? \"\" : token.substring(i + 1);\n                }\n            }\n        }\n\n        if (name == null) {\n            throw new IllegalArgumentException(\"Cookie is malformed : \" + cookieValue);\n        }\n\n        return new NewCookie(name, value, path, domain, version, comment, maxAge, expiry, secure, httpOnly);\n    }\n\n    @Override\n    public String toString(Cookie cookie) {\n        StringBuilder sb = new StringBuilder();\n\n        if (cookie.getVersion() != Cookie.DEFAULT_VERSION) {\n            sb.append(VERSION).append('=').append(cookie.getVersion()).append(';');\n        }\n        sb.append(cookie.getName()).append('=').append(cookie.getValue());\n        if (cookie.getPath() != null) {\n            sb.append(';').append(PATH).append('=').append(cookie.getPath());\n        }\n        if (cookie.getDomain() != null) {\n            sb.append(';').append(DOMAIN).append('=').append(cookie.getDomain());\n        }\n        if (cookie instanceof NewCookie) {\n            NewCookie newCookie = (NewCookie) cookie;\n            if (newCookie.getMaxAge() != NewCookie.DEFAULT_MAX_AGE) {\n                sb.append(';').append(MAX_AGE).append('=').append(newCookie.getMaxAge());\n            }\n            if (newCookie.getComment() != null) {\n                sb.append(';').append(COMMENT).append('=').append(newCookie.getComment());\n            }\n            if (newCookie.getExpiry() != null) {\n                //All HTTP date/time stamps MUST be represented in Greenwich Mean Time (GMT)\n                dateFormat.setTimeZone(TimeZone.getTimeZone(GMT_TIMEZONE));\n                sb.append(';').append(EXPIRES).append('=').append(dateFormat.format(newCookie.getExpiry()));\n            }\n            if (newCookie.isSecure()) {\n                sb.append(';').append(SECURE);\n            }\n            if (newCookie.isHttpOnly()) {\n                sb.append(';').append(HTTP_ONLY);\n            }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/main/java/org/wso2/msf4j/delegates/MSF4JResponse.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.delegates;\n\nimport java.lang.annotation.Annotation;\nimport java.net.URI;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.ws.rs.core.CacheControl;\nimport javax.ws.rs.core.EntityTag;\nimport javax.ws.rs.core.GenericType;\nimport javax.ws.rs.core.HttpHeaders;\nimport javax.ws.rs.core.Link;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.MultivaluedHashMap;\nimport javax.ws.rs.core.MultivaluedMap;\nimport javax.ws.rs.core.NewCookie;\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.core.Variant;\n\n/**\n * Trimmed MSF4J implementation of javax.ws.rs.core.Response.\n */\npublic class MSF4JResponse extends Response {\n\n    private Object entity;\n    private int status;\n    private MultivaluedMap<String, String> headers;\n    private Map<String, NewCookie> cookies = new HashMap<>();\n    private MediaType type;\n    private static final ThreadLocal<URI> baseUriThreadLocal = new ThreadLocal<>();\n\n    /**\n     * Set the {@code baseUri} of the actual request into the {@link InheritableThreadLocal}.\n     * <p>\n     * The {@code baseUri} will be used for absolutizing the location header\n     * content in case that only a relative URI is provided.\n     * </p>\n     * <p>\n     * After resource method invocation when the value is not needed\n     * any more to be stored in {@code ThreadLocal} {@link #clearBaseUri() clearBaseUri()} should be\n     * called for cleanup in order to prevent possible memory leaks.\n     * </p>\n     *\n     * @param baseUri - baseUri of the actual request\n     * @see Builder#location(URI)\n     * @since 2.1.1\n     */\n    public static void setBaseUri(URI baseUri) {\n        baseUriThreadLocal.set(baseUri);\n    }\n\n    /**\n     * Return request baseUri previously set by {@link #setBaseUri(java.net.URI)}.\n     *\n     * Returned {@link URI} is used for absolutization of the location header in case that only a relative\n     * {@code URI} was provided.\n     *\n     * @return baseUri of the actual request\n     * @see Builder#location(URI)\n     * @since 2.1.1\n     */\n    private static URI getBaseUri() {\n        return baseUriThreadLocal.get();\n    }\n\n    /**\n     * Remove the current thread's value for baseUri thread-local variable (set by {@link #setBaseUri(java.net.URI)}).\n     *\n     * Should be called after resource method invocation for cleanup.\n     *\n     * @see Builder#location(URI)\n     * @since 2.1.1\n     */\n    public static void clearBaseUri() {\n        baseUriThreadLocal.remove();\n    }\n\n    public void setHeaders(MultivaluedMap<String, String> headers) {\n        this.headers = headers;\n    }\n\n    public void setCookies(Map<String, NewCookie> cookies) {\n        this.cookies = cookies;\n    }\n\n    @Override\n    public int getStatus() {\n        return status;\n    }\n\n    public void setStatus(int status) {\n        this.status = status;\n    }\n\n    @Override\n    public StatusType getStatusInfo() {\n        return new Response.StatusType() {\n\n            public Status.Family getFamily() {\n                return Response.Status.Family.familyOf(MSF4JResponse.this.status);\n            }\n\n            public String getReasonPhrase() {\n                Response.Status statusEnum = Response.Status.fromStatusCode(MSF4JResponse.this.status);\n                return statusEnum != null ? statusEnum.getReasonPhrase() : \"\";\n            }\n\n            public int getStatusCode() {\n                return MSF4JResponse.this.status;\n            }\n\n        };\n    }\n\n    @Override\n    public Object getEntity() {\n        return entity;\n    }\n\n    public void setEntity(Object entity) {\n        this.entity = entity;\n    }\n\n    @Override\n    public <T> T readEntity(Class<T> entityType) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public <T> T readEntity(GenericType<T> entityType) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public <T> T readEntity(Class<T> entityType, Annotation[] annotations) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public <T> T readEntity(GenericType<T> entityType, Annotation[] annotations) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean hasEntity() {\n        return entity != null;\n    }\n\n    @Override\n    public boolean bufferEntity() {\n        return false;\n    }\n\n    @Override\n    public void close() {\n\n    }\n\n    @Override\n    public MediaType getMediaType() {\n        return type;\n    }\n\n    @Override\n    public Locale getLanguage() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int getLength() {\n        if (headers != null) {\n            String length = headers.getFirst(HttpHeaders.CONTENT_LENGTH);\n            return length == null ? -1 : Integer.parseInt(length);\n        }\n        return -1;\n    }\n\n    @Override\n    public Set<String> getAllowedMethods() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Map<String, NewCookie> getCookies() {\n        return cookies;\n    }\n\n    @Override\n    public EntityTag getEntityTag() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Date getDate() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Date getLastModified() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public URI getLocation() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Set<Link> getLinks() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean hasLink(String relation) {\n        return false;\n    }\n\n    @Override\n    public Link getLink(String relation) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Link.Builder getLinkBuilder(String relation) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public MultivaluedMap<String, Object> getMetadata() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public MultivaluedMap<String, String> getStringHeaders() {\n        return headers;\n    }\n\n    @Override\n    public String getHeaderString(String name) {\n        throw new UnsupportedOperationException();\n    }\n\n    public void setType(MediaType type) {\n        this.type = type;\n    }\n\n    /**\n     * Trimmed Convenient builder for MSF4JResponse instances.\n     */\n    public class Builder extends ResponseBuilder {\n\n        private Object entity;\n        private int status;\n        private MultivaluedMap<String, String> headers;\n        private MediaType type;\n\n        @Override\n        public Response build() {\n            MSF4JResponse msf4jResponse = new MSF4JResponse();\n            msf4jResponse.setStatus(status);\n            msf4jResponse.setEntity(entity);\n            msf4jResponse.setHeaders(headers);\n            msf4jResponse.setType(type);\n            msf4jResponse.setCookies(cookies);\n            return msf4jResponse;\n        }\n\n        @Override\n        public ResponseBuilder clone() {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder status(int status) {\n            this.status = status;\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder entity(Object entity) {\n            this.entity = entity;\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder entity(Object entity, Annotation[] annotations) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder allow(String... methods) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder allow(Set<String> methods) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder cacheControl(CacheControl cacheControl) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder encoding(String encoding) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder header(String name, Object value) {\n            if (headers == null) {\n                headers = new MultivaluedHashMap<>();\n            }\n            if (value instanceof List) {\n                List values = (List) value;\n                for (Object valueElement : values) {\n                    headers.add(name, valueElement.toString());\n                }\n            } else {\n                headers.add(name, value == null ? null : value.toString());\n            }\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder replaceAll(MultivaluedMap<String, Object> headers) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder language(String language) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder language(Locale language) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder type(MediaType type) {\n            this.type = type;\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder type(String type) {\n            this.type = MediaType.valueOf(type);\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder variant(Variant variant) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder contentLocation(URI location) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder cookie(NewCookie... cookies) {\n            Arrays.asList(cookies).forEach(cookie -> MSF4JResponse.this.cookies.put(cookie.getName(), cookie));\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder expires(Date expires) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder lastModified(Date lastModified) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder location(URI location) {\n            URI locationUri = location;\n            if (locationUri != null && !locationUri.isAbsolute()) {\n                URI baseUri = getBaseUri();\n                if (baseUri != null) {\n                    locationUri = baseUri.resolve(location);\n                }\n            }\n            header(HttpHeaders.LOCATION, locationUri);\n            return this;\n        }\n\n        @Override\n        public ResponseBuilder tag(EntityTag tag) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder tag(String tag) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder variants(Variant... variants) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder variants(List<Variant> variants) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder links(Link... links) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder link(URI uri, String rel) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public ResponseBuilder link(String uri, String rel) {\n            throw new UnsupportedOperationException();\n        }\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/main/java/org/wso2/msf4j/delegates/MSF4JRuntimeDelegate.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.delegates;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.core.Application;\nimport javax.ws.rs.core.Cookie;\nimport javax.ws.rs.core.Link;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response.ResponseBuilder;\nimport javax.ws.rs.core.UriBuilder;\nimport javax.ws.rs.core.Variant.VariantListBuilder;\nimport javax.ws.rs.ext.RuntimeDelegate;\n\n/**\n * <p>\n * Implementation of the RuntimeDelegate which is\n * required for the javax.ws.rs.core.Response.\n * <p>\n * This class will be loaded by javax.ws.rs.ext.RuntimeDelegate.\n */\npublic class MSF4JRuntimeDelegate extends RuntimeDelegate {\n\n    protected Map<Class<?>, HeaderDelegate<?>> headerProviders = new HashMap<>();\n\n    public MSF4JRuntimeDelegate() {\n        headerProviders.put(MediaType.class, new MediaTypeHeaderProvider());\n        headerProviders.put(Cookie.class, new CookieHeaderProvider());\n    }\n\n    @Override\n    public UriBuilder createUriBuilder() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public ResponseBuilder createResponseBuilder() {\n        return new MSF4JResponse().new Builder();\n    }\n\n    @Override\n    public VariantListBuilder createVariantListBuilder() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public <T> T createEndpoint(Application application, Class<T> endpointType)\n            throws IllegalArgumentException, UnsupportedOperationException {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> type) throws IllegalArgumentException {\n        if (type == null) {\n            throw new IllegalArgumentException(\"HeaderDelegate type is null\");\n        }\n        return (HeaderDelegate<T>) headerProviders.get(type);\n    }\n\n    @Override\n    public Link.Builder createLinkBuilder() {\n        throw new UnsupportedOperationException();\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/main/java/org/wso2/msf4j/delegates/MediaTypeHeaderProvider.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.delegates;\n\nimport java.util.Locale;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;\n\n/**\n * Provides conversions from MediaTypes to String and String to MediaType.\n */\npublic class MediaTypeHeaderProvider implements HeaderDelegate<MediaType> {\n\n    /**\n     * Convert a string media type to a MediaType object.\n     *\n     * @param mType media type string\n     * @return MediaType object\n     */\n    public MediaType fromString(String mType) {\n        if (mType == null) {\n            throw new IllegalArgumentException(\"Media type value can not be null\");\n        }\n\n        int i = mType.indexOf('/');\n        if (i == -1) {\n            throw new UnsupportedOperationException(\"Media types without subtype is not supported\");\n        }\n\n        int paramsStart = mType.indexOf(';', i + 1);\n        int end = paramsStart == -1 ? mType.length() : paramsStart;\n\n        String type = mType.substring(0, i);\n        String subtype = mType.substring(i + 1, end);\n\n        return new MediaType(type.trim().toLowerCase(Locale.US),\n                subtype.trim().toLowerCase(Locale.US));\n    }\n\n    /**\n     * Convert a media type object to a string.\n     *\n     * @param type MediaType object\n     * @return string media type\n     */\n    public String toString(MediaType type) {\n        if (type == null) {\n            throw new IllegalArgumentException(\"MediaType can not be null\");\n        }\n        return type.getType() + '/' + type.getSubtype();\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/main/resources/META-INF/services/javax.ws.rs.ext.RuntimeDelegate",
    "content": "org.wso2.msf4j.delegates.MSF4JRuntimeDelegate"
  },
  {
    "path": "jaxrs-delegates/src/test/java/org/wso2/msf4j/delegates/CookieHeaderProviderTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.delegates;\n\nimport org.testng.annotations.Test;\n\nimport java.util.Date;\nimport javax.ws.rs.core.Cookie;\nimport javax.ws.rs.core.NewCookie;\n\nimport static org.testng.Assert.assertEquals;\nimport static org.testng.Assert.assertNotNull;\n\npublic class CookieHeaderProviderTest {\n\n    @Test\n    public void testFromString() throws Exception {\n        Cookie cookie = Cookie.valueOf(\"JSESSIONID=3508015E4EF0ECA8C4B761FCC4BC1718\");\n        assertEquals(cookie.getName(), \"JSESSIONID\");\n        assertEquals(cookie.getValue(), \"3508015E4EF0ECA8C4B761FCC4BC1718\");\n    }\n\n    @Test\n    public void testFromStringWithExtendedParameters() {\n        String cookieString = \"Version=1; Application=msf4j; Path=/carbon; Domain=wso2; Expires=Sun, 06 Nov 1994 \" +\n                \"08:49:37 GMT; Secure; HttpOnly; MaxAge=50; Comment=TestOnly\";\n        String name = \"Application\";\n        String value = \"msf4j\";\n        String path = \"/carbon\";\n        String domain = \"wso2\";\n        long dateTime = 784111777000L;\n\n        NewCookie cookie = (NewCookie) Cookie.valueOf(cookieString);\n        assertEquals(cookie.getName(), name);\n        assertEquals(cookie.getValue(), value);\n        assertEquals(cookie.getPath(), path);\n        assertEquals(cookie.getVersion(), 1);\n        assertEquals(cookie.getDomain(), domain);\n        assertEquals(cookie.getComment(), \"TestOnly\");\n        assertEquals(cookie.getExpiry().getTime(), dateTime);\n        assertEquals(cookie.getMaxAge(), 50);\n        assertEquals(cookie.isSecure(), true);\n        assertEquals(cookie.isHttpOnly(), true);\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = \"Cookie value can \" +\n            \"not be null\")\n    public void testFromStringWithoutCookieString() {\n        Cookie.valueOf(null);\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testFromStringWithoutName() {\n        String cookieString = \"Version=1; Path=/carbon; Domain=wso2\";\n        Cookie.valueOf(cookieString);\n    }\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testFromStringWithoutValue() {\n        String cookieString = \"Version=1; Application;  Path=/carbon; Domain=wso2\";\n        Cookie.valueOf(cookieString);\n    }\n\n    @Test\n    public void testToString() throws Exception {\n        String expectedString = \"Version=2;Application=msf4j;Path=/carbon;Domain=wso2;MaxAge=50;Comment=TestOnly;\" +\n                \"Expires=Sun, 06 Nov 1994 08:49:37 GMT;Secure;HttpOnly\";\n        Cookie cookie = new NewCookie(\"Application\", \"msf4j\", \"/carbon\", \"wso2\", 2, \"TestOnly\", 50, new Date\n                (784111777000L), true, true);\n        CookieHeaderProvider cookieHeaderProvider = new CookieHeaderProvider();\n        String cookieString = cookieHeaderProvider.toString(cookie);\n        assertNotNull(cookieString);\n        assertEquals(cookieString, expectedString);\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/test/java/org/wso2/msf4j/delegates/MediaTypeHeaderProviderTest.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.delegates;\n\n\nimport org.testng.Assert;\nimport org.testng.annotations.Test;\n\nimport javax.ws.rs.core.MediaType;\n\n/**\n * Media Type Header Provider test class.\n */\npublic class MediaTypeHeaderProviderTest extends Assert {\n\n    @Test(expectedExceptions = IllegalArgumentException.class)\n    public void testNullValue() throws Exception {\n        MediaType.valueOf(null);\n    }\n\n    @Test\n    public void testTypeWithExtendedParameters() {\n        MediaType mt = MediaType.valueOf(\"multipart/related;type=application/dicom+xml\");\n\n        assertEquals(\"multipart\", mt.getType());\n        assertEquals(\"related\", mt.getSubtype());\n        ;\n    }\n\n    @Test\n    public void testTypeWithExtendedParametersQuote() {\n        MediaType mt = MediaType.valueOf(\"multipart/related;type=\\\"application/dicom+xml\\\"\");\n\n        assertEquals(\"multipart\", mt.getType());\n        assertEquals(\"related\", mt.getSubtype());\n    }\n\n    @Test\n    public void testTypeWithExtendedAndBoundaryParameter() {\n        MediaType mt = MediaType.valueOf(\n                \"multipart/related; type=application/dicom+xml; \" +\n                        \"boundary=\\\"uuid:b9aecb2a-ab37-48d6-a1cd-b2f4f7fa63cb\\\"\");\n        assertEquals(\"multipart\", mt.getType());\n        assertEquals(\"related\", mt.getSubtype());\n    }\n\n    @Test\n    public void testSimpleType() {\n        MediaType m = MediaType.valueOf(\"text/html\");\n        assertEquals(m, new MediaType(\"text\", \"html\"), \"Media type was not parsed correctly\");\n        assertEquals(MediaType.valueOf(\"text/html \"), new MediaType(\"text\", \"html\"),\n                \"Media type was not parsed correctly\");\n    }\n\n    @Test\n    public void testBadType() {\n        try {\n            new MediaTypeHeaderProvider().fromString(\"texthtml\");\n            fail(\"Parse exception must've been thrown\");\n        } catch (Exception pe) {\n            // expected\n        }\n\n    }\n\n    @Test\n    public void testTypeWithParameters() {\n        MediaType mt = MediaType.valueOf(\"text/html;q=1234;b=4321\");\n\n        assertEquals(\"text\", mt.getType());\n        assertEquals(\"html\", mt.getSubtype());\n    }\n\n    @Test\n    public void testSimpleToString() {\n        MediaTypeHeaderProvider provider =\n                new MediaTypeHeaderProvider();\n\n        assertEquals(\"text/plain\", provider.toString(new MediaType(\"text\", \"plain\")),\n                \"simple media type is not serialized\");\n    }\n\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/test/java/org/wso2/msf4j/models/SampleEntity.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.models;\n\n/**\n * This is a model class that is used for testing.\n */\npublic class SampleEntity {\n\n    private int field1;\n    private long field2;\n    private String field3;\n    private String field4;\n    private String field5;\n\n    public SampleEntity(int field1, long field2, String field3, String field4, String field5) {\n        this.field1 = field1;\n        this.field2 = field2;\n        this.field3 = field3;\n        this.field4 = field4;\n        this.field5 = field5;\n    }\n\n    public int getField1() {\n        return field1;\n    }\n\n    public void setField1(int field0) {\n        this.field1 = field0;\n    }\n\n    public long getField2() {\n        return field2;\n    }\n\n    public void setField2(long field2) {\n        this.field2 = field2;\n    }\n\n    public String getField3() {\n        return field3;\n    }\n\n    public void setField3(String field3) {\n        this.field3 = field3;\n    }\n\n    public String getField4() {\n        return field4;\n    }\n\n    public void setField4(String field4) {\n        this.field4 = field4;\n    }\n\n    public String getField5() {\n        return field5;\n    }\n\n    public void setField5(String field5) {\n        this.field5 = field5;\n    }\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/test/java/org/wso2/msf4j/service/ClientTestMicroService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.service;\n\nimport org.wso2.msf4j.models.SampleEntity;\n\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HeaderParam;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.MediaType;\n\n/**\n * This microservice is used to test the MSF4J client\n */\n@Path(\"/test\")\npublic class ClientTestMicroService {\n\n    @GET\n    @Path(\"hello\")\n    public String getHello() {\n        return \"Hello\";\n    }\n\n    @POST\n    @Path(\"hello\")\n    public String postHello() {\n        return \"PostHello\";\n    }\n\n    @PUT\n    @Path(\"hello\")\n    public String putHello() {\n        return \"PutHello\";\n    }\n\n    @DELETE\n    @Path(\"hello\")\n    public String deleteHello() {\n        return \"DeleteHello\";\n    }\n\n    @POST\n    @Path(\"sample-entity-json\")\n    @Consumes(MediaType.APPLICATION_JSON)\n    @Produces(MediaType.TEXT_PLAIN)\n    public String postSampleEntityJson(SampleEntity sampleEntity, @HeaderParam(\"Content-Length\") int len) {\n        boolean isAllSuccess = true;\n        if (len <= 0) {\n            isAllSuccess = false;\n        }\n        if (sampleEntity.getField1() != 1) {\n            isAllSuccess = false;\n        }\n        if (sampleEntity.getField2() != 2) {\n            isAllSuccess = false;\n        }\n        if (!sampleEntity.getField3().equals(\"val1\")) {\n            isAllSuccess = false;\n        }\n        if (!sampleEntity.getField4().equals(\"val2\")) {\n            isAllSuccess = false;\n        }\n        if (!sampleEntity.getField5().equals(\"val3\")) {\n            isAllSuccess = false;\n        }\n        return (isAllSuccess) ? \"success\" : \"failed\";\n    }\n\n}\n"
  },
  {
    "path": "jaxrs-delegates/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"MSF4J_Test-Suite\">\n\n    <test name=\"MediaTypeHeaderProviderTest-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.delegates.MediaTypeHeaderProviderTest\"/>\n        </classes>\n    </test>\n\n</suite>\n"
  },
  {
    "path": "perf-benchmark/README.md",
    "content": "##Echo message performance test\n\nIn this performance test, a sample echo service with 2 operations were created.\n1. Accept a payload and respond the same payload back\n2. Accept a payload, write to a temp file, read that file and respond the same payload back\nClient was created with each subjected microservices framework. See [echo-samples](echo-samples) directory for the \nsample services that were created for each framework.\n\n## Prerequisite\n* **apache2-utils** - This performance tests are executed using ApacheBench. Therefore in order to run the tests, apache2-utils\nshould be installed in the machine.\n\n## Throughput test\n\nTo measure the throughput, each of the above mentioned sample services were started and 1KB of payload was sent to \neach service repeatedly in varying concurrency levels using apache bench tool. After that the average throughput for\neach concurrency level is calculated and plotted for each framework.\n\n![EchoThroughput](graphs/echotps.png) \n![FileEchoThroughput](graphs/fileechotps.png) \n\nAll services were run out of the box without any tuning separately on a 16 core 24GB server in JVM v1.8.0_51 with default configuration.\n\n### Performing the throughput test\n\nBuild the samples using the following command from [perf-benchmark](perf-benchmark)\n\n```\n./run.sh build\n```\n\nRun all tests using the following command from [perf-benchmark](perf-benchmark)\n\n```\n./run.sh\n```\n\nThis script will perform the loads and provide you the average throughput, latency and all the percentiles for all the sample services.\n\nYou can customize the following parameters of the performance test by modifying the following values in [excecute-tests.sh](excecute-tests.sh)\n * concLevels - Space separated list of concurrency levels to test\n * perTestTime - Maximum time to spend on a single concurrency level\n * testLoops - Number of requests to perform for a sigle concurrency level\n * warmUpConc - Concurrency of the warm-up requests\n * warmUpLoop - Number of requests to send for warm-up\n\n\n## Memory Test\n\nTo measure the memory usage, above mentioned 1KB echo test was performed for each sample service. Then for each \nconcurrency level the heap usage was measured and an average value for each concurrency level was calculated. These\naverage heape usage values were plotted for each framework.\n\n![EchoMemory](graphs/echomem.png)\n![FileEchoMemory](graphs/fileechomem.png)\n\n### Performing the memory test\n\nFor each service in [echo-samples](echo-samples) directory,\n* Build service\n* Start the service with GC logging enabled with time stamp (-Xloggc:gc-log-file.log -verbose:gc -XX:+PrintGCDateStamps)\n* Perform the test using the automated [run.sh](run.sh) script as mentioned earlier\n* Get time range of each concurrency level from the output of the run-test.sh\n* Analyse the GC log for each concurrency level by matching the time range and calculate the average heap usage for each concurrency level\n\n\n## Latency Test\n\nTo measure the latency, above mentioned 1KB echo test was performed using same concurrency levels with 500000 requests per each concurrency level. \nLatency was measured using apache bench output. These values were plotted for each framework.\n\n**Note**\nDue to higher latency values, some of the framework are been removed from the charts.\n\n![MeanLatency](graphs/meanlatency.png)\n![MedianLatency](graphs/medianlatency.png)\n![90thPercentilLatency](graphs/90thpercentile.png)\n![95thPercentilLatency](graphs/95thpercentile.png)\n![99thPercentilLatency](graphs/99thpercentile.png)\n\n### Performing the Latency Test\n\nRun the perf test samples one at a time and execute the run-latency.sh script.\n```\n./run-latency.sh   service-url\n```\ne.g.\n```\n./run-latency.sh http://localhost:8080/EchoService/echo\n```\nThis will output the latency results to a latency-results.csv file. If you want to create seperate file you can pass the file suffix as 2nd parameter\ne.g.\n```\n./run-latency.sh http://localhost:8080/EchoService/echo msf4j\n```\nThis will output the latency results to a latency-results-msf4j.csv\n"
  },
  {
    "path": "perf-benchmark/Samples/dropwizard/README.md",
    "content": "Following curl command can be used to consume this service.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/dropwizard/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <artifactId>dropwizard-echo-message</artifactId>\n    <version>1.0-SNAPSHOT</version>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.dropwizard</groupId>\n            <artifactId>dropwizard-core</artifactId>\n            <version>${dropwizard.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.3</version>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>2.4.1</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <filters>\n                                <filter>\n                                    <artifact>*:*</artifact>\n                                    <excludes>\n                                        <exclude>META-INF/*.SF</exclude>\n                                        <exclude>META-INF/*.DSA</exclude>\n                                        <exclude>META-INF/*.RSA</exclude>\n                                    </excludes>\n                                </filter>\n                            </filters>\n\n                            <transformers>\n                                <transformer\n                                        implementation=\"org.apache.maven.plugins.shade.resource.ServicesResourceTransformer\"/>\n                                <transformer\n                                        implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                                    <mainClass>org.wso2.msf4j.perftest.echo.dropwizard.AppStart</mainClass>\n                                </transformer>\n                            </transformers>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <dropwizard.version>1.0.2</dropwizard.version>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "perf-benchmark/Samples/dropwizard/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/dropwizard-echo-message-*\"\nstartCmd=\"java -jar $artifact server\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/EchoService/fileecho\"\n\nlookFor=\"Server: Started\"\n\nwaitTimeout=15\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    cd $curDir\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/dropwizard/src/main/java/org/wso2/msf4j/perftest/echo/dropwizard/AppStart.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.dropwizard;\n\nimport io.dropwizard.Application;\nimport io.dropwizard.Configuration;\nimport io.dropwizard.setup.Environment;\n\n/**\n * AppStart entry point\n */\npublic class AppStart extends Application<Configuration> {\n\n    public static void main(String[] args) throws Exception {\n        new AppStart().run(args);\n    }\n\n    @Override\n    public void run(Configuration configuration,\n                    Environment environment) {\n        environment.jersey().register(new EchoService());\n    }\n\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/dropwizard/src/main/java/org/wso2/msf4j/perftest/echo/dropwizard/EchoService.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.dropwizard;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\n\n/**\n * Resource class\n */\n@Path(\"/EchoService\")\npublic class EchoService {\n\n    @POST\n    @Path(\"echo\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String echoPost(String body) {\n        return body;\n    }\n\n    @POST\n    @Path(\"fileecho\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String fileWrite(String body) throws InterruptedException, IOException {\n        String returnStr = \"\";\n        java.nio.file.Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n        Files.write(tempfile, body.getBytes(Charset.defaultCharset()),\n                    StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n        returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n        Files.delete(tempfile);\n        return returnStr;\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/README.md",
    "content": "Following curl command can be used to consume this service.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>ninja-echo-message</artifactId>\n    <!-- If you want to deploy to a war please -->\n    <!-- replace \"jar\" with \"war\" and -->\n    <!-- comment ninja-standalone dependency and  -->\n    <!-- uncomment the dependency for ninja-servlet -->\n    <packaging>jar</packaging>\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <version>1.0-SNAPSHOT</version>\n\n    <url>http://www.ninjaframework.org</url>\n\n    <properties>\n        <ninja.version>5.8.0</ninja.version>\n        <jetty.version>9.2.10.v20150310</jetty.version>\n    </properties>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.2</version>\n                <configuration>\n                    <source>1.7</source>\n                    <target>1.7</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-enforcer-plugin</artifactId>\n                <version>1.3.1</version>\n                <executions>\n                    <execution>\n                        <id>enforce-banned-dependencies</id>\n                        <goals>\n                            <goal>enforce</goal>\n                        </goals>\n                        <configuration>\n                            <rules>\n                                <bannedDependencies>\n                                    <excludes>\n                                        <exclude>commons-logging</exclude>\n                                    </excludes>\n                                </bannedDependencies>\n                            </rules>\n                            <fail>true</fail>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.eclipse.jetty</groupId>\n                <artifactId>jetty-maven-plugin</artifactId>\n                <version>${jetty.version}</version>\n                <configuration>\n                    <contextPath>/</contextPath>\n                    <stopKey>stop</stopKey>\n                    <stopPort>8889</stopPort>\n                    <scanIntervalSeconds>1</scanIntervalSeconds>\n                    <reload>automatic</reload>\n                    <scanTargetPatterns>\n                        <scanTargetPattern>\n                            <directory>target/classes</directory>\n                            <includes>\n                                <include>**/*</include>\n                            </includes>\n                            <excludes>\n                                <exclude>**/*.ftl.html</exclude>\n                                <exclude>assets/**</exclude>\n                            </excludes>\n                        </scanTargetPattern>\n                    </scanTargetPatterns>\n                    <systemProperties>\n                        <systemProperty>\n                            <name>ninja.mode</name>\n                            <value>dev</value>\n                        </systemProperty>\n                    </systemProperties>\n                </configuration>\n            </plugin>\n            <!-- Allows you to run Ninja via the SuperDevMode. -->\n            <!-- run \"mvn ninja:run\" on the command line for the best -->\n            <!-- development experience. -->\n            <plugin>\n                <groupId>org.ninjaframework</groupId>\n                <artifactId>ninja-maven-plugin</artifactId>\n                <version>${ninja.version}</version>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n                <version>2.8.2</version>\n                <configuration>\n                    <skip>true</skip>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>2.2</version>\n                <configuration>\n                    <createDependencyReducedPom>true</createDependencyReducedPom>\n                    <filters>\n                        <filter>\n                            <artifact>*:*</artifact>\n                            <excludes>\n                                <exclude>META-INF/*.SF</exclude>\n                                <exclude>META-INF/*.DSA</exclude>\n                                <exclude>META-INF/*.RSA</exclude>\n                            </excludes>\n                        </filter>\n                    </filters>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <transformers>\n                                <transformer\n                                        implementation=\"org.apache.maven.plugins.shade.resource.ServicesResourceTransformer\"/>\n                                <transformer\n                                        implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                                    <mainClass>ninja.standalone.NinjaJetty</mainClass>\n                                </transformer>\n                            </transformers>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n        <resources>\n            <resource>\n                <directory>src/main/java</directory>\n                <includes>\n                    <include>**/*</include>\n                </includes>\n                <excludes>\n                    <exclude>**/*.java</exclude>\n                </excludes>\n            </resource>\n            <resource>\n                <directory>src/main/resources</directory>\n                <includes>\n                    <include>**/*</include>\n                </includes>\n            </resource>\n        </resources>\n    </build>\n    <dependencies>\n        <dependency>\n            <groupId>org.webjars</groupId>\n            <artifactId>bootstrap</artifactId>\n            <version>3.3.4</version>\n        </dependency>\n        <dependency>\n            <groupId>org.webjars</groupId>\n            <artifactId>jquery</artifactId>\n            <version>2.1.3</version>\n        </dependency>\n        <dependency>\n            <groupId>com.h2database</groupId>\n            <artifactId>h2</artifactId>\n            <version>1.4.186</version>\n        </dependency>\n        <!-- If you want to deploy to a war please -->\n        <!-- comment ninja-standalone dependency and  -->\n        <!-- uncomment the dependency for ninja-servlet -->\n        <!--\n        <dependency>\n            <groupId>org.ninjaframework</groupId>\n            <artifactId>ninja-servlet</artifactId>\n            <version>${ninja.version}</version>\n        </dependency>\n        -->\n        <dependency>\n            <groupId>org.ninjaframework</groupId>\n            <artifactId>ninja-standalone</artifactId>\n            <version>${ninja.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.ninjaframework</groupId>\n            <artifactId>ninja-test-utilities</artifactId>\n            <version>${ninja.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ninjaframework</groupId>\n            <artifactId>ninja-jaxy-routes</artifactId>\n            <version>5.8.0</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>2.5</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/ninja-echo-message-*\"\nstartCmd=\"java -jar $artifact\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/EchoService/fileecho\"\n\nlookFor=\"Started jetty\"\n\nwaitTimeout=15\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    cd $curDir\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/conf/Module.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage conf;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Singleton;\nimport util.BodyParserEngineTextPlain;\n\n@Singleton\npublic class Module extends AbstractModule {\n\n    protected void configure() {\n        bind(BodyParserEngineTextPlain.class);\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/conf/Routes.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage conf;\n\nimport ninja.Router;\nimport ninja.application.ApplicationRoutes;\nimport ninja.jaxy.JaxyRoutes;\nimport ninja.utils.NinjaProperties;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.inject.Inject;\n\npublic class Routes implements ApplicationRoutes {\n\n    private Logger logger = LoggerFactory.getLogger(Routes.class);\n    private NinjaProperties ninjaProperties;\n\n    @Inject\n    public Routes(NinjaProperties ninjaProperties) {\n        this.ninjaProperties = ninjaProperties;\n\n    }\n\n    @Override\n    public void init(Router router) {\n        JaxyRoutes jaxyRoutes = new JaxyRoutes(ninjaProperties);\n        jaxyRoutes.init(router);\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/conf/application.conf",
    "content": "# The main properties file to configure your application\n#\n# Properties can be prefixed by \"%\".\n# \"%\"\" matches a mode you can set as system property. For instance when you\n# are using maven you can do: mvn -Dmode=test jetty:run\n#\n# Using that the following property:\n# %test.myproperty=test property\n# would overwrite the property\n# myproperty=my property\n#\n# You can define as many environments as you want. Simply set them in the mode.\napplication.name=ninja demo application\n\napplication.cookie.prefix=NINJA\n\n#ISO Language Code, optionally followed by a valid ISO Country Code. \napplication.languages=en\n\napplication.session.expire_time_in_seconds=3600\napplication.session.send_only_if_changed=true\napplication.session.transferred_over_https_only=false\napplication.secret = JY7y2BWPpbB4iJsk87lHE7fEpMSoO7YQRc5sGE68N1E0FbvU8oJi9TxC5hwvnViX\n\n# enable ssl with self-signed cert in dev & test modes\n#ninja.ssl.port=8443\n#application.secret = uewt6ESZ5bCVpZd5hTo3ZYWhwcZetxQIiXuiN0EniYn56AMydfd0dmGTYAfME7OC\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/conf/messages.properties",
    "content": "#\n# Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n# WSO2 Inc. licenses this file to you under the Apache License,\n# Version 2.0 (the \"License\"); you may not use this file except\n# 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,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n# This file is utf-8\nheader.title=Hello World!\nheader.home=BAM!\nhello.world=Hello World!\nhello.world.json=There is also Json rendering you can check out!"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/controllers/ApplicationController.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage controllers;\n\nimport com.google.inject.Singleton;\nimport ninja.Context;\nimport ninja.Result;\nimport ninja.Results;\nimport ninja.jaxy.Path;\nimport ninja.jaxy.POST;\nimport ninja.jaxy.Order;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\n\n@Singleton\n@Path(\"/EchoService\")\npublic class ApplicationController {\n\n    @Path(\"/echo\")\n    @POST\n    public Result echo(String text) {\n        return Results.text().render(text);\n    }\n\n    @Path(\"/fileecho\")\n    @POST\n    public Result fileecho(String body) throws InterruptedException, IOException {\n        java.nio.file.Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n        Files.write(tempfile, body.getBytes(Charset.defaultCharset()), StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n        String returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n        Files.delete(tempfile);\n        return Results.text().render(returnStr);\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/ehcache.xml",
    "content": "<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<ehcache xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"../config/ehcache.xsd\" updateCheck=\"false\">\n\n    <defaultCache\n            maxElementsInMemory=\"10000\"\n            eternal=\"false\"\n            timeToIdleSeconds=\"120\"\n            timeToLiveSeconds=\"120\"\n            overflowToDisk=\"false\"\n            maxElementsOnDisk=\"10000000\"\n            diskPersistent=\"false\"\n            diskExpiryThreadIntervalSeconds=\"120\"\n            memoryStoreEvictionPolicy=\"LRU\"\n    /> \n    \n</ehcache>\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/logback.xml",
    "content": "<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\n  <!-- Uncomment to enable file-based logging with \n       daily (or size exceeding) gzip archival.\n       Also uncomment the \"ROLLING\" reference in <root>.\n  <appender name=\"ROLLING\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\">\n    <file>mylog.log</file>\n    <rollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\">\n      <FileNamePattern>mylog.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>\n      <MaxHistory>30</MaxHistory>\n      <timeBasedFileNamingAndTriggeringPolicy\n        class=\"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP\">\n        <maxFileSize>10MB</maxFileSize>\n      </timeBasedFileNamingAndTriggeringPolicy>\n    </rollingPolicy>\n    <encoder>\n      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n    </encoder>\n  </appender> -->\n\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <!-- encoders are assigned the type\n         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\n    <encoder>\n      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n    </encoder>\n  </appender>\n\n  <root level=\"info\">\n    <appender-ref ref=\"STDOUT\" />\n    <!-- <appender-ref ref=\"ROLLING\" /> -->\n  </root>\n</configuration>\n"
  },
  {
    "path": "perf-benchmark/Samples/ninja-echo-message/src/main/java/util/BodyParserEngineTextPlain.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage util;\n\nimport ninja.Context;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.inject.Singleton;\n\nimport java.io.IOException;\nimport java.io.StringWriter;\n\nimport ninja.bodyparser.BodyParserEngine;\nimport org.apache.commons.io.IOUtils;\n\n@Singleton\npublic class BodyParserEngineTextPlain implements BodyParserEngine {\n\n    private final Logger logger = LoggerFactory.getLogger(BodyParserEngineTextPlain.class);\n\n    @Override\n    public <T> T invoke(Context context, Class<T> classOfT) {\n        String result = null;\n\n        if (!classOfT.equals(String.class)) {\n            logger.error(\"Can parse text/plain only into String. Requested is a {}\", classOfT);\n            throw new RuntimeException(\"Can parse text/plain only into String.\");\n        }\n\n        try {\n            StringWriter writer = new StringWriter();\n            IOUtils.copy(context.getInputStream(), writer, \"UTF-8\");\n            result = writer.toString();\n        } catch (IOException ioException) {\n            logger.error(\"Error parsing incoming text/plain\", ioException);\n        }\n\n        return (T) result;\n    }\n\n    @Override\n    public String getContentType() {\n        return \"text/plain\";\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/spark/README.md",
    "content": "Following curl command can be used to consume this service.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/spark/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <artifactId>spark-echo-message</artifactId>\n    <version>1.0-SNAPSHOT</version>\n\n    <name>Spark Microservice Sample</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.sparkjava</groupId>\n            <artifactId>spark-core</artifactId>\n            <version>2.5</version>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <version>1.7.21</version>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-simple</artifactId>\n            <version>1.7.21</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.3</version>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>2.4.1</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <filters>\n                                <filter>\n                                    <artifact>*:*</artifact>\n                                    <excludes>\n                                        <exclude>META-INF/*.SF</exclude>\n                                        <exclude>META-INF/*.DSA</exclude>\n                                        <exclude>META-INF/*.RSA</exclude>\n                                    </excludes>\n                                </filter>\n                            </filters>\n                            <transformers>\n                                <transformer\n                                        implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                                    <mainClass>org.wso2.msf4j.perftest.echo.spark.Application</mainClass>\n                                </transformer>\n                            </transformers>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "perf-benchmark/Samples/spark/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/spark-echo-message-*\"\nstartCmd=\"java -jar $artifact\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/EchoService/fileecho\"\n\nlookFor=\"Server - Started\"\n\nwaitTimeout=15\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    cd $curDir\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/spark/src/main/java/org/wso2/msf4j/perftest/echo/spark/Application.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.spark;\n\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\n\nimport static spark.Spark.port;\nimport static spark.Spark.post;\n\n/**\n * Application\n */\npublic class Application {\n    public static void main(String[] args) throws Exception {\n        port(8080);\n        post(\"/EchoService/echo\", (req, res) -> req.body());\n        post(\"/EchoService/fileecho\", (req, res) -> {\n            Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n            Files.write(tempfile, req.bodyAsBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n            String returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n            Files.delete(tempfile);\n            return returnStr;\n        });\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/springboot/README.md",
    "content": "Following curl command can be used to consume this service.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/springboot/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <artifactId>springboot-echo-message</artifactId>\n    <version>1.0-SNAPSHOT</version>\n\n    <parent>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-starter-parent</artifactId>\n        <version>1.4.1.RELEASE</version>\n    </parent>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-web</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <start-class>org.wso2.msf4j.perftest.echo.springboot.Application</start-class>\n    </properties>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>\n"
  },
  {
    "path": "perf-benchmark/Samples/springboot/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/springboot-echo-message-*\"\nstartCmd=\"java -jar $artifact\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/EchoService/fileecho\"\n\nlookFor=\"Started Application\"\n\nwaitTimeout=15\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    cd $curDir\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/springboot/src/main/java/org/wso2/msf4j/perftest/echo/springboot/Application.java",
    "content": "package org.wso2.msf4j.perftest.echo.springboot;/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport org.springframework.boot.SpringApplication;\n\n/**\n * Application entry point\n */\npublic class Application {\n\n    public static void main(String[] args) throws Exception {\n        SpringApplication.run(EchoService.class, args);\n    }\n}"
  },
  {
    "path": "perf-benchmark/Samples/springboot/src/main/java/org/wso2/msf4j/perftest/echo/springboot/EchoService.java",
    "content": "package org.wso2.msf4j.perftest.echo.springboot;/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport org.springframework.boot.autoconfigure.EnableAutoConfiguration;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\n\n/**\n * Resource class\n */\n@Controller\n@EnableAutoConfiguration\npublic class EchoService {\n\n    @RequestMapping(\"/EchoService/echo\")\n    @ResponseBody\n    String echo(@RequestBody String body) {\n        return body;\n    }\n\n    @RequestMapping(\"/EchoService/fileecho\")\n    @ResponseBody\n    public String fileWrite(@RequestBody String body) throws InterruptedException, IOException {\n        String returnStr = \"\";\n        java.nio.file.Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n        Files.write(tempfile, body.getBytes(Charset.defaultCharset()),\n                    StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n        returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n        Files.delete(tempfile);\n        return returnStr;\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/README.md",
    "content": "Following curl command can be used to consume this service after this is deployed in wildfly server.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/wildfly-echo-message/app/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <artifactId>wildfly-echo-message</artifactId>\n    <version>1.0-SNAPSHOT</version>\n    <packaging>war</packaging>\n\n    <properties>\n        <!-- Explicitly declaring the source encoding eliminates the following message: -->\n        <!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered\n            resources, i.e. build is platform dependent! -->\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\n        <!-- JBoss dependency versions -->\n\n        <version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>\n\n        <version.jboss.spec.javaee.7.0>1.0.3.Final</version.jboss.spec.javaee.7.0>\n\n\n        <!-- other plugin versions -->\n        <version.compiler.plugin>3.1</version.compiler.plugin>\n        <version.war.plugin>2.5</version.war.plugin>\n\n        <!-- maven-compiler-plugin -->\n        <maven.compiler.target>1.8</maven.compiler.target>\n        <maven.compiler.source>1.8</maven.compiler.source>\n    </properties>\n\n    <dependencyManagement>\n        <dependencies>\n            <!-- Define the version of JBoss' Java EE 7 APIs we want to import.\n                Any dependencies from org.jboss.spec will have their version defined by this\n                BOM -->\n            <!-- JBoss distributes a complete set of Java EE 7 APIs including\n                a Bill of Materials (BOM). A BOM specifies the versions of a \"stack\" (or\n                a collection) of artifacts. We use this here so that we always get the correct\n                versions of artifacts. Here we use the jboss-javaee-7.0 stack (you can\n                read this as the JBoss stack of the Java EE 7 APIs). You can actually\n                use this stack with any version of WildFly that implements Java EE 7, not\n                just WildFly 8! -->\n            <dependency>\n                <groupId>org.jboss.spec</groupId>\n                <artifactId>jboss-javaee-7.0</artifactId>\n                <version>${version.jboss.spec.javaee.7.0}</version>\n                <type>pom</type>\n                <scope>import</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <dependencies>\n\n        <!-- Import the CDI API, we use provided scope as the API is included in JBoss WildFly -->\n        <dependency>\n            <groupId>javax.enterprise</groupId>\n            <artifactId>cdi-api</artifactId>\n            <scope>provided</scope>\n        </dependency>\n\n        <!-- Import the Common Annotations API (JSR-250), we use provided scope\n            as the API is included in JBoss WildFly -->\n        <dependency>\n            <groupId>org.jboss.spec.javax.annotation</groupId>\n            <artifactId>jboss-annotations-api_1.2_spec</artifactId>\n            <scope>provided</scope>\n        </dependency>\n\n        <!-- Import the JSON API to build JSON Objects -->\n        <dependency>\n            <groupId>org.jboss.spec.javax.json</groupId>\n            <artifactId>jboss-json-api_1.0_spec</artifactId>\n            <scope>provided</scope>\n        </dependency>\n\n        <!-- Import the JAX-RS API, we use provided scope as the API is included in JBoss WildFly -->\n        <dependency>\n            <groupId>org.jboss.spec.javax.ws.rs</groupId>\n            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <!-- Set the name of the war, used as the context root when the app\n            is deployed -->\n        <finalName>${project.artifactId}</finalName>\n        <plugins>\n            <plugin>\n                <artifactId>maven-war-plugin</artifactId>\n                <version>${version.war.plugin}</version>\n                <configuration>\n                    <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n            <!-- WildFly plugin to deploy war -->\n            <plugin>\n                <groupId>org.wildfly.plugins</groupId>\n                <artifactId>wildfly-maven-plugin</artifactId>\n                <version>${version.wildfly.maven.plugin}</version>\n            </plugin>\n            <!-- Compiler plugin enforces Java 1.6 compatibility and activates\n                annotation processors -->\n            <plugin>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>${version.compiler.plugin}</version>\n                <configuration>\n                    <source>${maven.compiler.source}</source>\n                    <target>${maven.compiler.target}</target>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <profile>\n            <!-- When built in OpenShift the 'openshift' profile will be used when invoking mvn. -->\n            <!-- Use this profile for any OpenShift specific customization your app will need. -->\n            <!-- By default that is to put the resulting archive into the 'deployments' folder. -->\n            <!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->\n            <id>openshift</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <artifactId>maven-war-plugin</artifactId>\n                        <version>${version.war.plugin}</version>\n                        <configuration>\n                            <outputDirectory>deployments</outputDirectory>\n                            <warName>ROOT</warName>\n                            <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->\n                            <failOnMissingWebXml>false</failOnMissingWebXml>\n                        </configuration>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n</project>\n\n"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/wildfly-echo-*.war\"\nstartCmd=\"$baseDir/wildfly-10.0.0.Final/bin/standalone.sh\"\nstopCmd=\"$baseDir/wildfly-10.0.0.Final/bin/jboss-cli.sh --connect command=:shutdown\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/wildfly-echo-message/app/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/wildfly-echo-message/app/EchoService/fileecho\"\n\nlookFor=\"services are lazy, passive or on-demand\"\n\nwaitTimeout=30\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n    $stopCmd\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    if [ ! -d \"wildfly-10.0.0.Final\" ]\n    then\n        if [ -f \"wildfly-10.0.0.Final.zip\" ]\n        then\n            unzip \"wildfly-10.0.0.Final.zip\"\n        else\n            if which wget >/dev/null\n            then\n                wget \"http://download.jboss.org/wildfly/10.0.0.Final/wildfly-10.0.0.Final.zip\"\n                unzip \"wildfly-10.0.0.Final.zip\"\n            else\n                echo \"couldnot find 'wget' to download wildfly server\"\n                echo \"failed to prepare wildfly sample\"\n                return\n            fi\n        fi\n    fi\n    rm -f \"wildfly-10.0.0.Final/standalone/deployments/wildfly*\"\n    cd $curDir\n    cp -v $artifact \"$baseDir/wildfly-10.0.0.Final/standalone/deployments/\"\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/src/main/java/org/wso2/msf4j/perftest/echo/wildfly/EchoService.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.wildfly;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\n\n/**\n * Resource class\n */\n@Path(\"/EchoService\")\npublic class EchoService {\n\n    @POST\n    @Path(\"echo\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String echoPost(String body) {\n        return body;\n    }\n\n    @POST\n    @Path(\"fileecho\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String fileWrite(String body) throws InterruptedException, IOException {\n        String returnStr = \"\";\n        java.nio.file.Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n        Files.write(tempfile, body.getBytes(Charset.defaultCharset()),\n                    StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n        returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n        Files.delete(tempfile);\n        return returnStr;\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/src/main/java/org/wso2/msf4j/perftest/echo/wildfly/WFApplication.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.wildfly;\n\nimport javax.ws.rs.ApplicationPath;\nimport javax.ws.rs.core.Application;\n\n/**\n * Root path\n */\n@ApplicationPath(\"app\")\npublic class WFApplication extends Application {\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/wildfly/src/main/webapp/WEB-INF/beans.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!-- Marker file indicating CDI should be enabled -->\n<beans xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"\n        http://xmlns.jcp.org/xml/ns/javaee\n        http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd\" bean-discovery-mode=\"all\">\n</beans>\n"
  },
  {
    "path": "perf-benchmark/Samples/wso2msf4j/README.md",
    "content": "Following curl command can be used to consume this service.\n\n```\ncurl -v -X POST -H \"Transfer-Encoding: chunked\" -H \"Content-Type: text/plain\" -d @1kb_rand_data.txt http://localhost:8080/EchoService/echo\n```"
  },
  {
    "path": "perf-benchmark/Samples/wso2msf4j/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.perftest.echo</groupId>\n    <artifactId>wso2msf4j-echo-message</artifactId>\n    <version>2.8.14-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>WSO2 MSF4J Microservice benchmark service</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.perftest.echo.wso2msf4j.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "perf-benchmark/Samples/wso2msf4j/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\n\nartifact=\"$baseDir/target/wso2msf4j-echo-message-*\"\nstartCmd=\"java -jar $artifact\"\n\nendpoints=\"\"\nendpoints+=\"Echo->http://localhost:8080/EchoService/echo,\"\nendpoints+=\"File-Read-Write->http://localhost:8080/EchoService/fileecho\"\n\nlookFor=\"Microservices server started\"\n\nwaitTimeout=15\n\nserverLog=\"$baseDir/server.log\"\npidFile=\"$baseDir/pid\"\n\nfunction waitFor(){\n    local waitTime=0\n    while true\n    do\n        if [ $(tail \"$serverLog\" | grep \"$lookFor\" | wc -l) -gt 0 ]\n        then\n            echo true\n            return\n        fi\n        sleep 1\n        ((waitTime++))\n        if [ $waitTime -gt $waitTimeout ]\n        then\n            echo false\n            return\n        fi\n    done\n}\n\nfunction start(){\n    stop\n    nohup $startCmd > \"$serverLog\" &\n    local pid=$!\n    echo $pid > \"$pidFile\"\n    local ret=$(waitFor)\n    if [ $ret = \"false\" ]\n    then\n        echo \"Unable to start server within $waitTimeout\"\n        stop\n    else\n        echo \"Server started @ $pid\"\n    fi\n}\n\nfunction stop(){\n    if [ -f \"$pidFile\" ]\n    then\n        local pid=$(cat \"$pidFile\")\n        kill -9 $pid\n        echo \"Killed server @ $pid\"\n        rm -f \"$pidFile\"\n    fi\n    rm -f \"$serverLog\"\n}\n\nfunction getEndpoints(){\n    echo \"$endpoints\"\n}\n\nfunction buildSample(){\n    local curDir=$(pwd)\n    cd $baseDir\n    mvn clean package\n    cd $curDir\n}\n\nif [ \"$1\" = \"start\" ]\nthen\n    start\nelif [ \"$1\" = \"stop\" ]\nthen\n    stop\n    echo \"Waiting for server termination\"\n    sleep 1\nelif [ \"$1\" = \"endpoints\" ]\nthen\n    getEndpoints\nelif [ \"$1\" = \"build\" ]\nthen\n    buildSample\nfi\n"
  },
  {
    "path": "perf-benchmark/Samples/wso2msf4j/src/main/java/org/wso2/msf4j/perftest/echo/wso2msf4j/Application.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.wso2msf4j;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point\n */\npublic class Application {\n\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new EchoService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/Samples/wso2msf4j/src/main/java/org/wso2/msf4j/perftest/echo/wso2msf4j/EchoService.java",
    "content": "/*\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.msf4j.perftest.echo.wso2msf4j;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.StandardOpenOption;\nimport java.util.UUID;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\n\n/*\n * EchoService resource class\n */\n@Path(\"/EchoService\")\npublic class EchoService {\n\n    @POST\n    @Path(\"echo\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String echo(String body) {\n        return body;\n    }\n\n    @POST\n    @Path(\"fileecho\")\n    @Consumes(\"text/plain\")\n    @Produces(\"text/plain\")\n    public String fileWrite(String body) throws InterruptedException, IOException {\n        String returnStr = \"\";\n        java.nio.file.Path tempfile = Files.createTempFile(UUID.randomUUID().toString(), \".tmp\");\n        Files.write(tempfile, body.getBytes(Charset.defaultCharset()), StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n        returnStr = new String(Files.readAllBytes(tempfile), Charset.defaultCharset());\n        Files.delete(tempfile);\n        return returnStr;\n    }\n}\n"
  },
  {
    "path": "perf-benchmark/excecute-tests.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\nconcLevels=\"1 25 50 100 200 400 800 1600 3200\"\nperTestTime=30\ntestLoops=1000000\nwarmUpConc=200\nwarmUpLoop=50000\n\ntmpDir=\"$baseDir/tmpData\"\nvendorsLoc=\"$baseDir/Samples\"\npayload=\"$baseDir/1kb_rand_data.txt\"\ntimeStmp=$(date +%s)\n\ntypes=()\ndeclare -A MAP\n\nfunction printResultStructures(){\n    echo \"Printing types..\"\n    for type in ${types[@]}\n    do\n        echo \"$type\"\n    done\n    echo \"\"\n    echo \"Printing results map..\"\n    for key in ${!MAP[@]}\n    do\n      echo \"$key -> ${MAP[$key]}\"\n    done\n}\n\nfunction hash(){\n    echo -n $1 | md5sum | awk '{print $1}'\n}\n\nfunction addNewType(){\n    local newType=$1\n    local isNew=true\n    local type=\"\"\n    for type in ${types[@]}\n    do\n        if [ \"$type\" = \"$newType\" ]\n        then\n            isNew=false\n            break\n        fi\n    done\n    if \"$isNew\"\n    then\n        types+=($newType)\n    fi\n}\n\nfunction addNewVendor(){\n    local type=$1\n    local vendor=$2\n    if [ ${MAP[\"$type-vendor-n\"]} ]\n    then\n        local vendorN=${MAP[\"$type-vendor-n\"]}\n        MAP[\"$type-vendor-$vendorN\"]=\"$vendor\"\n        MAP[\"$type-vendor-n\"]=$((vendorN+1))\n    else\n        MAP[\"$type-vendor-0\"]=\"$vendor\"\n        MAP[\"$type-vendor-n\"]=1\n    fi\n}\n\nfunction processResults(){\n    local metric=$1\n    local resultsFile=$2\n    local type=\"\"\n    local vendorI=0\n    local conc=\"\"\n\n    rm -f \"$resultsFile\"\n\n    for type in \"${types[@]}\"\n    do\n        echo \"Test: $type,\" >> \"$resultsFile\"\n        local isPrintH=true\n        for conc in $concLevels\n        do\n            local header=\"\"\n            if \"$isPrintH\"\n            then\n                header=\"Concurrency\"\n            fi\n            local line=\"$conc\"\n            for vendorI in $(seq 0 $((MAP[\"$type-vendor-n\"]-1)))\n            do\n                local vendor=${MAP[\"$type-vendor-$vendorI\"]}\n                if \"$isPrintH\"\n                then\n                    header+=\", $vendor\"\n                fi\n                local tps=${MAP[\"$type-$vendor-$conc-$metric\"]}\n                line+=\", $tps\"\n            done\n            if \"$isPrintH\"\n            then\n                echo \"$header\" >> \"$resultsFile\"\n                isPrintH=false\n            fi\n            echo \"$line\" >> \"$resultsFile\"\n        done\n        echo \"\" >> \"$resultsFile\"\n    done\n    echo \"===========================================\"\n    echo \"            Results ($metric)              \"\n    echo \"===========================================\"\n    cat \"$resultsFile\"\n}\n\nfunction processPercentiles(){\n    local resultsFile=$1\n    local type=\"\"\n    local vendorI=0\n    local conc=\"\"\n\n    rm -f \"$resultsFile\"\n\n    local header=\"Vendor, Concurrency\"\n    for hVal in $(seq 0 100)\n    do\n        header+=\", $hVal\"\n    done\n\n    for type in \"${types[@]}\"\n    do\n        echo \"Test: $type,\" >> \"$resultsFile\"\n        for conc in $concLevels\n        do\n            local isPrintH=true\n            for vendorI in $(seq 0 $((MAP[\"$type-vendor-n\"]-1)))\n            do\n                local vendor=${MAP[\"$type-vendor-$vendorI\"]}\n                local percents=${MAP[\"$type-$vendor-$conc-percents\"]}\n                if \"$isPrintH\"\n                then\n                    echo \"$header\" >> \"$resultsFile\"\n                    isPrintH=false\n                fi\n                echo \"$percents\" >> \"$resultsFile\"\n            done\n            echo \"\" >> \"$resultsFile\"\n        done\n    done\n    echo \"===========================================\"\n    echo \"            Results (Percentiles)              \"\n    echo \"===========================================\"\n    cat \"$resultsFile\"\n}\n\nfunction warmUp(){\n    local service=$1\n    echo \"Warm up service $service\"\n    ab -k -p \"$payload\" -c $warmUpConc -n $warmUpLoop -H \"Accept:text/plain\" \"$service\" > /dev/null\n}\n\nfunction testConcLevel(){\n    local service=$1\n    local concLevel=$2\n    local type=$3\n    local vendor=$4\n\n    local resOut=\"$tmpDir/result-$type-$vendor-conc$concLevel-rep$loopRep-loops$testLoops-time$timeStmp-$(uuidgen)\"\n    local percentOut=\"$tmpDir/percentile-$type-$vendor-conc$concLevel-rep$loopRep-loops$testLoops-time$timeStmp-$(uuidgen)\"\n    echo \"Testing service: $service\"\n    echo \"Testing concurrency $concLevel at $resOut\"\n    ab -t \"$perTestTime\" -n \"$testLoops\" -c \"$concLevel\" -H \"Accept:text/plain\" -p \"$payload\" -k -e \"$percentOut\" \"$service\" > \"$resOut\"\n\n    local tps=$(cat \"$resOut\" | grep -Eo \"Requests per second.*\" | grep -Eo \"[0-9]+\" | head -1)\n\n    local meanLat=$(cat \"$resOut\" | grep -Eo \"Time per request.*\\(mean\\)\" | grep -Eo \"[0-9]+(\\.[0-9]+)?\")\n\n    local percents=$(cat \"$percentOut\" | grep -Eo \",.*\" | grep -Eo \"[0-9]+(\\.[0-9]+)?\" | tr '\\n' ',')\n    percents=\"$vendor, $concLevel, $percents\"\n\n    echo \"For $service at concurrency $concLevel\"\n\n    MAP[\"$type-$vendor-$concLevel-tps\"]=$tps\n    echo -e \"\\tThroughput $tps\"\n\n    MAP[\"$type-$vendor-$concLevel-meanLat\"]=$meanLat\n    echo -e \"\\tMean latency is $meanLat\"\n\n    MAP[\"$type-$vendor-$concLevel-percents\"]=$percents\n    echo -e \"\\tPercentiles are $percents\"\n}\n\nfunction iterateConcLevels(){\n    local vendorDir=$1\n    local type=$2\n    local vendor=$3\n    local service=$4\n    echo \"Testing concurrency levels in $vendorDir\"\n    warmUp \"$service\" # Warm up the service before getting results\n    local concLevel=\"\"\n    for concLevel in $concLevels\n    do\n        testConcLevel \"$service\" \"$concLevel\" \"$type\" \"$vendor\"\n    done\n}\n\nfunction iterateVendors(){\n    local vendors=$(ls \"$1\")\n    local type=\"\"\n    local vendor=\"\"\n    for vendor in $vendors\n    do\n        local vendorDir=\"$1/$vendor\"\n        if [ -f \"$vendorDir/run.sh\" ]\n        then\n            local startState=$($vendorDir/run.sh \"start\")\n            if [[ \"$startState\" = *\"Server started\"* ]]\n            then\n                echo \"Server started in $vendorDir\"\n                local endpoints=$($vendorDir/run.sh \"endpoints\")\n                endpoints=${endpoints//\",\"/\" \"}\n                for endpoint in $endpoints\n                do\n                    endpoint=(${endpoint//\"->\"/\" \"})\n                    local type=${endpoint[0]}\n                    local service=${endpoint[1]}\n                    addNewType \"$type\"\n                    addNewVendor \"$type\" \"$vendor\"\n                    iterateConcLevels \"$vendorDir\" \"$type\" \"$vendor\" \"$service\"\n                done\n                $vendorDir/run.sh \"stop\"\n            else\n                echo \"Server not started in $vendorDir\"\n            fi\n        fi\n    done\n\n    processResults \"tps\" \"$baseDir/results-tps.csv\"\n    echo \"\"\n    processResults \"meanLat\" \"$baseDir/results-latency.csv\"\n    echo \"\"\n    processPercentiles \"$baseDir/results-percentiles.csv\"\n    echo \"\"\n    #printResultStructures\n}\n\nmkdir -p \"$tmpDir\"\nbase64 /dev/urandom | head -c 1024 > \"$payload\"\n\niterateVendors \"$vendorsLoc\""
  },
  {
    "path": "perf-benchmark/run-latency.sh",
    "content": "#!/bin/bash\n\nservice=$1\nfileName=\"\"\nif [ -z $2 ]; then\n    fileName=\"latency-results.csv\"\nelse\n    fileName=\"latency-results-$2.csv\"\nfi\n\necho \"Running test for: $service\"\n\nbase64 /dev/urandom | head -c 1024 > 1kb_rand_data.txt\n\nrm $fileName\necho min, mean, [+/-sd], median, max, 66%, 75%, 80%, 90%, 95%, 98%, 99% >> $fileName\nfor i in 1 2 3\n    do\nfor i in 1 25 50 100 200 400 800 1600 3200\n    do\n        echo start concurrency $i on $(date)\n        val=$(ab -k -p 1kb_rand_data.txt -c $i -n 500000 -H \"Accept:text/plain\" $service \\\n        | pcregrep -M \"Total:.*(\\n|.)* 100%\" \\\n        | sed '4d' \\\n        | sed '11d' \\\n        | sed '2,3d' \\\n        | sed -r 's/\\Total:\\s*//' \\\n        | sed -r 's/[0-9]{1,10}%\\s*//' \\\n        | xargs \\\n        | tr ' ' ','/)\n       # echo \"Latency information for concurrency level $i\" >> $fileName\n        echo \"$val\" >> $fileName\n       # echo \"\\n\" >> $fileName\n        echo \"waiting for 5sec...\"\n        sleep 5\ndone\ndone\necho\necho ==================\necho =  Latency Info  =\necho ==================\necho\ncat $fileName\n"
  },
  {
    "path": "perf-benchmark/run.sh",
    "content": "#!/usr/bin/env bash\n\nbaseDir=$(dirname \"$0\")\nvendorsLoc=\"$baseDir/Samples\"\n\nfunction cleanup(){\n    local vendors=$(ls \"$vendorsLoc\")\n    local type=\"\"\n    local vendor=\"\"\n    for vendor in $vendors\n    do\n        local vendorDir=\"$vendorsLoc/$vendor\"\n        if [ -f \"$vendorDir/run.sh\" ]\n        then\n            local pidFile=$vendorDir/pid\n            if [ -f $pidFile ]\n            then\n                $vendorDir/run.sh \"stop\"\n            fi\n        fi\n    done\n}\n\nfunction buildSamples(){\n    local vendors=$(ls \"$vendorsLoc\")\n    local type=\"\"\n    local vendor=\"\"\n    for vendor in $vendors\n    do\n        local vendorDir=\"$vendorsLoc/$vendor\"\n        if [ -f \"$vendorDir/run.sh\" ]\n        then\n            $vendorDir/run.sh \"build\"\n        fi\n    done\n}\n\nif [ \"$1\" = \"build\" ]\nthen\n    cleanup\n    buildSamples\nelse\n    cleanup\n    $baseDir/excecute-tests.sh\nfi\n\nif [ ! \"$?\" = 0 ]\nthen\n    echo \"Test were not completed successfully\"\n    echo \"Cleaning up..\"\n    cleanup\nfi"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2</groupId>\n        <artifactId>wso2</artifactId>\n        <version>5.3</version>\n        <relativePath />\n    </parent>\n\n    <groupId>org.wso2.msf4j</groupId>\n    <artifactId>msf4j</artifactId>\n    <packaging>pom</packaging>\n    <version>2.8.14-SNAPSHOT</version>\n\n    <scm>\n        <url>https://github.com/wso2/msf4j.git</url>\n        <developerConnection>scm:git:https://github.com/wso2/msf4j.git</developerConnection>\n        <connection>scm:git:https://github.com/wso2/msf4j.git</connection>\n        <tag>HEAD</tag>\n    </scm>\n\n    <developers>\n        <developer>\n            <name>WSO2</name>\n            <email>architecture@wso2.org</email>\n            <organization>WSO2 Inc</organization>\n            <organizationUrl>https://github.com/wso2/msf4j</organizationUrl>\n        </developer>\n    </developers>\n\n    <build>\n        <extensions>\n            <extension>\n                <groupId>org.apache.maven.wagon</groupId>\n                <artifactId>wagon-ssh</artifactId>\n            </extension>\n        </extensions>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n                <version>${maven.checkstyleplugin.version}</version>\n            </plugin>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>findbugs-maven-plugin</artifactId>\n                <version>${maven.findbugsplugin.version}</version>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-release-plugin</artifactId>\n                <configuration>\n                    <preparationGoals>clean install</preparationGoals>\n                    <autoVersionSubmodules>true</autoVersionSubmodules>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <id>docs</id>\n                        <phase>compile</phase>\n                        <goals>\n                            <goal>javadoc</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <modules>\n        <module>poms/parent</module>\n        <module>jaxrs-delegates</module>\n        <module>core</module>\n        <module>swagger</module>\n        <module>spring</module>\n        <module>deployer</module>\n        <module>poms/msf4j-service</module>\n        <module>analytics/msf4j-analytics</module>\n        <module>analytics/msf4j-analytics-common</module>\n        <module>analytics/wso2das-tracing-capp</module>\n        <module>analytics/zipkin-tracing</module>\n\n        <module>client</module>\n\n        <module>templating/msf4j-mustache-template</module>\n        <module>archetypes/msf4j-microservice</module>\n        <!-- Distribution -->\n        <module>distribution/msf4j-all</module>\n        <module>distribution/binary</module>\n        <module>features/org.wso2.msf4j.feature</module>\n        <module>features/org.wso2.msf4j.deployer.feature</module>\n        <!-- MSF4J Samples -->\n        <module>samples/helloworld</module>\n        <module>samples/formparam</module>\n        <module>samples/http-session</module>\n        <module>samples/stockquote/fatjar</module>\n        <module>samples/stockquote/bundle</module>\n        <module>samples/stockquote/deployable-jar</module>\n        <module>samples/basicauth-security</module>\n        <module>samples/oauth2-security</module>\n        <module>samples/metrics</module>\n        <module>samples/http-monitoring</module>\n        <module>samples/petstore</module>\n        <module>samples/fileserver</module>\n        <module>samples/template</module>\n        <module>samples/lifecycle</module>\n        <module>samples/jwt-claims</module>\n        <module>samples/spring-helloworld</module>\n        <module>samples/jpa</module>\n        <module>samples/circuitbreaker</module>\n        <module>samples/regex-pathparam</module>\n        <module>samples/message-tracing/das/</module>\n        <module>samples/message-tracing/zipkin/</module>\n        <module>samples/subresource</module>\n        <module>samples/spring-profile</module>\n        <module>samples/interceptor/interceptor-common</module>\n        <module>samples/interceptor/fatjar-interceptor-service</module>\n        <module>samples/interceptor/deployable-jar-interceptor-service</module>\n        <module>samples/interceptor/osgi-interceptor-service</module>\n        <module>samples/websocket/chatApp/bundle</module>\n        <module>samples/websocket/chatApp/deployable-jar</module>\n        <module>samples/websocket/chatApp/fatjar</module>\n\n        <module>perf-benchmark/Samples/wso2msf4j</module>\n        <module>tests</module>\n    </modules>\n\n    <properties>\n        <maven.checkstyleplugin.version>2.16</maven.checkstyleplugin.version>\n        <maven.findbugsplugin.version>3.0.2</maven.findbugsplugin.version>\n    </properties>\n</project>\n"
  },
  {
    "path": "poms/msf4j-service/README.md",
    "content": "# WSO2 MSF4J - Parent POM for Microservices\n\nThis parent POM file makes life easy for developers who write microservices using WSO2 MSF4J. The following example\nfrom the [stockquote-fatjar](../samples/stockquote/fatjar) example demonstrates how to quickly write a POM for your \nmicroservice using the MSF4J Service Parent POM. Please see [archtypes](../../archetypes) for easily creating an \nMSF4J project using archtypes.\n\n```xml\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../../msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.example</groupId>\n    <artifactId>stockquote-fatjar</artifactId>\n    <packaging>jar</packaging>\n\n    <name>StockQuote Service</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.StockQuoteService</microservice.mainClass>\n    </properties>\n</project>\n```\n\nThe microservice.mainClass Maven property should be used to define your main class. i.e. the class that includes\nthe main method.\n\n\n\n"
  },
  {
    "path": "poms/msf4j-service/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j</groupId>\n    <artifactId>msf4j-service</artifactId>\n    <packaging>pom</packaging>\n    <version>2.8.14-SNAPSHOT</version>\n\n    <name>MSF4J-Parent</name>\n\n    <description>\n        Parent POM for WSO2 MSF4J Microservices\n    </description>\n    <url>http://www.wso2.org/</url>\n    <organization>\n        <name>WSO2</name>\n        <url>http://www.wso2.org/</url>\n    </organization>\n    <licenses>\n        <license>\n            <name>The Apache Software License, Version 2.0</name>\n            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n        </license>\n    </licenses>\n\n    <developers>\n        <developer>\n            <name>WSO2 Developer</name>\n            <email>dev@wso2.org</email>\n            <organization>WSO2</organization>\n            <organizationUrl>http://www.wso2.org/</organizationUrl>\n        </developer>\n    </developers>\n\n    <repositories>\n        <!-- WSO2 released artifact repository -->\n        <repository>\n            <id>wso2.releases</id>\n            <name>WSO2 Releases Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/releases/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </repository>\n\n        <!-- WSO2 Snapshot artifact repository -->\n        <repository>\n            <id>wso2.snapshots</id>\n            <name>WSO2 Snapshot Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>\n            <snapshots>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n            </snapshots>\n            <releases>\n                <enabled>false</enabled>\n            </releases>\n        </repository>\n\n        <repository>\n            <id>wso2-nexus</id>\n            <name>WSO2 internal Repository</name>\n            <url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </repository>\n    </repositories>\n\n    <pluginRepositories>\n        <pluginRepository>\n            <id>wso2.releases</id>\n            <name>WSO2 Releases Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/releases/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </pluginRepository>\n\n        <pluginRepository>\n            <id>wso2.snapshots</id>\n            <name>WSO2 Snapshot Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>\n            <snapshots>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n            </snapshots>\n            <releases>\n                <enabled>false</enabled>\n            </releases>\n        </pluginRepository>\n\n        <pluginRepository>\n            <id>wso2-nexus</id>\n            <name>WSO2 internal Repository</name>\n            <url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </pluginRepository>\n    </pluginRepositories>\n\n    <distributionManagement>\n        <repository>\n            <id>nexus-releases</id>\n            <name>WSO2 Nexus Release Repository</name>\n            <url>https://maven.wso2.org/nexus/service/local/staging/deploy/maven2/</url>\n        </repository>\n        <snapshotRepository>\n            <id>wso2.snapshots</id>\n            <name>WSO2 Snapshot Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>\n        </snapshotRepository>\n    </distributionManagement>\n\n    <mailingLists>\n        <mailingList>\n            <name>WSO2 Dev List</name>\n            <subscribe>dev-request@wso2.org</subscribe>\n            <unsubscribe>dev-request@wso2.org</unsubscribe>\n            <post>dev@wso2.org</post>\n            <archive>http://mail.wso2.org/mailarchive/dev/</archive>\n        </mailingList>\n    </mailingLists>\n\n    <scm>\n        <connection>scm:git:https://github.com/wso2/carbon-parent.git</connection>\n        <url>https://github.com/wso2/carbon-parent.git</url>\n        <developerConnection>scm:git:https://github.com/wso2/carbon-parent.git</developerConnection>\n        <tag>carbon-parent-4</tag>\n    </scm>\n\n    <build>\n        <extensions>\n            <extension>\n                <groupId>org.apache.maven.wagon</groupId>\n                <artifactId>wagon-ssh</artifactId>\n                <version>${maven.wagon.ssh.version}</version>\n            </extension>\n        </extensions>\n        <pluginManagement>\n            <plugins>\n                <!-- set versions of common plugins for reproducibility, ordered alphabetically -->\n                <plugin>\n                    <groupId>org.apache.felix</groupId>\n                    <artifactId>maven-bundle-plugin</artifactId>\n                    <version>${maven.bundle.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-antrun-plugin</artifactId>\n                    <version>${maven.antrun.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-assembly-plugin</artifactId>\n                    <version>${maven.assembly.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-checkstyle-plugin</artifactId>\n                    <version>${maven.checkstyleplugin.version}</version>\n                    <executions>\n                        <execution>\n                            <id>validate</id>\n                            <phase>validate</phase>\n                            <configuration>\n                                <configLocation>\n                                    https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/checkstyle.xml\n                                </configLocation>\n                                <suppressionsLocation>\n                                    https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/suppressions.xml\n                                </suppressionsLocation>\n                                <encoding>UTF-8</encoding>\n                                <consoleOutput>true</consoleOutput>\n                                <failsOnError>true</failsOnError>\n                                <includeTestSourceDirectory>true</includeTestSourceDirectory>\n                                <!--Exclude sources-->\n                                <excludes>${maven.checkstyleplugin.excludes}</excludes>\n                            </configuration>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-clean-plugin</artifactId>\n                    <version>${maven.clean.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-compiler-plugin</artifactId>\n                    <version>${maven.compiler.plugin.version}</version>\n                    <configuration>\n                        <source>${wso2.maven.compiler.source}</source>\n                        <target>${wso2.maven.compiler.target}</target>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-dependency-plugin</artifactId>\n                    <version>${maven.dependency.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-deploy-plugin</artifactId>\n                    <version>${maven.deploy.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-docck-plugin</artifactId>\n                    <version>${maven.docck.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-enforcer-plugin</artifactId>\n                    <version>${maven.enforcer.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-failsafe-plugin</artifactId>\n                    <version>${maven.failsafe.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-gpg-plugin</artifactId>\n                    <version>${maven.gpg.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-install-plugin</artifactId>\n                    <version>${maven.install.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-invoker-plugin</artifactId>\n                    <version>${maven.invoker.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-jar-plugin</artifactId>\n                    <version>${maven.jar.plugin.version}</version>\n                    <configuration>\n                        <archive>\n                            <manifest>\n                                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>\n                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>\n                            </manifest>\n                        </archive>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-javadoc-plugin</artifactId>\n                    <version>${maven.javadoc.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-plugin-plugin</artifactId>\n                    <version>${maven.plugin.plugin.version}</version>\n                </plugin>\n                <!-- START SNIPPET: release-plugin-configuration -->\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-release-plugin</artifactId>\n                    <version>${maven.release.plugin.version}</version>\n                </plugin>\n                <!-- END SNIPPET: release-plugin-configuration -->\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-remote-resources-plugin</artifactId>\n                    <version>${maven.remote.resources.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-resources-plugin</artifactId>\n                    <version>${maven.resources.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-scm-plugin</artifactId>\n                    <version>${maven.scm.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-scm-publish-plugin</artifactId>\n                    <version>${maven.scm.publish.plugin.version}</version>\n                    <!-- last version compatible with Maven 2: latest is configured in profile -->\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-site-plugin</artifactId>\n                    <version>${maven.site.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-source-plugin</artifactId>\n                    <version>${maven.source.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-surefire-plugin</artifactId>\n                    <version>${maven.surefire.plugin.version}</version>\n                    <!-- keep maven-failsafe-plugin in sync -->\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.rat</groupId>\n                    <artifactId>apache-rat-plugin</artifactId>\n                    <version>${apache.rat.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.codehaus.mojo</groupId>\n                    <artifactId>buildnumber-maven-plugin</artifactId>\n                    <version>${maven.buildnumber.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.codehaus.mojo</groupId>\n                    <artifactId>clirr-maven-plugin</artifactId>\n                    <version>${clirr.maven.plugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.codehaus.mojo</groupId>\n                    <artifactId>findbugs-maven-plugin</artifactId>\n                    <version>${maven.findbugsplugin.version}</version>\n                    <configuration>\n                        <effort>Max</effort>\n                        <threshold>Low</threshold>\n                        <xmlOutput>true</xmlOutput>\n                        <findbugsXmlOutputDirectory>${project.build.directory}/findbugs</findbugsXmlOutputDirectory>\n                        <!--Exclude sources-->\n                        <excludeFilterFile>${mavan.findbugsplugin.exclude.file}</excludeFilterFile>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <id>analyze-compile</id>\n                            <phase>compile</phase>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-shade-plugin</artifactId>\n                    <version>${maven.shadeplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.skife.maven</groupId>\n                    <artifactId>really-executable-jar-maven-plugin</artifactId>\n                    <version>${maven.reallyexecutablejarplugin.version}</version>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n                <extensions>${maven.bundle.plugin.extensions}</extensions>\n                <configuration>\n                    <obrRepository>NONE</obrRepository>\n                    <instructions>\n                        <Bundle-Activator>${bundle.activator}</Bundle-Activator>\n                        <Bundle-ActivationPolicy>${bundle.activation.policy}</Bundle-ActivationPolicy>\n                        <Bundle-ClassPath>${bundle.classpath}</Bundle-ClassPath>\n                        <Bundle-Contributors>${bundle.contributors}</Bundle-Contributors>\n                        <Bundle-Copyright>WSO2 Inc</Bundle-Copyright>\n                        <Bundle-Description>${project.description}</Bundle-Description>\n                        <Bundle-Developers>${bundle.developers}</Bundle-Developers>\n                        <Bundle-DocURL>${bundle.docurl}</Bundle-DocURL>\n                        <Bundle-License>http://www.apache.org/licenses/LICENSE-2.0.txt</Bundle-License>\n                        <Bundle-Name>${bundle.name}</Bundle-Name>\n                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>\n                        <Bundle-Vendor>WSO2 Inc</Bundle-Vendor>\n                        <Conditional-Package>${conditional.package}</Conditional-Package>\n                        <DynamicImport-Package>${dynamic.import.package}</DynamicImport-Package>\n                        <Export-Package>${export.package}</Export-Package>\n                        <Fragment-Host>${fragment.host}</Fragment-Host>\n                        <Import-Package>${import.package}</Import-Package>\n                        <Meta-Persistence>${meta.persistence}</Meta-Persistence>\n                        <Private-Package>${private.package}</Private-Package>\n                        <Provide-Capability>${provide.capability}</Provide-Capability>\n                        <Require-Bundle>${require.bundle}</Require-Bundle>\n                        <Require-Capability>${require.capability}</Require-Capability>\n                        <Service-Component>${service.component}</Service-Component>\n                        <Microservices>${microservices}</Microservices>\n                        <_dsannotations>${dsannotations}</_dsannotations>\n                        <Startup-Component>${startup.component}</Startup-Component>\n                        <_include>${_include}</_include>\n                        <SCM-Revision>${buildNumber}</SCM-Revision>\n                    </instructions>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>buildnumber-maven-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <phase>validate</phase>\n                        <goals>\n                            <goal>create</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <doCheck>false</doCheck>\n                    <doUpdate>false</doUpdate>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                        <configuration>\n                            <filters>\n                                <filter>\n                                    <artifact>*:*</artifact>\n                                    <excludes>\n                                        <exclude>META-INF/*.SF</exclude>\n                                        <exclude>META-INF/*.DSA</exclude>\n                                        <exclude>META-INF/*.RSA</exclude>\n                                    </excludes>\n                                </filter>\n                            </filters>\n                            <transformers>\n                                <transformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                                    <mainClass>${microservice.mainClass}</mainClass>\n                                </transformer>\n                                <transformer implementation=\"org.apache.maven.plugins.shade.resource.ServicesResourceTransformer\" />\n                            </transformers>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-core</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-analytics</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-swagger</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>zipkin-tracing</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-client</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>com.nimbusds</groupId>\n                    <artifactId>nimbus-jose-jwt</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi.services</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.launcher</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.google.code.findbugs</groupId>\n                    <artifactId>jsr305</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>commons-pool</groupId>\n                    <artifactId>commons-pool</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.runtime.feature</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.kernel.feature</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <!-- Maven plugin versions -->\n        <maven.antrun.plugin.version>1.8</maven.antrun.plugin.version>\n        <maven.assembly.plugin.version>3.0</maven.assembly.plugin.version>\n        <maven.clean.plugin.version>3.0.0</maven.clean.plugin.version>\n        <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>\n        <maven.dependency.plugin.version>2.10</maven.dependency.plugin.version>\n        <maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version>\n        <maven.docck.plugin.version>1.1</maven.docck.plugin.version>\n        <maven.enforcer.plugin.version>1.4.1</maven.enforcer.plugin.version>\n        <maven.failsafe.plugin.version>2.19.1</maven.failsafe.plugin.version>\n        <maven.gpg.plugin.version>1.6</maven.gpg.plugin.version>\n        <maven.install.plugin.version>2.5.2</maven.install.plugin.version>\n        <maven.invoker.plugin.version>2.0.0</maven.invoker.plugin.version>\n        <maven.jar.plugin.version>2.6</maven.jar.plugin.version>\n        <maven.javadoc.plugin.version>2.10.3</maven.javadoc.plugin.version>\n        <maven.plugin.plugin.version>3.4</maven.plugin.plugin.version>\n        <maven.remote.resources.plugin.version>1.5</maven.remote.resources.plugin.version>\n        <maven.release.plugin.version>2.5.3</maven.release.plugin.version>\n        <maven.resources.plugin.version>2.7</maven.resources.plugin.version>\n        <maven.scm.plugin.version>1.9.4</maven.scm.plugin.version>\n        <maven.scm.publish.plugin.version>1.1</maven.scm.publish.plugin.version>\n        <maven.site.plugin.version>3.5</maven.site.plugin.version>\n        <maven.source.plugin.version>3.0.0</maven.source.plugin.version>\n        <maven.surefire.plugin.version>2.19.1</maven.surefire.plugin.version>\n        <apache.rat.plugin.version>0.11</apache.rat.plugin.version>\n        <clirr.maven.plugin.version>2.7</clirr.maven.plugin.version>\n        <apache.source.release.assembly.descriptor.version>1.0.5</apache.source.release.assembly.descriptor.version>\n        <maven.checkstyleplugin.version>2.17</maven.checkstyleplugin.version>\n        <maven.findbugsplugin.version>3.0.3</maven.findbugsplugin.version>\n        <maven.buildnumber.plugin.version>1.4</maven.buildnumber.plugin.version>\n        <maven.shadeplugin.version>2.4.1</maven.shadeplugin.version>\n        <maven.reallyexecutablejarplugin.version>1.5.0</maven.reallyexecutablejarplugin.version>\n        <feign.version>9.3.1</feign.version>\n\n        <!-- Other dependency versions -->\n        <maven.wagon.ssh.version>2.10</maven.wagon.ssh.version>\n\n        <msf4j.version>2.8.14-SNAPSHOT</msf4j.version>\n\n        <wso2.maven.compiler.source>1.8</wso2.maven.compiler.source>\n        <wso2.maven.compiler.target>1.8</wso2.maven.compiler.target>\n        <sourceReleaseAssemblyDescriptor>source-release</sourceReleaseAssemblyDescriptor>\n        <project.scm.id>my-scm-server</project.scm.id>\n\n        <!--Maven bundle plugin configuration -->\n        <maven.bundle.plugin.version>3.0.1</maven.bundle.plugin.version>\n        <maven.bundle.plugin.vendor>WSO2 Inc</maven.bundle.plugin.vendor>\n        <maven.bundle.plugin.extensions>true</maven.bundle.plugin.extensions>\n        <bundle.classpath>.</bundle.classpath>\n        <dsannotations>*</dsannotations>\n        <bundle.contributors>WSO2 Inc</bundle.contributors>\n        <bundle.developers>WSO2 Inc</bundle.developers>\n        <bundle.docurl>https://docs.wso2.com</bundle.docurl>\n        <bundle.name>${project.artifactId}</bundle.name>\n        <import.package>*</import.package>\n    </properties>\n</project>\n"
  },
  {
    "path": "poms/parent/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2</groupId>\n        <artifactId>wso2</artifactId>\n        <version>5.3</version>\n        <relativePath />\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j</groupId>\n    <artifactId>msf4j-parent</artifactId>\n    <packaging>pom</packaging>\n    <version>2.8.14-SNAPSHOT</version>\n    <name>WSO2 MSF4J - Parent Pom</name>\n    <description>WSO2 MSF4J Parent Pom</description>\n    <url>http://wso2.org</url>\n\n    <prerequisites>\n        <maven>3.0.0</maven>\n    </prerequisites>\n\n    <pluginRepositories>\n        <pluginRepository>\n            <id>wso2-nexus</id>\n            <name>WSO2 internal Repository</name>\n            <url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </pluginRepository>\n    </pluginRepositories>\n\n    <build>\n        <extensions>\n            <extension>\n                <groupId>org.apache.maven.wagon</groupId>\n                <artifactId>wagon-ssh</artifactId>\n                <version>${maven.wagon.ssh.version}</version>\n            </extension>\n            <extension>\n                <groupId>org.apache.maven.archetype</groupId>\n                <artifactId>archetype-packaging</artifactId>\n                <version>${maven.archetype.version}</version>\n            </extension>\n        </extensions>\n        <pluginManagement>\n            <plugins>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-checkstyle-plugin</artifactId>\n                    <version>${maven.checkstyleplugin.version}</version>\n                    <executions>\n                        <execution>\n                            <id>validate</id>\n                            <phase>validate</phase>\n                            <configuration>\n                                <configLocation>\n                                    https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/checkstyle.xml\n                                </configLocation>\n                                <suppressionsLocation>\n                                    https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/suppressions.xml\n                                </suppressionsLocation>\n                                <encoding>UTF-8</encoding>\n                                <consoleOutput>true</consoleOutput>\n                                <failsOnError>true</failsOnError>\n                                <includeTestSourceDirectory>true</includeTestSourceDirectory>\n                            </configuration>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin>\n                    <groupId>org.codehaus.mojo</groupId>\n                    <artifactId>findbugs-maven-plugin</artifactId>\n                    <version>${maven.findbugsplugin.version}</version>\n                    <configuration>\n                        <effort>Max</effort>\n                        <threshold>Low</threshold>\n                        <xmlOutput>true</xmlOutput>\n                        <findbugsXmlOutputDirectory>${project.build.directory}/findbugs</findbugsXmlOutputDirectory>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <id>analyze-compile</id>\n                            <phase>compile</phase>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-compiler-plugin</artifactId>\n                    <version>${maven.compilerplugin.version}</version>\n                    <configuration>\n                        <source>1.8</source>\n                        <target>1.8</target>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-release-plugin</artifactId>\n                    <configuration>\n                        <preparationGoals>clean install</preparationGoals>\n                        <autoVersionSubmodules>false</autoVersionSubmodules>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-deploy-plugin</artifactId>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-javadoc-plugin</artifactId>\n                    <version>${maven.javadocplugin.version}</version>\n                    <configuration>\n                        <additionalparam>-Xdoclint:none</additionalparam>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <id>docs</id>\n                            <phase>compile</phase>\n                            <goals>\n                                <goal>javadoc</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-jar-plugin</artifactId>\n                    <configuration>\n                        <archive>\n                            <manifestEntries>\n                                <Microservices>${microservice.resourceClasses}</Microservices>\n                            </manifestEntries>\n                        </archive>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-shade-plugin</artifactId>\n                    <version>${maven.shadeplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-surefire-plugin</artifactId>\n                    <version>${maven.surefireplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.jacoco</groupId>\n                    <artifactId>jacoco-maven-plugin</artifactId>\n                    <version>${maven.jacocoplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-source-plugin</artifactId>\n                    <version>${maven.sourceplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-gpg-plugin</artifactId>\n                    <version>${maven.gpgplugin.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-archetype-plugin</artifactId>\n                    <version>${maven.archetype.version}</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.wso2.carbon.config</groupId>\n                    <artifactId>org.wso2.carbon.config.maven.plugin</artifactId>\n                    <version>${carbon.config.version}</version>\n                    <executions>\n                        <execution>\n                            <goals>\n                                <goal>create-doc</goal>\n                            </goals>\n                            <phase>compile</phase>\n                        </execution>\n                    </executions>\n                </plugin>\n                <plugin><!-- Overridden from parent pom to exclude generated sources -->\n                    <groupId>com.github.spotbugs</groupId>\n                    <artifactId>spotbugs-maven-plugin</artifactId>\n                    <configuration combine.self=\"override\">\n                        <effort>Max</effort>\n                        <threshold>Low</threshold>\n                        <xmlOutput>true</xmlOutput>\n                        <spotbugsXmlOutputDirectory>${project.build.directory}/findbugs</spotbugsXmlOutputDirectory>\n                        <!--Exclude generated sources-->\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <id>analyze-compile</id>\n                            <phase>compile</phase>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n    </build>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.launcher</artifactId>\n                <version>${carbon.kernel.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.core</artifactId>\n                <version>${carbon.kernel.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.utils</groupId>\n                <artifactId>org.wso2.carbon.utils</artifactId>\n                <version>${carbon.utils.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.config</groupId>\n                <artifactId>org.wso2.carbon.config</artifactId>\n                <version>${carbon.config.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.deployment</groupId>\n                <artifactId>org.wso2.carbon.deployment.engine</artifactId>\n                <version>${carbon.deployment.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.pax.exam.feature</artifactId>\n                <version>${carbon.kernel.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.server.feature</artifactId>\n                <version>${carbon.kernel.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.osgi.feature</artifactId>\n                <version>${carbon.kernel.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.runtime.feature</artifactId>\n                <version>${carbon.kernel.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>org.wso2.carbon.container</artifactId>\n                <version>${carbon.kernel.version}</version>\n            </dependency>\n            <!-- NEtty Dependencies-->\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-common</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-buffer</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-transport</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-handler</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-codec</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-handler-proxy</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-codec-http</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-codec-http2</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-resolver</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-codec-socks</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-transport-native-unix-common</artifactId>\n                <version>${netty.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-tcnative-boringssl-static</artifactId>\n                <version>${netty-tcnative.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.netty</groupId>\n                <artifactId>netty-tcnative-classes</artifactId>\n                <version>${netty-tcnative.version}</version>\n            </dependency>\n            <!--Test Distribution-->\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-all</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-core</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-analytics</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-analytics-common</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>zipkin-tracing</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>jaxrs-delegates</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-spring</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-deployer</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>msf4j-swagger</artifactId>\n                <version>${msf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.google.guava</groupId>\n                <artifactId>guava</artifactId>\n                <version>${guava.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.google.guava</groupId>\n                <artifactId>failureaccess</artifactId>\n                <version>${guava.failureaccess.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>org.wso2.msf4j.feature</artifactId>\n                <version>${msf4j.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.msf4j</groupId>\n                <artifactId>org.wso2.msf4j.deployer.feature</artifactId>\n                <version>${msf4j.version}</version>\n                <type>zip</type>\n            </dependency>\n            <dependency>\n                <groupId>javax.ws.rs</groupId>\n                <artifactId>javax.ws.rs-api</artifactId>\n                <version>${rs-api.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>javax.websocket</groupId>\n                <artifactId>javax.websocket-api</artifactId>\n                <version>${javax.websocket.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.orbit.javax.ws.rs</groupId>\n                <artifactId>javax.ws.rs-api.fragment</artifactId>\n                <version>${javax.ws.rs-api.fragment.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>commons-pool.wso2</groupId>\n                <artifactId>commons-pool</artifactId>\n                <version>${commons.pool.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.messaging</groupId>\n                <artifactId>org.wso2.carbon.messaging</artifactId>\n                <version>${carbon.messaging.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.transport.http</groupId>\n                <artifactId>org.wso2.transport.http.netty</artifactId>\n                <version>${org.wso2.transport.http.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.httpcomponents</groupId>\n                <artifactId>httpclient</artifactId>\n                <version>${org.apache.httpcomponents.httpclient.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.osgi</groupId>\n                <artifactId>org.osgi.core</artifactId>\n                <version>${osgi.api.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.eclipse.osgi</groupId>\n                <artifactId>org.eclipse.osgi</artifactId>\n                <version>${equinox.osgi.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.eclipse.osgi</groupId>\n                <artifactId>org.eclipse.osgi.services</artifactId>\n                <version>${equinox.osgi.services.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.slf4j</groupId>\n                <artifactId>slf4j-api</artifactId>\n                <version>${slf4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.slf4j</groupId>\n                <artifactId>slf4j-log4j12</artifactId>\n                <version>${slf4j.log4j.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.google.code.gson</groupId>\n                <artifactId>gson</artifactId>\n                <version>${gson.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.google.code.findbugs</groupId>\n                <artifactId>jsr305</artifactId>\n                <version>${jsr305.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.servicemix.bundles</groupId>\n                <artifactId>org.apache.servicemix.bundles.commons-beanutils</artifactId>\n                <version>${beanutils.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.wso2.orbit.io.swagger.core</groupId>\n                <artifactId>swagger-core</artifactId>\n                <version>${swagger.orbit.version}</version>\n                <exclusions>\n                    <exclusion>\n                        <groupId>org.slf4j</groupId>\n                        <artifactId>slf4j-api</artifactId>\n                    </exclusion>\n                    <exclusion>\n                        <groupId>org.yaml</groupId>\n                        <artifactId>snakeyaml</artifactId>\n                    </exclusion>\n                    <exclusion>\n                        <groupId>com.fasterxml.jackson.core</groupId>\n                        <artifactId>jackson-annotations</artifactId>\n                    </exclusion>\n                    <exclusion>\n                        <groupId>com.fasterxml.jackson.core</groupId>\n                        <artifactId>jackson-databind</artifactId>   \n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.orbit.io.swagger.jaxrs</groupId>\n                <artifactId>swagger-jaxrs</artifactId>\n                <version>${swagger.orbit.version}</version>\n                <exclusions>\n                    <exclusion>\n                        <groupId>javax.ws.rs</groupId>\n                        <artifactId>jsr311-api</artifactId>\n                    </exclusion>\n                    <exclusion>\n                        <groupId>com.fasterxml.jackson.core</groupId>\n                        <artifactId>jackson-annotations</artifactId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>io.swagger</groupId>\n                <artifactId>swagger-annotations</artifactId>\n                <version>${io.swagger.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.fasterxml.jackson.core</groupId>\n                <artifactId>jackson-databind</artifactId>\n                <version>${com.fasterxml.jackson.databind.version}</version>\n                <exclusions>\n                    <exclusion>\n                        <groupId>com.fasterxml.jackson.core</groupId>\n                        <artifactId>jackson-annotations</artifactId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>com.fasterxml.jackson.core</groupId>\n                <artifactId>jackson-annotations</artifactId>\n                <version>${com.fasterxml.jackson.annotations.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.fasterxml.jackson.core</groupId>\n                <artifactId>jackson-core</artifactId>\n                <version>${com.fasterxml.jackson.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.fasterxml.jackson.dataformat</groupId>\n                <artifactId>jackson-dataformat-yaml</artifactId>\n                <version>${com.fasterxml.jackson.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>javax.validation</groupId>\n                <artifactId>validation-api</artifactId>\n                <version>${javax.validation.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>javax.annotation</groupId>\n                <artifactId>javax.annotation-api</artifactId>\n                <version>${javax.annotation.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.orbit.org.apache.commons</groupId>\n                <artifactId>commons-lang3</artifactId>\n                <version>${apache.commons.lang3.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>javax.servlet</groupId>\n                <artifactId>javax.servlet-api</artifactId>\n                <version>${javax.servlet-api.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.orbit.org.reflections</groupId>\n                <artifactId>reflections</artifactId>\n                <version>${reflections.orbit.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.javassist</groupId>\n                <artifactId>javassist</artifactId>\n                <version>${javassist.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>commons-io.wso2</groupId>\n                <artifactId>commons-io</artifactId>\n                <version>${commons-io.wso2.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.yaml</groupId>\n                <artifactId>snakeyaml</artifactId>\n                <version>${org.snakeyaml.version}</version>\n            </dependency>\n            <!-- Metrics Dependencies - Start -->\n            <dependency>\n                <groupId>org.wso2.carbon.metrics</groupId>\n                <artifactId>org.wso2.carbon.metrics.core</artifactId>\n                <version>${carbon.metrics.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.metrics</groupId>\n                <artifactId>org.wso2.carbon.metrics.jdbc.core</artifactId>\n                <version>${carbon.metrics.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.wso2.carbon.metrics</groupId>\n                <artifactId>org.wso2.carbon.metrics.das.core</artifactId>\n                <version>${carbon.metrics.version}</version>\n            </dependency>\n            <!-- Metrics Dependencies - End -->\n            <!-- Zipkin tracing dependencies - Start -->\n            <dependency>\n                <groupId>io.zipkin.brave</groupId>\n                <artifactId>brave-spancollector-http</artifactId>\n                <version>${zipkin.brave.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.zipkin.brave</groupId>\n                <artifactId>brave-http</artifactId>\n                <version>${zipkin.brave.version}</version>\n            </dependency>\n            <!-- Zipkin tracing dependencies - End -->\n            <dependency>\n                <groupId>com.nimbusds</groupId>\n                <artifactId>nimbus-jose-jwt</artifactId>\n                <version>${nimbus.jose.jwt.version}</version>\n            </dependency>\n            <!-- MSF4J-Feign client dependencies -->\n            <dependency>\n                <groupId>io.github.openfeign</groupId>\n                <artifactId>feign-core</artifactId>\n                <version>${feign.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.github.openfeign</groupId>\n                <artifactId>feign-gson</artifactId>\n                <version>${feign.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>io.github.openfeign</groupId>\n                <artifactId>feign-jackson</artifactId>\n                <version>${feign.version}</version>\n                <exclusions>\n                        <exclusion>\n                        <groupId>com.fasterxml.jackson.core</groupId>\n                        <artifactId>jackson-databind</artifactId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>io.github.openfeign</groupId>\n                <artifactId>feign-hystrix</artifactId>\n                <version>${feign.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.httpcomponents</groupId>\n                <artifactId>httpclient-osgi</artifactId>\n                <version>${httpclient.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.httpcomponents</groupId>\n                <artifactId>httpcore-osgi</artifactId>\n                <version>${httpcore.version}</version>\n            </dependency>\n            <!-- Feign client dependencies - End -->\n            <!-- Test dependencies -->\n            <dependency>\n                <groupId>commons-io</groupId>\n                <artifactId>commons-io</artifactId>\n                <version>2.4</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>ch.qos.logback</groupId>\n                <artifactId>logback-core</artifactId>\n                <version>${logback.version}</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>ch.qos.logback</groupId>\n                <artifactId>logback-classic</artifactId>\n                <version>${logback.version}</version>\n                <scope>test</scope>\n            </dependency>\n\n            <dependency>\n                <groupId>org.wso2.carbon</groupId>\n                <artifactId>osgi-test-util</artifactId>\n                <version>${carbon.kernel.version}</version>\n                <scope>test</scope>\n            </dependency>\n\n            <!-- PAX Exam -->\n            <dependency>\n                <groupId>org.testng</groupId>\n                <artifactId>testng</artifactId>\n                <version>${testng.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam-inject</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam-extender-service</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.base</groupId>\n                <artifactId>ops4j-base</artifactId>\n                <version>${ops4j.base.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.geronimo.specs</groupId>\n                <artifactId>geronimo-atinject_1.0_spec</artifactId>\n                <version>${geronimo.atinject.spec.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam-container-native</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam-testng</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.exam</groupId>\n                <artifactId>pax-exam-link-mvn</artifactId>\n                <version>${pax.exam.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ops4j.pax.url</groupId>\n                <artifactId>pax-url-aether</artifactId>\n                <version>${pax.url.aether.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>org.ow2.spec.ee</groupId>\n                <artifactId>ow2-jta-1.1-spec</artifactId>\n                <version>${ow2.jta.spec.version}</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.jacoco</groupId>\n                <artifactId>org.jacoco.ant</artifactId>\n                <version>${org.jacoco.ant.version}</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.osgi</groupId>\n                <artifactId>org.osgi.compendium</artifactId>\n                <version>${org.osgi.compendium.version}</version>\n                <scope>test</scope>\n            </dependency>\n\n        </dependencies>\n    </dependencyManagement>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <!-- Maven plugins -->\n        <maven.checkstyleplugin.version>2.17</maven.checkstyleplugin.version>\n        <maven.findbugsplugin.version>3.0.2</maven.findbugsplugin.version>\n        <maven.compilerplugin.version>3.3</maven.compilerplugin.version>\n        <maven.wagon.ssh.version>2.1</maven.wagon.ssh.version>\n        <maven.javadocplugin.version>2.10.3</maven.javadocplugin.version>\n        <maven.shadeplugin.version>2.4.1</maven.shadeplugin.version>\n        <maven.surefireplugin.version>2.14.1</maven.surefireplugin.version>\n        <maven.jacocoplugin.version>0.7.1.201405082137</maven.jacocoplugin.version>\n        <maven.sourceplugin.version>2.2.1</maven.sourceplugin.version>\n        <maven.gpgplugin.version>1.5</maven.gpgplugin.version>\n        <maven.archetype.version>2.4</maven.archetype.version>\n\n        <!-- Dependencies -->\n        <netty.version>4.1.132.Final</netty.version>\n        <netty-tcnative.version>2.0.75.Final</netty-tcnative.version>\n        <netty.version.range>(4,5]</netty.version.range>\n        <commons.pool.version>1.5.6.wso2v1</commons.pool.version>\n        <carbon.kernel.version>5.2.0</carbon.kernel.version>\n        <carbon.kernel.version.range>[5.0.0,6.0.0)</carbon.kernel.version.range>\n        <carbon.touchpoint.version>1.1.0</carbon.touchpoint.version>\n        <carbon.utils.version>2.0.2</carbon.utils.version>\n        <carbon.utils.package.import.version.range>[2.0.0, 3.0.0)</carbon.utils.package.import.version.range>\n        <carbon.config.version>2.1.17</carbon.config.version>\n        <carbon.config.package.import.version.range>[2.1.5, 3.0.0)</carbon.config.package.import.version.range>\n        <carbon.secvault.version>5.0.21</carbon.secvault.version>\n        <carbon.secvault.version.range>[5.0.0, 6.0.0)</carbon.secvault.version.range>\n        <carbon.deployment.version>5.1.9</carbon.deployment.version>\n        <carbon.deployment.version.range>[5.1.9, 6.0.0)</carbon.deployment.version.range>\n        <carbon.messaging.version>3.0.2</carbon.messaging.version>\n        <carbon.messaging.version.range>[3,4)</carbon.messaging.version.range>\n        <carbon.jndi.version>1.0.4</carbon.jndi.version>\n        <carbon.datasources.version>1.1.3</carbon.datasources.version>\n        <org.wso2.transport.http.version>6.3.54</org.wso2.transport.http.version>\n        <org.wso2.transport.http.version.range>[6.0.64,7)</org.wso2.transport.http.version.range>\n        <org.wso2.carbon.transport.http.netty.version>5.0.1</org.wso2.carbon.transport.http.netty.version>\n        <javax.websocket.version>1.1</javax.websocket.version>\n        <javax.websocket.version.range>[1.1, 1.2)</javax.websocket.version.range>\n        <org.apache.httpcomponents.httpclient.version>4.5.2</org.apache.httpcomponents.httpclient.version>\n        <msf4j.version>2.8.14-SNAPSHOT</msf4j.version>\n        <msf4j.version.range>[2.6.0,3.0.0)</msf4j.version.range>\n        <zipkin.brave.version>3.9.1</zipkin.brave.version>\n        <carbon.metrics.version>2.3.2</carbon.metrics.version>\n        <carbon.metrics.version.range>[2.0,3)</carbon.metrics.version.range>\n        <carbon.analytics.common.version>5.0.6</carbon.analytics.common.version>\n        <carbon.analytics.common.version.range>[5.0,6)</carbon.analytics.common.version.range>\n        <disruptor.orbit.version>3.4.2.wso2v1</disruptor.orbit.version>\n        <metrics.version>3.1.2</metrics.version>\n        <commons-io.wso2.version>2.17.0.wso2v1</commons-io.wso2.version>\n        <commons-io.version.range>[2.7.0, 2.20)</commons-io.version.range>\n        <libthrift.wso2.version>0.8.0.wso2v1</libthrift.wso2.version>\n        <commons.pool.version>1.5.6.wso2v1</commons.pool.version>\n        <javax.ws.rs-api.fragment.version>1.0.0.wso2v1</javax.ws.rs-api.fragment.version>\n        <feign.version>9.3.1</feign.version>\n        <httpclient.version>4.5.2</httpclient.version>\n        <httpcore.version>4.4.5</httpcore.version>\n        <javax.websocket.version>1.1</javax.websocket.version>\n        <javax.annotation.version>1.3.2</javax.annotation.version>\n\n        <osgi.api.version>6.0.0</osgi.api.version>\n        <equinox.osgi.version>3.10.2.v20150203-1939</equinox.osgi.version>\n        <equinox.osgi.services.version>3.4.0.v20140312-2051</equinox.osgi.services.version>\n        <rs-api.version>2.0</rs-api.version>\n        <slf4j.version>1.7.35</slf4j.version>\n        <slf4j.version.range>[1.7,2)</slf4j.version.range>\n        <slf4j.log4j.version>1.6.0</slf4j.log4j.version>\n        <gson.version>2.9.1</gson.version>\n        <gson.version.range>[2.2,3)</gson.version.range>\n        <guava.version>32.1.3-jre</guava.version>\n        <guava.bundle.version>32.1.3.jre</guava.bundle.version>\n        <guava.version.range>[20.0,34.0)</guava.version.range>\n        <guava.failureaccess.version>1.0.1</guava.failureaccess.version>\n        <jsr305.version>2.0.1</jsr305.version>\n        <beanutils.version>1.8.3_2</beanutils.version>\n        <beanutils.version.range>[1.8,2)</beanutils.version.range>\n        <beanutils.osgi.version>1.8.3.2</beanutils.osgi.version>\n        <logback.version>1.0.9</logback.version>\n        <nimbus.jose.jwt.version>2.25</nimbus.jose.jwt.version>\n        <io.swagger.version>1.6.9</io.swagger.version>\n        <swagger.orbit.version>1.6.9.wso2v2</swagger.orbit.version>\n        <io.swagger.version.range>[1.5.16,1.7.0)</io.swagger.version.range>\n        <com.fasterxml.jackson.version>2.21.2</com.fasterxml.jackson.version>\n        <com.fasterxml.jackson.annotations.version>2.21</com.fasterxml.jackson.annotations.version>\n        <com.fasterxml.jackson.databind.version>2.21.2</com.fasterxml.jackson.databind.version>\n        <com.fasterxml.jackson.version.range>[2.15.0,2.21.2]</com.fasterxml.jackson.version.range>\n        <javax.validation.version>1.1.0.Final</javax.validation.version>\n        <apache.commons.lang3.version>3.20.0.wso2v1</apache.commons.lang3.version>\n        <javax.servlet-api.version>3.1.0</javax.servlet-api.version>\n        <reflections.orbit.version>0.9.11.wso2v4</reflections.orbit.version>\n        <javassist.version>3.19.0-GA</javassist.version>\n\n        <osgi.framework.import.version.range>[1.8.0, 2.0.0)</osgi.framework.import.version.range>\n        <osgi.service.tracker.import.version.range>[1.5.1, 2.0.0)</osgi.service.tracker.import.version.range>\n        <carbon.feature.plugin.version>3.1.5</carbon.feature.plugin.version>\n\n        <!-- Dependencies for OSGi PAX exam tests -->\n        <!--PAX Logging related dependency versions-->\n        <pax.logging.api.version>1.8.4</pax.logging.api.version>\n        <pax.logging.log4j2.version>1.8.4</pax.logging.log4j2.version>\n        <org.eclipse.equinox.cm.version>1.1.0.v20131021-1936</org.eclipse.equinox.cm.version>\n\n        <!--Pax Exam Versions-->\n        <pax.exam.version>4.6.0</pax.exam.version>\n        <pax.url.aether.version>1.6.0</pax.url.aether.version>\n        <slf4j.api.version>1.7.12</slf4j.api.version>\n        <javax.inject.version>1</javax.inject.version>\n\n        <!--Other dependency versions -->\n        <jacoco.version>0.7.5.201505241946</jacoco.version>\n        <javax.inject.version>1</javax.inject.version>\n        <apache.felix.gogo.command.version>0.10.0.v201209301215</apache.felix.gogo.command.version>\n        <apache.felix.gogo.shell.version>0.10.0.v201212101605</apache.felix.gogo.shell.version>\n        <apache.felix.gogo.runtime.version>0.10.0.v201209301036</apache.felix.gogo.runtime.version>\n        <equinox.app.version>1.3.200.v20130910-1609</equinox.app.version>\n        <equinox.common.version>3.6.200.v20130402-1505</equinox.common.version>\n        <equinox.concurrent.version>1.1.0.v20130327-1442</equinox.concurrent.version>\n        <equinox.console.version>1.1.0.v20140131-1639</equinox.console.version>\n        <equinox.ds.version>1.4.200.v20131126-2331</equinox.ds.version>\n        <equinox.frameworkadmin.version>2.0.100.v20131209-2144</equinox.frameworkadmin.version>\n        <equinox.frameworkadmin.equinox.version>1.0.500.v20131211-1531</equinox.frameworkadmin.equinox.version>\n        <equinox.launcher.version>1.3.0.v20140415-2008</equinox.launcher.version>\n        <equinox.preferences.version>3.5.200.v20140224-1527</equinox.preferences.version>\n        <equinox.registry.version>3.5.400.v20140428-1507</equinox.registry.version>\n        <equinox.simpleconfigurator.manipulator.version>2.0.0.v20131217-1203\n        </equinox.simpleconfigurator.manipulator.version>\n        <equinox.util.version>1.0.500.v20130404-1337</equinox.util.version>\n        <org.snakeyaml.version>2.6</org.snakeyaml.version>\n        <equinox.simpleconfigurator.version>1.1.0.v20131217-1203</equinox.simpleconfigurator.version>\n        <testng.version>6.9.4</testng.version>\n        <maven.paxexam.plugin.version>1.2.4</maven.paxexam.plugin.version>\n        <org.jacoco.ant.version>0.7.5.201505241946</org.jacoco.ant.version>\n        <org.springframework.version>4.2.0.RELEASE</org.springframework.version>\n\n        <!--Pax Exam Versions-->\n        <pax.exam.version>4.8.0</pax.exam.version>\n        <pax.url.aether.version>1.6.0</pax.url.aether.version>\n        <slf4j.api.version>1.7.12</slf4j.api.version>\n        <javax.inject.version>1</javax.inject.version>\n        <ops4j.base.version>1.5.0</ops4j.base.version>\n        <osgi.compendium.version>4.3.1</osgi.compendium.version>\n        <geronimo.atinject.spec.version>1.0</geronimo.atinject.spec.version>\n        <ow2.jta.spec.version>1.0.12</ow2.jta.spec.version>\n        <org.jacoco.ant.version>0.7.5.201505241946</org.jacoco.ant.version>\n        <org.osgi.compendium.version>4.3.1</org.osgi.compendium.version>\n    </properties>\n</project>\n"
  },
  {
    "path": "pull_request_template.md",
    "content": "## Purpose\r\n> Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.\r\n\r\n## Goals\r\n> Describe the solutions that this feature/fix will introduce to resolve the problems described above\r\n\r\n## Approach\r\n> Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.\r\n\r\n## User stories\r\n> Summary of user stories addressed by this change>\r\n\r\n## Release note\r\n> Brief description of the new feature or bug fix as it will appear in the release notes\r\n\r\n## Documentation\r\n> Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact\r\n\r\n## Training\r\n> Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable\r\n\r\n## Certification\r\n> Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.\r\n\r\n## Marketing\r\n> Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable\r\n\r\n## Automation tests\r\n - Unit tests \r\n   > Code coverage information\r\n - Integration tests\r\n   > Details about the test cases and coverage\r\n\r\n## Security checks\r\n - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no\r\n - Ran FindSecurityBugs plugin and verified report? yes/no\r\n - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no\r\n\r\n## Samples\r\n> Provide high-level details about the samples related to this feature\r\n\r\n## Related PRs\r\n> List any other related PRs\r\n\r\n## Migrations (if applicable)\r\n> Describe migration steps and platforms on which migration has been tested\r\n\r\n## Test environment\r\n> List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested\r\n \r\n## Learning\r\n> Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem."
  },
  {
    "path": "samples/README.md",
    "content": "# WSO2 Microservices Framework for Java (MSF4J) Samples\n\nThis directory contain a comprehensive suite of samples demonstrating the capabilities of WSO2 MSF4J.\n\n# Requirements\n* JDK 1.8.*\n* Maven 3.0.x\n\n#Samples \nIn increasing order of complexity;\n\n* [Hello World](helloworld) - Running a basic Microservice\n* [Spring Hello World](spring-helloworld) - Running a basic Microservice using the Spring framework  \n* [Session-aware Service](http-session) - Shows how to use HTTP sessions in services \n* [StockQuote (Fat jar)](stockquote/fatjar) - Developing a Microservice as a single jar which packs all the dependencies\n* [StockQuote (OSGi bundle)](stockquote/bundle) - Creating a Microservice as an OSGi Bundle\n* [Lifecycle](lifecycle) - Using Service Lifecycle Methods\n* [Metrics](metrics) - Using Metrics Interceptor\n* [HTTP Monitoring](http-monitoring) - Using HTTP Monitoring Interceptor\n* [Regex PathParam](regex-pathparam) - How to use regex with PathParam annotation\n* [File Server](fileserver) - Handling Files including streaming input & output\n* [FormParam](formparam) - Shows usage of the FormParam annotation\n* [Circuit Breaker](circuitbreaker) - Using the circuit breaker pattern\n* [Interceptor (Fat jar)](interceptor/fatjar-interceptor-service) - Creating an Interceptor as a single jar which packs \nall the dependencies\n* [Interceptor (Deployable jar)](interceptor/deployable-jar-interceptor-service) - Creating an Interceptor as a \ndeployable jar\n* [Interceptor (OSGi bundle)](interceptor/osgi-interceptor-service) - Creating an Interceptor as an OSGi Bundle\n* [Hello World JPA](jpa) - Simple JPA Hibernate based sample\n* [BasicAuth Security](basicauth-security) - Securing Microservice using BasicAuth\n* [OAuth2 Security](oauth2-security) - Securing Microservice using OAuth2\n* [Template](template) - Rendering a Model from a Template\n* [WSO2 DAS Tracing](message-tracing/das) - Using WSO2 DAS for tracing messages\n* [Zipkin Tracing](message-tracing/zipkin) - Using Zipkin for tracing messages\n* [Pet-store](petstore) - Running as an MSA Application\n* [WebSocket Chat App](websocket/chatApp) - How to use MSF4J WebSocket capabilities to create a simple chat app\n\n"
  },
  {
    "path": "samples/basicauth-security/README.md",
    "content": "# BasicAuth Security Sample\n\nThis shows how to implement and register a SecurityInterceptor with MicroservicesRunner.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n\nUse following command to run the application\n\n```\njava -jar target/basicauth-security-*.jar\n```\n\n## How to tests the sample\n\nUse following cURL commands.\n\n```\ncurl --user sam:sam http://localhost:9090/hello/sam -v\n\ncurl --user sam:wrong http://localhost:9090/hello/sam -v\n\n```\n"
  },
  {
    "path": "samples/basicauth-security/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>basicauth-security</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Securing microservices in MSF4J using OAuth2</name>\n    <description>Demostrates how to secure microservices in WSO2 MSF4J</description>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/basicauth-security/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private Application() {\n    }\n\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(new UsernamePasswordSecurityInterceptor())\n                .deploy(new Helloworld())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/basicauth-security/src/main/java/org/wso2/msf4j/example/Helloworld.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Helloworld resource class.\n */\n@Path(\"/hello\")\npublic class Helloworld {\n\n    @GET\n    @Path(\"/{user}\")\n    public String getUser(@PathParam(\"user\") String user) {\n        return \"Hello \" + user;\n    }\n\n}\n"
  },
  {
    "path": "samples/basicauth-security/src/main/java/org/wso2/msf4j/example/UsernamePasswordSecurityInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.security.basic.AbstractBasicAuthSecurityInterceptor;\n\n/**\n * A simple security interceptor which handled username/password based authentication\n */\npublic class UsernamePasswordSecurityInterceptor extends AbstractBasicAuthSecurityInterceptor {\n\n    @Override\n    protected boolean authenticate(String username, String password) {\n        // Authentication logic is added in here. For simplicity, we just check that username == password\n        if (username.equals(password)) {\n            return true;\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "samples/circuitbreaker/README.md",
    "content": "# MSF4J Circuit Breaker Sample\n\n## Introduction\nCircuit breaker is a pattern used for fault tolerance and the term was first introduced by Michael Nygard in his \nfamous book titled \"Release It!\". The idea is, rather than wasting valuable resources trying to invoke an operation \nthat keeps failing, the system backs off for a period of time, and later tries to see whether the operation that was \noriginally failing works.\n\n![Nygard Circuit Breaker](images/circuit-breaker-state-transition.png) \n\nA good example would be, a service receiving a request, which in turn leads to a database call. At some point in time, \nthe connectivity to the database could fail. After a series of failed calls, the circuit trips, and there will be no \nfurther attempts to connect to the database for a period of time. We call this the \"open\" state of the circuit breaker. \nDuring this period, the callers of the service will be served from a cache. After this period has elapsed, the next \ncall to the service will result in a call to the database. This stage of the circuit breaker is called the \"half-open\" \nstage. If this call succeeds, then the circuit breaker goes back to the closed stage and all subsequent calls will \nresult in calls to the database. However, if the database call during the half-open state fails, the circuit breaker \ngoes back to the open state and will remain there for a period of time, before transitioning to the half-open state \nagain.\n\nOther typical examples of the circuit breaker pattern being useful would be a service making a call to another service, \nand a client making a call to a service. In both cases, the calls could fail, and instead of indefinitely trying to \ncall the relevant service, the circuit breaker would introduce some back-off period, before attempting to call the \nservice which was failing.\n\n## About this sample\n\nThis sample will demonstrate how a circuit breaker can be implemented using the WSO2 Microservices Framework for Java \n(MSF4J) & Netflix Hystrix. We take the stockquote service sample, and enable circuit breaker. Assume that \nthe stock quotes are loaded from a database. We wrap the calls to this database in a Hystrix command. \nIf database calls fail, the circuit trips and stock quotes are served from cache.\n\nNOTE: To keep things simple and focus on the implementation of the circuit breaker pattern, \nrather than making actual database calls, we have a class called org.example.service.StockQuoteDatabase and calls \nto its getStock method could result in timeouts or failures. To see an MSF4J example on how to make actual database \ncalls, see the [JPA sample](../jpa).\n\nThe complete call sequence is shown below. StockQuoteService is an MSF4J microservice.\n\n![Scenario](images/scenario.png)\n\nThe circuit breaker is configured as shown below.\n\n```java\nCircuitBreakerCommand(StockQuoteDatabase db, String symbol) {\n    super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(\"MyGroup\"))\n            .andCommandPropertiesDefaults(\n                    HystrixCommandProperties.Setter()\n                            .withCircuitBreakerEnabled(true)\n                            .withCircuitBreakerRequestVolumeThreshold(50)\n                            .withExecutionTimeoutEnabled(true)\n                            .withExecutionTimeoutInMilliseconds(10)\n            ));\n    this.db = db;\n    this.symbol = symbol;\n}\n```\n\nWe are enabling circuit breaker & timeout, and then setting the threshold of failures which will trigger circuit \ntripping to 50, and also timeout to 10ms. So any database call that takes more than 10ms will also be registered as a \nfailure. \nFor other configuration parameters, please see \n[https://github.com/Netflix/Hystrix/wiki/Configuration](https://github.com/Netflix/Hystrix/wiki/Configuration)\n\n## Building and Running the Sample\nUse Maven to build the sample.\n\n```\nmvn clean package\n\n```\n\nNext run the MSF4J service.\n\n```\njava -jar target/circuitbreaker-*.jar\n```\nNow let's use cURL to repeatedly invoke the service. Run the following command;\n\n```\nwhile true; do curl -v http://localhost:9090/stockquote/IBM ; done\n```\n\nThe above command will keep invoking the service. Observe the output of the service in the terminal. \nYou will see that some of the calls will fail on the service side and you will be able to see the circuit breaker \nfallback in action and also the circuit breaker tripping, then going into the half-open state, and then closing.\n"
  },
  {
    "path": "samples/circuitbreaker/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>circuitbreaker</artifactId>\n\n    <name>MSF4J Circuit breaker sample</name>\n\n    <dependencies>\n        <!-- Uncomment the following if you want to enable metrics & monitoring -->\n        <!--\n        <dependency>\n           <groupId>org.wso2.msf4j</groupId>\n           <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        -->\n        <dependency>\n            <groupId>com.netflix.hystrix</groupId>\n            <artifactId>hystrix-core</artifactId>\n            <version>1.5.1</version>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.example.service.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/circuitbreaker/src/main/java/org/example/service/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.example.service;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n *\n * @since 0.1-SNAPSHOT\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new StockQuoteService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/circuitbreaker/src/main/java/org/example/service/CircuitBreakerCommand.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.example.service;\n\nimport com.netflix.hystrix.HystrixCommand;\nimport com.netflix.hystrix.HystrixCommandGroupKey;\nimport com.netflix.hystrix.HystrixCommandKey;\nimport com.netflix.hystrix.HystrixCommandMetrics;\nimport com.netflix.hystrix.HystrixCommandProperties;\n\npublic class CircuitBreakerCommand extends HystrixCommand<Stock> {\n\n    private StockQuoteDatabase db;\n    private final String symbol;\n\n    CircuitBreakerCommand(StockQuoteDatabase db, String symbol) {\n        super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(\"MyGroup\"))\n                .andCommandPropertiesDefaults(\n                        HystrixCommandProperties.Setter()\n                                .withCircuitBreakerEnabled(true)\n                                .withCircuitBreakerRequestVolumeThreshold(50)\n                                .withExecutionTimeoutEnabled(true)\n                                .withExecutionTimeoutInMilliseconds(10)\n                ));\n        this.db = db;\n        this.symbol = symbol;\n    }\n\n    @Override\n    protected Stock run() {\n        printMetrics();\n        return db.getStock(symbol);\n    }\n\n    @Override\n    protected Stock getFallback() {\n        if (isCircuitBreakerOpen()) {\n            System.out.println(\"Circuit is open\");\n        }\n        printMetrics();\n        return db.getCachedStock(symbol);\n    }\n\n    private void printMetrics() {\n        HystrixCommandMetrics metrics =\n                HystrixCommandMetrics.\n                        getInstance(HystrixCommandKey.Factory.asKey(this.getClass().getSimpleName()));\n        StringBuilder m = new StringBuilder();\n        if (metrics != null) {\n            HystrixCommandMetrics.HealthCounts health = metrics.getHealthCounts();\n            m.append(\"Requests: \").append(health.getTotalRequests()).append(\" \");\n            m.append(\"Errors: \").append(health.getErrorCount()).append(\" (\").\n                    append(health.getErrorPercentage()).append(\"%)   \");\n            m.append(\"Mean: \").append(metrics.getExecutionTimePercentile(50)).append(\" \");\n            m.append(\"75th: \").append(metrics.getExecutionTimePercentile(75)).append(\" \");\n            m.append(\"90th: \").append(metrics.getExecutionTimePercentile(90)).append(\" \");\n            m.append(\"99th: \").append(metrics.getExecutionTimePercentile(99)).append(\" \");\n        }\n        System.out.println(m);\n    }\n}\n"
  },
  {
    "path": "samples/circuitbreaker/src/main/java/org/example/service/Stock.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.example.service;\n\n/**\n * Represents a stock item.\n */\n@SuppressWarnings(\"unused\")\npublic class Stock {\n\n    private String symbol;\n    private String name;\n    private double last;\n    private double low;\n    private double high;\n\n    /**\n     * No arg constructor is required for xml marshalling\n     */\n    public Stock() {\n    }\n\n    public Stock(String symbol, String name) {\n        this.symbol = symbol;\n        this.name = name;\n    }\n\n    public Stock(String symbol, String name, double last, double low, double high) {\n        this(symbol, name);\n        this.last = last;\n        this.low = low;\n        this.high = high;\n    }\n\n    public String getSymbol() {\n        return symbol;\n    }\n\n    public void setSymbol(String symbol) {\n        this.symbol = symbol;\n    }\n\n    public void setHigh(double high) {\n        this.high = high;\n    }\n\n    public void setLast(double last) {\n        this.last = last;\n    }\n\n    public void setLow(double low) {\n        this.low = low;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public double getHigh() {\n        return high;\n    }\n\n    public double getLast() {\n        return last;\n    }\n\n    public double getLow() {\n        return low;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n\n"
  },
  {
    "path": "samples/circuitbreaker/src/main/java/org/example/service/StockQuoteDatabase.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.example.service;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Random;\n\n/**\n * Retrieves stockquotes\n */\npublic class StockQuoteDatabase {\n    private Random random = new Random();\n\n    // Map that stores stocks (symbol -> stock).\n    private Map<String, Stock> stockQuotes = new HashMap<>();\n\n    private Map<String, Stock> stockQuotesCache = new HashMap<>();\n\n    /**\n     * Add initial stocks IBM, GOOG, AMZN.\n     */\n    public StockQuoteDatabase() {\n        stockQuotes.put(\"IBM\", new Stock(\"IBM\", \"International Business Machines\", 149.62, 150.78, 149.18));\n        stockQuotes.put(\"GOOG\", new Stock(\"GOOG\", \"Alphabet Inc.\", 652.30, 657.81, 643.15));\n        stockQuotes.put(\"AMZN\", new Stock(\"AMZN\", \"Amazon.com\", 548.90, 553.20, 543.10));\n    }\n\n    public Stock getStock(String symbol) {\n        // To simulate failures, timeout & circuit breaker behaviour, this method will randomly fail\n\n        int rand = random.nextInt(3);\n        if (rand == 0) { // Simulate a timeout\n            System.out.println(\"Failed. Timeout!\");\n            delay(50);\n        } else if (rand == 1) {  // Simulate a failure\n            System.out.println(\"Failed. Exception!\");\n            throw new RuntimeException(\"Failed. Exception!\");\n        }\n        System.out.println(\"No failure\");\n        Stock stock = stockQuotes.get(symbol);\n        stockQuotesCache.put(symbol, stock);\n        return stock;\n    }\n\n    private void delay(int millis) {\n        try {\n            Thread.sleep(millis);\n        } catch (InterruptedException ignored) {\n        }\n    }\n\n    public Stock getCachedStock(String symbol) {\n        return stockQuotesCache.get(symbol);\n    }\n}\n"
  },
  {
    "path": "samples/circuitbreaker/src/main/java/org/example/service/StockQuoteService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.example.service;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * This is the Microservice resource class.\n * See <a href=\"https://github.com/wso2/msf4j#getting-started\">https://github.com/wso2/msf4j#getting-started</a>\n * for the usage of annotations.\n *\n */\n\n@Path(\"/stockquote\")\npublic class StockQuoteService {\n\n    private StockQuoteDatabase db = new StockQuoteDatabase();\n\n    /**\n     * Retrieve a stock for a given symbol.\n     * http://localhost:8080/stockquote/IBM\n     *\n     * @param symbol Stock symbol will be taken from the path parameter.\n     * @return Response\n     */\n    @GET\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    public Response getQuote(@PathParam(\"symbol\") String symbol) {\n        Stock stock = new CircuitBreakerCommand(db, symbol).execute();\n        return (stock == null) ?\n                Response.status(Response.Status.NOT_FOUND).build() :\n                Response.status(Response.Status.OK).entity(stock).build();\n    }\n}\n"
  },
  {
    "path": "samples/fileserver/README.md",
    "content": "# File handling\n\n\n## Serve Files with WSO2 MSF4J\n\nYou can serve files from the resource methods by returning a java.io.File, \n java.io.InputStream or by returning a javax.ws.rs.core.Response object with a java.io.File or \njava.io.InputStream entity. Streaming is supported by default for java.io.File and java.io.InputStream\nentities. \n\njavax.ws.rs.core.StreamingOutput is also supported by MSF4J. This provides the service author more control\nover the chunk size.\n\nSee the following sample.\n\n```java\n    @GET\n    @Path(\"/{fileName}\")\n    public Response getFile(@PathParam(\"fileName\") String fileName) {\n        File file = Paths.get(MOUNT_PATH, fileName).toFile();\n        if (file.exists()) {\n            return Response.ok(file).build();\n        }\n        return Response.status(Response.Status.NOT_FOUND).build();\n    }\n```\n\n## Streaming (Chunked) HTTP Request Handling\n\n\nWith WSO2 MSF4J, you can handle chunked requests in two ways.\n\n### 1. Handle requests using HttpStreamHandler\n\nFirst way is to implement org.wso2.msf4j.HttpStreamHandler as shown in the below example to handle chunked http \nrequests in a zero copy manner.\n\n```java\n    @POST\n    @Path(\"/stream\")\n    @Consumes(\"text/plain\")\n    public void stream(@Context HttpStreamer httpStreamer) {\n        final StringBuffer sb = new StringBuffer();\n        httpStreamer.callback(new HttpStreamHandler() {\n            @Override\n            public void chunk(ByteBuf request, HttpResponder responder) {\n                sb.append(request.toString(Charsets.UTF_8));\n            }\n\n            @Override\n            public void finished(ByteBuf request, HttpResponder responder) {\n                sb.append(request.toString(Charsets.UTF_8));\n                responder.sendString(HttpResponseStatus.OK, sb.toString());\n            }\n\n            @Override\n            public void error(Throwable cause) {\n                sb.delete(0, sb.length());\n            }\n        });\n    }\n```\n\nIn the above example when the request chunks arrive, chunk() method is called. When the last chunk is arrived the \nfinished() method is called. error() method will be called if an error occurs while processing the request.\n\n\n### 2. Handle requests by aggregating chunks \nSecond way of handling chunked requests is to implement a normal resource method to handle the request ignoring \nwhether the requests is chunked as shown in the below example. In this case MSF4J internally \naggregates all the chunks of the request and presents it as a full http request to the resource method.\n\n```java\n    @POST\n    @Path(\"/aggregate\")\n    @Consumes(\"text/plain\")\n    public String aggregate(String content) {\n        return content;\n    }\n```\n\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean package\n```\n\n## How to run the sample\n\nUse following command to run the application\n```\njava -jar target/fileserver-*.jar\n```\n\n## How to test the sample\n\nRun the following curl command to upload file\n```\ncurl -v -X POST --data-binary @/testPng.png http://localhost:9090/filename.png\n```\nHere /testPng.png will be uploaded with the name filename.png\n\n---\n\nRun the following curl command to download the file:\n\n```\ncurl -v -X GET http://localhost:9090/filename.png > result.png\n```\n\nNow the file will be downloaded as result.png to the current directory.\n\nAlternatively, to see how streaming works with java.io.InputStream, run the following command:\n\n```\ncurl -v -X GET http://localhost:9090/ip/filename.png > result-ipstream.png\n```\n\nTo see how streaming works with javax.ws.rs.core.StreamingOutput , run the following command:\n\n```\ncurl -v -X GET http://localhost:9090/op/filename.png > result-opstream.png\n```\n"
  },
  {
    "path": "samples/fileserver/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>fileserver</artifactId>\n\n    <name>Sample: File server Microservice</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/fileserver/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new FileServer())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/fileserver/src/main/java/org/wso2/msf4j/example/FileServer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.apache.commons.io.FilenameUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.HttpStreamHandler;\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.internal.mime.MimeMapper;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.file.Paths;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.core.StreamingOutput;\n\n/**\n * FileServer service class. This uses request streaming\n * to save the submitted files in the server. Also this demonstrates\n * how to respond with files.\n */\n@Path(\"/\")\npublic class FileServer {\n\n    private static final Logger log = LoggerFactory.getLogger(FileServer.class);\n    private static final java.nio.file.Path MOUNT_PATH = Paths.get(\".\");\n\n    /**\n     * Upload a file with streaming.\n     *\n     * @param httpStreamer Handle for setting the {@link HttpStreamHandler}callback for streaming.\n     * @param fileName     Name of the file that was uploaded.\n     * @throws IOException\n     */\n    @POST\n    @Path(\"/{fileName}\")\n    public void postFile(@Context HttpStreamer httpStreamer,\n                         @PathParam(\"fileName\") String fileName) throws IOException {\n        httpStreamer.callback(new HttpStreamHandlerImpl(fileName));\n    }\n\n    /**\n     * Download file with streaming using a {@link File} object in the response. Streaming is automatically handled\n     * by MSF4J.\n     *\n     * @param fileName Name of the file to be downloaded.\n     * @return Response\n     */\n    @GET\n    @Path(\"/{fileName}\")\n    public Response getFile(@PathParam(\"fileName\") String fileName) {\n        File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n        if (file.exists()) {\n            return Response.ok(file).build();\n        }\n        return Response.status(Response.Status.NOT_FOUND).build();\n    }\n\n    /**\n     * Download file with streaming using a {@link java.io.InputStream} object in the response.\n     * Streaming is automatically handled by MSF4J.\n     *\n     * @param fileName Name of the file to be downloaded.\n     * @return Response\n     */\n    @GET\n    @Path(\"/ip/{fileName}\")\n    public Response getFileFromInputStream(@PathParam(\"fileName\") String fileName) throws FileNotFoundException {\n        String mimeType = MimeMapper.getMimeType(FilenameUtils.getExtension(fileName));\n        File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n        return Response.ok(new FileInputStream(file)).type(mimeType).build();\n    }\n\n    /**\n     * Download file with Streaming using using {@link javax.ws.rs.core.StreamingOutput}.\n     * You have more control over streaming chunk sizes when this method is used.\n     *\n     * @param fileName Name of the file to be downloaded.\n     * @return Response\n     */\n    @GET\n    @Path(\"/op/{fileName}\")\n    public Response getFileUsingStreamingOutput(@PathParam(\"fileName\") String fileName) {\n        StreamingOutput stream = os -> {\n            File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n            int chunkSize = 4096;\n            byte[] buf = new byte[chunkSize];\n            InputStream is = new FileInputStream(file);\n            int c = 0;\n            while ((c = is.read(buf, 0, buf.length)) > 0) {\n                os.write(buf, 0, c);\n                os.flush();\n            }\n            os.close();\n            is.close();\n        };\n        String mimeType = MimeMapper.getMimeType(FilenameUtils.getExtension(fileName));\n        return Response.ok(stream).type(mimeType).build();\n    }\n\n    private static class HttpStreamHandlerImpl implements HttpStreamHandler {\n        private FileChannel fileChannel = null;\n        private org.wso2.msf4j.Response response;\n\n        public HttpStreamHandlerImpl(String fileName) throws FileNotFoundException {\n            File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n            if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {\n                fileChannel = new FileOutputStream(file).getChannel();\n            }\n        }\n\n        @Override\n        public void init(org.wso2.msf4j.Response response) {\n            this.response = response;\n        }\n\n        @Override\n        public void end() throws Exception {\n            fileChannel.close();\n            response.setStatus(Response.Status.ACCEPTED.getStatusCode());\n            response.send();\n        }\n\n        @Override\n        public void chunk(ByteBuffer content) throws Exception {\n            if (fileChannel == null) {\n                throw new IOException(\"Unable to write file\");\n            }\n            fileChannel.write(content);\n        }\n\n        @Override\n        public void error(Throwable cause) {\n            try {\n                if (fileChannel != null) {\n                    fileChannel.close();\n                }\n            } catch (IOException e) {\n                // Log if unable to close the output stream\n                log.error(\"Unable to close file output stream\", e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/formparam/README.md",
    "content": "#  MSF4J FormParam Support\nIn JAX-RS, we can use @FormParam annotation to bind HTML form parameters value to a Java method. \nMSF4J supports below content types for FormParam\n1. application/x-www-form-urlencoded\n2. multipart/form-data\n\n### For the application/x-www-form-urlencoded \nThis is pretty much similar to the QueryParam. MSF4J reads the Request body and get the decode the encoded values and pass the values to the service.\n\nE.g.\nSample service for application/x-www-form-urlencoded content type\n```java\n@POST\n@Path(\"/formParam\")\npublic Response testFormParam(@FormParam(\"age\") int age, @FormParam(\"name\") String name) {\n   System.out.println(\"Name \" + name);\n   System.out.println(\"Age\" + age);\n   return Response.ok().entity(\"Name and age \" + name + \", \" + age).build();\n}\n```\nParameters should be based on http://docs.oracle.com/javaee/7/api/javax/ws/rs/FormParam.html\n\n### For the multipart/form-data\n```java\n@POST\n@Path(\"/formParam\")\n@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})\npublic Response testFormParam(@FormParam(\"age\") int age, @FormParam(\"name\") String name) {\n   System.out.println(\"Name \" + name);\n   System.out.println(\"Age\" + age);\n   return Response.ok().entity(\"Name and age \" + name + \", \" + age).build();\n}\n```\nIf a user wants, MSF4J will not process the stream but rather directly pass an FormParamIterator which can be used to retrieve the parameter values. \nYou can inject that with @Context  annotation. Type must be FormParamIterator.\ne.g.\n```java\npublic Response simpleFormStreaming(@Context FormParamIterator formParamIterator) {\n```\nFormParamIterator.next() and FormParamIterator.hasNext() method can be used to retrieve and check if more items are available.\nFormParamIterator.next() returns a **FormItem** object which is corresponding to a item in the form. \nFormItem.openStream() returns an InputStream for the particular item of the form.\nFormItem.getContentType() returns the content type of the item\nFormItem.getFieldName() returns the name of the item\n\nE.g.\nSample service for multipart/form-data content-type with file upload\n```java\n@POST\n@Path(\"/simpleFormStreaming\")\n@Consumes(MediaType.MULTIPART_FORM_DATA)\npublic Response simpleFormStreaming(@Context FormParamIterator formParamIterator) {\n   try {\n       while (formParamIterator.hasNext()) {\n           FormItem item = formParamIterator.next();\n           if (item.isFormField()) {\n               System.out.println(item.getFieldName() + \" - \" + StreamUtil.asString(item.openStream()));\n           } else {\n               Files.copy(item.openStream(), Paths.get(System.getProperty(\"java.io.tmpdir\"), item.getName()));\n           }\n       }\n   } catch (FileUploadException e) {\n       log.error(\"Error while uploading the file \" + e.getMessage(), e);\n   } catch (IOException e) {\n       log.error(\"Unable to upload the file \" + e.getMessage(), e);\n   }\n   return Response.ok().entity(\"Request completed\").build();\n}\n```\nIf you like use non streaming mode then you can directly get File objects in a file upload. Here rather than @FormParam you need to use *@FormDataParam* annotation. This annotation can be used with all FormParam supported data types plus File and bean types as well as InputStreams.\n\nIf you want to upload set of files. Then a sample service would be like as follows:\n```java\n@POST\n@Path(\"/multipleFiles\")\n@Consumes(MediaType.MULTIPART_FORM_DATA)\npublic Response multipleFiles(@FormDataParam(\"files\") List<File> files) {\n   files.forEach(file -> {\n       try {\n           Files.copy(file.toPath(), Paths.get(System.getProperty(\"java.io.tmpdir\"), file.getName()));\n       } catch (IOException e) {\n           log.error(\"Error while Copying the file \" + e.getMessage(), e);\n       }\n   });\n   return Response.ok().entity(\"Request completed\").build();\n}\n```\nYou can use more complex times with combination of primitives, beans and files as follows\n```java\n@POST\n@Path(\"/complexForm\")\n@Consumes(MediaType.MULTIPART_FORM_DATA)\npublic Response complexForm(@FormDataParam(\"file\") File file,\n                       @FormDataParam(\"id\") int id,\n                       @FormDataParam(\"people\") List<Person> personList,\n                       @FormDataParam(\"company\") Company animal) {\n   System.out.println(\"First Person in List \" + personList.get(0).getName());\n   System.out.println(\"Id \" + id);\n   System.out.println(\"Company \" + animal.getType());\n   try {\n       Files.copy(file.toPath(), Paths.get(System.getProperty(\"java.io.tmpdir\"), file.getName()));\n   } catch (IOException e) {\n       log.error(\"Error while Copying the file \" + e.getMessage(), e);\n   }\n   return Response.ok().entity(\"Request completed\").build();\n}\n```\n\nIf you like to get the InputStream of a file then you can go ahead like below example. There FileInfo bean will hold the filename and the content type attributes of the particular inputstream. Note that attribute names must be equal when you use InpuStream. Here I’ve used ‘file’ for the both params.\n```java\n@POST\n@Path(\"/streamFile\")\n@Consumes(MediaType.MULTIPART_FORM_DATA)\npublic Response multipleFiles(@FormDataParam(\"file\") FileInfo fileInfo,\n                             @FormDataParam(\"file\") InputStream inputStream) {\n   try {\n       Files.copy(inputStream, Paths.get(System.getProperty(\"java.io.tmpdir\"), fileInfo.getFileName()));\n   } catch (IOException e) {\n       log.error(\"Error while Copying the file \" + e.getMessage(), e);\n       return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();\n   } finally {\n       IOUtils.closeQuietly(inputStream);\n   }\n   return Response.ok().entity(\"Request completed\").build();\n}\n```\n\n# FormParam Sample\n\nThis is the MSF4J sample which demonstrate how to use FormParam.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom this directory, run\n```\njava -jar target/formparam-*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\nSimple client is also available in the sample\n\n## Sample CURL Commands \n1. For simpleForm and simpleFormWithFormParam operations in the FormService. Change the url based on the operations you invoke\n```\ncurl -X POST -H \"Content-Type: application/x-www-form-urlencoded\" -d 'name=WSO2&age=10' \"http://localhost:9090/formService/simpleFormWithFormParam\"\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"name=WSO2\" -F \"age=10\" \"http://localhost:9090/formService/simpleFormWithFormParam\"\n```\n2. For simpleFormWithFormParamAndList, simpleFormWithFormParamAndSet and simpleFormWithFormParamAndSortedSet operations in the FormService. Change the url based on the operations you invoke\n```\ncurl -X POST -H \"Content-Type: application/x-www-form-urlencoded\" -d 'name=WSO2&name=IBM' \"http://localhost:9090/formService/simpleFormWithFormParamAndList\"\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"name=WSO2\" -F \"name=IBM\" -F \"name=Oracle\" \"http://localhost:9090/formService/simpleFormWithFormParamAndList\"\n```\n3. For simpleFormStreaming operation in the FormService\n```\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"name=WSO2\" -F \"age=10\" -F \"image=@abc.png\" \"http://localhost:9090/formService/simpleFormStreaming\"\n```\nYou can also use a simple html form like below or a rest client e.g. Postman, Advanced RestClient\n```html\n<form method=\"post\" action=\"http://localhost:9090/formService/simpleFormStreaming\">\n    <table>\n        <tr>\n    \t    <td>Name:</td>\n    \t    <td><input type=\"text\" name=\"name\" /></td>\n        </tr>\n        <tr>\n    \t    <td>Age:</td>\n    \t    <td><input type=\"text\" name=\"age\" /></td>\n        </tr>\n        <tr>\n    \t    <td>Photo:</td>\n    \t    <td><input type=\"file\" name=\"photo\" /></td>\n        </tr>\n        <tr>\n    \t    <td colspan=\"1\"><input name=\"submit\" type=\"submit\" value=\"Add User\" /></td>\n        </tr>\n    </table>\n</form>\n```\n\n4. For multipleFiles operation in the FormService\n```\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"files=@file1.txt\" -F \"files=@file2.jpg\" \"http://localhost:9090/formService/multipleFiles\"\n```\n5. For streamFile operation in the FormService\n```\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"file=@file1.txt\" \"http://localhost:9090/formService/streamFile\"\n```\nPlease refer to the SampleClient code to invoke the complexForm operation\n"
  },
  {
    "path": "samples/formparam/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>formparam</artifactId>\n\n    <name>Sample: FormParam Service</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.apache.httpcomponents</groupId>\n            <artifactId>httpmime</artifactId>\n            <version>4.3.1.wso2v1</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "samples/formparam/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner().deploy(new FormService()).start();\n    }\n}\n"
  },
  {
    "path": "samples/formparam/src/main/java/org/wso2/msf4j/example/FormService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.apache.commons.io.IOUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.example.bean.Company;\nimport org.wso2.msf4j.example.bean.Person;\nimport org.wso2.msf4j.formparam.FileInfo;\nimport org.wso2.msf4j.formparam.FormDataParam;\nimport org.wso2.msf4j.formparam.FormItem;\nimport org.wso2.msf4j.formparam.FormParamIterator;\nimport org.wso2.msf4j.formparam.exception.FormUploadException;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\n\n/**\n * Sample FormParam Service class.\n *\n */\n@Path(\"/formService\")\npublic class FormService {\n\n    private static final Logger log = LoggerFactory.getLogger(FormService.class);\n\n    @POST\n    @Path(\"/simpleFormWithFormParam\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleFormWithFormParam(@FormParam(\"age\") Long age, @FormParam(\"name\") String name) {\n        return Response.ok().entity(\"Name and age \" + name + \", \" + age).build();\n    }\n\n    @POST\n    @Path(\"/simpleFormWithFormParamAndList\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleFormWithFormParamAndList(@FormParam(\"name\") List<String> name) {\n        return Response.ok().entity(name).build();\n    }\n\n    @POST\n    @Path(\"/simpleFormWithFormParamAndSet\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleFormWithFormParamAndSet(@FormParam(\"name\") Set<String> name) {\n        return Response.ok().entity(name).build();\n    }\n\n    @POST\n    @Path(\"/simpleFormWithFormParamAndSortedSet\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleFormWithFormParamAndSortedSet(@FormParam(\"name\") SortedSet<String> name) {\n        return Response.ok().entity(name).build();\n    }\n\n    @POST\n    @Path(\"/simpleForm\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleForm(@FormDataParam(\"age\") int age, @FormDataParam(\"name\") String name) {\n        return Response.ok().entity(\"Name and age \" + name + \", \" + age).build();\n    }\n\n    @POST\n    @Path(\"/simpleFormWithList\")\n    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA })\n    public Response simpleFormWithList(@FormDataParam(\"name\") List<String> name) {\n        return Response.ok().entity(\"Name \" + name).build();\n    }\n\n    @POST\n    @Path(\"/simpleFormStreaming\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response simpleFormStreaming(@Context FormParamIterator formParamIterator) {\n        StringBuilder response = new StringBuilder();\n        while (formParamIterator.hasNext()) {\n            FormItem item = formParamIterator.next();\n            InputStream inputStream = null;\n            try {\n                inputStream = item.openStream();\n                if (item.isFormField()) {\n                    System.out.println(item.getFieldName() + \" - \" + StreamUtil.asString(inputStream));\n                } else {\n                    Files.copy(inputStream, Paths.get(System.getProperty(\"java.io.tmpdir\"), item.getName()));\n                }\n            } catch (FormUploadException e) {\n                log.error(\"Error while uploading the file \" + e.getMessage(), e);\n                response.append(\"Error while uploading the file \").append(e.getMessage());\n            } catch (IOException e) {\n                log.error(\"Unable to upload the file \" + e.getMessage(), e);\n                response.append(\"Unable to upload the file \").append(e.getMessage());\n            } finally {\n                IOUtils.closeQuietly(inputStream);\n            }\n        }\n        if (!response.toString().isEmpty()) {\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(response.toString()).build();\n        }\n        return Response.ok().entity(\"Request completed\").build();\n    }\n\n    @POST\n    @Path(\"/complexForm\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response complexForm(@FormDataParam(\"file\") File file,\n                                @FormDataParam(\"id\") int id,\n                                @FormDataParam(\"people\") List<Person> personList,\n                                @FormDataParam(\"company\") Company company) {\n        System.out.println(\"First Person in List \" + personList.get(0).getName());\n        System.out.println(\"Id \" + id);\n        System.out.println(\"Company \" + company.getType());\n        try {\n            Files.copy(file.toPath(), Paths.get(System.getProperty(\"java.io.tmpdir\"), file.getName()));\n        } catch (IOException e) {\n            log.error(\"Error while Copying the file \" + e.getMessage(), e);\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();\n        }\n        return Response.ok().entity(\"Request completed\").build();\n    }\n\n    @POST\n    @Path(\"/multipleFiles\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response multipleFiles(@FormDataParam(\"files\") List<File> files) {\n        StringBuilder response = new StringBuilder();\n        files.forEach(file -> {\n            try {\n                Files.copy(file.toPath(), Paths.get(System.getProperty(\"java.io.tmpdir\"), file.getName()));\n            } catch (IOException e) {\n                response.append(\"Unable to upload the file \").append(e.getMessage());\n                log.error(\"Error while Copying the file \" + e.getMessage(), e);\n            }\n        });\n        if (!response.toString().isEmpty()) {\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(response.toString()).build();\n        }\n        return Response.ok().entity(\"Request completed\").build();\n    }\n\n    @POST\n    @Path(\"/streamFile\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response multipleFiles(@FormDataParam(\"file\") FileInfo fileInfo,\n                                  @FormDataParam(\"file\") InputStream inputStream) {\n        try {\n            Files.copy(inputStream, Paths.get(System.getProperty(\"java.io.tmpdir\"), fileInfo.getFileName()));\n        } catch (IOException e) {\n            log.error(\"Error while Copying the file \" + e.getMessage(), e);\n            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();\n        } finally {\n            IOUtils.closeQuietly(inputStream);\n        }\n        return Response.ok().entity(\"Request completed\").build();\n    }\n}\n"
  },
  {
    "path": "samples/formparam/src/main/java/org/wso2/msf4j/example/SampleClient.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.entity.ContentType;\nimport org.apache.http.entity.mime.MultipartEntityBuilder;\nimport org.apache.http.entity.mime.content.StringBody;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.formparam.util.StreamUtil;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\n\n/**\n * Sample Client to invoke the {{@link FormService}}\n */\npublic class SampleClient {\n    private static final Logger log = LoggerFactory.getLogger(SampleClient.class);\n\n    public static void main(String[] args) throws IOException {\n        HttpEntity messageEntity = createMessageForComplexForm();\n        // Uncomment the required message body based on the method that want to be used\n        //HttpEntity messageEntity = createMessageForMultipleFiles();\n        //HttpEntity messageEntity = createMessageForSimpleFormStreaming();\n\n        String serverUrl = \"http://localhost:8080/formService/complexForm\";\n        // Uncomment the required service url based on the method that want to be used\n        //String serverUrl = \"http://localhost:8080/formService/multipleFiles\";\n        //String serverUrl = \"http://localhost:8080/formService/simpleFormStreaming\";\n\n        URL url = URI.create(serverUrl).toURL();\n        HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n        connection.setDoOutput(true);\n        connection.setRequestMethod(\"POST\");\n        connection.setRequestProperty(\"Content-Type\", messageEntity.getContentType().getValue());\n        try (OutputStream out = connection.getOutputStream()) {\n            messageEntity.writeTo(out);\n        }\n\n        InputStream inputStream = connection.getInputStream();\n        String response = StreamUtil.asString(inputStream);\n        IOUtils.closeQuietly(inputStream);\n        connection.disconnect();\n        System.out.println(response);\n\n    }\n\n    private static HttpEntity createMessageForSimpleFormStreaming() {\n        HttpEntity reqEntity = null;\n        try {\n            reqEntity = MultipartEntityBuilder.create().addTextBody(\"name\", \"WSO2\").addTextBody(\"age\", \"10\")\n                                              .addBinaryBody(\"file\",\n                                                             new File(Thread.currentThread().getContextClassLoader().getResource(\"sample.txt\").toURI()),\n                                                             ContentType.DEFAULT_BINARY, \"sample.txt\").build();\n        } catch (URISyntaxException e) {\n            log.error(\"Error while getting the file from resource.\" + e.getMessage(), e);\n        }\n        return reqEntity;\n    }\n\n    private static HttpEntity createMessageForComplexForm() {\n        HttpEntity reqEntity = null;\n        try {\n            StringBody companyText = new StringBody(\"{\\\"type\\\": \\\"Open Source\\\"}\", ContentType.APPLICATION_JSON);\n            StringBody personList = new StringBody(\n                    \"[{\\\"name\\\":\\\"Richard Stallman\\\",\\\"age\\\":63}, {\\\"name\\\":\\\"Linus Torvalds\\\",\\\"age\\\":46}]\",\n                    ContentType.APPLICATION_JSON);\n            reqEntity = MultipartEntityBuilder.create().addTextBody(\"id\", \"1\")\n                                              .addPart(\"company\", companyText)\n                                              .addPart(\"people\", personList).addBinaryBody(\"file\", new File(\n                            Thread.currentThread().getContextClassLoader().getResource(\"sample.txt\").toURI()), ContentType.DEFAULT_BINARY, \"sample.txt\")\n                                              .build();\n        } catch (URISyntaxException e) {\n            log.error(\"Error while getting the file from resource.\" + e.getMessage(), e);\n        }\n        return reqEntity;\n    }\n\n    private static HttpEntity createMessageForMultipleFiles() {\n        HttpEntity reqEntity = null;\n        try {\n            reqEntity = MultipartEntityBuilder.create().addBinaryBody(\"files\", new File(\n                    Thread.currentThread().getContextClassLoader().getResource(\"sample.txt\").toURI()), ContentType.DEFAULT_BINARY, \"sample.txt\")\n                                              .addBinaryBody(\"files\",\n                                                             new File(Thread.currentThread().getContextClassLoader().getResource(\"sample.jpg\").toURI()),\n                                                             ContentType.DEFAULT_BINARY, \"sample.jpg\").build();\n        } catch (URISyntaxException e) {\n            log.error(\"Error while getting the file from resource.\" + e.getMessage(), e);\n        }\n        return reqEntity;\n    }\n}\n"
  },
  {
    "path": "samples/formparam/src/main/java/org/wso2/msf4j/example/bean/Company.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example.bean;\n\n/**\n * Simple bean class for a company\n */\npublic class Company {\n    private String type;\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    @Override\n    public String toString() {\n        return \"Company {\" +\n               \"type='\" + type + '\\'' +\n               '}';\n    }\n}\n"
  },
  {
    "path": "samples/formparam/src/main/java/org/wso2/msf4j/example/bean/Person.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example.bean;\n\n/**\n * Simple Bean class for a Person\n */\npublic class Person {\n    private String name;\n    private int age;\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String toString() {\n        return \"Person{\" +\n               \"name='\" + name + '\\'' +\n               \", age=\" + age +\n               '}';\n    }\n}\n"
  },
  {
    "path": "samples/formparam/src/main/resources/sample.txt",
    "content": "This is a sample txt file"
  },
  {
    "path": "samples/helloworld/README.md",
    "content": "# Hello Service Sample\n\nThis is the MSF4J Hello World sample that reponds to you saying hello.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom the target directory, run\n```\njava -jar helloworld-*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\n\n```\ncurl http://localhost:9090/hello/wso2\n```\n\nYou should get a response similar to the following:\n\n```\nHello wso2\n```\n"
  },
  {
    "path": "samples/helloworld/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>helloworld</artifactId>\n\n    <name>Sample: Hello World Microservice</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/helloworld/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new HelloService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/helloworld/src/main/java/org/wso2/msf4j/example/HelloService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Hello service resource class.\n */\n@Path(\"/hello\")\npublic class HelloService {\n\n    @GET\n    @Path(\"/{name}\")\n    public String hello(@PathParam(\"name\") String name) {\n        System.out.println(\"Hello\");\n        return \"Hello \" + name;\n    }\n}\n"
  },
  {
    "path": "samples/http-monitoring/README.md",
    "content": "# HTTP Monitoring Sample\n\nThis sample shows the use of HTTP Monitoring Interceptor.\n\nHTTP Monitoring events are published to WSO2 Data Analytics Server (DAS).\n\nThe HTTP Monitoring Interceptor is configured using a YAML file. The default \"http-monitoring.yaml\" is included in final the JAR.\n\nThe HTTP Monitoring is disabled by default. In this sample, there is a custom http-monitoring.yaml file is added to enable the \nData Publisher to publish HTTP events to WSO2 DAS.\n\nThis samples also uses Metrics Interceptor and the Metrics is configured to publish events to WSO2 DAS. There is a metrics.yaml \nfile added to configure the Metrics DAS Reporter.\n\nSee also the [Metrics sample](../metrics).\n\n### HTTP Monitoring Annotation\n\nUse the @HTTPMonitored annotation when you want to monitor each HTTP request. \n\nSee [HTTP Monitoring Annotation](../../../../#http-monitoring-annotation) for more details.\n\nSee the following example to use the annotation at the Class level.\n\n```java\n@Path(\"/demo\")\n@HTTPMonitored\npublic class DemoService {\n\n}\n```\n\nSee the following example to use the annotation at the Method level.\n\n\n```java\n    @GET\n    @Path(\"/{nic}\")\n    @Produces(\"application/json\")\n    @HTTPMonitored\n    public Student getStudent(@PathParam(\"nic\") String nic) {\n        return students.get(nic);\n    }\n```\n\n**How to add and initialize HTTP Monitoring Interceptor**\n\n```java\nnew MicroservicesRunner().addInterceptor(new HTTPMonitoringInterceptor())\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nYou must first configure WSO2 Data Analytics Server (DAS) and run it in order to receive the events published by this sample.\nPlease refer the [analytics documentation](../../analytics)\nfor more information on configuring WSO2 DAS.\n\n## Running the sample\n\nNote: The Metrics DAS Reporters have a \"Polling Period\" in seconds. This is the period for polling metrics from the metric registry \nand reporting to WSO2 DAS. The HTTP Monitoring Interceptor sends events for each request.\n\nRun the JAR file in target directory.\n\n```\njava -jar target/http-monitoring*.jar\nOR\njava -Dmsf4j.conf=<MSF4J Deployment YAML configuration path> -jar target/http-monitoring*.jar\n```\n\n## How to test the sample\n\nUse the following cURL commands.\n```\ncurl -v http://localhost:9090/student/910760234V\n\ncurl -v --data \"{'nic':'860766123V','firstName':'Jack','lastName':'Black','age':29}\" -H \"Content-Type: application/json\" http://localhost:8080/student\n\ncurl -v http://localhost:9090/student/860766123V\n\ncurl -v http://localhost:9090/student\n\n```\n\n**Analytics Dashboard in WSO2 Data Analytics Server**\n\nThe HTTP Monitoring events sent by this sample can be seen from the HTTP Monitoring Dashboard in WSO2 DAS.\nYou can access the dashboard from [http://localhost:9763/monitoring/](http://localhost:9763/monitoring/).\n"
  },
  {
    "path": "samples/http-monitoring/data-agent-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<DataAgentsConfiguration>\n    <Agent>\n        <Name>Thrift</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.thrift.ThriftDataEndpoint</DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n\n    <Agent>\n        <Name>Binary</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.binary.BinaryDataEndpoint\n        </DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n</DataAgentsConfiguration>\n\n"
  },
  {
    "path": "samples/http-monitoring/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>http-monitoring</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: HTTP-Monitoring</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.sample.httpmonitoring.Application</microservice.mainClass>\n        <baseimage.name>java:openjdk-8u66-jre</baseimage.name>\n        <maven.dockerplugin.version>0.3.5</maven.dockerplugin.version>\n    </properties>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>com.spotify</groupId>\n                <artifactId>docker-maven-plugin</artifactId>\n                <version>${maven.dockerplugin.version}</version>\n                <configuration>\n                    <imageName>${project.artifactId}:${project.version}</imageName>\n                    <baseImage>${baseimage.name}</baseImage>\n                    <entryPoint>[\"java\", \"-jar\", \"/${project.build.finalName}.jar\"]</entryPoint>\n                    <!-- copy the service's jar file from target into the root directory of the image -->\n                    <resources>\n                        <resource>\n                            <targetPath>/</targetPath>\n                            <directory>${project.build.directory}</directory>\n                            <include>${project.build.finalName}.jar</include>\n                        </resource>\n                    </resources>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "samples/http-monitoring/src/main/java/org/wso2/msf4j/sample/httpmonitoring/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.sample.httpmonitoring;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\nimport org.wso2.msf4j.sample.httpmonitoring.service.StudentService;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private static final Logger logger = LoggerFactory.getLogger(Application.class);\n\n    public static void main(String[] args) {\n        logger.info(\"Starting the Microservice with HTTP Monitoring\");\n        new MicroservicesRunner()\n                .addInterceptor(new HTTPMonitoringInterceptor(), new MetricsInterceptor())\n                .deploy(new StudentService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/http-monitoring/src/main/java/org/wso2/msf4j/sample/httpmonitoring/service/Student.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.sample.httpmonitoring.service;\n\n/**\n * Student.\n */\npublic class Student {\n\n    private String nic;\n\n    private String firstName;\n\n    private String lastName;\n\n    private int age;\n\n    public Student() {\n    }\n\n    public String getNic() {\n        return nic;\n    }\n\n    public void setNic(String nic) {\n        this.nic = nic;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n}\n"
  },
  {
    "path": "samples/http-monitoring/src/main/java/org/wso2/msf4j/sample/httpmonitoring/service/StudentService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.sample.httpmonitoring.service;\n\n\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\n\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\n\n/**\n * StudentService class.\n */\n@Path(\"/student\")\n@Timed\npublic class StudentService {\n\n    private Map<String, Student> students = new ConcurrentHashMap<>();\n\n    public StudentService() {\n        Student student = new Student();\n        student.setNic(\"910760234V\");\n        student.setFirstName(\"Joseph\");\n        student.setLastName(\"Rodgers\");\n        student.setAge(14);\n        addStudent(student);\n    }\n\n    @GET\n    @Path(\"/{nic}\")\n    @Produces(\"application/json\")\n    @HTTPMonitored(tracing = true)\n    public Student getStudent(@PathParam(\"nic\") String nic) {\n        return students.get(nic);\n    }\n\n    @POST\n    @Consumes(\"application/json\")\n    @HTTPMonitored(tracing = true)\n    public void addStudent(Student student) {\n        students.put(student.getNic(), student);\n    }\n\n    @GET\n    @Produces(\"application/json\")\n    @HTTPMonitored\n    public Collection<Student> getAll() {\n        return students.values();\n    }\n\n}\n"
  },
  {
    "path": "samples/http-monitoring/src/main/resources/deployment.yaml",
    "content": "# Copyright 2017 WSO2 Inc. (http://wso2.org)\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  # MSF4J Analytics configuration\nwso2.msf4j.analytics.configuration:\n    # Whether HTTP Monitoring is enables or not\n  enabled: false\n    # DAS configuration\n  das:\n      # The type used with Data Publisher\n    type: thrift\n      # Data Receiver URL used by the Data Publisher\n    receiverURL: tcp://localhost:7611\n    username: admin\n    password: admin\n      # The path for Data Bridge Agent configuration\n    dataAgentConfigPath: data-agent-config.xml"
  },
  {
    "path": "samples/http-monitoring/src/main/resources/http-monitoring.yaml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\nwso2.http.monitoring:\n  enabled: true\n\n  das:\n    receiverURL: tcp://localhost:7611\n    # authURL: ssl://localhost:7711\n    type: thrift\n    username: admin\n    password: admin\n    dataAgentConfigPath: data-agent-config.xml\n"
  },
  {
    "path": "samples/http-monitoring/src/main/resources/metrics.yaml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nwso2.metrics:\n  enabled: true\n\n  jmx:\n    registerMBean: true\n    name: org.wso2.msf4j:type=Metrics\n\n  das:\n    - &DAS01\n      receiverURL: tcp://localhost:7611\n      # authURL: ssl://localhost:7711\n      type: thrift\n      username: admin\n      password: admin\n      dataAgentConfigPath: data-agent-config.xml\n\n  reporting:\n    jmx:\n      - name: JMX\n        enabled: true\n\n    console:\n      - name: Console\n        enabled: false\n        pollingPeriod: 30\n\n    csv:\n      - name: CSV\n        enabled: false\n        location: metrics\n        pollingPeriod: 30\n\n    slf4j:\n      - name: SLF4J\n        enabled: true\n        loggerName: metrics\n        pollingPeriod: 30\n\n    das:\n      - name: DAS\n        enabled: true\n        das: *DAS01\n        pollingPeriod: 30\n"
  },
  {
    "path": "samples/http-session/README.md",
    "content": "# Session-aware Service Sample\n\nThis sample demonstrates how to use HTTP sessions in your microservice.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom the target directory, run\n\n```\njava -jar session-*.jar\n```\n\n## How to test the sample\n\nPoint your Web browser to [http://localhost:9090](http://localhost:9090) & keep refreshing the page.\n\nYou will see the count being printed on the browser window, and everytime you refresh, the count will be incremented \nand once the count reaches 100, it will be reset because the session is invalidated.\n\nYou can also use cURL or any other REST client to invoke your service.\n\n```\ncurl -v http://localhost:9090\n```\n\nYou should get a response similar to the following:\n\n```\n> \n< HTTP/1.1 200 OK\n< Connection: keep-alive\n< Set-Cookie: JSESSIONID=3508015E4EF0ECA8C4B761FCC4BC1718\n< Content-Length: 1\n< Content-Type: */*\n< \n* Connection #0 to host localhost left intact\n1\n```\n\nNext we will send the JSESSIONID cookie with the curl requests so that the same session can be referred to on the service\nend.\n\n```\ncurl --header \"Cookie:  JSESSIONID=3508015E4EF0ECA8C4B761FCC4BC1718\" http://localhost:9090\n```\n\nKeep repeating the above command and you should see that the counter being incremented upto 100, and then being reset.\nOnce the counter gets reset, you will need to retrieve the new JSESSIONID and repeat the requests."
  },
  {
    "path": "samples/http-session/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>session</artifactId>\n\n    <name>Sample: Session-aware Microservice</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/http-session/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.PersistentSessionManager;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new CounterService())\n                .setSessionManager(new PersistentSessionManager())  // this is optional\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/http-session/src/main/java/org/wso2/msf4j/example/CounterService.java",
    "content": "/*\n *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Session;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Context;\n\n/**\n * Session-aware counter service which counts &amp; returns the number of requests from each session.\n */\n@Path(\"/\")\npublic class CounterService {\n\n    private static final String COUNTER = \"counter\";\n\n    @GET\n    public int count(@Context Request request) {\n        Session session = request.getSession();\n\n        // Create & set the counter in the session\n        Object attribute = session.getAttribute(COUNTER);\n        if (attribute == null) {\n            attribute = 0;\n        }\n        int counter = (int) attribute;\n        counter++;\n        session.setAttribute(COUNTER, counter);\n\n        // Invalidate this session if the count goes beyond 100\n        if (counter >= 100) {\n            session.invalidate();\n        }\n        return counter;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/README.md",
    "content": "# Applying interceptors\n\n* Please refer [MSF4J Interceptors - Common](../interceptor/interceptor-common) for writing request and response interceptors\n* Please refer [MSF4J Interceptor Service - Fat Jar mode](../interceptor/fatjar-interceptor-service) for using interceptors in fat jar mode\n* Please refer [MSF4J Interceptor Service - Deployable Jar mode](../interceptor/deployable-jar-interceptor-service) for using interceptors in deployable jar mode\n* Please refer [MSF4J Interceptor Service - OSGi mode](../interceptor/osgi-interceptor-service) for using interceptors in OSGi mode\n* Please refer [MSF4J Interceptors with MSF4J Spring - Fat Jar mode](../spring-fatjar-interceptor-service) for using interceptors with MSF4J Spring in fat jar mode\n\n# Priority order of Interceptors\n\n## General order of interceptors\n1) Global request interceptors\n2) Class level annotated request interceptors\n3) Method level annotated request interceptors\n4) Resource method execution\n5) Sub-resource class level annotated request interceptors\n6) Sub-resource method level annotated request interceptors\n7) Sub-resource execution\n8) Sub-resource method level annotated response interceptors\n9) Sub-resource class level annotated response interceptors\n10) Method level annotated response interceptors\n11) Class level annotated response interceptors\n12) Global response interceptors\n\nPriority of the interceptors in the global level will be exactly the order in which\nthey are registered (order in which they are written)\n\n\nPriority for resource / sub-resource interceptors will be the order in which they are\nwritten inside the @RequestInterceptor / @ResponseInterceptor annotation.\n\n# Special notes\n### Why not use JAX-RS @NameBinding ?\n\n* The performance hit in fat jar at the service start time would be significant (when scanning request and response interceptors at the start time)\n* The developer has to write annotations for each different request or response filter he/she introduces.\n* Not fail safe when introducing global interceptors (humans are error prone)"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/README.md",
    "content": "# Request and response interceptors MSF4J deployable jar Sample\n\nThis sample demonstrates how to create deployable interceptors for hot deployment.\n\n* See also; [MSF4J Interceptor Service - Fat Jar mode](../fatjar-interceptor-service)\n* See also; [MSF4J Interceptor Service - OSGi mode](../osgi-interceptor-service)\n* See also; [MSF4J Interceptors with MSF4J Spring - Fat Jar mode](../spring-fatjar-interceptor-service)\n\n```java\n@Path(\"/interceptor-service\")\npublic class InterceptorService implements Microservice {\n\n    // resource methods are here..\n\n}\n```\n\nYou have to add full classpath of the microservice class in <microservice.resourceClasses> under properties in the pom\n.xml of deployable jar as shown in the following code.\n\n```xml\n    <properties>\n        <microservice.resourceClasses>org.wso2.msf4j.samples.deployablejarinterceptorservice.InterceptorService</microservice.resourceClasses>\n    </properties>\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFirst you need to install the MSF4J feature in to carbon kernel. To proceed with this navigate to [MSF4J Kernel pom](../../../tests/test-distribution/)\n(test distribution pom) and execute the command below:\n```\nmvn clean install\n```\nThis will install the msf4j and other required features to the kernel and build up a product.\nYou can find the product in the resources/target directory\n\nGo to the target/wso2msf4j-<version>/bin directory\nThen run the following command to start the MSF4J server.\n```\n./carbon.sh\n```\n\nFinally copy the target/deployable-jar-interceptor-service-\\<version>.jar to deployment/microservices directory of MSF4J server.\nThis will trigger the jar to be automatically deployed during the server runtime.\n\n## How to test the sample\n\nUse following cURL commands.\n```\ncurl http://localhost:9090/interceptor-service/service-name\n```"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.samples</groupId>\n    <artifactId>deployable-jar-interceptor-service</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Deployable Jar Interceptor Service</name>\n    <url>http://maven.apache.org</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.resourceClasses>org.wso2.msf4j.samples.deployablejarinterceptorservice.InterceptorService\n        </microservice.resourceClasses>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/InterceptorService.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\nimport org.wso2.msf4j.internal.DataHolder;\nimport org.wso2.msf4j.internal.MSF4JConstants;\nimport org.wso2.msf4j.internal.MicroservicesRegistryImpl;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.HTTPRequestLogger;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.HTTPResponseLogger;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.LogTextResponseInterceptor;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.PropertyAddRequestInterceptor;\nimport org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors.PropertyGetResponseInterceptor;\n\nimport java.util.Map;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n/**\n * Interceptor example micro-service class.\n */\n@Path(\"/interceptor-service\")\npublic class InterceptorService implements Microservice {\n\n    private static final Logger log = LoggerFactory.getLogger(InterceptorService.class);\n\n    public InterceptorService() {\n        Map<String, MicroservicesRegistryImpl> microservicesRegistryMap = DataHolder.getInstance()\n                .getMicroservicesRegistries();\n        MicroservicesRegistryImpl microServicesRegistry = microservicesRegistryMap.get(MSF4JConstants.CHANNEL_ID);\n\n        if (microServicesRegistry != null) {\n            addInterceptorsToRegistry(microServicesRegistry);\n        } else {\n            microservicesRegistryMap.values().forEach(this::addInterceptorsToRegistry);\n        }\n    }\n\n    /**\n     * Method for getting the micro-service name.\n     * curl http://localhost:9090/interceptor-service/service-name\n     *\n     * @return name of the micro-service.\n     */\n    @GET\n    @Path(\"/service-name\")\n    @RequestInterceptor({HTTPRequestLogger.class, LogTextRequestInterceptor.class})\n    @ResponseInterceptor({HTTPResponseLogger.class, LogTextResponseInterceptor.class})\n    public String getServiceName() {\n        log.info(\"HTTP Method Execution - getServiceName()\");\n        return \"Interceptor example micro-service\";\n    }\n\n    /**\n     * Add interceptors for the micro-services registry.\n     *\n     * @param microServicesRegistry MicroService Registry instance\n     */\n    private void addInterceptorsToRegistry(MicroservicesRegistryImpl microServicesRegistry) {\n        microServicesRegistry\n                .addGlobalRequestInterceptor(new LogTextRequestInterceptor(), new PropertyAddRequestInterceptor());\n        microServicesRegistry\n                .addGlobalResponseInterceptor(new LogTextResponseInterceptor(), new PropertyGetResponseInterceptor());\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/HTTPRequestLogger.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Class for logging HTTP requests.\n */\npublic class HTTPRequestLogger implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(HTTPRequestLogger.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        log.info(\"Logging HTTP request { HTTPMethod: \" + request.getHttpMethod() + \", URI: \" + request.getUri() + \"}\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/HTTPResponseLogger.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * HTTP response logging class.\n */\npublic class HTTPResponseLogger implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(HTTPResponseLogger.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        log.info(\"Logging HTTP response { Status code: \" + response.getStatusCode() + \" }\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/LogTextRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Interceptor to log some text.\n */\npublic class LogTextRequestInterceptor implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(LogTextRequestInterceptor.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        log.info(\"Text logger request interceptor\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/LogTextResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * Interceptor to log some text.\n */\npublic class LogTextResponseInterceptor implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(LogTextResponseInterceptor.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        log.info(\"Text logger response interceptor\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/PropertyAddRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Interceptor demonstrating setting a property.\n */\npublic class PropertyAddRequestInterceptor implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(PropertyAddRequestInterceptor.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        String propertyName = \"SampleProperty\";\n        String property = \"Sample Object\";\n        request.setProperty(propertyName, property);\n        log.info(\"Property {} set to request\", propertyName);\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/deployable-jar-interceptor-service/src/main/java/org/wso2/msf4j/samples/deployablejarinterceptorservice/interceptors/PropertyGetResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.deployablejarinterceptorservice.interceptors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * Interceptor demonstrating getting a property.\n */\npublic class PropertyGetResponseInterceptor implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(PropertyGetResponseInterceptor.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        String propertyName = \"SampleProperty\";\n        String property = (String) request.getProperty(propertyName);\n        log.info(\"Value of property {} is {} \", propertyName, property);\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/fatjar-interceptor-service/README.md",
    "content": "# Request and response interceptors MSF4J fat jar Sample\n\nA fat jar is a jar file which includes all the dependencies in one fat (uber) jar. This mode of creating a fat jar\nand running it in a Java process is also referred to as server-less execution.\n\n* See also; [MSF4J Interceptor Service - Deployable Jar mode](../deployable-jar-interceptor-service)\n* See also; [MSF4J Interceptor Service - OSGi mode](../osgi-interceptor-service)\n* See also; [MSF4J Interceptors with MSF4J Spring - Fat Jar mode](../spring-fatjar-interceptor-service)\n\n## Writing the pom.xml \n\nYour POM can inherit from [msf4j-service](../../../poms/msf4j-service). \nSee details [here](../../../poms/msf4j-service).\n\nThe pom should include the following plugins\n\n```xml\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.skife.maven</groupId>\n                <artifactId>really-executable-jar-maven-plugin</artifactId>\n                <version>${maven.reallyexecutablejarplugin.version}</version>\n                <configuration>\n                    <programFile>restinterceptor</programFile>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>really-executable-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n```\n\nThe pom should include the following properties\n\n```xml\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.samples.fatjarinterceptorservice.Application</microservice.mainClass>\n    </properties>\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n\nUse following command to run the application\n```\njava -jar target/fatjar-interceptor-service-\\<version>.jar\n```\n\n## How to test the sample\n\nUse following cURL command.\n\n```\ncurl http://localhost:9090/interceptor-service/service-name\n```\n\nYou should get a successful response if everything worked fine.\n\n## Invoking the service via HTTPS\n\nUse following cURL command.\n\n```\ncurl --insecure https://localhost:8444/interceptor-service/service-name\n```\n\nYou should get a successful response if everything worked fine."
  },
  {
    "path": "samples/interceptor/fatjar-interceptor-service/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n -  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n -\n -  WSO2 Inc. licenses this file to you under the Apache License,\n -  Version 2.0 (the \"License\"); you may not use this file except\n -  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,\n - software distributed under the License is distributed on an\n - \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n - KIND, either express or implied.  See the License for the\n - specific language governing permissions and limitations\n - under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.samples</groupId>\n    <artifactId>fatjar-interceptor-service</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Fat Jar Interceptor Service</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j.samples</groupId>\n            <artifactId>interceptor-common</artifactId>\n            <version>${interceptor-common.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.skife.maven</groupId>\n                <artifactId>really-executable-jar-maven-plugin</artifactId>\n                <version>${maven.reallyexecutablejarplugin.version}</version>\n                <configuration>\n                    <programFile>fatjarinterceptor</programFile>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>really-executable-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <interceptor-common.version>2.8.14-SNAPSHOT</interceptor-common.version>\n        <microservice.mainClass>org.wso2.msf4j.samples.fatjarinterceptorservice.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/interceptor/fatjar-interceptor-service/src/main/java/org/wso2/msf4j/samples/fatjarinterceptorservice/Application.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.fatjarinterceptorservice;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyAddRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyGetResponseInterceptor;\n\n/**\n * Main class of starting the interceptor micro-service.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new InterceptorService())\n                .addGlobalRequestInterceptor(new LogTextRequestInterceptor(), new PropertyAddRequestInterceptor())\n                .addGlobalResponseInterceptor(new LogTextResponseInterceptor(), new PropertyGetResponseInterceptor())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/fatjar-interceptor-service/src/main/java/org/wso2/msf4j/samples/fatjarinterceptorservice/InterceptorService.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.fatjarinterceptorservice;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPRequestLogger;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPResponseLogger;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n/**\n * Interceptor example micro-service class.\n */\n@Path(\"/interceptor-service\")\npublic class InterceptorService {\n\n    private static final Logger log = LoggerFactory.getLogger(InterceptorService.class);\n\n    /**\n     * Method for getting the micro-service name.\n     * curl http://localhost:8080/interceptor-service/service-name\n     *\n     * @return name of the micro-service.\n     */\n    @GET\n    @Path(\"/service-name\")\n    @RequestInterceptor({HTTPRequestLogger.class, LogTextRequestInterceptor.class})\n    @ResponseInterceptor({HTTPResponseLogger.class, LogTextResponseInterceptor.class})\n    public String getServiceName() {\n        log.info(\"HTTP Method Execution - getServiceName()\");\n        return \"Interceptor example micro-service\";\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n -  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n -\n -  WSO2 Inc. licenses this file to you under the Apache License,\n -  Version 2.0 (the \"License\"); you may not use this file except\n -  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,\n - software distributed under the License is distributed on an\n - \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n - KIND, either express or implied.  See the License for the\n - specific language governing permissions and limitations\n - under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.samples</groupId>\n    <artifactId>interceptor-common</artifactId>\n    <name>Sample: Interceptor Common</name>\n    <packaging>bundle</packaging>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <import.package>\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.wso2.msf4j.*,\n            javax.ws.rs.*,\n            javax.xml.bind*,\n            org.slf4j.*,\n            io.swagger.annotations.*,\n            org.wso2.carbon.messaging.*\n        </import.package>\n        <export.package>org.wso2.msf4j.samples.interceptor.common.*</export.package>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/HTTPRequestLogger.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Class for logging HTTP requests.\n * Please note that the @Component annotation is only required in OSGI mode\n */\npublic class HTTPRequestLogger implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(HTTPRequestLogger.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        log.info(\"Logging HTTP request { HTTPMethod: {}, URI: {} }\", request.getHttpMethod(), request.getUri());\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/HTTPResponseLogger.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * HTTP response logging class.\n * Please note that the @Component annotation is only required in OSGI mode\n */\npublic class HTTPResponseLogger implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(HTTPResponseLogger.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        log.info(\"Logging HTTP response { Status code: {} }\", response.getStatusCode());\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/LogTextRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Interceptor to log some text.\n */\npublic class LogTextRequestInterceptor implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(LogTextRequestInterceptor.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        log.info(\"Text logger request interceptor\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/LogTextResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * Interceptor to log some text.\n */\npublic class LogTextResponseInterceptor implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(LogTextResponseInterceptor.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        log.info(\"Text logger response interceptor\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/PropertyAddRequestInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Interceptor demonstrating setting a property.\n */\npublic class PropertyAddRequestInterceptor implements RequestInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(PropertyAddRequestInterceptor.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        String propertyName = \"SampleProperty\";\n        String property = \"Sample Object\";\n        request.setProperty(propertyName, property);\n        log.info(\"Property {} set to request\", propertyName);\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/interceptor-common/src/main/java/org/wso2/msf4j/samples/interceptor/common/PropertyGetResponseInterceptor.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.interceptor.common;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.ResponseInterceptor;\n\n/**\n * Interceptor demonstrating getting a property.\n */\npublic class PropertyGetResponseInterceptor implements ResponseInterceptor {\n\n    private static final Logger log = LoggerFactory.getLogger(PropertyGetResponseInterceptor.class);\n\n    @Override\n    public boolean interceptResponse(Request request, Response response) throws Exception {\n        String propertyName = \"SampleProperty\";\n        String property = (String) request.getProperty(propertyName);\n        log.info(\"Value of property {} is {} \", propertyName, property);\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/osgi-interceptor-service/README.md",
    "content": "# Request and response interceptors MSF4J OSGi Bundle Sample\n\nThis sample demonstrates how to create MSF4J interceptors as an OSGi bundle.\n\n* See also; [MSF4J Interceptor Service - Fat Jar mode](../fatjar-interceptor-service)\n* See also; [MSF4J Interceptor Service - Deployable Jar mode](../deployable-jar-interceptor-service)\n* See also; [MSF4J Interceptors with MSF4J Spring - Fat Jar mode](../spring-fatjar-interceptor-service)\n\nIn this sample we have exposed the InterceptorService as an OSGi service that implements \norg.wso2.msf4j.Microservice interface as shown in the following code.\n\n```java\n@Component(\n        name = \"InterceptorService\",\n        service = Microservice.class,\n        immediate = true\n)\n@Path(\"/interceptor-service\")\npublic class InterceptorService implements Microservice {\n    \n\n    private static final Logger log = LoggerFactory.getLogger(InterceptorService.class);\n    \n\n    /**\n     * Method for getting the micro-service name.\n     *\n     * @return name of the micro-service.\n     */\n    @GET\n    @Path(\"/service-name\")\n    @RequestInterceptor(HTTPRequestLogger.class)\n    @ResponseInterceptor(HTTPResponseLogger.class)\n    public String getServiceName() {\n        log.info(\"HTTP Method Execution - getServiceName()\");\n        return \"WSO2 Service\";\n    }\n}\n```\n\nFurther more we have to define the request and response interceptor order. In order to proceed with include the \nfollowing dependency in the pom. This dependency will contain the interceptors to be used.\n\n```xml\n        <dependency>\n            <groupId>org.wso2.msf4j.samples</groupId>\n            <artifactId>interceptor-common</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n```\n\n###Defining the order of global interceptors\n\nPlease do refer to the [SampleInterceptorConfig](./src/main/java/org/wso2/msf4j/samples/osgiinterceptorservice/config/SampleInterceptorConfig.java)\nclass.\n\nIn here you inherit from the [OSGiInterceptorConfig](../../../core/src/main/java/org/wso2/msf4j/interceptor/OSGiInterceptorConfig.java)\nclass. All you need to do is to add a list of global request interceptors (optional) and global response interceptors \n(optional) using \"addGlobalRequestInterceptors\" and \"addGlobalResponseInterceptors\" respectively. The order in which you define\n the global interceptors are defined is the order in which they are executed.\n \nPlease do make sure to add the `@component` annotation as stated below.\n\n```java\n@Component(\n        name = \"SampleInterceptorConfig\",\n        service = OSGiInterceptorConfig.class,\n        immediate = true\n)\npublic class SampleInterceptorConfig extends OSGiInterceptorConfig {\n    @Override\n    public void createRequestInterceptors() {\n        addGlobalRequestInterceptors(new LogTextRequestInterceptor(), new PropertyAddRequestInterceptor());\n        addGlobalResponseInterceptors(new LogTextResponseInterceptor(), new PropertyGetResponseInterceptor());\n    }\n}\n```\n \n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n### <a name=\"osgiconsole\"></a>Using OSGi Console\n\nFirst you need to install the MSF4J feature in to carbon kernel. To proceed with this navigate to [MSF4J Kernel pom](../../../tests/test-distribution/)\n(test distribution pom) and execute the command below:\n```\nmvn clean install\n```\nThis will install the msf4j and other required features to the kernel and build up a product.\nYou can find the product in the resources/target directory\n\nGo to the target/wso2msf4j-<version>/bin directory\nThen run the following command to start the MSF4J server.\n```\n./carbon.sh\n```\n\nInstall the target/osgi-interceptor-service-\\<version>.jar and ../../interceptor-common/target/\ninterceptor-common-\\<version>.jar as an OSGi bundle to \ncarbon kernel using it's OSGi console with the following command.\n\n```\ninstall file://<path to target directory>/osgi-interceptor-service-\\<version>.jar\ninstall file://<path to target directory>/interceptor-common-\\<version>.jar\n```\n\nWhen the installation of the bundle is successful, use the bundle ID of the installed bundle to start  \nit. Use the following command in the OSGi console for that.\n\n```\nstart <bundle ID>\n```\n\nWhen the bundle is started, the microservice that is exposed as an OSGi service will be picked by the runtime and \nwill be exposed as a REST service.\n\n### Using dropins directory\nInstall MSF4J feature to the carbon kernel as described in section [Using OSGi Console](#osgiconsole)\n\nCopy the target/osgi-interceptor-service-\\<version>.jar and ../../interceptor-common/target/\ninterceptor-common-\\<version>.jar to [SERVER-HOME]/lib\" directory.\n\nThen navigate to the bin directory and run the following command to start WSO2 carbon kernel.\n```\n./carbon.sh\n```\nWhen the server is being started, the bundle in the dropins directory will be automatically \nloaded and it's microservices that are there as OSGi services will be exposed as REST services.\n\n\n## How to test the sample\n\nUse following cURL commands.\n```\ncurl http://localhost:9090/interceptor-service/service-name\n```"
  },
  {
    "path": "samples/interceptor/osgi-interceptor-service/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n -  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n -\n -  WSO2 Inc. licenses this file to you under the Apache License,\n -  Version 2.0 (the \"License\"); you may not use this file except\n -  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,\n - software distributed under the License is distributed on an\n - \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n - KIND, either express or implied.  See the License for the\n - specific language governing permissions and limitations\n - under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.samples</groupId>\n    <artifactId>osgi-interceptor-service</artifactId>\n    <packaging>bundle</packaging>\n    <name>Sample: OSGI Interceptor Service</name>\n    <url>http://maven.apache.org</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j.samples</groupId>\n            <artifactId>interceptor-common</artifactId>\n            <version>${interceptor-common.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-swagger</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <interceptor-common.version>2.8.14-SNAPSHOT</interceptor-common.version>\n        <maven-bundle-plugin.version>3.2.0</maven-bundle-plugin.version>\n        <import.package>\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.wso2.msf4j.*,\n            javax.ws.rs.*,\n            javax.xml.bind*,\n            org.slf4j.*,\n            io.swagger.annotations.*,\n            org.wso2.carbon.messaging.*\n        </import.package>\n        <export.package>\n            org.wso2.msf4j.samples.osgiinterceptorservice.*\n        </export.package>\n        <carbon.component>\n            osgi.service; objectClass=\"org.wso2.msf4j.Microservice\",\n            osgi.service; objectClass=\"org.wso2.msf4j.interceptor.OSGiInterceptorConfig\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/interceptor/osgi-interceptor-service/src/main/java/org/wso2/msf4j/samples/osgiinterceptorservice/InterceptorService.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.osgiinterceptorservice;\n\nimport org.osgi.service.component.annotations.Component;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPRequestLogger;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPResponseLogger;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n/**\n * Interceptor example micro-service class.\n */\n@Component(\n        name = \"org.wso2.msf4j.samples.osgiinterceptorservice.InterceptorService\",\n        service = Microservice.class,\n        immediate = true\n)\n@Path(\"/interceptor-service\")\npublic class InterceptorService implements Microservice {\n\n    private static final Logger log = LoggerFactory.getLogger(InterceptorService.class);\n\n    /**\n     * Method for getting the micro-service name.\n     * curl http://localhost:9090/interceptor-service/service-name\n     *\n     * @return name of the micro-service.\n     */\n    @GET\n    @Path(\"/service-name\")\n    @RequestInterceptor({HTTPRequestLogger.class, LogTextRequestInterceptor.class})\n    @ResponseInterceptor({HTTPResponseLogger.class, LogTextResponseInterceptor.class})\n    public String getServiceName() {\n        log.info(\"HTTP Method Execution - getServiceName()\");\n        return \"Interceptor example micro-service\";\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/osgi-interceptor-service/src/main/java/org/wso2/msf4j/samples/osgiinterceptorservice/config/SampleInterceptorConfig.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.osgiinterceptorservice.config;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.wso2.msf4j.interceptor.OSGiInterceptorConfig;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyAddRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyGetResponseInterceptor;\n\n/**\n * OSGi request interceptor configuration.\n */\n@Component(\n        name = \"org.wso2.msf4j.samples.osgiinterceptorservice.config.SampleInterceptorConfig\",\n        service = OSGiInterceptorConfig.class,\n        immediate = true\n)\npublic class SampleInterceptorConfig extends OSGiInterceptorConfig {\n\n    @Activate\n    protected void activate(BundleContext bundleContext) {\n        addGlobalRequestInterceptors(new LogTextRequestInterceptor(), new PropertyAddRequestInterceptor());\n        addGlobalResponseInterceptors(new LogTextResponseInterceptor(), new PropertyGetResponseInterceptor());\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/spring-fatjar-interceptor-service/README.md",
    "content": "# Request and response interceptors MSF4J Spring fat jar Sample\n\nA fat jar is a jar file which includes all the dependencies in one fat (uber) jar. This mode of creating a fat jar\nand running it in a Java process is also referred to as server-less execution.\n\n* See also; [MSF4J Interceptor Service - Fat Jar mode](../fatjar-interceptor-service)\n* See also; [MSF4J Interceptor Service - Deployable Jar mode](../deployable-jar-interceptor-service)\n* See also; [MSF4J Interceptor Service - OSGi mode](../osgi-interceptor-service)\n\n## Writing the pom.xml \n\nYour POM can inherit from [msf4j-service](../../../poms/msf4j-service). \nSee details [here](../../../poms/msf4j-service).\n\nThe pom should include the following plugins\n\n```xml\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.skife.maven</groupId>\n                <artifactId>really-executable-jar-maven-plugin</artifactId>\n                <version>${maven.reallyexecutablejarplugin.version}</version>\n                <configuration>\n                    <programFile>restinterceptor</programFile>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>really-executable-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n```\n\nThe pom should include the following properties\n\n```xml\n    <properties>\n        <microservice.mainClass>\n            org.wso2.msf4j.samples.springfatjarinterceptorservice.Application\n        </microservice.mainClass>\n    </properties>\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n\nUse following command to run the application\n```\njava -jar target/spring-fatjar-interceptor-service-\\<version>.jar\n```\n\n## How to test the sample\n\nUse following cURL command.\n\n```\ncurl http://localhost:8090/reception-service/say-hello/John\n```\n\nYou should get a hello response if everything worked fine (Hello John in this case)."
  },
  {
    "path": "samples/interceptor/spring-fatjar-interceptor-service/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n -  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n -\n -  WSO2 Inc. licenses this file to you under the Apache License,\n -  Version 2.0 (the \"License\"); you may not use this file except\n -  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,\n - software distributed under the License is distributed on an\n - \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n - KIND, either express or implied.  See the License for the\n - specific language governing permissions and limitations\n - under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.4.2-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.msf4j.samples</groupId>\n    <artifactId>spring-fatjar-interceptor-service</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Spring Fat Jar Interceptor Service</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j.samples</groupId>\n            <artifactId>interceptor-common</artifactId>\n            <version>${interceptor-common.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-spring</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.skife.maven</groupId>\n                <artifactId>really-executable-jar-maven-plugin</artifactId>\n                <version>${maven.reallyexecutablejarplugin.version}</version>\n                <configuration>\n                    <programFile>fatjarinterceptor</programFile>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>really-executable-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <properties>\n        <interceptor-common.version>2.4.2-SNAPSHOT</interceptor-common.version>\n        <microservice.mainClass>\n            org.wso2.msf4j.samples.springfatjarinterceptorservice.Application\n        </microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/interceptor/spring-fatjar-interceptor-service/src/main/java/org/wso2/msf4j/samples/springfatjarinterceptorservice/Application.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.springfatjarinterceptorservice;\n\nimport org.springframework.context.ConfigurableApplicationContext;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyAddRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.PropertyGetResponseInterceptor;\nimport org.wso2.msf4j.spring.MSF4JSpringApplication;\n\n/**\n * Main class of starting the spring interceptor demo.\n *\n * @since 2.4.2\n */\npublic class Application {\n    public static void main(String[] args) {\n        MSF4JSpringApplication msf4JSpringApplication = new MSF4JSpringApplication(ReceptionService.class);\n        ConfigurableApplicationContext configurableApplicationContext =\n                MSF4JSpringApplication.run(ReceptionService.class, \"--http.port=8090\");\n        msf4JSpringApplication.addService(configurableApplicationContext, ReceptionService.class,\n                \"/reception-service\")\n                .addGlobalRequestInterceptor(new LogTextRequestInterceptor(), new PropertyAddRequestInterceptor())\n                .addGlobalResponseInterceptor(new LogTextResponseInterceptor(), new PropertyGetResponseInterceptor());\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/spring-fatjar-interceptor-service/src/main/java/org/wso2/msf4j/samples/springfatjarinterceptorservice/CustomerService.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.samples.springfatjarinterceptorservice;\n\nimport org.springframework.stereotype.Component;\n\n/**\n * {@link CustomerService} class to be injected to {@link ReceptionService} resource through Spring.\n *\n * @since 2.4.2\n */\n@Component\npublic class CustomerService {\n\n    public String sayHello(String name) {\n        return \"Hello \" + name;\n    }\n}\n"
  },
  {
    "path": "samples/interceptor/spring-fatjar-interceptor-service/src/main/java/org/wso2/msf4j/samples/springfatjarinterceptorservice/ReceptionService.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.samples.springfatjarinterceptorservice;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPRequestLogger;\nimport org.wso2.msf4j.samples.interceptor.common.HTTPResponseLogger;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextRequestInterceptor;\nimport org.wso2.msf4j.samples.interceptor.common.LogTextResponseInterceptor;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Interceptor example MSF4J spring micro-service class.\n */\n@Component\n@Path(\"/reception-service\")\npublic class ReceptionService {\n\n    private static final Logger log = LoggerFactory.getLogger(ReceptionService.class);\n\n    @Autowired\n    private CustomerService customerService;\n\n    /**\n     * Method for saying hello to a customer.\n     *\n     * @return hello message for the customer\n     */\n    @GET\n    @Path(\"/say-hello/{name}\")\n    @RequestInterceptor({HTTPRequestLogger.class, LogTextRequestInterceptor.class})\n    @ResponseInterceptor({HTTPResponseLogger.class, LogTextResponseInterceptor.class})\n    public String sayHello(@PathParam(\"name\") String name) throws NoSuchMethodException {\n        log.info(\"HTTP Method Execution - \" + customerService.getClass().getMethod(\"sayHello\", String.class));\n        return customerService.sayHello(name);\n    }\n}\n"
  },
  {
    "path": "samples/jpa/README.md",
    "content": "# Helloworld JPA\n\nThis sample demonstrates how to use JPA API and Hibernate with WSO2 MSF4J framework. You can use in-memoery H2 database or MySQL database server with this sample. \n\n![Image of Sample] (https://raw.githubusercontent.com/sagara-gunathunga/msf4j-intro-webinar-samples/master/etc/jpa.png)\n\n# How to build and run using Maven \n\n1. Run following command \n\n```shell\nmvn clean package \n```\n \n2. Run the application using following java commend \n\n```shell\njava -jar target/jpa-*.jar\n```\n\n# How to test this sample \nUse following cURL commands\n\nAdd a sample user \n```shell\ncurl -v -X POST http://localhost:9090/users/fname/jhon/lname/snow \n```\n\nGet detailss of all the users \n\n```shell\ncurl -v http://localhost:9090/users \n```\n\nGet detailss of first user \n\n```shell\ncurl -v http://localhost:9090/users/1 \n```\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "samples/jpa/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>jpa</artifactId>\n\n    <properties>\n        <hibernate.version>5.0.1.Final</hibernate.version>\n        <netty.version>4.0.30.Final</netty.version>\n        <slf4j.version>1.7.5</slf4j.version>\n        <slf4j.log4j.version>1.6.0</slf4j.log4j.version>\n        <gson.version>2.2.4</gson.version>\n        <rs-api.version>2.0</rs-api.version>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n    <dependencies>\n\n        <dependency>\n            <groupId>org.hibernate</groupId>\n            <artifactId>hibernate-core</artifactId>\n            <version>${hibernate.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.hibernate</groupId>\n            <artifactId>hibernate-entitymanager</artifactId>\n            <version>${hibernate.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>com.h2database</groupId>\n            <artifactId>h2</artifactId>\n            <version>1.2.145</version>\n        </dependency>\n\n        <!--<dependency>-->\n            <!--<groupId>mysql</groupId>-->\n            <!--<artifactId>mysql-connector-java</artifactId>-->\n            <!--<version>5.1.36</version>-->\n        <!--</dependency>-->\n    </dependencies>\n</project>\n"
  },
  {
    "path": "samples/jpa/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.example.dao.UserRepository;\nimport org.wso2.msf4j.example.resource.UserResource;\n\nimport javax.persistence.Persistence;\n\n/**\n * Main Application class.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new UserResource(getUserRepository()))\n                .start();\n    }\n\n    public static UserRepository getUserRepository() {\n        return new UserRepository(Persistence.createEntityManagerFactory(\"org.hibernate.tutorial.jpa\"));\n    }\n\n}\n"
  },
  {
    "path": "samples/jpa/src/main/java/org/wso2/msf4j/example/dao/AbstractRepository.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example.dao;\n\nimport org.wso2.msf4j.example.model.User;\n\nimport java.util.List;\nimport javax.persistence.EntityManager;\nimport javax.persistence.EntityManagerFactory;\nimport javax.persistence.TypedQuery;\nimport javax.persistence.criteria.CriteriaBuilder;\nimport javax.persistence.criteria.CriteriaQuery;\nimport javax.persistence.criteria.Root;\n\n/**\n *\n * Abstract Repository class\n * @param <T>\n */\npublic abstract class AbstractRepository<T> {\n\n    private EntityManagerFactory emf;\n\n    public AbstractRepository(EntityManagerFactory emf) {\n        this.emf = emf;\n    }\n\n    protected EntityManager getEntityManager() {\n        return emf.createEntityManager();\n    }\n\n\n    protected void create(T t) {\n        EntityManager manager = getEntityManager();\n        manager.getTransaction().begin();\n        manager.persist(t);\n        manager.getTransaction().commit();\n        manager.close();\n    }\n\n    protected void remove(T t) {\n        EntityManager manager = getEntityManager();\n        manager.getTransaction().begin();\n        manager.remove(t);\n        manager.getTransaction().commit();\n        manager.close();\n    }\n\n    protected User find(long id) {\n        return getEntityManager().find(User.class, id);\n    }\n\n    protected List<T> findAll(Class<T> clazz) {\n        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();\n        CriteriaQuery<T> cq = cb.createQuery(clazz);\n        Root<T> rootEntry = cq.from(clazz);\n        CriteriaQuery<T> all = cq.select(rootEntry);\n        TypedQuery<T> allQuery = getEntityManager().createQuery(all);\n        return allQuery.getResultList();\n    }\n}\n"
  },
  {
    "path": "samples/jpa/src/main/java/org/wso2/msf4j/example/dao/UserRepository.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example.dao;\n\n\nimport org.wso2.msf4j.example.model.User;\n\nimport java.util.List;\nimport javax.persistence.EntityManagerFactory;\n\n/**\n * UserRepository class which is extended from AbstractRepository class.\n *\n */\npublic class UserRepository extends AbstractRepository<User> {\n\n    public UserRepository(EntityManagerFactory emf) {\n        super(emf);\n    }\n\n    public void createUser(User user) {\n        create(user);\n    }\n\n    public void removeUser(User user) {\n        remove(user);\n    }\n\n    public User findUser(long id) {\n        return find(id);\n    }\n\n    public List<User> findUsers() {\n        return findAll(User.class);\n    }\n}\n"
  },
  {
    "path": "samples/jpa/src/main/java/org/wso2/msf4j/example/model/User.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example.model;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.GeneratedValue;\nimport javax.persistence.GenerationType;\nimport javax.persistence.Id;\nimport javax.persistence.Table;\n\n/**\n * JPA annotated POJO class\n */\n\n@Entity\n@Table(name = \"user\")\npublic class User {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    Long id;\n\n    @Column\n    private String firstName;\n\n    @Column\n    private String lastName;\n\n    public User() {\n    }\n\n    public User(long id, String firstname, String lastname) {\n        this.id = id;\n        this.firstName = firstname;\n        this.lastName = lastname;\n    }\n\n    public User(String firstname, String lastname) {\n        this.firstName = firstname;\n        this.lastName = lastname;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n               \"id=\" + id +\n               \", firstName='\" + firstName + '\\'' +\n               \", lastName='\" + lastName + '\\'' +\n               '}';\n    }\n}\n"
  },
  {
    "path": "samples/jpa/src/main/java/org/wso2/msf4j/example/resource/UserResource.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example.resource;\n\nimport org.wso2.msf4j.example.dao.UserRepository;\nimport org.wso2.msf4j.example.model.User;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.Response;\n\n/**\n * Annotated Resource class.\n */\n\n@Path(\"/users\")\npublic class UserResource {\n\n    private UserRepository users;\n\n    public UserResource(UserRepository users) {\n        this.users = users;\n    }\n\n    @POST\n    @Path(\"/fname/{fname}/lname/{lname}\")\n    public Response addUser(@PathParam(\"fname\") String fname,\n                            @PathParam(\"lname\") String lname) {\n        User user = new User(fname, lname);\n        users.createUser(user);\n        return Response.accepted().build();\n    }\n\n    @GET\n    @Path(\"/{id}\")\n    public Response getUser(@PathParam(\"id\") long id) {\n        User user = users.findUser(id);\n        if (user != null) {\n            return Response.status(Response.Status.ACCEPTED).entity(user).build();\n        }\n        return Response.status(Response.Status.NOT_FOUND).build();\n    }\n\n    @GET\n    @Path(\"/\")\n    public Response getUsers() {\n        return Response.status(Response.Status.ACCEPTED).entity(users.findUsers()).build();\n    }\n\n}\n"
  },
  {
    "path": "samples/jpa/src/main/resources/META-INF/persistence.xml",
    "content": "<!--\n  ~ Hibernate, Relational Persistence for Idiomatic Java\n  ~\n  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as\n  ~ indicated by the @author tags or express copyright attribution\n  ~ statements applied by the authors.  All third-party contributions are\n  ~ distributed under license by Red Hat Inc.\n  ~\n  ~ This copyrighted material is made available to anyone wishing to use, modify,\n  ~ copy, or redistribute it subject to the terms and conditions of the GNU\n  ~ Lesser General Public License, as published by the Free Software Foundation.\n  ~\n  ~ This program is distributed in the hope that it will be useful,\n  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n  ~ for more details.\n  ~\n  ~ You should have received a copy of the GNU Lesser General Public License\n  ~ along with this distribution; if not, write to:\n  ~ Free Software Foundation, Inc.\n  ~ 51 Franklin Street, Fifth Floor\n  ~ Boston, MA  02110-1301  USA\n  -->\n<persistence xmlns=\"http://java.sun.com/xml/ns/persistence\"\n             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n             xsi:schemaLocation=\"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd\"\n             version=\"2.0\">\n\n    <persistence-unit name=\"org.hibernate.tutorial.jpa\">\n\n        <class>org.wso2.msf4j.example.model.User</class>\n\n        <!-- For in-memory H2 database -->\n        <properties>\n        <property name=\"javax.persistence.jdbc.driver\" value=\"org.h2.Driver\" />\n        <property name=\"javax.persistence.jdbc.url\" value=\"jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE\" />\n        <property name=\"javax.persistence.jdbc.user\" value=\"sa\" />\n        <property name=\"javax.persistence.jdbc.password\" value=\"\" />\n\n        <property name=\"hibernate.show_sql\" value=\"true\" />\n        <property name=\"hibernate.hbm2ddl.auto\" value=\"create\" />\n        </properties>\n\n        <!-- For MySQL database -->\n        <!--<properties>-->\n            <!--<property name=\"javax.persistence.jdbc.driver\" value=\"com.mysql.jdbc.Driver\"/>-->\n            <!--<property name=\"javax.persistence.jdbc.url\" value=\"jdbc:mysql://localhost:3306/users\"/>-->\n            <!--<property name=\"javax.persistence.jdbc.user\" value=\"root\"/>-->\n            <!--<property name=\"javax.persistence.jdbc.password\" value=\"root\"/>-->\n\n            <!--<property name=\"hibernate.show_sql\" value=\"true\"/>-->\n            <!--<property name=\"hibernate.connection.autocommit\" value=\"true\"/>-->\n        <!--</properties>-->\n\n    </persistence-unit>\n\n</persistence>\n"
  },
  {
    "path": "samples/jwt-claims/JWTAccessTokenBuilder/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>jwt-claims</artifactId>\n        <groupId>org.wso2.msf4j</groupId>\n        <version>2.8.14-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>JWTAccessTokenBuilder</artifactId>\n    <packaging>bundle</packaging>\n\n    <repositories>\n        <repository>\n            <id>wso2-nexus</id>\n            <name>WSO2 internal Repository</name>\n            <url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </repository>\n        <repository>\n            <id>wso2.snapshots</id>\n            <name>WSO2 Snapshot Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>\n            <snapshots>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n            </snapshots>\n            <releases>\n                <enabled>false</enabled>\n            </releases>\n        </repository>\n    </repositories>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.core</artifactId>\n            <version>4.4.3</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.identity</groupId>\n            <artifactId>org.wso2.carbon.claim.mgt</artifactId>\n            <version>5.1.0</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.user.api</artifactId>\n            <version>4.4.3</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.user.core</artifactId>\n            <version>4.4.3</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.utils</artifactId>\n            <version>4.4.3</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.identity</groupId>\n            <artifactId>org.wso2.carbon.identity.application.authentication.framework</artifactId>\n            <version>5.1.0</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.identity</groupId>\n            <artifactId>org.wso2.carbon.identity.oauth</artifactId>\n            <version>5.1.0</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-logging</groupId>\n            <artifactId>commons-logging</artifactId>\n            <version>1.0.4</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>2.0</version>\n                <configuration>\n                    <source>1.5</source>\n                    <target>1.5</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-scr-plugin</artifactId>\n                <version>1.0.10</version>\n                <executions>\n                    <execution>\n                        <id>generate-scr-scrdescriptor</id>\n                        <goals>\n                            <goal>scr</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n                <version>1.4.0</version>\n                <extensions>true</extensions>\n                <configuration>\n                    <instructions>\n                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>\n                        <Bundle-Name>${project.artifactId}</Bundle-Name>\n                        <Private-Package>\n                            com.wso2.jwt.token.builder.internal\n                        </Private-Package>\n                        <Export-Package>\n                            !com.wso2.jwt.token.builder.internal,\n                            com.wso2.jwt.token.builder.*,\n                        </Export-Package>\n                        <Import-Package>\n                            org.wso2.carbon.identity.application.authentication.framework.*\n                            *;resolution:=optional\n                        </Import-Package>\n                        <DynamicImport-Package>*</DynamicImport-Package>\n                    </instructions>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n\n\n</project>\n"
  },
  {
    "path": "samples/jwt-claims/JWTAccessTokenBuilder/src/main/java/com/wso2/jwt/token/builder/Constants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage com.wso2.jwt.token.builder;\n\n/**\n * Constants.\n */\npublic class Constants {\n\n    public static final String CUSTOMER_ID_CLAIM_URI = \"customer_id\";\n    public static final String KEY_STORE_EXTENSION = \".jks\";\n    public static final String AUTHORIZATION_PARTY = \"azp\";\n\n}\n"
  },
  {
    "path": "samples/jwt-claims/JWTAccessTokenBuilder/src/main/java/com/wso2/jwt/token/builder/JWTAccessTokenBuilder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage com.wso2.jwt.token.builder;\n\nimport com.nimbusds.jose.Algorithm;\nimport com.nimbusds.jose.JOSEException;\nimport com.nimbusds.jose.JWSAlgorithm;\nimport com.nimbusds.jose.JWSHeader;\nimport com.nimbusds.jose.JWSSigner;\nimport com.nimbusds.jose.crypto.RSASSASigner;\nimport com.nimbusds.jwt.JWTClaimsSet;\nimport com.nimbusds.jwt.PlainJWT;\nimport com.nimbusds.jwt.SignedJWT;\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.apache.oltu.oauth2.common.exception.OAuthSystemException;\nimport org.wso2.carbon.base.MultitenantConstants;\nimport org.wso2.carbon.core.util.KeyStoreManager;\nimport org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;\nimport org.wso2.carbon.identity.application.common.model.Claim;\nimport org.wso2.carbon.identity.application.common.model.ClaimMapping;\nimport org.wso2.carbon.identity.core.util.IdentityTenantUtil;\nimport org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;\nimport org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;\nimport org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext;\nimport org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;\nimport org.wso2.carbon.identity.oauth2.token.OauthTokenIssuerImpl;\nimport org.wso2.carbon.identity.oauth2.util.OAuth2Util;\n\nimport java.security.Key;\nimport java.security.interfaces.RSAPrivateKey;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * JWTAccessTokenBuilder.\n */\npublic class JWTAccessTokenBuilder extends OauthTokenIssuerImpl {\n\n    /**\n     * Signature algorithms\n     */\n    private static final String NONE = \"NONE\";\n    private static final String SHA256_WITH_RSA = \"SHA256withRSA\";\n    private static final String SHA384_WITH_RSA = \"SHA384withRSA\";\n    private static final String SHA512_WITH_RSA = \"SHA512withRSA\";\n    private static final String SHA256_WITH_HMAC = \"SHA256withHMAC\";\n    private static final String SHA384_WITH_HMAC = \"SHA384withHMAC\";\n    private static final String SHA512_WITH_HMAC = \"SHA512withHMAC\";\n    private static final String SHA256_WITH_EC = \"SHA256withEC\";\n    private static final String SHA384_WITH_EC = \"SHA384withEC\";\n    private static final String SHA512_WITH_EC = \"SHA512withEC\";\n\n    private static final Log log = LogFactory.getLog(JWTAccessTokenBuilder.class);\n    /**\n     * Map for private keys\n     */\n    private static Map<Integer, Key> privateKeys = new ConcurrentHashMap<Integer, Key>();\n    private OAuthServerConfiguration config = null;\n    private Algorithm signatureAlgorithm = null;\n\n    public JWTAccessTokenBuilder() throws IdentityOAuth2Exception {\n        if (log.isDebugEnabled()) {\n            log.debug(\"JWT Access token builder is initiated\");\n        }\n        config = OAuthServerConfiguration.getInstance();\n        //map signature algorithm from identity.xml to nimbus format, this is a one time configuration\n        signatureAlgorithm = mapSignatureAlgorithm(config.getSignatureAlgorithm());\n    }\n\n    public String accessToken(OAuthTokenReqMessageContext oAuthTokenReqMessageContext) throws OAuthSystemException {\n        if (log.isDebugEnabled()) {\n            log.debug(\"Access token request with token request message context. Authorized user \" +\n                    oAuthTokenReqMessageContext.getAuthorizedUser().toString());\n        }\n        try {\n            return this.buildIDToken(oAuthTokenReqMessageContext);\n        } catch (IdentityOAuth2Exception e) {\n            if (log.isDebugEnabled()) {\n                log.debug(\"Error occurred while issuing jwt access token. Hence returning default token\", e);\n            }\n            // Return default access token if it fails to build jwt\n            return super.accessToken(oAuthTokenReqMessageContext);\n        }\n    }\n\n\n    public String accessToken(OAuthAuthzReqMessageContext oAuthAuthzReqMessageContext) throws OAuthSystemException {\n        if (log.isDebugEnabled()) {\n            log.debug(\"Access token request with authorization request message context message context. Authorized \" +\n                    \"user \" + oAuthAuthzReqMessageContext.getAuthorizationReqDTO().getUser().toString());\n        }\n        try {\n            return this.buildIDToken(oAuthAuthzReqMessageContext);\n        } catch (IdentityOAuth2Exception e) {\n            if (log.isDebugEnabled()) {\n                log.debug(\"Error occurred while issuing jwt access token. Hence returning default token\", e);\n            }\n            // Return default access token if it fails to build jwt\n            return super.accessToken(oAuthAuthzReqMessageContext);\n        }\n    }\n\n    /**\n     * To build id token from OauthToken request message context\n     *\n     * @param request Token request message context\n     * @return Signed jwt string.\n     * @throws IdentityOAuth2Exception\n     */\n    protected String buildIDToken(OAuthTokenReqMessageContext request)\n            throws IdentityOAuth2Exception {\n\n        String issuer = OAuth2Util.getIDTokenIssuer();\n        long lifetimeInMillis = OAuthServerConfiguration.getInstance().\n                getApplicationAccessTokenValidityPeriodInSeconds() * 1000;\n        long curTimeInMillis = Calendar.getInstance().getTimeInMillis();\n        // setting subject\n        String subject = request.getAuthorizedUser().getAuthenticatedSubjectIdentifier();\n        if (!StringUtils.isNotBlank(subject)) {\n            subject = request.getAuthorizedUser().getUserName();\n        }\n        // Set claims to jwt token.\n        JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();\n        jwtClaimsSet.setIssuer(issuer);\n        jwtClaimsSet.setSubject(subject);\n        jwtClaimsSet.setAudience(Arrays.asList(request.getOauth2AccessTokenReqDTO().getClientId()));\n        jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY, request.getOauth2AccessTokenReqDTO().getClientId());\n        jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));\n        jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));\n        addUserClaims(jwtClaimsSet, request.getAuthorizedUser());\n\n        if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {\n            return new PlainJWT(jwtClaimsSet).serialize();\n        }\n        return signJWT(jwtClaimsSet, request);\n    }\n\n    /**\n     * Build a signed jwt token from authorization request message context\n     *\n     * @param request Oauth authorization message context\n     * @return Signed jwt string\n     * @throws IdentityOAuth2Exception\n     */\n    protected String buildIDToken(OAuthAuthzReqMessageContext request)\n            throws IdentityOAuth2Exception {\n\n        String issuer = OAuth2Util.getIDTokenIssuer();\n        long lifetimeInMillis = OAuthServerConfiguration.getInstance().\n                getApplicationAccessTokenValidityPeriodInSeconds() * 1000;\n        long curTimeInMillis = Calendar.getInstance().getTimeInMillis();\n        // setting subject\n        String subject = request.getAuthorizationReqDTO().getUser().getAuthenticatedSubjectIdentifier();\n\n        if (!StringUtils.isNotBlank(subject)) {\n            subject = request.getAuthorizationReqDTO().getUser().getUserName();\n        }\n\n        JWTClaimsSet jwtClaimsSet = new JWTClaimsSet();\n        jwtClaimsSet.setIssuer(issuer);\n        jwtClaimsSet.setSubject(subject);\n        jwtClaimsSet.setAudience(Arrays.asList(request.getAuthorizationReqDTO().getConsumerKey()));\n        jwtClaimsSet.setClaim(Constants.AUTHORIZATION_PARTY, request.getAuthorizationReqDTO().getConsumerKey());\n        jwtClaimsSet.setExpirationTime(new Date(curTimeInMillis + lifetimeInMillis));\n        jwtClaimsSet.setIssueTime(new Date(curTimeInMillis));\n        addUserClaims(jwtClaimsSet, request.getAuthorizationReqDTO().getUser());\n\n        if (JWSAlgorithm.NONE.getName().equals(signatureAlgorithm.getName())) {\n            return new PlainJWT(jwtClaimsSet).serialize();\n        }\n        return signJWT(jwtClaimsSet, request);\n    }\n\n    /**\n     * sign JWT token from RSA algorithm\n     *\n     * @param jwtClaimsSet contains JWT body\n     * @param request\n     * @return signed JWT token\n     * @throws IdentityOAuth2Exception\n     */\n    protected String signJWTWithRSA(JWTClaimsSet jwtClaimsSet, OAuthTokenReqMessageContext request)\n            throws IdentityOAuth2Exception {\n        try {\n\n            String tenantDomain = request.getAuthorizedUser().getTenantDomain();\n            int tenantId = IdentityTenantUtil.getTenantId(tenantDomain);\n\n            Key privateKey;\n\n            if (!(privateKeys.containsKey(tenantId))) {\n                // get tenant's key store manager\n                KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId);\n\n                if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {\n                    // derive key store name\n                    String ksName = tenantDomain.trim().replace(\".\", \"-\");\n                    String jksName = ksName + Constants.KEY_STORE_EXTENSION;\n                    // obtain private key\n                    privateKey = tenantKSM.getPrivateKey(jksName, tenantDomain);\n\n                } else {\n                    try {\n                        privateKey = tenantKSM.getDefaultPrivateKey();\n                    } catch (Exception e) {\n                        throw new IdentityOAuth2Exception(\"Error while obtaining private key for super tenant\", e);\n                    }\n                }\n                //privateKey will not be null always\n                privateKeys.put(tenantId, privateKey);\n            } else {\n                //privateKey will not be null because containsKey() true says given key is exist and ConcurrentHashMap\n                // does not allow to store null values\n                privateKey = privateKeys.get(tenantId);\n            }\n            JWSSigner signer = new RSASSASigner((RSAPrivateKey) privateKey);\n            SignedJWT signedJWT = null;\n            if (signatureAlgorithm instanceof JWSAlgorithm) {\n                signedJWT = new SignedJWT(new JWSHeader((JWSAlgorithm) signatureAlgorithm), jwtClaimsSet);\n                signedJWT.sign(signer);\n                return signedJWT.serialize();\n            }\n        } catch (JOSEException e) {\n            throw new IdentityOAuth2Exception(\"Error occurred while signing JWT\", e);\n        }\n        return null;\n    }\n\n    protected String signJWTWithRSA(JWTClaimsSet jwtClaimsSet, OAuthAuthzReqMessageContext request)\n            throws IdentityOAuth2Exception {\n        try {\n\n            // All applications are registered under super tenant domain and currently we dont have access to SP\n            // tenant domain.\n            String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;\n            int tenantId = IdentityTenantUtil.getTenantId(tenantDomain);\n            Key privateKey;\n\n            if (!(privateKeys.containsKey(tenantId))) {\n                // get tenant's key store manager\n                KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId);\n\n                if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {\n                    // derive key store name\n                    String ksName = tenantDomain.trim().replace(\".\", \"-\");\n                    String jksName = ksName + Constants.KEY_STORE_EXTENSION;\n                    // obtain private key\n                    privateKey = tenantKSM.getPrivateKey(jksName, tenantDomain);\n\n                } else {\n                    try {\n                        privateKey = tenantKSM.getDefaultPrivateKey();\n                    } catch (Exception e) {\n                        throw new IdentityOAuth2Exception(\"Error while obtaining private key for super tenant\", e);\n                    }\n                }\n                //privateKey will not be null always\n                privateKeys.put(tenantId, privateKey);\n            } else {\n                //privateKey will not be null because containsKey() true says given key is exist and ConcurrentHashMap\n                // does not allow to store null values\n                privateKey = privateKeys.get(tenantId);\n            }\n            JWSSigner signer = new RSASSASigner((RSAPrivateKey) privateKey);\n            SignedJWT signedJWT = null;\n            if (signatureAlgorithm instanceof JWSAlgorithm) {\n                signedJWT = new SignedJWT(new JWSHeader((JWSAlgorithm) signatureAlgorithm), jwtClaimsSet);\n                signedJWT.sign(signer);\n                return signedJWT.serialize();\n            }\n        } catch (JOSEException e) {\n            throw new IdentityOAuth2Exception(\"Error occurred while signing JWT\", e);\n        }\n        return null;\n    }\n\n    /**\n     * Generic Signing function\n     *\n     * @param jwtClaimsSet contains JWT body\n     * @param request\n     * @return\n     * @throws IdentityOAuth2Exception\n     */\n    protected String signJWT(JWTClaimsSet jwtClaimsSet, OAuthTokenReqMessageContext request)\n            throws IdentityOAuth2Exception {\n\n        if (JWSAlgorithm.RS256.equals(signatureAlgorithm) || JWSAlgorithm.RS384.equals(signatureAlgorithm) ||\n                JWSAlgorithm.RS512.equals(signatureAlgorithm)) {\n            return signJWTWithRSA(jwtClaimsSet, request);\n        } else if (JWSAlgorithm.HS256.equals(signatureAlgorithm) || JWSAlgorithm.HS384.equals(signatureAlgorithm) ||\n                JWSAlgorithm.HS512.equals(signatureAlgorithm)) {\n            // return signWithHMAC(jwtClaimsSet,jwsAlgorithm,request); implementation need to be done\n            return null;\n        } else {\n            // return signWithEC(jwtClaimsSet,jwsAlgorithm,request); implementation need to be done\n            return null;\n        }\n    }\n\n    protected String signJWT(JWTClaimsSet jwtClaimsSet, OAuthAuthzReqMessageContext request)\n            throws IdentityOAuth2Exception {\n\n        if (JWSAlgorithm.RS256.equals(signatureAlgorithm) || JWSAlgorithm.RS384.equals(signatureAlgorithm) ||\n                JWSAlgorithm.RS512.equals(signatureAlgorithm)) {\n            return signJWTWithRSA(jwtClaimsSet, request);\n        } else if (JWSAlgorithm.HS256.equals(signatureAlgorithm) || JWSAlgorithm.HS384.equals(signatureAlgorithm) ||\n                JWSAlgorithm.HS512.equals(signatureAlgorithm)) {\n            // return signWithHMAC(jwtClaimsSet,jwsAlgorithm,request); implementation need to be done\n            return null;\n        } else {\n            // return signWithEC(jwtClaimsSet,jwsAlgorithm,request); implementation need to be done\n            return null;\n        }\n    }\n\n    /**\n     * This method map signature algorithm define in identity.xml to nimbus\n     * signature algorithm\n     * format, Strings are defined inline hence there are not being used any\n     * where\n     *\n     * @param signatureAlgorithm\n     * @return\n     * @throws IdentityOAuth2Exception\n     */\n    protected JWSAlgorithm mapSignatureAlgorithm(String signatureAlgorithm) throws IdentityOAuth2Exception {\n\n        if (NONE.equals(signatureAlgorithm)) {\n            return new JWSAlgorithm(JWSAlgorithm.NONE.getName());\n        } else if (SHA256_WITH_RSA.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.RS256;\n        } else if (SHA384_WITH_RSA.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.RS384;\n        } else if (SHA512_WITH_RSA.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.RS512;\n        } else if (SHA256_WITH_HMAC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.HS256;\n        } else if (SHA384_WITH_HMAC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.HS384;\n        } else if (SHA512_WITH_HMAC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.HS512;\n        } else if (SHA256_WITH_EC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.ES256;\n        } else if (SHA384_WITH_EC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.ES384;\n        } else if (SHA512_WITH_EC.equals(signatureAlgorithm)) {\n            return JWSAlgorithm.ES512;\n        }\n        throw new IdentityOAuth2Exception(\"Unsupported Signature Algorithm in identity.xml\");\n    }\n\n    private void addUserClaims(JWTClaimsSet jwtClaimsSet, AuthenticatedUser user) {\n        for (Map.Entry<ClaimMapping, String> entry : user.getUserAttributes().entrySet()) {\n            ClaimMapping claimMapping = entry.getKey();\n            Claim claim = claimMapping.getLocalClaim();\n            if (claim != null && Constants.CUSTOMER_ID_CLAIM_URI.equalsIgnoreCase(claim.getClaimUri())) {\n                jwtClaimsSet.setClaim(Constants.CUSTOMER_ID_CLAIM_URI, entry.getValue());\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "samples/jwt-claims/JWTAccessTokenBuilder/src/main/java/com/wso2/jwt/token/builder/internal/JWTAccessTokenBuilderDSComponent.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage com.wso2.jwt.token.builder.internal;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.osgi.service.component.ComponentContext;\nimport org.wso2.carbon.registry.core.service.RegistryService;\nimport org.wso2.carbon.user.core.service.RealmService;\n\n/**\n * @scr.component name=\"carbon.custom.claim.handler.dscomponent\" immediate=\"true\"\n * @scr.reference name=\"user.realmservice.default\"\n *                interface=\"org.wso2.carbon.user.core.service.RealmService\"\n *                cardinality=\"1..1\" policy=\"dynamic\" bind=\"setRealmService\"\n *                unbind=\"unsetRealmService\"\n * @scr.reference name=\"registry.service\"\n *                interface=\"org.wso2.carbon.registry.core.service.RegistryService\"\n *                cardinality=\"1..1\" policy=\"dynamic\" bind=\"setRegistryService\"\n *                unbind=\"unsetRegistryService\"\n */\npublic class JWTAccessTokenBuilderDSComponent {\n\n    private static Log log = LogFactory.getLog(JWTAccessTokenBuilderDSComponent.class);\n    private static RealmService realmService;\n    private static RegistryService registryService;\n\n    private static synchronized void setStaticRealmService(RealmService realmService) {\n        JWTAccessTokenBuilderDSComponent.realmService = realmService;\n    }\n\n    public static RealmService getRealmService() {\n        return JWTAccessTokenBuilderDSComponent.realmService;\n    }\n\n    protected void setRealmService(RealmService realmService) {\n        setStaticRealmService(realmService);\n        if (log.isDebugEnabled()) {\n            log.debug(\"RealmService is set in the custom token builder bundle\");\n        }\n\n    }\n\n    private static synchronized void setStaticRegistryService(RegistryService registryService) {\n        JWTAccessTokenBuilderDSComponent.registryService = registryService;\n    }\n\n    public static RegistryService getRegistryService() {\n        return JWTAccessTokenBuilderDSComponent.registryService;\n    }\n\n    protected void setRegistryService(RegistryService registryService) {\n        setStaticRegistryService(registryService);\n        if (log.isDebugEnabled()) {\n            log.debug(\"RegistryService is set in the custom token builder bundle\");\n        }\n\n    }\n\n    protected void activate(ComponentContext ctxt) {\n        try {\n            log.info(\"Custom token builder activated successfully.\");\n        } catch (Exception e) {\n            log.error(\"Failed to activate custom token builder \", e);\n        }\n    }\n\n    protected void deactivate(ComponentContext ctxt) {\n        if (log.isDebugEnabled()) {\n            log.debug(\"Custom token builder is deactivated \");\n        }\n    }\n\n    protected void unsetRealmService(RealmService realmService) {\n        setStaticRealmService(null);\n        if (log.isDebugEnabled()) {\n            log.debug(\"RealmService is unset in the custom token builder bundle\");\n        }\n\n    }\n\n    protected void unsetRegistryService(RegistryService registryService) {\n        setStaticRegistryService(null);\n        if (log.isDebugEnabled()) {\n            log.debug(\"RegistryService is unset in the custom token builder bundle\");\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "samples/jwt-claims/README.md",
    "content": "# JWT token Sample\n\nThis sample shows how to verify signed JWT tokens and use claims in microservices deployed in WSO2 MSF4J.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nUse following command to run the application\n\n```\njava -jar jwt-sample/target/jwt-sample-2.0.0.jar\n```\n\n## Setting up the Authorization Server with web app.\n\nHere we use WSO2 Identity server as the authorization server.\n*This sample is compatible with Identity Server version 5.2.0 and above*\n\n1) Download and unzip the latest version of the WSO2 Identity Server from http://wso2.com/products/identity-server.\n\n2) Add JWTAccessTokenBuilder/target/JWTAccessTokenBuilder-2.0.0.jar into \\<IS_HOME\\>/repository/components/lib folder.\n\n3) Add the following property in <IS_HOME>/repository/conf/identity/identity.xml under oauth tag:\n\"\\<IdentityOAuthTokenGenerator\\>com.wso2.jwt.token.builder.JWTAccessTokenBuilder\\</IdentityOAuthTokenGenerator\\>\"\n\n4) Using the sso-agent-for-jwt-webapp/target/travelocity.com.war, configure the single sign-on web app as indicated in this\ndocument:\n[https://docs.wso2.com/display/IS520/Configuring+Single+Sign-On]\n(https://docs.wso2.com/display/IS520/Configuring+Single+Sign-On)\n\n5) Configure OAuth2-OpenID connect for single sign-on following the instructions in this document for the web app:\n[https://docs.wso2.com/display/IS520/Configuring+OAuth2-OpenID+Connect+Single-Sign-On]\n(https://docs.wso2.com/display/IS520/Configuring+OAuth2-OpenID+Connect+Single-Sign-On)\n\n6) Configure SAML2 Bearer assertion profile for OAuth 2 with the travelocity web app following the instruction in\nthis document:\n [https://docs.wso2.com/display/IS520/SAML2+Bearer+Assertion+Profile+for+OAuth+2.0+with+WSO2+Travelocity]\n (https://docs.wso2.com/display/IS520/SAML2+Bearer+Assertion+Profile+for+OAuth+2.0+with+WSO2+Travelocity)\n\n## How to test the sample\n\n1) Open the travelocity web app from http://localhost:8080/travelocity.com\n\n2) Login using your credentials with SAML SSO.\n\n3) Click on Request OAuth2 Access Token and send to micro service.\n\nYou will see the following response in the page.\n\n```\nYour OAuth2 Access Token details\nToken Type: Bearer\nExpiry In: 3600\n\nMicro service details\nMicro service URL: http://localhost:8081/hello/\nResponse from micro service: Hello there admin@carbon.super\n```\n"
  },
  {
    "path": "samples/jwt-claims/jwt-sample/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>msf4j-service</artifactId>\n        <groupId>org.wso2.msf4j</groupId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>jwt-sample</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Microservices in MSF4J with signed JWT</name>\n    <description>Demonstrates how to work with JWT tokens and microservices in WSO2 MSF4J</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n            <version>2.25</version>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/jwt-claims/jwt-sample/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.security.JWTSecurityInterceptor;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private Application() {\n    }\n\n    public static void main(String[] args) {\n        // Port 8081 is used since the default port of tomcat is 8080\n        new MicroservicesRunner(8081)\n                .addGlobalRequestInterceptor(new JWTSecurityInterceptor(), new CustomJWTClaimsInterceptor())\n                .deploy(new Helloworld())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/jwt-sample/src/main/java/org/wso2/msf4j/example/CustomJWTClaimsInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport com.nimbusds.jwt.ReadOnlyJWTClaimsSet;\nimport com.nimbusds.jwt.SignedJWT;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\nimport javax.ws.rs.core.HttpHeaders;\n\n/**\n * Interceptor for handling custom JWT claims.\n */\npublic class CustomJWTClaimsInterceptor implements RequestInterceptor {\n\n    private static final String JWT_HEADER = \"X-JWT-Assertion\";\n    private static final String AUTH_TYPE_JWT = \"JWT\";\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        HttpHeaders headers = request.getHeaders();\n        if (headers != null) {\n            String jwtHeader = headers.getHeaderString(JWT_HEADER);\n            if (jwtHeader != null) {\n                SignedJWT signedJWT = SignedJWT.parse(jwtHeader);\n                ReadOnlyJWTClaimsSet readOnlyJWTClaimsSet = signedJWT.getJWTClaimsSet();\n                if (readOnlyJWTClaimsSet != null) {\n                    // Do something with claims\n                    return true;\n                }\n            }\n        }\n        response.setHeader(javax.ws.rs.core.HttpHeaders.WWW_AUTHENTICATE, AUTH_TYPE_JWT);\n        response.setStatus(javax.ws.rs.core.Response.Status.UNAUTHORIZED.getStatusCode());\n        return false;\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/jwt-sample/src/main/java/org/wso2/msf4j/example/Helloworld.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Helloworld resource class.\n */\n@Path(\"/hello\")\npublic class Helloworld {\n\n    @GET\n    @Path(\"/{user}\")\n    public String getUser(@PathParam(\"user\") String user) {\n        return \"Hello there \" + user + \"\\n\";\n    }\n\n}\n"
  },
  {
    "path": "samples/jwt-claims/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>jwt-claims</artifactId>\n    <packaging>pom</packaging>\n\n    <modules>\n        <module>sso-agent-for-jwt-webapp</module>\n        <module>jwt-sample</module>\n        <!--<module>sso-agent-sample</module>-->\n        <module>JWTAccessTokenBuilder</module>\n    </modules>\n\n</project>\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j</groupId>\n    <artifactId>sso-agent-sample-webapp</artifactId>\n    <version>2.8.14-SNAPSHOT</version>\n    <packaging>war</packaging>\n    <name>Travelocity.COM ServiceProvider / RelyingParty Webapp</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.opensaml</groupId>\n            <artifactId>opensaml</artifactId>\n            <version>2.4.1</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>commons-collections</groupId>\n                    <artifactId>commons-collections</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.santuario</groupId>\n            <artifactId>xmlsec</artifactId>\n            <version>1.4.4</version>\n        </dependency>\n        <dependency>\n            <groupId>org.opensaml</groupId>\n            <artifactId>xmltooling</artifactId>\n            <version>1.3.1</version>\n        </dependency>\n        <dependency>\n            <groupId>org.opensaml</groupId>\n            <artifactId>openws</artifactId>\n            <version>1.4.1</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.identity</groupId>\n            <artifactId>org.wso2.carbon.identity.sso.agent</artifactId>\n            <version>5.1.0</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>opensaml.wso2</groupId>\n                    <artifactId>opensaml2</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>commons-collections.wso2</groupId>\n                    <artifactId>commons-collections</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.ws.commons.axiom</groupId>\n            <artifactId>axiom-api</artifactId>\n            <version>1.2.11-wso2v6</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-lang</groupId>\n            <artifactId>commons-lang</artifactId>\n            <version>2.6</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-collections</groupId>\n            <artifactId>commons-collections</artifactId>\n            <version>3.2.2</version>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>servlet-api</artifactId>\n            <version>2.5</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>travelocity.com</finalName>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.3</version>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                </configuration>\n            </plugin>\n\n            <plugin>\n                <artifactId>maven-deploy-plugin</artifactId>\n                <version>2.8.1</version>\n                <configuration>\n                    <altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo\n                    </altDeploymentRepository>\n                </configuration>\n            </plugin>\n\n        </plugins>\n    </build>\n\n    <repositories>\n        <repository>\n            <id>wso2-nexus</id>\n            <name>WSO2 internal Repository</name>\n            <url>https://maven.wso2.org/nexus/content/groups/wso2-public/</url>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n        </repository>\n        <repository>\n            <id>wso2.snapshots</id>\n            <name>WSO2 Snapshot Repository</name>\n            <url>https://maven.wso2.org/nexus/content/repositories/snapshots/</url>\n            <snapshots>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n            </snapshots>\n            <releases>\n                <enabled>false</enabled>\n            </releases>\n        </repository>\n    </repositories>\n\n    <distributionManagement>\n        <repository>\n            <id>internal.repo</id>\n            <name>Temporary Staging Repository</name>\n            <url>file://${project.build.directory}/mvn-repo</url>\n        </repository>\n    </distributionManagement>\n</project>\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/java/org/wso2/sample/is/sso/agent/ForwardingServlet.java",
    "content": "/**\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n * <p>\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.sample.is.sso.agent;\n\nimport java.io.IOException;\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\n/**\n * ForwardingServlet.\n */\npublic class ForwardingServlet extends HttpServlet {\n\n    private static final long serialVersionUID = 6399244426134325214L;\n\n    protected void service(HttpServletRequest request,\n                           HttpServletResponse response) throws ServletException, IOException {\n\n        if (request.getRequestURI().endsWith(\"/samlsso\") || request.getRequestURI().endsWith(\"/openid\") ||\n                request.getRequestURI().endsWith(\"/token\")) {\n            request.getRequestDispatcher(\"home.jsp\").forward(request, response);\n        } else if (request.getRequestURI().endsWith(\"/logout\")) {\n            request.getRequestDispatcher(\"index.jsp\").forward(request, response);\n        }\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/java/org/wso2/sample/is/sso/agent/SSOAgentSampleFilter.java",
    "content": "/*\n *  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.sample.is.sso.agent;\n\nimport org.apache.axiom.om.util.Base64;\nimport org.apache.commons.lang.StringUtils;\nimport org.wso2.carbon.identity.sso.agent.SSOAgentConstants;\nimport org.wso2.carbon.identity.sso.agent.SSOAgentFilter;\nimport org.wso2.carbon.identity.sso.agent.bean.SSOAgentConfig;\n\nimport java.io.IOException;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.servlet.FilterChain;\nimport javax.servlet.FilterConfig;\nimport javax.servlet.ServletException;\nimport javax.servlet.ServletRequest;\nimport javax.servlet.ServletResponse;\n\n/**\n * SSOAgentSampleFilter.\n */\npublic class SSOAgentSampleFilter extends SSOAgentFilter {\n\n    private static final Logger LOGGER = Logger.getLogger(\"org.wso2.sample.is.sso.agent\");\n\n    private static final String USERNAME = \"username\";\n    private static final String PASSWORD = \"password\";\n    private static final String CHARACTER_ENCODING = \"UTF-8\";\n    private static Properties properties;\n    protected FilterConfig filterConfig = null;\n\n    static {\n        properties = SampleContextEventListener.getProperties();\n    }\n\n    @Override\n    public void init(FilterConfig filterConfig) throws ServletException {\n        this.filterConfig = filterConfig;\n    }\n\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,\n                         FilterChain filterChain) throws IOException, ServletException {\n\n        String httpBinding = servletRequest.getParameter(\n                SSOAgentConstants.SSOAgentConfig.SAML2.HTTP_BINDING);\n        if (httpBinding != null && !httpBinding.isEmpty()) {\n            if (\"HTTP-POST\".equals(httpBinding)) {\n                httpBinding = \"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\";\n            } else if (\"HTTP-Redirect\".equals(httpBinding)) {\n                httpBinding = \"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\";\n            } else {\n                LOGGER.log(Level.INFO, \"Unknown SAML2 HTTP Binding. Defaulting to HTTP-POST\");\n                httpBinding = \"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\";\n            }\n        } else {\n            LOGGER.log(Level.INFO, \"SAML2 HTTP Binding not found in request. Defaulting to HTTP-POST\");\n            httpBinding = \"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\";\n        }\n        SSOAgentConfig config = (SSOAgentConfig) filterConfig.getServletContext().\n                getAttribute(SSOAgentConstants.CONFIG_BEAN_NAME);\n        config.getSAML2().setHttpBinding(httpBinding);\n        config.getOpenId().setClaimedId(servletRequest.getParameter(\n                SSOAgentConstants.SSOAgentConfig.OpenID.CLAIMED_ID));\n        config.getOpenId().setMode(servletRequest.getParameter(\n                SSOAgentConstants.OpenID.OPENID_MODE));\n\n        if (StringUtils.isNotEmpty(servletRequest.getParameter(USERNAME)) &&\n                StringUtils.isNotEmpty(servletRequest.getParameter(PASSWORD))) {\n\n            String authorization = servletRequest.getParameter(USERNAME) + \":\" + servletRequest.getParameter(PASSWORD);\n            // Base64 encoded username:password value\n            authorization = Base64.encode(authorization.getBytes(CHARACTER_ENCODING));\n            String htmlPayload = \"<html>\\n\" +\n                    \"<body>\\n\" +\n                    \"<p>You are now redirected back to \" + properties.getProperty(\"SAML2.IdPURL\") + \" \\n\" +\n                    \"If the redirection fails, please click the post button.</p>\\n\" +\n                    \"<form method='post' action='\" + properties.getProperty(\"SAML2.IdPURL\") + \"'>\\n\" +\n                    \"<input type='hidden' name='sectoken' value='\" + authorization + \"'/>\\n\" +\n                    \"<p>\\n\" +\n                    \"<!--$saml_params-->\\n\" +\n                    \"<button type='submit'>POST</button>\\n\" +\n                    \"</p>\\n\" +\n                    \"</form>\\n\" +\n                    \"<script type='text/javascript'>\\n\" +\n                    \"document.forms[0].submit();\\n\" +\n                    \"</script>\\n\" +\n                    \"</body>\\n\" +\n                    \"</html>\";\n            config.getSAML2().setPostBindingRequestHTMLPayload(htmlPayload);\n        } else {\n            // Reset previously sent HTML payload\n            config.getSAML2().setPostBindingRequestHTMLPayload(null);\n        }\n        servletRequest.setAttribute(SSOAgentConstants.CONFIG_BEAN_NAME, config);\n        super.doFilter(servletRequest, servletResponse, filterChain);\n    }\n\n    @Override\n    public void destroy() {\n\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/java/org/wso2/sample/is/sso/agent/SampleAttributesRequestor.java",
    "content": "/*\n *  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.wso2.sample.is.sso.agent;\n\nimport org.wso2.carbon.identity.sso.agent.openid.AttributesRequestor;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *  SampleAttributesRequestor.\n */\npublic class SampleAttributesRequestor implements AttributesRequestor {\n\n    List<String> requestedAttributes = new ArrayList<String>();\n    Map<String, Boolean> requiredMap = new HashMap<String, Boolean>();\n    Map<String, String> typeURIMap = new HashMap<String, String>();\n    Map<String, Integer> countMap = new HashMap<String, Integer>();\n\n    public void init() {\n        requestedAttributes.add(\"nickname\");\n        requiredMap.put(\"nickname\", true);\n        typeURIMap.put(\"nickname\", \"http://axschema.org/namePerson/first\");\n        countMap.put(\"nickname\", 1);\n        requestedAttributes.add(\"lastname\");\n        requiredMap.put(\"lastname\", true);\n        typeURIMap.put(\"lastname\", \"http://axschema.org/namePerson/last\");\n        countMap.put(\"lastname\", 1);\n        requestedAttributes.add(\"email\");\n        requiredMap.put(\"email\", true);\n        typeURIMap.put(\"email\", \"http://axschema.org/contact/email\");\n        countMap.put(\"email\", 0);\n        requestedAttributes.add(\"country\");\n        requiredMap.put(\"country\", true);\n        typeURIMap.put(\"country\", \"http://axschema.org/contact/country/home\");\n        countMap.put(\"country\", 1);\n        requestedAttributes.add(\"dob\");\n        requiredMap.put(\"dob\", true);\n        typeURIMap.put(\"dob\", \"http://axschema.org/birthDate\");\n        countMap.put(\"dob\", 1);\n    }\n\n    public String[] getRequestedAttributes(String s) {\n        String[] attrArray = new String[requestedAttributes.size()];\n        return requestedAttributes.toArray(attrArray);\n    }\n\n    public boolean isRequired(String s, String s2) {\n        return requiredMap.get(s2);\n    }\n\n    public String getTypeURI(String s, String s2) {\n        return typeURIMap.get(s2);\n    }\n\n    public int getCount(String s, String s2) {\n        return countMap.get(s2);\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/java/org/wso2/sample/is/sso/agent/SampleContextEventListener.java",
    "content": "/**\n * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n * <p>\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n * <p>\n * http://www.apache.org/licenses/LICENSE-2.0\n * <p>\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.sample.is.sso.agent;\n\nimport org.wso2.carbon.identity.sso.agent.SSOAgentConstants;\nimport org.wso2.carbon.identity.sso.agent.SSOAgentException;\nimport org.wso2.carbon.identity.sso.agent.bean.SSOAgentConfig;\nimport org.wso2.carbon.identity.sso.agent.saml.SSOAgentX509Credential;\nimport org.wso2.carbon.identity.sso.agent.saml.SSOAgentX509KeyStoreCredential;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.servlet.ServletContextEvent;\nimport javax.servlet.ServletContextListener;\n\n/**\n * SampleContextEventListener.\n */\npublic class SampleContextEventListener implements ServletContextListener {\n\n    private static final Logger LOGGER = Logger.getLogger(\"org.wso2.sample.is.sso.agent\");\n\n    private static Properties properties = new Properties();\n\n    public void contextInitialized(ServletContextEvent servletContextEvent) {\n        try {\n            if (servletContextEvent.getServletContext().getContextPath().contains(\"travelocity.com\")) {\n                properties.load(servletContextEvent.getServletContext().\n                        getResourceAsStream(\"/WEB-INF/classes/travelocity.properties\"));\n            } else if (servletContextEvent.getServletContext().getContextPath().contains(\"avis.com\")) {\n                properties.load(servletContextEvent.getServletContext().\n                        getResourceAsStream(\"/WEB-INF/classes/avis.properties\"));\n            }\n            InputStream keyStoreInputStream = servletContextEvent.getServletContext().\n                    getResourceAsStream(\"WEB-INF/classes/wso2carbon.jks\");\n            SSOAgentX509Credential credential =\n                    new SSOAgentX509KeyStoreCredential(keyStoreInputStream,\n                            properties.getProperty(\"KeyStorePassword\").toCharArray(),\n                            properties.getProperty(\"IdPPublicCertAlias\"),\n                            properties.getProperty(\"PrivateKeyAlias\"),\n                            properties.getProperty(\"PrivateKeyPassword\").toCharArray());\n            SSOAgentConfig config = new SSOAgentConfig();\n            config.initConfig(properties);\n            config.getSAML2().setSSOAgentX509Credential(credential);\n            config.getOpenId().setAttributesRequestor(new SampleAttributesRequestor());\n            servletContextEvent.getServletContext().\n                    setAttribute(SSOAgentConstants.CONFIG_BEAN_NAME, config);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, e.getMessage(), e);\n        } catch (SSOAgentException e) {\n            LOGGER.log(Level.SEVERE, e.getMessage(), e);\n        }\n    }\n\n    public void contextDestroyed(ServletContextEvent servletContextEvent) {\n\n    }\n\n    /**\n     * Get the properties of the sample\n     * @return Properties\n     */\n    public static Properties getProperties() {\n        return properties;\n    }\n}\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/resources/avis.properties",
    "content": "#  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n#  WSO2 Inc. licenses this file to you under the Apache License,\n#  Version 2.0 (the \"License\"); you may not use this file except\n#  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,\n#  software distributed under the License is distributed on an\n#  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n#  specific language governing permissions and limitations\n#  under the License.\n\n\nEnableSAML2SSOLogin=true\nEnableOpenIDLogin=true\nEnableOAuth2SAML2Grant=false\n\n#Url to do send SAML2 SSO AuthnRequest\nSAML2SSOURL=samlsso\n\n#Url to do initiate OAuth2 SAML2 Grant Request\nOAuth2SAML2GrantURL=token\n\n#Url to initiate OpenID Authentication Request\nOpenIdURL=openid\n\n#URIs to skip SSOAgentFilter; comma separated values\nSkipURIs=/avis.com/index.jsp\n\n#A unique identifier for this SAML 2.0 Service Provider application\nSAML2.SPEntityId=avis.com\n\n#The URL of the SAML 2.0 Assertion Consumer\nSAML2.AssertionConsumerURL=http://localhost:8080/avis.com/home.jsp\n\n#A unique identifier for this SAML 2.0 Service Provider application\nSAML2.IdPEntityId=localhost\n\n#The URL of the SAML 2.0 Identity Provider\nSAML2.IdPURL=https://localhost:9443/samlsso\n\n#Identifier given for the Service Provider for SAML 2.0 attributes \n#exchange\n#SAML2.AttributeConsumingServiceIndex=1701087467\n\n#Specify if SingleLogout is enabled/disabled\nSAML2.EnableSLO=true\n\n#This is the URL that is used for SLO\nSAML2.SLOURL=logout\n\n#Specify if SAMLResponse element is signed\nSAML2.EnableResponseSigning=true\n\n#Specify if SAMLAssertion element is signed\nSAML2.EnableAssertionSigning=true\n\n#Specify if SAMLAssertion element is encrypted\nSAML2.EnableAssertionEncryption=false\n\n#Specify if AuthnRequests and LogoutRequests should be signed\nSAML2.EnableRequestSigning=true\n\n#Password of the KeyStore for SAML and OpenID\nKeyStorePassword=wso2carbon\n\n#Alias of the IdP's public certificate\nIdPPublicCertAlias=wso2carbon\n\n#Alias of the SP's private key \nPrivateKeyAlias=wso2carbon\n\n#Private key password to retrieve the private key used to sign \n#AuthnRequest and LogoutRequest messages\nPrivateKeyPassword=wso2carbon\n\n#OAuth2 token endpoint URL\nOAuth2.TokenURL=https://localhost:9443/oauth2/token\n\n#OAuth2 Client ID\nOAuth2.ClientId=Qn5DQHCYfshxeZh6R9SL1HM2lsMa\n\n#OAuth2 Client Secret\nOAuth2.ClientSecret=cbkAs1gajdwPAMbrSR54hPAIcz0a\n\n#OpenId Provider Url\nOpenId.ProviderURL=https://localhost:9443/openid/\n\n#openid.return_to parameter\nOpenId.ReturnToURL=http://localhost:8080/avis.com/home.jsp\n\n#Custom SAML post binding request page\n#SAML.PostBinding.RequestPage=path/to/the/html\n\n#Additional request parameters\n#QueryParams=tenantDomain=-1234\n\n#SAML2.IsForceAuthn=true\n\n#Specify whether the consumer requests user attributes from the provider\nOpenId.EnableAttributeExchange=true\n\n#Specify whether the consumer runs in dumb mode\nOpenId.EnableDumbMode=false\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/resources/travelocity.properties",
    "content": "#  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n#  WSO2 Inc. licenses this file to you under the Apache License,\n#  Version 2.0 (the \"License\"); you may not use this file except\n#  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,\n#  software distributed under the License is distributed on an\n#  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n#  specific language governing permissions and limitations\n#  under the License.\n\n\nEnableSAML2SSOLogin=true\nEnableOpenIDLogin=true\nEnableOAuth2SAML2Grant=true\n\n#Url to do send SAML2 SSO AuthnRequest\nSAML2SSOURL=samlsso\n\n#Url to do initiate OAuth2 SAML2 Grant Request\nOAuth2SAML2GrantURL=token\n\n#Url to initiate OpenID Authentication Request\nOpenIdURL=openid\n\n#URIs to skip SSOAgentFilter; comma separated values\nSkipURIs=/travelocity.com/index.jsp\n\n#A unique identifier for this SAML 2.0 Service Provider application\nSAML2.SPEntityId=travelocity.com\n\n#The URL of the SAML 2.0 Assertion Consumer\nSAML2.AssertionConsumerURL=http://localhost:8080/travelocity.com/home.jsp\n\n#A unique identifier for this SAML 2.0 Service Provider application\nSAML2.IdPEntityId=localhost\n\n#The URL of the SAML 2.0 Identity Provider\nSAML2.IdPURL=https://localhost:9443/samlsso\n\n#Identifier given for the Service Provider for SAML 2.0 attributes \n#exchange\n#SAML2.AttributeConsumingServiceIndex=1701087467\n\n#Specify if SingleLogout is enabled/disabled\nSAML2.EnableSLO=true\n\n#This is the URL that is used for SLO\nSAML2.SLOURL=logout\n\n#Specify if SAMLResponse element is signed\nSAML2.EnableResponseSigning=true\n\n#Specify if SAMLAssertion element is signed\nSAML2.EnableAssertionSigning=true\n\n#Specify if SAMLAssertion element is encrypted\nSAML2.EnableAssertionEncryption=false\n\n#Specify if AuthnRequests and LogoutRequests should be signed\nSAML2.EnableRequestSigning=true\n\n#Password of the KeyStore for SAML and OpenID\nKeyStorePassword=wso2carbon\n\n#Alias of the IdP's public certificate\nIdPPublicCertAlias=wso2carbon\n\n#Alias of the SP's private key \nPrivateKeyAlias=wso2carbon\n\n#Private key password to retrieve the private key used to sign \n#AuthnRequest and LogoutRequest messages\nPrivateKeyPassword=wso2carbon\n\n#OAuth2 token endpoint URL\nOAuth2.TokenURL=https://localhost:9443/oauth2/token\n\n#OAuth2 Client ID\nOAuth2.ClientId=lAamjD62sOF4rTSRtjhHzCBZQdoa\n\n#OAuth2 Client Secret\nOAuth2.ClientSecret=M_owezcWYU3kNiPusMYmBCmg7l8a\n\n#OpenId Provider Url\nOpenId.ProviderURL=https://localhost:9443/openid/\n\n#openid.return_to parameter\nOpenId.ReturnToURL=http://localhost:8080/travelocity.com/home.jsp\n\n#Custom SAML post binding request page\n#SAML.PostBinding.RequestPage=path/to/the/html\n\n#Additional request parameters\n#QueryParams=tenantDomain=-1234\n\n#SAML2.IsForceAuthn=true\n\n#Specify whether the consumer requests user attributes from the provider\nOpenId.EnableAttributeExchange=true\n\n#Specify whether the consumer runs in dumb mode\nOpenId.EnableDumbMode=false\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n~ Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n~\n~ WSO2 Inc. licenses this file to you under the Apache License,\n~ Version 2.0 (the \"License\"); you may not use this file except\n~ 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,\n~ software distributed under the License is distributed on an\n~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n~ KIND, either express or implied.  See the License for the\n~ specific language governing permissions and limitations\n~ under the License.\n-->\n<web-app id=\"travelocity.com\" version=\"2.5\"\n         xmlns=\"http://java.sun.com/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\">\n\n    <display-name>Travelocity.COM</display-name>\n\n    <servlet>\n        <servlet-name>ForwardingServlet</servlet-name>\n        <servlet-class>org.wso2.sample.is.sso.agent.ForwardingServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n    <servlet-mapping>\n        <servlet-name>ForwardingServlet</servlet-name>\n        <url-pattern>/samlsso</url-pattern>\n    </servlet-mapping>\n    <servlet-mapping>\n        <servlet-name>ForwardingServlet</servlet-name>\n        <url-pattern>/openid</url-pattern>\n    </servlet-mapping>\n    <servlet-mapping>\n        <servlet-name>ForwardingServlet</servlet-name>\n        <url-pattern>/token</url-pattern>\n    </servlet-mapping>\n    <servlet-mapping>\n        <servlet-name>ForwardingServlet</servlet-name>\n        <url-pattern>/logout</url-pattern>\n    </servlet-mapping>\n\n    <filter>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <filter-class>org.wso2.sample.is.sso.agent.SSOAgentSampleFilter</filter-class>\n    </filter>\n    <filter-mapping>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <url-pattern>*.jsp</url-pattern>\n    </filter-mapping>\n    <filter-mapping>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <url-pattern>/samlsso</url-pattern>\n    </filter-mapping>\n    <filter-mapping>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <url-pattern>/openid</url-pattern>\n    </filter-mapping>\n    <filter-mapping>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <url-pattern>/token</url-pattern>\n    </filter-mapping>\n    <filter-mapping>\n        <filter-name>SSOAgentSampleFilter</filter-name>\n        <url-pattern>/logout</url-pattern>\n    </filter-mapping>\n\n    <listener>\n        <listener-class>org.wso2.sample.is.sso.agent.SampleContextEventListener</listener-class>\n    </listener>\n    <listener>\n        <listener-class>org.wso2.carbon.identity.sso.agent.saml.SSOAgentHttpSessionListener</listener-class>\n    </listener>\n\n    <error-page>\n        <exception-type>org.wso2.carbon.identity.sso.agent.SSOAgentException</exception-type>\n        <location>/errors.jsp</location>\n    </error-page>\n\n</web-app>\n"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/webapp/css/cart-styles.css",
    "content": "/*Page layout styles*/\n\nhtml, body {\n    margin: 0;\n    padding: 0;\n    height: 100%; /* needed for container min-height */\n\n    font-family: \"Trebuchet MS\",Verdana,sans-serif;\n    font-size: small;\n    background-image:url(../images/cart-page-back.jpg);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    background-color:#f3f4f8;\n}\na{\n    cursor:pointer;\n}\ndiv#container {\n    position: relative; /* needed for footer positioning*/\n    margin: 0 auto; /* center, not in IE5 */\n/*width:750px;*/\n\n    height: auto !important; /* real browsers */\n    height: 100%; /* IE6: treaded as min-height*/\n\n    min-height: 100%; /* real browsers */\n}\n\ndiv#header-area {\n    padding-left: 1em;\n    width: 980px;\n    height:139px;\n    background-image:url(../images/chart-headder-back.jpg);\n    background-repeat:no-repeat;\n    background-position:0 0;\n}\n\ndiv#content-area {\n    padding: 1em 1em 1em 1em; /* bottom padding for footer */\n    width: 980px;\n    padding-bottom: 70px;\n    margin-top:-30px;\n}\n\ndiv#footer-area {\n    position: relative;\n    width: 99%;\n    bottom: 0; /* stick to bottom */\n    background-color:#e6e6e6;\n    border-top:solid 3px #14566d;\n    padding-top:1em;\n    font-size:11px;\n    color:#333;\n    padding-bottom:50px;\n}\ndiv#footer-area p {\n    padding-left:20px;    \n}\n\n/* Page decration styles*/\n.cart-expbox{\n    width:100%;    \n}\n.cart-expbox-02{\n    background-image:url(../images/cart-expbox-02.gif);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    font-size:1px;\n    height:9px;\n}\n.cart-expbox-04{\n    background-image:url(../images/cart-expbox-04.gif);\n    background-repeat:repeat-y;\n    background-position:0 0;\n    width:10px;\n    font-size:1px;\n}\n.cart-expbox-06{\n    background-image:url(../images/cart-expbox-06.gif);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    font-size:1px;\n    height:9px;\n}\n.cart-expbox-08{\n    background-image:url(../images/cart-expbox-08.gif);\n    background-repeat:repeat-y;\n    background-position:0 0;\n    width:10px;\n}\n.cart-expbox-09{\n    background-image:url(../images/cart-expbox-09.gif);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    background-color:#4f9db9;\n    text-align:right;\n}\n.cart-expbox-09 a{\n    color:#fff;\n    padding-left:30px;\n    padding-right:10px;\n}\n.cart-expbox-09 a.cart-checkout{\n    background-image:url(../images/cart-checkout-icon.gif);\n    background-repeat:no-repeat;\n    background-position:0 0;\n}\n.cart-expbox-09 a.cart-show-white{\n    background-image:url(../images/cart-cart-icon-white.gif);\n    background-repeat:no-repeat;\n    background-position:0 0;\n}\na.cart-show-black{\n    padding-left:30px;\n    font-weight:bold;\n    background-image:url(../images/cart-cart-icon-black.gif);\n    background-repeat:no-repeat;\n    background-position:0 0;\n}\n.cart-tab-mid{\n    background-image:url(../images/cart-tab-mid.gif);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    cursor:pointer;\n}\n.cart-tab-left{\n    width:11px;\n    font-size:1px;\n}\n.cart-tab-right{\n    width:11px;\n    font-size:1px;\n}\n.cart-tabs{\n    padding-left:20px;\n}\n.product-box{\n    background-image:url(../images/cart-content-back.gif);\n    background-repeat:repeat-x;\n    background-position:0 0;\n    border:solid 1px #ececec;\n    background-color:#fff;\n    margin-top:10px;\n    padding:1em;\n    margin-bottom:40px;\n    color:#535353;\n    line-height:30px; \n}\n.price{\n    color:#dc0000;\n    font-size:24px;\n}\n.cartData{\n    text-align:left;\n}\n.show-items{\n    color:#fffc8f;\n}\n.item-list{\n    border-left:solid 1px #d2e6ec;\n    border-top:solid 1px #d2e6ec;\n    width:100%;\n}\n.item-list thead th{\n    background-color:#a1d2e5;\n    border-right:solid 1px #d2e6ec;\n    border-bottom:solid 1px #d2e6ec;\n    padding-left:5px;\n    padding-top:3px;\n}\n.item-list tbody td{\n    border-right:solid 1px #d2e6ec;\n    border-bottom:solid 1px #d2e6ec;\n    padding-left:5px;\n    padding-right:3px;\n    padding-top:3px;\n    color:#fff;\n}\n.delete-icon{\n    background-image:url(../images/trash.gif);\n    background-repeat:no-repeat;\n    background-position:0 0;\n}\n.lastColWidth{\n    width:100px;\n}\n.pricecol{\n    text-align:right;\n}\n.price-total{\n    padding-top:10px;\n    font-size:20px;\n    color:#fff;\n}\n.checkout-wrapper{\n    padding-top:10px;\n    text-align:right;\n}\n.cartData h1{\n    color:#fff;\n}"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/webapp/errors.jsp",
    "content": "<!--\n~ Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n~\n~ WSO2 Inc. licenses this file to you under the Apache License,\n~ Version 2.0 (the \"License\"); you may not use this file except\n~ 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,\n~ software distributed under the License is distributed on an\n~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n~ KIND, either express or implied.  See the License for the\n~ specific language governing permissions and limitations\n~ under the License.\n-->\n<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\n         pageEncoding=\"UTF-8\"%>\n<%@ page isErrorPage=\"true\"%>\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"css/cart-styles.css\">\n    <title>User Logged out</title>\n</head>\n<body>\n<div id=\"container\">\n    <div id=\"header-area\">\n        <img src=\"images/cart-logo.gif\" alt=\"Logo\" vspace=\"10\" />\n\n    </div>\n    <div id=\"content-area\">\n        <div class=\"cart-tabs\">\n            <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                <tr>\n                    <td class=\"cart-tab-left\"><img src=\"images/cart-tab-left.gif\"\n                                                   alt=\"-\"></td>\n                    <td class=\"cart-tab-mid\"><a>Home</a></td>\n                    <td class=\"cart-tab-right\"><img\n                            src=\"images/cart-tab-right.gif\" alt=\"-\"></td>\n                </tr>\n            </table>\n        </div>\n        <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"cart-expbox\">\n            <tr>\n                <td><img src=\"images/cart-expbox-01.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-02\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-03.gif\" alt=\"-\"></td>\n            </tr>\n            <tr>\n                <td class=\"cart-expbox-08\">&nbsp</td>\n                <td class=\"cart-expbox-09\">\n                    <!--all content for cart and links goes here-->\n                </td>\n                <td class=\"cart-expbox-04\">&nbsp</td>\n            </tr>\n            <tr>\n                <td><img src=\"images/cart-expbox-07.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-06\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-05.gif\" alt=\"-\"></td>\n            </tr>\n\n        </table>\n        <h1>Travelocity.COM</h1>\n        <hr />\n        <a href=\"../avis.com\"> Avis.COM </a>&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"index.jsp\"> Go to Login page </a>\n        <hr/>\n        <h2>An error has occurred</h2>\n        <%=exception.getMessage()%>\n        <hr/>\n    </div>\n    <div id=\"footer-area\">\n        <p>©2016 WSO2</p>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/webapp/home.jsp",
    "content": "<!--\n~ Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n~\n~ WSO2 Inc. licenses this file to you under the Apache License,\n~ Version 2.0 (the \"License\"); you may not use this file except\n~ 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,\n~ software distributed under the License is distributed on an\n~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n~ KIND, either express or implied.  See the License for the\n~ specific language governing permissions and limitations\n~ under the License.\n-->\n<%@ page import=\"java.util.List\" %>\n<%@ page import=\"java.util.Map\" %>\n<%@ page import=\"java.util.Iterator\" %>\n<%@ page import=\"org.wso2.carbon.identity.sso.agent.bean.LoggedInSessionBean\" %>\n<%@ page import=\"org.wso2.carbon.identity.sso.agent.bean.SSOAgentConfig\" %>\n<%@ page import=\"org.wso2.carbon.identity.sso.agent.SSOAgentConstants\" %>\n\n<%@ page import=\"org.apache.commons.httpclient.HttpClient\" %>\n<%@ page import=\"org.apache.commons.httpclient.methods.GetMethod\" %>\n<%@ page contentType=\"text/html;charset=UTF-8\" language=\"java\" pageEncoding=\"UTF-8\" %>\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"css/cart-styles.css\">\n    <title>WSO2</title>\n</head>\n<%\n    String claimedId = null;\n    String subjectId = null;\n    Map<String, List<String>> openIdAttributes = null;\n    Map<String, String> saml2SSOAttributes = null;\n    if(request.getSession(false) != null &&\n            request.getSession(false).getAttribute(SSOAgentConstants.SESSION_BEAN_NAME) == null){\n        request.getSession().invalidate();\n%>\n        <script type=\"text/javascript\">\n        location.href = \"index.jsp\";\n        </script>\n<%\n        return;\n    }\n    SSOAgentConfig ssoAgentConfig = (SSOAgentConfig)getServletContext().getAttribute(SSOAgentConstants.CONFIG_BEAN_NAME);\n    LoggedInSessionBean sessionBean = (LoggedInSessionBean)session.getAttribute(SSOAgentConstants.SESSION_BEAN_NAME);\n    LoggedInSessionBean.AccessTokenResponseBean accessTokenResponseBean = null;\n\n    if(sessionBean != null){\n        if(sessionBean.getOpenId() != null) {\n            claimedId = sessionBean.getOpenId().getClaimedId();\n            openIdAttributes = sessionBean.getOpenId().getSubjectAttributes();\n        } else if(sessionBean.getSAML2SSO() != null) {\n            subjectId = sessionBean.getSAML2SSO().getSubjectId();\n            saml2SSOAttributes = sessionBean.getSAML2SSO().getSubjectAttributes();\n            accessTokenResponseBean = sessionBean.getSAML2SSO().getAccessTokenResponseBean();\n        } else {\n%>\n            <script type=\"text/javascript\">\n                location.href = \"index.jsp\";\n            </script>\n<%\n            return;\n        }\n    } else {\n%>\n        <script type=\"text/javascript\">\n            location.href = \"index.jsp\";\n        </script>\n<%\n        return;\n    }\n%>\n<body>\n<div>\n    <div id=\"header-area\">\n        <img src=\"images/cart-logo.gif\" alt=\"Logo\" vspace=\"10\" />\n    </div>\n    <div id=\"content-area\">\n        <div class=\"cart-tabs\">\n            <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                <tr>\n                    <td class=\"cart-tab-left\">\n                        <img src=\"images/cart-tab-left.gif\" alt=\"-\">\n                    </td>\n                    <td class=\"cart-tab-mid\">\n                        <a>Home</a>\n                    </td>\n                    <td class=\"cart-tab-right\">\n                        <img src=\"images/cart-tab-right.gif\" alt=\"-\">\n                    </td>\n                </tr>\n            </table>\n        </div>\n        <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"cart-expbox\">\n            <tr>\n                <td><img src=\"images/cart-expbox-01.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-02\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-03.gif\" alt=\"-\"></td>\n            </tr>\n            <tr>\n                <td class=\"cart-expbox-08\">&nbsp</td>\n                <td class=\"cart-expbox-09\">\n                    <!--all content for cart and links goes here-->\n                </td>\n                <td class=\"cart-expbox-04\">&nbsp</td>\n            </tr>\n            <tr>\n                <td><img src=\"images/cart-expbox-07.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-06\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-05.gif\" alt=\"-\"></td>\n            </tr>\n\n        </table>\n        <h1>Travelocity.COM</h1>\n        <hr />\n        <div class=\"product-box\">\n            <%\n                if(subjectId != null){\n            %>\n                    <h2> You are logged in as <%=subjectId%></h2>\n            <%\n                } else if (claimedId != null) {\n            %>\n                    <h2> You are logged in as <%=claimedId%></h2>\n            <%\n                }\n            %>\n            <a href=\"../avis.com/home.jsp\"> Avis.COM </a>&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"index.jsp\">Go to Login page</a><br/>\n            <table>\n                <%\n                    if(saml2SSOAttributes != null){\n                        for (Map.Entry<String, String> entry:saml2SSOAttributes.entrySet()) {\n                %>\n                            <tr>\n                                <td><%=entry.getKey()%></td>\n                                <td><%=entry.getValue()%></td>\n                            </tr>\n                <%\n                        }\n                    } else if (openIdAttributes != null) {\n                        for(Map.Entry<String, List<String>> entry:openIdAttributes.entrySet()) {\n                %>\n                            <tr>\n                                <td><%=entry.getKey()%></td>\n                                <td>\n                                    <%\n                                        Iterator it = entry.getValue().iterator();\n                                        if(it.hasNext()){\n                                    %>\n                                            <%=it.next().toString()%>\n                                    <%\n                                        }\n                                    %>\n                                </td>\n                            </tr>\n                <%\n                        }\n                    }\n                %>\n            </table>\n            <%\n                if (subjectId != null) {\n                    if(accessTokenResponseBean != null) {\n            %>\n                        <u><b>Your OAuth2 Access Token details</b></u>\n                        <div style=\"text-indent: 50px\">Token Type: <%=accessTokenResponseBean.getTokenType()%> <br/></div>\n                        <div style=\"text-indent: 50px\">Expiry In: <%=accessTokenResponseBean.getExpiresIn()%> <br/></div>\n            <%\n                        // Creates an HTTP REST call to micro service\n                        // Create an instance of HttpClient.\n                        HttpClient client = new HttpClient();\n                        String microServiceURL = \"http://localhost:8081/hello/\";\n\n                        // Create a method instance.\n                        GetMethod method = new GetMethod(microServiceURL + subjectId);\n                        method.setRequestHeader(\"X-JWT-Assertion\", accessTokenResponseBean.getAccessToken());\n\n\n                        try {\n                            client.executeMethod(method);\n                            byte[] responseBody = method.getResponseBody();\n                            String responseString = new String(responseBody);\n            %>\n                            <u><b>Micro service details</b></u>\n                            <div style=\"text-indent: 50px\">Micro service URL: <%=microServiceURL%> <br/></div>\n                            <div style=\"text-indent: 50px\">Response from micro service: <%=responseString%> <br/></div>\n            <%\n                        } catch (Exception e) {\n            %>\n                            <u><b>Error</b></u>\n                            <div style=\"text-indent: 50px\">An error occurred while calling\n                                the micro service: <%=e.getMessage()%> <br/></div>\n            <%\n                        }\n                    } else {\n                        if(ssoAgentConfig.isOAuth2SAML2GrantEnabled()){\n            %>\n                            <a href=\"token\">Request OAuth2 Access Token and send to micro service</a><br/>\n            <%\n\n                        }\n                    }\n                }\n            %>\n            <hr/>\n            <%\n                if(subjectId != null && ssoAgentConfig.getSAML2().isSLOEnabled()){\n            %>\n            <a href=\"logout?SAML2.HTTPBinding=HTTP-Redirect\">Logout (HTTPRedirect)\n            </a>&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"logout?SAML2.HTTPBinding=HTTP-POST\">Logout (HTTP Post)</a><br/>\n\n            <%\n\n                }\n            %>\n        </div>\n    </div>\n    <div id=\"footer-area\">\n        <p>©2014 WSO2</p>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "samples/jwt-claims/sso-agent-for-jwt-webapp/src/main/webapp/index.jsp",
    "content": "<!--\n~ Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n~\n~ WSO2 Inc. licenses this file to you under the Apache License,\n~ Version 2.0 (the \"License\"); you may not use this file except\n~ 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,\n~ software distributed under the License is distributed on an\n~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n~ KIND, either express or implied.  See the License for the\n~ specific language governing permissions and limitations\n~ under the License.\n-->\n<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ page import=\"org.wso2.carbon.identity.sso.agent.bean.SSOAgentConfig\" %>\n<%@ page import=\"org.wso2.carbon.identity.sso.agent.SSOAgentConstants\" %>\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"css/cart-styles.css\">\n    <title>User Logged out</title>\n</head>\n<%\n    session.setAttribute(\"scope\", \"openid\");\n%>\n<body>\n<div id=\"container\">\n    <div id=\"header-area\">\n        <img src=\"images/cart-logo.gif\" alt=\"Logo\" vspace=\"10\" />\n    </div>\n    <div id=\"content-area\">\n        <div class=\"cart-tabs\">\n            <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                <tr>\n                    <td class=\"cart-tab-left\"><img src=\"images/cart-tab-left.gif\"\n                                                   alt=\"-\"></td>\n                    <td class=\"cart-tab-mid\"><a>Home</a></td>\n                    <td class=\"cart-tab-right\"><img\n                            src=\"images/cart-tab-right.gif\" alt=\"-\"></td>\n                </tr>\n            </table>\n        </div>\n        <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"cart-expbox\">\n            <tr>\n                <td><img src=\"images/cart-expbox-01.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-02\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-03.gif\" alt=\"-\"></td>\n            </tr>\n            <tr>\n                <td class=\"cart-expbox-08\">&nbsp</td>\n                <td class=\"cart-expbox-09\">\n                    <!--all content for cart and links goes here-->\n                </td>\n                <td class=\"cart-expbox-04\">&nbsp</td>\n            </tr>\n            <tr>\n                <td><img src=\"images/cart-expbox-07.gif\" alt=\"-\"></td>\n                <td class=\"cart-expbox-06\">&nbsp</td>\n                <td><img src=\"images/cart-expbox-05.gif\" alt=\"-\"></td>\n            </tr>\n\n        </table>\n        <h1>Travelocity.COM</h1>\n        <hr />\n        <a href=\"../avis.com\"> Avis.COM </a>\n        <div class=\"product-box\">\n            <form method=\"post\" action=\"samlsso?SAML2.HTTPBinding=HTTP-POST\">\n                <h2>Login with <img src=\"images/saml2-logo.png\" height=\"22\" width=\"60\"/> (Post Binding) from\n                <img src=\"images/identity_logo.gif\" height=\"20\" width=\"120\"/> with user credentials</h2>\n                Username : <input type=\"text\" name=\"username\"/>\n                Password : <input type=\"password\" name=\"password\">\n                <input type=\"submit\" value=\"Login\"/>\n            </form>\n            <hr/>\n            <h2>Click <a href=\"samlsso?SAML2.HTTPBinding=HTTP-Redirect\">here</a> to login with <img src=\"images/saml2-logo.png\" height=\"22\" width=\"60\"/>\n                (Redirect binding) from <img src=\"images/identity_logo.gif\" height=\"20\" width=\"120\"/></h2>\n            <hr/>\n            <h2>Click <a href=\"samlsso?SAML2.HTTPBinding=HTTP-POST\">here</a> to login with\n                <img src=\"images/saml2-logo.png\" height=\"22\" width=\"60\"/> (Post Binding) from <img\n                    src=\"images/identity_logo.gif\" height=\"20\" width=\"120\"/></h2>\n            <hr/>\n            <h2>Click <a href=\"openid?OpenId.ClaimedId=<%=((SSOAgentConfig)getServletContext().getAttribute(SSOAgentConstants.CONFIG_BEAN_NAME)).getOpenId().getProviderURL()%>\">here</a> to login with <img src=\"images/openid-logo.svg\" height=\"20\" width=\"55\"/> from <img src=\"images/identity_logo.gif\" height=\"20\" width=\"120\"/></h2>\n            <hr/>\n            <h2>Click <a href=\"openid?OpenId.ClaimedId=https://www.google.com/accounts/o8/id\">here</a> to login with <img src=\"images/google-openid.png\" height=\"20\" width=\"75\"/></h2>\n            <hr/>\n            <fieldset>\n                <legend>Login with your Claimed OpenID URI</legend>\n                <form action=\"openid\" method=\"post\">\n                    <div align=\"center\">\n                        <input type=\"text\" name=\"OpenId.ClaimedId\" size=\"30\"/> <input type=\"submit\" name=\"login\" value=\"Login\"/>\n                    </div>\n                </form>\n            </fieldset>\n        </div>\n    </div>\n    <div id=\"footer-area\">\n        <p>©2014 WSO2</p>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "samples/jwt-claims/sso-agent-sample/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>jwt-claims</artifactId>\n        <groupId>org.wso2.msf4j</groupId>\n        <version>2.1.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>sso-agent-sample</artifactId>\n    <name>Travelocity.COM ServiceProvider / RelyingParty Webapp</name>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-dependency-plugin</artifactId>\n                <version>2.3</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>copy</goal>\n                        </goals>\n                        <configuration>\n                            <artifactItems>\n                                <artifactItem>\n                                    <groupId>org.wso2.msf4j</groupId>\n                                    <artifactId>sso-agent-sample-webapp</artifactId>\n                                    <version>${project.version}</version>\n                                    <type>war</type>\n                                    <destFileName>travelocity.com.war</destFileName>\n                                </artifactItem>\n                            </artifactItems>\n                            <outputDirectory>${project.build.directory}</outputDirectory>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>\n"
  },
  {
    "path": "samples/lifecycle/README.md",
    "content": "# Lifecycle Sample\n\nThis sample shows how to use service lifecycle methods on WSO2 MSF4J.\n\nYou can notice following 2 lifecycle methods in Helloworld service class.\n\n```java\n    @PostConstruct\n    public void init() {\n        LOG.info(\"Helloworld :: calling PostConstruct method\");\n    }\n\n    @PreDestroy\n    public void close() {\n        LOG.info(\"Helloworld :: calling PreDestroy method\");\n    }\n\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean package\n```\n\n## How to run the sample\n\nUse following command to run the application\n```\njava -jar target/lifecycle-*.jar\n```\n\n## How to tests the sample\n\n\nDuring the service startup you should be able to see the following output.\n```\n2015-11-12 17:31:28 INFO  Helloworld:40 - Helloworld :: calling PostConstruct method\n\n\n```\n\nShutdown the server using CTRL+C, now you should be able to see the following output.\n\n```\n2015-11-12 17:31:38 INFO  Helloworld:45 - Helloworld :: calling PreDestroy method\n\n```\n"
  },
  {
    "path": "samples/lifecycle/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>lifecycle</artifactId>\n\n    <name>Sample: MSF4J Microservice Lifecycle Management</name>\n    <description>Demonstrates how to use service lifecycle methods in microservices in WSO2 MSF4J</description>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/lifecycle/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private static final Logger logger = LoggerFactory.getLogger(Application.class);\n\n    public static void main(String[] args) {\n        logger.info(\"Starting the Microservice\");\n        new MicroservicesRunner().deploy(new Helloworld()).start();\n    }\n}\n"
  },
  {
    "path": "samples/lifecycle/src/main/java/org/wso2/msf4j/example/Helloworld.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *   WSO2 Inc. licenses this file to you under the Apache License,\n *   Version 2.0 (the \"License\"); you may not use this file except\n *   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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.example;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.annotation.PostConstruct;\nimport javax.annotation.PreDestroy;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Helloworld resource class.\n */\n@Path(\"/hello\")\npublic class Helloworld {\n\n    private static final Logger LOG = LoggerFactory.getLogger(Helloworld.class);\n\n    @PostConstruct\n    public void init() {\n        LOG.info(\"Helloworld :: calling PostConstruct method\");\n    }\n\n    @PreDestroy\n    public void close() {\n        LOG.info(\"Helloworld :: calling PreDestroy method\");\n    }\n\n    @GET\n    @Path(\"/{user}\")\n    public String getUser(@PathParam(\"user\") String user) {\n        return \"Hello \" + user;\n    }\n\n}\n"
  },
  {
    "path": "samples/log-interceptor-bundle/pom.xml",
    "content": ""
  },
  {
    "path": "samples/message-tracing/das/README.md",
    "content": "# Using Open Feign HTTP Client with MSF4J\n\nThis is the MSF4J sample that demonstrates how to use [Open Feign](https://github.com/OpenFeign/feign) client to call microservices deployed in MSF4J and trace the request response flow with [WSO2 DAS](http://wso2.com/products/data-analytics-server/).\nFeign is a java to http client binder that allows you to write Java HTTP REST clients easily. You can create a Java interface and declare your service contracts using annotations.\nIn this example we create 3 microservices; CustomerService, InvoiceService, ReportService. This sample contains Java HTTP/REST bindings and Feign clients created for CustomerService and InvoiceService microservices.\nThe service message flow is as follows;\n\n![Message Flow](resources/message-flow.png)\n\nThe ReportService uses Feign clients to call InvoiceService and CustomerService to generate the report. It uses a TracingClient (which extends feign.Client.Default class) to trace request/response flow by injecting traceable headers to the request. TracingClient publishes trace events which are created in request/response exchanges to WSO2 Data Analytics Server.\n\n## Points to note in the code\n\nAdd the msf4j tracing and Open Feign dependencies to the pom of you MSF4J service.\n```xml\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        \n        <!-- Feign -->\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-core</artifactId>            \n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-slf4j</artifactId>            \n        </dependency>\n        <dependency>\n            <groupId>io.github.openfeign</groupId>\n            <artifactId>feign-gson</artifactId>            \n        </dependency>\n    </dependencies>\n```\n\nRegister the tracing interceptor when starting the microservice.\n```java\n        new MicroservicesRunner()\n                .addExceptionMapper(new EntityNotFoundMapper(), new CustomerNotFoundMapper())\n                .addInterceptor(new MSF4JTracingInterceptor(\"Service-Chaining\"))\n                .deploy(new InvoiceService())\n                .deploy(new CustomerService())\n                .deploy(new ReportService())\n                .start();\n```\n\nCustomerServiceAPI is defined as a Java interface which binds to HTTP/REST API via annotations.\n```java\n        public interface CustomerServiceAPI {\n            @RequestLine(\"GET /customer/{id}\")\n            Customer getCustomer(@Param(\"id\") String id) throws ClientException;\n        }\n```\n\n\nRegister the FeignTracingClient (which extends feign.Client.Default) when building the Feign client instance. You only need FeignTracingClient to trace request/response flow with WSO2 Data Analytics Server.\nThis client will publish client request/response trace events to WSO2 DAS. You can use MSF4J Message Tracing Dashboard to visualize the trace events. See below for installation instructions.\n\n```java\n        Feign.Builder b = Feign.builder()\n                .client(new FeignTracingClient(\"Customer-Service-Client\", analyticsEndpoint))\n                .encoder(new GsonEncoder(ModelUtils.GSON))\n                .logger(new Slf4jLogger())\n                .decoder(new GsonDecoder(ModelUtils.GSON))\n                .errorDecoder(new ClientErrorDecoder());\n        CustomerServiceAPI client = b.target(CustomerServiceAPI.class, serviceEndpoint);\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nDownload [WSO2 DAS Version 3.0.1](http://wso2.com/products/data-analytics-server/) and start it with default configurations.\n\nBuild [wso2das-tracing-capp](../../analytics/wso2das-tracing-capp) module and get the wso2das-msf4j-tracing-*.car file. \nThen, [deploy wso2das-msf4j-tracing-*.car file](https://docs.wso2.com/display/DAS301/Packaging+Artifacts+as+a+C-App+Archive#PackagingArtifactsasaC-AppArchive-DeployingacAppDeployingaC-App) \nin the WSO2 DAS instance you just started. Now you can check the MSF4J Message Tracing Dashboard at \n[https://localhost:9443/portal/dashboards/msf4j-message-tracing](https://localhost:9443/portal/dashboards/msf4j-message-tracing).\n\nAfter that, from the target directory of this sample, run the following command to start the sample microservice.\n```\njava -jar das-tracing-feign-client-*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\n\n```\ncurl http://localhost:9090/report/invoice/I001\n```\n\nYou should get a response similar to the following:\n\n```\n{\"id\":\"I001\",\"customer\":{\"id\":\"C001\",\"firstName\":\"Akila\",\"lastName\":\"Perera\",\"address\":\"DreamWorld!\"},\"amount\":250.15,\"date\":\"Aug 22, 2016 4:50:23 PM\"}\n```\n\nThe above response was generated by 'ReportService' which in turn calls 'InvoiceService' and 'CustomerService' microservices to aggregate the result.\nSo after receiving the above response, you can go to the WSO2 DAS dashboard and find the traces.\n\n\n![WSO2 DAS Tracing Dashboard](resources/wso2das-tracing-gadget.png)"
  },
  {
    "path": "samples/message-tracing/das/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>das-tracing-feign-client</artifactId>\n\n    <name>Sample: MSF4J Service Chaining</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-client</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.tracing.MSF4JTracingInterceptor;\nimport org.wso2.msf4j.example.exception.CustomerNotFoundMapper;\nimport org.wso2.msf4j.example.exception.EntityNotFoundMapper;\nimport org.wso2.msf4j.example.exception.GenericServerErrorMapper;\nimport org.wso2.msf4j.example.exception.InvoiceNotFoundMapper;\nimport org.wso2.msf4j.example.service.CustomerService;\nimport org.wso2.msf4j.example.service.InvoiceService;\nimport org.wso2.msf4j.example.service.ReportService;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n\n        new MicroservicesRunner(8081)\n                .addExceptionMapper(new EntityNotFoundMapper(), new CustomerNotFoundMapper(), new\n                        GenericServerErrorMapper())\n                .addInterceptor(new MSF4JTracingInterceptor(\"Customer-Service\"))\n                .deploy(new CustomerService())\n                .start();\n\n        new MicroservicesRunner(8082)\n                .addExceptionMapper(new EntityNotFoundMapper(), new InvoiceNotFoundMapper(), new\n                        GenericServerErrorMapper())\n                .addInterceptor(new MSF4JTracingInterceptor(\"Invoice-Service\"))\n                .deploy(new InvoiceService())\n                .start();\n        new MicroservicesRunner()\n                .addExceptionMapper(new EntityNotFoundMapper(), new CustomerNotFoundMapper(), new\n                        InvoiceNotFoundMapper(), new GenericServerErrorMapper())\n                .addInterceptor(new MSF4JTracingInterceptor(\"Report-Service\"))\n                .deploy(new ReportService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/ModelUtils.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\n\n/**\n * Converts Object to gson\n */\npublic class ModelUtils {\n    public static final Gson GSON = new GsonBuilder().setPrettyPrinting()\n            .disableHtmlEscaping().create();\n\n    public static String toString(Object o) {\n        return GSON.toJson(o);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/api/CustomerServiceAPI.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.client.api;\n\nimport feign.Param;\nimport feign.RequestLine;\nimport org.wso2.msf4j.client.exception.RestServiceException;\nimport org.wso2.msf4j.example.client.exception.CustomerNotFoundRestServiceException;\nimport org.wso2.msf4j.example.model.Customer;\n\npublic interface CustomerServiceAPI {\n    // Customer service\n    @RequestLine(\"GET /customer/{id}\")\n    Customer getCustomer(@Param(\"id\") String id) throws CustomerNotFoundRestServiceException, RestServiceException;\n}"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/api/InvoiceServiceAPI.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.client.api;\n\nimport feign.Param;\nimport feign.RequestLine;\nimport org.wso2.msf4j.example.client.exception.InvoiceNotFoundRestServiceException;\nimport org.wso2.msf4j.example.model.Invoice;\n\npublic interface InvoiceServiceAPI {\n    // Invoice service\n    @RequestLine(\"GET /invoice/{id}\")\n    Invoice getInvoice(@Param(\"id\") String id) throws InvoiceNotFoundRestServiceException;\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/exception/CustomerNotFoundResponseMapper.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.client.exception;\n\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\n\n/**\n * RestErrorResponseMapper which maps REST service response error to CustomerNotFoundRestServiceException\n */\npublic class CustomerNotFoundResponseMapper extends RestErrorResponseMapper<CustomerNotFoundRestServiceException> {\n\n    public static final String ERROR_CODE = \"30001\";\n\n    @Override\n    public String getExceptionKey() {\n        return ERROR_CODE;\n    }\n\n    @Override\n    public Class<CustomerNotFoundRestServiceException> getExceptionClass() {\n        return CustomerNotFoundRestServiceException.class;\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/exception/CustomerNotFoundRestServiceException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.client.exception;\n\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\npublic class CustomerNotFoundRestServiceException extends RestServiceException {\n\n    public CustomerNotFoundRestServiceException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/exception/InvoiceNotFoundResponseMapper.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.client.exception;\n\nimport org.wso2.msf4j.client.codec.RestErrorResponseMapper;\n\n/**\n * RestErrorResponseMapper which maps REST service response error to CustomerNotFoundRestServiceException\n */\npublic class InvoiceNotFoundResponseMapper extends RestErrorResponseMapper<InvoiceNotFoundRestServiceException> {\n    public static final String ERROR_CODE = \"30002\";\n\n    @Override\n    public String getExceptionKey() {\n        return ERROR_CODE;\n    }\n\n    @Override\n    public Class<InvoiceNotFoundRestServiceException> getExceptionClass() {\n        return InvoiceNotFoundRestServiceException.class;\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/client/exception/InvoiceNotFoundRestServiceException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.client.exception;\n\nimport org.wso2.msf4j.client.exception.RestServiceException;\n\npublic class InvoiceNotFoundRestServiceException extends RestServiceException {\n\n    public InvoiceNotFoundRestServiceException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/CustomerNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * Thrown when a Customer record is not found.\n */\npublic class CustomerNotFoundException extends EntityNotFoundException {\n    public CustomerNotFoundException() {\n        super();\n    }\n\n    public CustomerNotFoundException(String message) {\n        super(message);\n    }\n\n    public CustomerNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public CustomerNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected CustomerNotFoundException(String message, Throwable cause,\n                                        boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/CustomerNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport org.wso2.msf4j.example.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handles CustomerNotFoundException.\n */\npublic class CustomerNotFoundMapper implements ExceptionMapper<CustomerNotFoundException> {\n\n    private static final String ERROR_CODE = \"30001\";\n\n    public Response toResponse(CustomerNotFoundException ex) {\n        return Response.status(404)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/EntityNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * EntityNotFoundException.\n */\npublic class EntityNotFoundException extends Exception {\n    public EntityNotFoundException() {\n        super();\n    }\n\n    public EntityNotFoundException(String message) {\n        super(message);\n    }\n\n    public EntityNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public EntityNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected EntityNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/EntityNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * EntityNotFoundMapper.\n */\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/GenericServerErrorException.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.exception;\n\n/**\n * Thrown when a generic exception occurs while handling a micro service request\n */\npublic class GenericServerErrorException extends Exception {\n    public GenericServerErrorException() {\n        super();\n    }\n\n    public GenericServerErrorException(String message) {\n        super(message);\n    }\n\n    public GenericServerErrorException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public GenericServerErrorException(Throwable cause) {\n        super(cause);\n    }\n\n    protected GenericServerErrorException(String message, Throwable cause,\n                                          boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/GenericServerErrorMapper.java",
    "content": "/*\n *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport org.wso2.msf4j.example.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handled GenericServerErrorException.\n */\npublic class GenericServerErrorMapper implements ExceptionMapper<GenericServerErrorException> {\n\n    private static final String ERROR_CODE = \"10000\";\n\n    @Override\n    public Response toResponse(GenericServerErrorException ex) {\n        return Response.status(500)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/InvoiceNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * Thrown when a Invoice record is not found.\n */\npublic class InvoiceNotFoundException extends EntityNotFoundException {\n    public InvoiceNotFoundException() {\n        super();\n    }\n\n    public InvoiceNotFoundException(String message) {\n        super(message);\n    }\n\n    public InvoiceNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public InvoiceNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected InvoiceNotFoundException(String message, Throwable cause,\n                                       boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/exception/InvoiceNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport org.wso2.msf4j.example.model.ServiceErrorResponse;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handles InvoiceNotFoundException.\n */\npublic class InvoiceNotFoundMapper implements ExceptionMapper<InvoiceNotFoundException> {\n\n    private static final String ERROR_CODE = \"30002\";\n\n    public Response toResponse(InvoiceNotFoundException ex) {\n        return Response.status(404)\n                .entity(new ServiceErrorResponse(ERROR_CODE, ex.getMessage()))\n                .type(\"text/plain\")\n                .build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/model/Customer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example.model;\n\nimport org.wso2.msf4j.example.ModelUtils;\n\n/**\n * Represents a Customer item\n */\n@SuppressWarnings(\"unused\")\npublic class Customer {\n\n    private String id;\n    private String firstName;\n    private String lastName;\n    private String address;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public Customer() {\n    }\n\n    public Customer(String id, String firstName, String lastName, String address) {\n        this.id = id;\n        this.firstName = firstName;\n        this.lastName = lastName;\n        this.address = address;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getAddress() {\n        return address;\n    }\n\n    public void setAddress(String address) {\n        this.address = address;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/model/Invoice.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example.model;\n\n\nimport org.wso2.msf4j.example.ModelUtils;\n\nimport java.util.Date;\n\n/**\n * Represents an Invoice item\n */\n@SuppressWarnings(\"unused\")\npublic class Invoice {\n\n    private String id;\n    private String customerId;\n    private double amount;\n    private Date date;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public Invoice() {\n    }\n\n    public Invoice(String id, String customerId, double amount, Date date) {\n        this.id = id;\n        this.customerId = customerId;\n        this.amount = amount;\n        this.date = date;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getCustomerId() {\n        return customerId;\n    }\n\n    public void setCustomerId(String customerId) {\n        this.customerId = customerId;\n    }\n\n    public double getAmount() {\n        return amount;\n    }\n\n    public void setAmount(double amount) {\n        this.amount = amount;\n    }\n\n    public Date getDate() {\n        return date;\n    }\n\n    public void setDate(Date date) {\n        this.date = date;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/model/InvoiceReport.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example.model;\n\nimport org.wso2.msf4j.example.ModelUtils;\n\nimport java.util.Date;\n\n/**\n * Represents an Invoice Report item.\n */\n@SuppressWarnings(\"unused\")\npublic class InvoiceReport {\n\n    private String id;\n    private Customer customer;\n    private double amount;\n    private Date date;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public InvoiceReport() {\n    }\n\n    public InvoiceReport(Invoice invoice, Customer customer) {\n        this.id = invoice.getId();\n        this.customer = customer;\n        this.amount = invoice.getAmount();\n        this.date = invoice.getDate();\n    }\n\n    public InvoiceReport(String id, Customer customer, double amount, Date date) {\n        this.id = id;\n        this.customer = customer;\n        this.amount = amount;\n        this.date = date;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public Customer getCustomer() {\n        return customer;\n    }\n\n    public void setCustomer(Customer customer) {\n        this.customer = customer;\n    }\n\n    public double getAmount() {\n        return amount;\n    }\n\n    public void setAmount(double amount) {\n        this.amount = amount;\n    }\n\n    public Date getDate() {\n        return date;\n    }\n\n    public void setDate(Date date) {\n        this.date = date;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/model/ServiceErrorResponse.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example.model;\n\nimport org.wso2.msf4j.example.ModelUtils;\n\n/**\n * Represents error response body to be sent back to the client\n */\npublic class ServiceErrorResponse {\n    private String errorCode;\n    private String message;\n\n    /**\n     * No arg constructor is required for marshalling\n     */\n    public ServiceErrorResponse() {\n    }\n\n    public ServiceErrorResponse(String errorCode, String message) {\n        this.errorCode = errorCode;\n        this.message = message;\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n\n    public String getErrorCode() {\n        return errorCode;\n    }\n\n    public void setErrorCode(String errorCode) {\n        this.errorCode = errorCode;\n    }\n\n    @Override\n    public String toString() {\n        return ModelUtils.toString(this);\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/service/CustomerService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.example.exception.CustomerNotFoundException;\nimport org.wso2.msf4j.example.model.Customer;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * CustomerService resource class.\n */\n@Path(\"/customer\")\npublic class CustomerService {\n\n    private static final Logger log = LoggerFactory.getLogger(CustomerService.class);\n    private Map<String, Customer> customerMap = new HashMap<>();\n\n    public CustomerService() {\n        customerMap.put(\"C001\", new Customer(\"C001\", \"Akila\", \"Perera\", \"DreamWorld!\"));\n    }\n\n    /**\n     * Retrieves a customer record for a given customer ID.\n     * http://localhost:8080/customer/C001\n     *\n     * @param id Customer ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/{id}\")\n    @Produces({\"application/json\"})\n    public Response getCustomer(@PathParam(\"id\") String id) throws CustomerNotFoundException {\n        Customer customer = customerMap.get(id);\n        if (customer == null) {\n            log.info(\"Request for non-existing customer: \" + id);\n            throw new CustomerNotFoundException(\"Customer ID \" + id + \" not found\");\n        }\n        return Response.status(Response.Status.OK).entity(customer).build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/service/InvoiceService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.example.exception.InvoiceNotFoundException;\nimport org.wso2.msf4j.example.model.Invoice;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * CustomerService resource class.\n */\n@Path(\"/invoice\")\npublic class InvoiceService {\n\n    private static final Logger log = LoggerFactory.getLogger(InvoiceService.class);\n    private Map<String, Invoice> invoiceMap = new HashMap<>();\n\n    public InvoiceService() {\n        invoiceMap.put(\"I001\", new Invoice(\"I001\", \"C001\", 250.15, new Date(System.currentTimeMillis())));\n    }\n\n    /**\n     * Retrieves an invoice record for a given invoice ID.\n     * http://localhost:8080/invoice/I001\n     *\n     * @param id Invoice ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/{id}\")\n    @Produces({\"application/json\"})\n    public Response getCustomer(@PathParam(\"id\") String id) throws InvoiceNotFoundException {\n        Invoice invoice = invoiceMap.get(id);\n        if (invoice == null) {\n            log.info(\"Request for non-existing invoice: \" + id);\n            throw new InvoiceNotFoundException(\"Invoice ID \" + id + \" not found\");\n        }\n        return Response.status(Response.Status.OK).entity(invoice).build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/das/src/main/java/org/wso2/msf4j/example/service/ReportService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.service;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.client.MSF4JClient;\nimport org.wso2.msf4j.example.client.api.CustomerServiceAPI;\nimport org.wso2.msf4j.example.client.api.InvoiceServiceAPI;\nimport org.wso2.msf4j.example.client.exception.CustomerNotFoundResponseMapper;\nimport org.wso2.msf4j.example.client.exception.CustomerNotFoundRestServiceException;\nimport org.wso2.msf4j.example.client.exception.InvoiceNotFoundResponseMapper;\nimport org.wso2.msf4j.example.client.exception.InvoiceNotFoundRestServiceException;\nimport org.wso2.msf4j.example.exception.CustomerNotFoundException;\nimport org.wso2.msf4j.example.exception.GenericServerErrorException;\nimport org.wso2.msf4j.example.exception.InvoiceNotFoundException;\nimport org.wso2.msf4j.example.model.Customer;\nimport org.wso2.msf4j.example.model.Invoice;\nimport org.wso2.msf4j.example.model.InvoiceReport;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * ReportService resource class.\n */\n@Path(\"/report\")\npublic class ReportService {\n\n    private static final Logger log = LoggerFactory.getLogger(ReportService.class);\n    private static final String CUSTOMER_SERVICE_URL = \"http://localhost:8081\";\n    private static final String INVOICE_SERVICE_URL = \"http://localhost:8082\";\n    private static final String DAS_RECEIVER_URL = \"http://localhost:9763/endpoints/msf4jtracereceiver\";\n    private final MSF4JClient<CustomerServiceAPI> customerServiceClient;\n    private final MSF4JClient<InvoiceServiceAPI> invoiceServiceClient;\n\n    public ReportService() {\n        customerServiceClient = new MSF4JClient.Builder<CustomerServiceAPI>()\n                .analyticsEndpoint(DAS_RECEIVER_URL)\n                .apiClass(CustomerServiceAPI.class)\n                .enableTracing()\n                .instanceName(\"CustomerServiceClient\")\n                .serviceEndpoint(CUSTOMER_SERVICE_URL)\n                .addErrorResponseMapper(new CustomerNotFoundResponseMapper())\n                .build();\n\n        invoiceServiceClient = new MSF4JClient.Builder<InvoiceServiceAPI>()\n                .analyticsEndpoint(DAS_RECEIVER_URL)\n                .apiClass(InvoiceServiceAPI.class)\n                .enableTracing()\n                .instanceName(\"InvoiceServiceClient\")\n                .serviceEndpoint(INVOICE_SERVICE_URL)\n                .addErrorResponseMapper(new InvoiceNotFoundResponseMapper())\n                .build();\n    }\n\n    /**\n     * Retrieves the invoice report for a given invoice ID.\n     * http://localhost:8080/report/invoice/I001\n     *\n     * @param id Invoice ID will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/invoice/{id}\")\n    @Produces({\"application/json\"})\n    public Response getInvoiceReport(@PathParam(\"id\") String id) throws InvoiceNotFoundException,\n            CustomerNotFoundException, GenericServerErrorException {\n        InvoiceReport invoiceReport;\n        Invoice invoice;\n        try {\n            invoice = invoiceServiceClient.api().getInvoice(id);\n            if (log.isDebugEnabled()) {\n                log.info(\"Invoice retrieved: \" + invoice);\n            }\n        } catch (InvoiceNotFoundRestServiceException e) {\n            throw new InvoiceNotFoundException(e);\n        } catch (Exception e) {\n            log.error(\"Generic exception encountered\", e);\n            throw new GenericServerErrorException(\"Server Error: Something went wrong!\");\n        }\n\n        try {\n            String customerId = invoice.getCustomerId();\n            Customer customer = customerServiceClient.api().getCustomer(customerId);\n            if (log.isDebugEnabled()) {\n                log.debug(\"Customer retrieved: \" + customer);\n            }\n            invoiceReport = new InvoiceReport(invoice, customer);\n        } catch (CustomerNotFoundRestServiceException e) {\n            throw new CustomerNotFoundException(e);\n        } catch (Exception e) {\n            log.error(\"Generic exception encountered\", e);\n            throw new GenericServerErrorException(\"Server Error: Something went wrong!\");\n        }\n\n        return Response.status(Response.Status.OK).entity(invoiceReport).build();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/zipkin/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>zipkin-tracing-feign-client</artifactId>\n\n    <name>Sample: MSF4J distributed tracing with Zipkin</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>zipkin-tracing</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-client</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/message-tracing/zipkin/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.zipkintracing.MSF4JZipkinTracingInterceptor;\n\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner().addInterceptor(new MSF4JZipkinTracingInterceptor(\"message-tracing\"))\n                                 .deploy(new TraceableService()).start();\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/zipkin/src/main/java/org/wso2/msf4j/example/TraceableService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.analytics.common.tracing.TracingConstants;\nimport org.wso2.msf4j.client.MSF4JClient;\nimport org.wso2.msf4j.client.codec.MSF4JDecoder;\n\nimport java.util.Random;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n/**\n * TraceableService resource class.\n */\n@Path(\"/service\")\npublic class TraceableService {\n\n    final private Random random = new Random();\n\n    private MSF4JClient<TraceableServiceInterface> client = new MSF4JClient.Builder<TraceableServiceInterface>()\n            .apiClass(TraceableServiceInterface.class)\n            .enableTracing()\n            .decoder(new MSF4JDecoder())\n            .tracingType(TracingConstants.TracingType.ZIPKIN)\n            .instanceName(\"TraceableServiceClient\")\n            .analyticsEndpoint(\"http://localhost:9411\")\n            .serviceEndpoint(\"http://localhost:8080\")\n            .build();\n\n    @GET\n    @Path(\"/aaaa\")\n    public String aaaaEndpoint() throws InterruptedException {\n        String responseB = client.api().bbbbEndpoint();\n        String responseC = client.api().ccccEndpoint();\n        Thread.sleep(random.nextInt(1000));\n        return \"aaaa-res:\" + responseB + \":\" + responseC;\n    }\n\n    @GET\n    @Path(\"/bbbb\")\n    public String bbbbEndpoint() throws InterruptedException {\n        String responseD = client.api().ddddEndpoint();\n        String responseE = client.api().eeeeEndpoint();\n        Thread.sleep(random.nextInt(1000));\n        return \"bbbb-res:\" + responseD + \":\" + responseE;\n    }\n\n    @GET\n    @Path(\"/cccc\")\n    public String ccccEndpoint() throws InterruptedException {\n        String responseF = client.api().ffffEndpoint();\n        Thread.sleep(random.nextInt(1000));\n        return \"cccc-res:\" + responseF;\n    }\n\n    @GET\n    @Path(\"/dddd\")\n    public String ddddEndpoint() throws InterruptedException {\n        Thread.sleep(random.nextInt(1000));\n        return \"dddd\";\n    }\n\n    @GET\n    @Path(\"/eeee\")\n    public String eeeeEndpoint() throws InterruptedException {\n        Thread.sleep(random.nextInt(1000));\n        return \"eeee\";\n    }\n\n    @GET\n    @Path(\"/ffff\")\n    public String ffffEndpoint() throws InterruptedException {\n        String responseG = client.api().ggggEndpoint();\n        Thread.sleep(random.nextInt(1000));\n        return \"ffff-res:\" + responseG;\n    }\n\n    @GET\n    @Path(\"/gggg\")\n    public String ggggEndpoint() throws InterruptedException {\n        Thread.sleep(random.nextInt(1000));\n        return \"gggg\";\n    }\n}\n"
  },
  {
    "path": "samples/message-tracing/zipkin/src/main/java/org/wso2/msf4j/example/TraceableServiceInterface.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport feign.RequestLine;\n\npublic interface TraceableServiceInterface {\n\n    @RequestLine(\"GET /service/aaaa\")\n    String aaaaEndpoint();\n\n    @RequestLine(\"GET /service/bbbb\")\n    String bbbbEndpoint();\n\n    @RequestLine(\"GET /service/cccc\")\n    String ccccEndpoint();\n\n    @RequestLine(\"GET /service/dddd\")\n    String ddddEndpoint();\n\n    @RequestLine(\"GET /service/eeee\")\n    String eeeeEndpoint();\n\n    @RequestLine(\"GET /service/ffff\")\n    String ffffEndpoint();\n\n    @RequestLine(\"GET /service/gggg\")\n    String ggggEndpoint();\n}\n"
  },
  {
    "path": "samples/metrics/README.md",
    "content": "# Metrics Sample\n\nThis sample shows the use of Metrics Interceptor. The metrics needs to be configured using a YAML file.\n\nThe default \"metrics.yml\" is included in final the JAR. In this sample, there is a custom metrics.yml file added to configure\nthe Metrics Reporters.\n\nMetrics can also be published to WSO2 Data Analytics Server (DAS). \n\nSee the [HTTP Monitoring sample](../http-monitoring) for an example of publishing Metrics events to WSO2 DAS.\n\n### Metrics Annotations\n\nThere are three metrics annotations: @Counted, @Metered and @Timed.\n\nUse @Counted annotation when you need to count the method invocations. The @Metered annotation can measure the rate of events.\nUse @Timed to keep a histogram of durations of each method invocation. \n\nThe @Metered annotation also keeps a count. The @Timed annotation keeps the count and rate of events as well.\n\nSee [Metrics Annotations](../../../../#metrics-annotations) for more details.\n\nSee the following example:\n\n```java\n@Path(\"/demo\")\npublic class DemoService {\n\n    private final Random random = new Random();\n\n    private final LongAdder longAdder = new LongAdder();\n\n    @GET\n    @Path(\"/rand/{bound}\")\n    @Metered\n    public int getRandomInt(@PathParam(\"bound\") int bound) {\n        return random.nextInt(bound);\n    }\n\n    @GET\n    @Path(\"/echo/{string}\")\n    @Timed\n    public String echo(@PathParam(\"string\") String string) {\n        try {\n            Thread.sleep(random.nextInt(5000));\n        } catch (InterruptedException e) {\n        }\n        return string;\n    }\n\n    @GET\n    @Path(\"/count/{number}\")\n    @Counted(monotonic = true)\n    public long getCount(@PathParam(\"number\") long number) {\n        longAdder.add(number);\n        return longAdder.longValue();\n    }\n\n}\n```\n\n**How to add and initialize Metrics Interceptor**\n\nThe init() method accepts the MetricReporter types.\n\n```java\nnew MicroservicesRunner().addInterceptor(new MetricsInterceptor())\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nRun the JAR file in target directory.\n\n```\njava -jar target/metrics*.jar\nOR\njava -Dmetrics.config=<Metrics YAML configuration file path> -jar target/metrics*.jar\n```\n\n## How to test the sample\n\nYou can use following cURL commands.\n```\ncurl -v http://localhost:9090/demo/rand/500\n\ncurl -v http://localhost:9090/demo/count/10\n\ncurl -v http://localhost:9090/demo/echo/test\n```\n\n**Metrics Reporters**\n\nSee the [metrics.yaml](src/main/resources/metrics.yaml) configuration.\n\nThe JMX, Console, CSV and SLF4J reporters are configured in this sample.\n"
  },
  {
    "path": "samples/metrics/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>metrics</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: Metrics</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.sample.metrics.Application</microservice.mainClass>\n        <baseimage.name>java:openjdk-8u66-jre</baseimage.name>\n        <maven.dockerplugin.version>0.3.5</maven.dockerplugin.version>\n    </properties>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>com.spotify</groupId>\n                <artifactId>docker-maven-plugin</artifactId>\n                <version>${maven.dockerplugin.version}</version>\n                <configuration>\n                    <imageName>${project.artifactId}:${project.version}</imageName>\n                    <baseImage>${baseimage.name}</baseImage>\n                    <entryPoint>[\"java\", \"-jar\", \"/${project.build.finalName}.jar\"]</entryPoint>\n                    <!-- copy the service's jar file from target into the root directory of the image -->\n                    <resources>\n                        <resource>\n                            <targetPath>/</targetPath>\n                            <directory>${project.build.directory}</directory>\n                            <include>${project.build.finalName}.jar</include>\n                        </resource>\n                    </resources>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "samples/metrics/src/main/java/org/wso2/msf4j/sample/metrics/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.sample.metrics;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\nimport org.wso2.msf4j.sample.metrics.service.DemoService;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private static final Logger logger = LoggerFactory.getLogger(Application.class);\n\n    public static void main(String[] args) {\n        logger.info(\"Starting the Microservice with Metrics\");\n        new MicroservicesRunner()\n                .addInterceptor(new MetricsInterceptor())\n                .deploy(new DemoService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/metrics/src/main/java/org/wso2/msf4j/sample/metrics/service/DemoService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.sample.metrics.service;\n\nimport org.wso2.carbon.metrics.core.annotation.Counted;\nimport org.wso2.carbon.metrics.core.annotation.Metered;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\n\nimport java.util.Random;\nimport java.util.concurrent.atomic.LongAdder;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Demonstrating the use of Metrics Annotations.\n */\n@Path(\"/demo\")\npublic class DemoService {\n\n    private final Random random = new Random();\n\n    private final LongAdder longAdder = new LongAdder();\n\n    @GET\n    @Path(\"/rand/{bound}\")\n    @Metered\n    public int getRandomInt(@PathParam(\"bound\") int bound) {\n        return random.nextInt(bound);\n    }\n\n    @GET\n    @Path(\"/echo/{string}\")\n    @Timed\n    public String echo(@PathParam(\"string\") String string) {\n        try {\n            Thread.sleep(random.nextInt(5000));\n        } catch (InterruptedException e) {\n        }\n        return string;\n    }\n\n    @GET\n    @Path(\"/count/{number}\")\n    @Counted(monotonic = true)\n    public long getCount(@PathParam(\"number\") long number) {\n        longAdder.add(number);\n        return longAdder.longValue();\n    }\n\n}\n"
  },
  {
    "path": "samples/metrics/src/main/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\nwso2.metrics:\n  enabled: true\n\n  jmx:\n    registerMBean: true\n    name: org.wso2.msf4j:type=Metrics\n\n  reporting:\n    jmx:\n      - name: JMX\n        enabled: true\n\n    console:\n      - name: Console\n        enabled: true\n        pollingPeriod: 30\n\n    csv:\n      - name: CSV\n        enabled: true\n        location: metrics\n        pollingPeriod: 30\n\n    slf4j:\n      - name: SLF4J\n        enabled: true\n        loggerName: metrics\n        pollingPeriod: 120\n"
  },
  {
    "path": "samples/metrics/src/main/resources/metrics.yaml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nwso2.metrics:\n  enabled: true\n\n  jmx:\n    registerMBean: true\n    name: org.wso2.msf4j:type=Metrics\n\n  reporting:\n    jmx:\n      - name: JMX\n        enabled: true\n\n    console:\n      - name: Console\n        enabled: true\n        pollingPeriod: 30\n\n    csv:\n      - name: CSV\n        enabled: true\n        location: metrics\n        pollingPeriod: 30\n\n    slf4j:\n      - name: SLF4J\n        enabled: true\n        loggerName: metrics\n        pollingPeriod: 120\n\n"
  },
  {
    "path": "samples/oauth2-security/README.md",
    "content": "# OAuth2 Security Sample\n\nThis sample shows how to secure microservices deployed in WSO2 MSF4J using OAuth2.\n\n## Setting up the Authorization Server.\n\nHere we use WSO2 Identity server as the authorization server.\n\n1) Download and unzip the latest version of the WSO2 Identity Server from http://wso2.com/products/identity-server.\n\n2) Copy resources/introspect.war to wso2is-5.1.0/repository/deployment/server/webapps directory.\n\n3) Create a Service Provider by following the instructions in the this document\n [https://docs.wso2.com/display/IS510/Configuring+a+Service+Provider]\n (https://docs.wso2.com/display/IS510/Configuring+a+Service+Provider)\n\n4) Then under the \"configure inbound authentication\" section, create an OAuth2 application which represents your\nclient application. Instructions are available in the above documentation link. \n\nFor \"Callback Url\", provide \"https://localhost:9443/oauth2/token\"\n\nOnce the OAuth2 application is created,\nyou will get a pair of keys called OAuth Client Key and OAuth Client Secret.\n\n5) Execute following command from the installation directory to start the server.  e.g. /home/user/wso2is-5.1.0/\n\n ```\n sh bin/wso2server.sh\n ```\n\n6) Execute the following command using OAuth Client Key and OAuth Client Secret.\nThis command should return with a JSON response which contains the access token.\n\n ```\n curl -v -k -X POST --basic -u <OAuth Client Key>:<OAuth Client Secret> -H \"Content-Type: application/x-www-form-urlencoded;charset=UTF-8\" -d \"grant_type=client_credentials\" https://localhost:9443/oauth2/token\n ```\n\n ```\n {\"access_token\":\"ded91567bbc7573d5c47e77e700f62ac\",\"token_type\":\"Bearer\",\"expires_in\":3600}\n ```\n\nNote the access_token value.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nWhen you start the MSF4J server, you need to pass a system property with the endpoint of the authorization server.\n\ne.g. AUTH_SERVER_URL=http://localhost:9763/introspect\n\nIf the system property is not specified, then a default value of \"http://localhost:9763/introspect\" will be set in this\n sample\n\nUse following command to run the application\n\n```\njava -DAUTH_SERVER_URL=http://localhost:9763/introspect -jar target/security-*.jar\n```\n\n## How to tests the sample\n\nUse following cURL commands.\n\n```\ncurl -v -H \"Authorization: Bearer <access_token>\" http://localhost:9090/hello/john\n\n> GET /hello/john HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.43.0\n> Accept: */*\n> Authorization: Bearer <access_token>\n>\n< HTTP/1.1 200 OK\n< Content-Type: */*\n< Content-Length: 13\n< Connection: keep-alive\n\nHello john\n\n```\n"
  },
  {
    "path": "samples/oauth2-security/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>oauth2-security</artifactId>\n    <packaging>jar</packaging>\n    <name>Sample: Securing microservices in MSF4J using OAuth2</name>\n    <description>Demostrates how to secure microservices in WSO2 MSF4J</description>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/oauth2-security/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.example.service.Helloworld;\nimport org.wso2.msf4j.security.oauth2.OAuth2SecurityInterceptor;\n\n/**\n * Main Application Class.\n */\npublic class Application {\n\n    private static final Logger logger = LoggerFactory.getLogger(Application.class);\n\n    public static void main(String[] args) {\n        logger.info(\"Starting the Microservice\");\n\n        String authServerURL = System.getProperty(\"AUTH_SERVER_URL\");\n        if (authServerURL == null || authServerURL.equals(\"\")) {\n            System.setProperty(\"AUTH_SERVER_URL\", \"http://localhost:9763/introspect\");\n        }\n\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(new OAuth2SecurityInterceptor())\n                .deploy(new Helloworld())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/oauth2-security/src/main/java/org/wso2/msf4j/example/service/Helloworld.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example.service;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Helloworld resource class.\n */\n@Path(\"/hello\")\npublic class Helloworld {\n\n    @GET\n    @Path(\"/{user}\")\n    public String getUser(@PathParam(\"user\") String user) {\n        return \"Hello \" + user;\n    }\n\n}\n"
  },
  {
    "path": "samples/petstore/README.md",
    "content": "# Pet Store Sample\n\nThis sample modeled after the popular JavaEE Pet Store sample, show cases how to use WSO2 Microservices Framework\nfor Java (MSF4J) as well as other technologies such as Vagrant & Kubernetes to build a \nMicroservices Architecture solution.\n\nThis sample contains the following microservices;\n\n1. Pet - This MSF4J microservice is used to represent the pet resource\n2. Transaction -  This MSF4J microservice is used to represent the transaction resource which is used for handling transactions\nin the pet store\n3. Security -  This MSF4J microservice contains an embedded LDAP server & handles authentication as well as issuing JWT tokens\n4. Frontend admin - a PHP front end for administering the pet store\n5. Fronend user - a PHP store front end for the pet store\n6. File server - This MSF4J microservice which handles file storing & retrieving\n7. Redis - the database used by the pet store\n\n# Deploying the Pet Store Microservice Solution\nGo to the deployment directory & follow the instructions in that directory to deploy the complete pet store. This\ndeployment is dependent on Vagrant, Docker & Kubernetes (k8s)."
  },
  {
    "path": "samples/petstore/deployment/docker-compose/README.md",
    "content": "# Automated deployment of the Petstore sample\n\n## Pre-requisites\n\n * Docker \n * Docker compose\n\n#### Docker installation for linux\n```\nwget -qO- https://get.docker.com/ | sh\n\n```\n\n#### Docker installation for Mac\n\nhttps://docs.docker.com/docker-for-mac/\n\n#### Docker installation for Windows\n\nhttps://docs.docker.com/docker-for-windows/\n\n#### Docker Compose Installation\n\nhttps://docs.docker.com/compose/install/\n\n##Run automated deployment \n\nRun the following commands.\n\n```\n./run.sh\n```\n#### Access Petstore Admin UI\n\nhttp://localhost:32080\n\n#### Access Petstore Store UI\nhttp://localhost:32081\n\n#### Access Analytics UI\nhttp://localhost:39763/monitoring/\n\n#### Clean up\n```\n./clean.sh\n```\nClean.sh will clean all docker compose resources\n\n## How to run in Docker Swarm Cluster\n\n### Setup Docker Swarm Cluster in Amazon AWS\n\nhttps://beta.docker.com/docs/aws/\n\n### Deploy on Swarm\n\nChange docker-compose image names according to your docker private registry or public registry.\n\neg. If you have a docker public registry account (say account name is \"lakwarus\"), you can change images as following\n\n```\ndocker.wso2.com/petstore-security\t-> lakwarus/petstore-security\ndocker.wso2.com/petstore-transaction\t-> lakwarus/petstore-transaction\ndocker.wso2.com/petstore-pet\t\t-> lakwarus/petstore-pet\ndocker.wso2.com/petstore-fileserver\t-> lakwarus/petstore-fileserver\ndocker.wso2.com/petstore-admin-fe\t-> lakwarus/petstore-admin-fe\ndocker.wso2.com/petstore-store-fe\t-> lakwarus/petstore-store-fe\ndocker.wso2.com/petstore-das\t\t-> lakwarus/petstore-das\n```\n```\ndocker-compose build\n```\nThis will build all docker images\n\n```\ndocker-compose push\n```\n\nThis will push newly built images to relevant docker registry\n\n```\ndocker-compose bundle\n```\nThis will create dockercompose.dab json file\n\nCopy dockercompose.dab file to docker swarm manager node and run following\n\n```\ndocker deploy dockercompose\n```\nThis will deploy all docker services on swarm cluster\n\n```\ndocker service update --publish-add 32080:80 dockercompose_admin-fe\ndocker service update --publish-add 32081:80 dockercompose_store-fe\ndocker service update --publish-add 39763:9763 dockercompose_das\n```\n\nPoint your browser to AWS ELB domain with relevent ports to access deployed petstore in swarm cluster\n\n\n\n\n"
  },
  {
    "path": "samples/petstore/deployment/docker-compose/clean.sh",
    "content": "#!/bin/bash\n\ndocker-compose down\n"
  },
  {
    "path": "samples/petstore/deployment/docker-compose/das/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright 2016 WSO2, Inc. (http://wso2.com)\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\nFROM wso2/wso2das:3.0.1\nMAINTAINER architecture@wso2.org\n\nRUN mkdir -p /mnt/wso2das-3.0.1/repository/deployment/server/carbonapps\nCOPY modules /mnt/wso2-artifacts/modules/\nCOPY repository /mnt/wso2-artifacts/repository/\n#COPY packages/wso2das-msf4j-tracing-2.1.0-SNAPSHOT.car /mnt/wso2das-3.0.1/repository/deployment/server/carbonapps\n\nENTRYPOINT [\"/usr/local/bin/init.sh\"]\n"
  },
  {
    "path": "samples/petstore/deployment/docker-compose/docker-compose.yaml",
    "content": "version: '2'\nservices:\n  security:\n    image: docker.wso2.com/petstore-security\n    build:\n      context: .\n      dockerfile: security/Dockerfile\n    ports:\n      - \"8080\"\n    environment:\n      - METRICS_REPORTING_DAS_RECEIVERURL=tcp://das:7611\n      - HTTP_MONITORING_DAS_RECEIVERURL=tcp://das:7611\n    depends_on:\n      - das\n\n  transaction:\n    image: docker.wso2.com/petstore-transaction\n    build:\n      context: .\n      dockerfile: transaction/Dockerfile\n    ports:\n      - \"8080\"\n    environment:\n      - REDIS_MASTER_HOST=redis\n      - REDIS_MASTER_PORT=6379\n      - METRICS_REPORTING_DAS_RECEIVERURL=tcp://das:7611\n      - HTTP_MONITORING_DAS_RECEIVERURL=tcp://das:7611\n    depends_on:\n       - redis\n       - das\n\n  pet:\n    image: docker.wso2.com/petstore-pet\n    build:\n      context: .\n      dockerfile: pet/Dockerfile\n    ports:\n      - \"8080\"\n    environment:\n      - REDIS_MASTER_HOST=redis\n      - REDIS_MASTER_PORT=6379\n      - METRICS_REPORTING_DAS_RECEIVERURL=tcp://das:7611\n      - HTTP_MONITORING_DAS_RECEIVERURL=tcp://das:7611\n    depends_on:\n      - redis\n      - das\n\n  fileserver:\n    image: docker.wso2.com/petstore-fileserver\n    build:\n      context: .\n      dockerfile: fileserver/Dockerfile\n    ports:\n      - \"31111:8080\"\n    environment:\n      - METRICS_REPORTING_DAS_RECEIVERURL=tcp://das:7611\n      - HTTP_MONITORING_DAS_RECEIVERURL=tcp://das:7611\n    depends_on:\n      - das\n    volumes:\n      - /tmp/petstore/fileserver:/var/www/html/upload\n\n  admin-fe:\n    image: docker.wso2.com/petstore-admin-fe\n    build:\n      context: admin-fe\n      dockerfile: Dockerfile\n    ports:\n      - \"32080:80\"\n    environment:\n      - FILE_SERVICE_HOST=fileserver\n      - FILE_SERVICE_PORT=8080\n      - FILE_SERVICE_NODE_PORT=31111\n      - PET_SERVICE_HOST=pet\n      - PET_SERVICE_PORT=8080\n      - SECURITY_SERVICE_HOST=security\n      - SECURITY_SERVICE_PORT=8080\n    depends_on:\n      - pet\n      - security\n      - fileserver\n\n  store-fe:\n    image: docker.wso2.com/petstore-store-fe\n    build:\n      context: store-fe\n      dockerfile: Dockerfile\n    ports:\n      - \"32081:80\"\n    environment:\n      - FILE_SERVICE_HOST=fileserver\n      - FILE_SERVICE_PORT=8080\n      - FILE_SERVICE_NODE_PORT=31111\n      - PET_SERVICE_HOST=pet\n      - PET_SERVICE_PORT=8080\n      - SECURITY_SERVICE_HOST=security\n      - SECURITY_SERVICE_PORT=8080\n      - TXN_SERVICE_HOST=transaction\n      - TXN_SERVICE_PORT=8080\n    depends_on:\n      - pet\n      - security\n      - fileserver\n      - transaction\n\n  redis:\n    image: redis:3\n    ports:\n      - \"36379:6379\"\n    volumes:\n      - /tmp/petstore/redis/data:/data\n\n  das:\n    image: docker.wso2.com/petstore-das\n    build:\n      context: das\n      dockerfile: Dockerfile\n    ports:\n      - \"39443:9443\"\n      - \"39763:9763\"\n"
  },
  {
    "path": "samples/petstore/deployment/docker-compose/run.sh",
    "content": "#!/bin/bash\n\nPRE_REQ=1\nIS_PACK=\"wso2is-5.0.0.zip\"\nDAS_PACK=\"wso2das-3.0.0.zip\"\nHOME=`pwd`\nPET_HOME=\"../../microservices/pet/\"\nFILESERVER_HOME=\"../../microservices/fileserver/\"\nADMIN=\"../../microservices/frontend-admin/\"\nSTORE_FE=\"../../microservices/frontend-user/\"\nSECURITY=\"../../microservices/security/\"\nTRANSACTION=\"../../microservices/transaction/\"\n\n# Checking prerequisites for the build\ncommand -v docker >/dev/null 2>&1 || { echo >&2 \"Missing Docker!!! Build required docker install in the host. Try 'curl -sSL https://get.docker.com/ | sh' \"; $PRE_REQ=1; }\n\nif [ $PRE_REQ -eq 0 ];then\n    echo \"--------------------------------------------------------------\"\n    echo \"All prerequisite not met. Existing build...\"\n    echo \"--------------------------------------------------------------\"\n    exit;\nfi\n\nrm -rf das/modules das/repository packages/* security pet transaction fileserver admin-fe store-fe\n\ngit pull\n\n[ ! -d $HOME/packages ] && mkdir -p $HOME/packages\n\necho \"--------------------------------------------------------------\"\necho \"Building petstore sample\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $PET_HOME\nmvn clean install -Dmaven.test.skip=true\n\ncd $HOME\ncd ../../microservices/security/\nmvn clean install -Dmaven.test.skip=true\n\ncd $HOME\ncd ../../microservices/transaction/\nmvn clean install -Dmaven.test.skip=true\n\ncd $HOME\ncd ../../microservices/fileserver/\nmvn clean install -Dmaven.test.skip=true\n\n# Copy DAS CApps\necho \"--------------------------------------------------------------\"\necho \"Copy DAS CApps\"\necho \"--------------------------------------------------------------\"\ncd $HOME\n../../../../analytics/das-setup/setup.sh -d $HOME/das\n\n# copy Pet\necho \"--------------------------------------------------------------\"\necho \"Copy Pet\"\necho \"--------------------------------------------------------------\"\ncd $HOME\n[ ! -d $HOME/pet ] && mkdir -p $HOME/pet\ncp -f $PET_HOME/target/petstore-pet-*.jar $HOME/packages/petstore-pet.jar\ncp -f $PET_HOME/data-agent-conf.xml $HOME/packages/data-agent-conf.xml\ncp -f $PET_HOME/client-truststore.jks $HOME/packages/client-truststore.jks\n#copy Dockerfile\ncp -f ../../microservices/pet/container/docker/Dockerfile $HOME/pet/\n\necho \"--------------------------------------------------------------\"\necho \"Copy FileServer\"\necho \"--------------------------------------------------------------\"\ncd $HOME\n[ ! -d $HOME/fileserver ] && mkdir -p $HOME/fileserver\ncp -f $FILESERVER_HOME/target/petstore-fileserver-*.jar $HOME/packages/petstore-fileserver.jar\ncp -f $FILESERVER_HOME/data-agent-conf.xml $HOME/packages/data-agent-conf.xml\ncp -f $FILESERVER_HOME/client-truststore.jks $HOME/packages/client-truststore.jks\n#copy Dockerfile\ncp -f ../../microservices/fileserver/container/docker/Dockerfile $HOME/fileserver/\n\n\necho \"--------------------------------------------------------------\"\necho \"Copy FrontEnd Admin\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncp -fr $ADMIN/container/docker $HOME/admin-fe\n\necho \"--------------------------------------------------------------\"\necho \"Copy FrontEnd User\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncp -fr $STORE_FE/container/docker $HOME/store-fe\n\necho \"--------------------------------------------------------------\"\necho \"Copy Security\"\necho \"--------------------------------------------------------------\"\n[ ! -d $HOME/security ] && mkdir -p $HOME/security\ncp -f $SECURITY/target/petstore-security-*.jar $HOME/packages/petstore-security.jar\ncp -f $SECURITY/data-agent-conf.xml $HOME/packages/data-agent-conf.xml\ncp -f $SECURITY/client-truststore.jks $HOME/packages/client-truststore.jks\n#copy Dockerfile\ncp -f ../../microservices/security/container/docker/Dockerfile $HOME/security/\n\n\necho \"--------------------------------------------------------------\"\necho \"Copy Transaction\"\necho \"--------------------------------------------------------------\"\n[ ! -d $HOME/transaction ] && mkdir -p $HOME/transaction\ncp -f $TRANSACTION/target/petstore-txn-*.jar $HOME/packages/petstore-txn.jar\ncp -f $TRANSACTION/data-agent-conf.xml $HOME/packages/data-agent-conf.xml\ncp -f $TRANSACTION/client-truststore.jks $HOME/packages/client-truststore.jks\n#copy Dockerfile\ncp -f ../../microservices/transaction/container/docker/Dockerfile $HOME/transaction/\n\n\ndocker-compose up --build\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/README.md",
    "content": "# Automated deployment of the Petstore sample\n\n## Pre-requisites\n\n * Kubernetes cluster with SKY DNS support\n * Can use one of following links to setup kubernetes cluster\n  - https://github.com/imesh/kubernetes-vagrant-setup\n  - https://github.com/pires/kubernetes-vagrant-coreos-cluster\n\n##Run automated deployment \n\nCopy WSO2 Data Analytics Server pack (zip) into packs folder\n\nRun the following commands.\n\n```\n./petstore.sh\n```\n\nDeploy k8s resources for petstore sample.\n\n#### List all k8s nodes\n```\n$ kubectl get nodes\nNAME           LABELS                                             STATUS    AGE\n172.17.8.102   disktype=ssd,kubernetes.io/hostname=172.17.8.102   Ready     6d\n172.17.8.103   kubernetes.io/hostname=172.17.8.103                Ready     6d\n```\n#### List all k8s pods\n```\n$ kubectl get pods\nNAME                   READY     STATUS    RESTARTS   AGE\nadmin-fe-povyi         1/1       Running   0          39s\nfileserver-mrxhj       1/1       Running   0          39s\npet-jdd2u              1/1       Running   0          40s\nredis-0kfqa            1/1       Running   0          1m\nredis-lgem8            1/1       Running   0          2m\nredis-master-sstyy     1/1       Running   0          39s\nredis-sentinel-kvv69   1/1       Running   0          1m\nredis-sentinel-m7t08   1/1       Running   0          1m\nredis-sentinel-ur0za   1/1       Running   0          39s\nredis-y5o9d            1/1       Running   0          2m\nsecurity-rslsf         1/1       Running   0          39s\nstore-fe-8xyzh         1/1       Running   0          39s\ntxn-5csjp              1/1       Running   0          39s\n```\n#### List all k8s services\n```\n$ kubectl get svc\nNAME              CLUSTER_IP       EXTERNAL_IP   PORT(S)     SELECTOR              AGE\nadmin-fe          10.100.2.62      nodes         80/TCP      name=admin-fe         1m\nfileserver        10.100.173.68    nodes         80/TCP      name=fileserver       1m\nidentity-server   10.100.123.101   <none>        9443/TCP    <none>                3m\nkubernetes        10.100.0.1       <none>        443/TCP     <none>                5d\npet               10.100.59.232    nodes         80/TCP      name=pet              1m\nredis-master      10.100.70.115    <none>        6379/TCP    name=redis-master     1m\nredis-sentinel    10.100.90.239    nodes         26379/TCP   redis-sentinel=true   3m\nsecurity          10.100.151.122   nodes         80/TCP      name=security         1m\nstore-fe          10.100.227.224   nodes         80/TCP      name=store-fe         1m\ntxn               10.100.222.102   nodes         80/TCP      name=txn              1m\n```\n#### Access Petstore Admin UI\n```\n$ kubectl describe svc/admin-fe\nName:\t\t\tadmin-fe\nNamespace:\t\tdefault\nLabels:\t\t\tname=admin-fe\nSelector:\t\tname=admin-fe\nType:\t\t\tNodePort\nIP:\t\t\t10.100.2.62\nPort:\t\t\t<unnamed>\t80/TCP\nNodePort:\t\t<unnamed>\t30313/TCP\nEndpoints:\t\t10.244.98.7:80\nSession Affinity:\tClientIP\nNo events.\n```\nPoint your browser to http://172.17.8.102:30313 # get relevant port from above `kubectl describe svc/admin-fe` command\n\n#### Access Petstore Store UI\n```\n$ kubectl describe svc/store-fe\nName:\t\t\tstore-fe\nNamespace:\t\tdefault\nLabels:\t\t\tname=store-fe\nSelector:\t\tname=store-fe\nType:\t\t\tNodePort\nIP:\t\t\t10.100.227.224\nPort:\t\t\t<unnamed>\t80/TCP\nNodePort:\t\t<unnamed>\t31691/TCP\nEndpoints:\t\t10.244.98.9:80\nSession Affinity:\tClientIP\nNo events.\n```\nPoint your browser to http://172.17.8.102:31691 # get relevant port from above `kubectl describe svc/store-fe` command\n\n```\n./clean.sh\n```\n\nClean.sh will clean all k8s resources\n\n\n\n## Troubleshooting\n\n#### I'm getting errors while waiting for Kubernetes master to become ready on a MacOS host!\n\nYou probably have a pre-existing Kubernetes config file on your system at `~/.kube/config`. Delete or move that file and try again.\n\n#### When I run \"kubectl get pods\" I can see many pods not become to running state or they have lot of restarts.\n\nThis may happend first time when you run the system due to slow internet. Because it took lot of time to download k8s packs. You may resolve this by running following commands\n```\n./clean.sh\n./petstore.sh\n```\n\n\n\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/clean.sh",
    "content": "#!/bin/bash\n\n# exporting paths\nsource path.sh\n\ncd $HOME/packs/${DAS_PACK%.zip}/bin/\n./wso2server.sh stop\n\n\nkubectl delete services --all\nkubectl delete rc --all\nkubectl delete pods --all\n\n\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/external-endpoints/das-endpoint.yaml",
    "content": "{\n    \"kind\": \"Endpoints\",\n    \"apiVersion\": \"v1\",\n    \"metadata\": {\n        \"name\": \"data-analytics-server\"\n    },\n    \"subsets\": [\n        {\n            \"addresses\": [\n                { \"ip\": \"172.17.8.1\" }\n             ],\n            \"ports\": [\n                { \"port\": 7612 }\n             ]\n         }\n    ]\n}\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/external-endpoints/das-service.yaml",
    "content": "{\n    \"kind\": \"Service\",\n    \"apiVersion\": \"v1\",\n    \"metadata\": {\n        \"name\": \"data-analytics-server\"\n    },\n    \"spec\": {\n        \"ports\": [\n            {\n                \"protocol\": \"TCP\",\n                \"port\": 7612,\n                \"targetPort\": 7612\n            }\n        ]\n    }\n}\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/external-endpoints/is-endpoint.yaml",
    "content": "{\n    \"kind\": \"Endpoints\",\n    \"apiVersion\": \"v1\",\n    \"metadata\": {\n        \"name\": \"identity-server\"\n    },\n    \"subsets\": [\n        {\n            \"addresses\": [\n                { \"ip\": \"172.17.8.1\" }\n             ],\n            \"ports\": [\n                { \"port\": 9443 }\n             ]\n         }\n    ]\n}\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/external-endpoints/is-service.yaml",
    "content": "{\n    \"kind\": \"Service\",\n    \"apiVersion\": \"v1\",\n    \"metadata\": {\n        \"name\": \"identity-server\"\n    },\n    \"spec\": {\n        \"ports\": [\n            {\n                \"protocol\": \"TCP\",\n                \"port\": 9443,\n                \"targetPort\": 9443\n            }\n        ]\n    }\n}\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/packs/README.md",
    "content": "Download and copy WSO2 Identity Server Pack(zip) and WSO2 Data Analytics Server Pack(zip)\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/path.sh",
    "content": "#!/bin/bash\n\n\nPRE_REQ=1\nIS_PACK=\"wso2is-5.0.0.zip\"\nDAS_PACK=\"wso2das-3.0.0.zip\"\nHOME=`pwd`\nVAGRANT_HOME=\"$HOME/kubernetes-vagrant-coreos-cluster\"\nSHARE_FOLDER=\"$VAGRANT_HOME/docker/\"\nPET_HOME=\"../microservices/pet\"\nFILESERVER_HOME=\"../microservices/fileserver\"\nREDIS_HOME=\"../microservices/redis\"\nFRONTEND_ADMIN=\"../microservices/frontend-admin\"\nFRONTEND_USER=\"../microservices/frontend-user\"\nSECURITY=\"../microservices/security\"\nTRANSACTION=\"../microservices/transaction\"\n\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/petstore.sh",
    "content": "#!/bin/bash\n\n# exporting paths\nsource path.sh\n\ncd $HOME/packs\n[ -d ${DAS_PACK%.zip} ] && rm -fr ${DAS_PACK%.*}\nunzip $DAS_PACK\necho \"--------------------------------------------------------------\"\necho \"Setting up WSO2 Data Analytics Server\"\necho \"--------------------------------------------------------------\"\necho \"DAS Pack:\"${DAS_PACK%.zip}\n../../../../analytics/das-setup/./setup.sh -d ${DAS_PACK%.zip}\npwd\necho \"--------------------------------------------------------------\"\necho \"Starting WSO2 Data Analytics Server\"\necho \"--------------------------------------------------------------\"\ncd ${DAS_PACK%.zip}/bin/\n./wso2server.sh start -DportOffset=1\n\necho \"--------------------------------------------------------------\"\necho \"Creating Kube-System Namespace, Kube-DNS, Kube-UI\"\necho \"--------------------------------------------------------------\"\n#kubectl create -f $VAGRANT_HOME/plugins/namespace/kube-system.json\n#kubectl create -f $VAGRANT_HOME/plugins/dns/dns-service.yaml\n#kubectl create -f $VAGRANT_HOME/plugins/dns/dns-controller.yaml\n#kubectl create -f $VAGRANT_HOME/plugins/kube-ui/kube-ui-controller.yaml\n#kubectl create -f $VAGRANT_HOME/plugins/kube-ui/kube-ui-service.yaml\n#sleep 20\n\n\necho \"--------------------------------------------------------------\"\necho \"Creating services for external endpoints\"\necho \"--------------------------------------------------------------\"\ncd $HOME\nkubectl create -f external-endpoints/\n\n\necho \"--------------------------------------------------------------\"\necho \"Deploying Redis Cluster\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $REDIS_HOME/container/kubernetes/\nkubectl create -f redis-master.yaml\nsleep 30\nkubectl create -f redis-sentinel-service.yaml\nkubectl create -f redis-controller.yaml\nkubectl create -f redis-sentinel-controller.yaml\nkubectl scale rc redis --replicas=3\nsleep 30\nkubectl scale rc redis-sentinel --replicas=3\nsleep 30\nkubectl delete pods redis-master\n\n\nsleep 20\n\necho \"--------------------------------------------------------------\"\necho \"Deploying Pet\"\necho \"--------------------------------------------------------------\"\n\ncd $HOME\ncd $PET_HOME/container/kubernetes/\nkubectl create -f .\n\n\necho \"--------------------------------------------------------------\"\necho \"Deploying FileServer\"\necho \"--------------------------------------------------------------\"\ncd $HOME\nkubectl label nodes 172.17.8.102 disktype=ssd\ncd $FILESERVER_HOME/container/kubernetes/\nkubectl create -f .\n\n\necho \"--------------------------------------------------------------\"\necho \"Deploying FrontEnd Admin\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $FRONTEND_ADMIN/container/kubernetes/\nkubectl create -f .\n\necho \"--------------------------------------------------------------\"\necho \"Deploying FrontEnd User\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $FRONTEND_USER/container/kubernetes/\nkubectl create -f .\n\n\necho \"--------------------------------------------------------------\"\necho \"Deploying Security\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $SECURITY/container/kubernetes/\nkubectl create -f .\n\n\necho \"--------------------------------------------------------------\"\necho \"Deploying Transaction\"\necho \"--------------------------------------------------------------\"\ncd $HOME\ncd $TRANSACTION/container/kubernetes/\nkubectl create -f .\n\n"
  },
  {
    "path": "samples/petstore/deployment/kubernetes/scale.sh",
    "content": "#!/bin/bash\n\nkubectl scale rc pet --replicas=3\nsleep 20\nkubectl scale rc security --replicas=3\nsleep 20\nkubectl scale rc store-fe --replicas=3\nsleep 20\nkubectl scale rc txn --replicas=3\nkubectl scale rc admin-fe --replicas=3\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/README.md",
    "content": "Fileserver for saving files\n\nSample REST call for upload file\n\n```\ncurl -i -F fileName=image-name.jpg -F file=@/Users/lakmal/Documents/image.jpg http://<serverIP>\n```\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/container/docker/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM java:8-jre\nMAINTAINER architecture@wso2.org\n\nWORKDIR /opt\n\n# --------------------------------\n# Copy scripts, packages & plugins\n# --------------------------------\nCOPY packages/petstore-fileserver.jar /opt/\nCOPY packages/client-truststore.jks /opt/\nCOPY packages/data-agent-conf.xml /opt/\n\n# --------------------------------\n# HTTP Monitoring and metrics specific config\n# --------------------------------\nENV METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV METRICS_REPORTING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\nENV HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV HTTP_MONITORING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\n\n# ----------------------\n# Expose container ports\n# ----------------------\nEXPOSE 8080\n\nENTRYPOINT java -jar /opt/petstore-fileserver.jar\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/container/docker/README.md",
    "content": "Build fileserver docker image and upload to k8s workes\n\n```\ndocker build -t wso2msf4j/petstore-fileserver .\n```\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/container/kubernetes/README.md",
    "content": "Prerequisite\n\n1. You need to set \"ssd\" label to one of your nodes\n\n    -eg:kubectl label nodes 172.17.4.201 disktype=ssd\n    \n2. Create /home/core/fileserver folder in above node\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/container/kubernetes/fileserver-rc.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: fileserver\n  labels:\n    name: fileserver\nspec:\n  replicas: 1\n  selector:\n    name: fileserver\n  template:\n    metadata:\n      labels:\n        name: fileserver\n    spec: \n      containers: \n        - resources:\n          image: wso2msf4j/petstore-fileserver:2.0.0\n          name: fileserver\n          env:\n          - name: GET_HOSTS_FROM\n            value: dns\n          ports: \n            - containerPort: 8080\n              name: fileserver\n          volumeMounts:\n              # name must match the volume name below\n            - name: fileserver-persistent-storage\n              # mount path within the container\n              mountPath: /var/www/html/upload\n      volumes:\n        - name: fileserver-persistent-storage\n          hostPath:\n             path: /home/core\n      #nodeSelector:\n      #  disktype: ssd\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/container/kubernetes/fileserver-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata: \n  labels: \n    name: fileserver\n  name: fileserver\nspec: \n  ports:\n    - port: 80\n      targetPort: 8080\n      \"nodePort\": 31111\n  type: NodePort\n  selector: \n    name: fileserver\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/data-agent-conf.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<DataAgentsConfiguration>\n    <Agent>\n        <Name>Thrift</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.thrift.ThriftDataEndpoint</DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n\n    <Agent>\n        <Name>Binary</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.binary.BinaryDataEndpoint\n        </DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n</DataAgentsConfiguration>\n\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore-fileserver</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: [Pet Store] - Pet store microservices example - file server microservice</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n            <version>2.25</version>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.examples.petstore.fileserver.Runner</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/src/main/java/org/wso2/msf4j/examples/petstore/fileserver/FileServerService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.fileserver;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.HttpStreamHandler;\nimport org.wso2.msf4j.HttpStreamer;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.file.Paths;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.Response;\n\n/**\n * FileServer service class. This uses request streaming\n * to save the submitted files in the server.\n */\n@HTTPMonitored\n@Path(\"/\")\npublic class FileServerService {\n\n    private static final Logger log = LoggerFactory.getLogger(FileServerService.class);\n    private static final java.nio.file.Path MOUNT_PATH = Paths.get(File.separator + \"var\", \"www\", \"html\", \"upload\");\n\n    @POST\n    @Path(\"/{fileName}\")\n    @Timed\n    public void postFile(@Context HttpStreamer httpStreamer,\n                         @PathParam(\"fileName\") String fileName)\n            throws IOException {\n        log.info(\"Adding file: \" + fileName);\n        httpStreamer.callback(new HttpStreamHandlerImpl(fileName));\n    }\n\n    @GET\n    @Path(\"/{fileName}\")\n    @Timed\n    public Response getFile(@PathParam(\"fileName\") String fileName) {\n        log.info(\"Retrieving file: \" + fileName);\n        File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n        if (file.exists()) {\n            return Response.ok(file).build();\n        }\n        return Response.status(Response.Status.NOT_FOUND).build();\n    }\n\n    private static class HttpStreamHandlerImpl implements HttpStreamHandler {\n        private FileChannel fileChannel = null;\n        private org.wso2.msf4j.Response response;\n\n        public HttpStreamHandlerImpl(String fileName) throws FileNotFoundException {\n            File file = Paths.get(MOUNT_PATH.toString(), fileName).toFile();\n            if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {\n                fileChannel = new FileOutputStream(file).getChannel();\n            }\n        }\n\n        @Override\n        public void init(org.wso2.msf4j.Response response) {\n            this.response = response;\n        }\n\n        @Override\n        public void end() throws Exception {\n            fileChannel.close();\n            response.setStatus(Response.Status.ACCEPTED.getStatusCode());\n            response.send();\n        }\n\n        @Override\n        public void chunk(ByteBuffer content) throws Exception {\n            if (fileChannel == null) {\n                throw new IOException(\"Unable to write file\");\n            }\n            fileChannel.write(content);\n        }\n\n        @Override\n        public void error(Throwable cause) {\n            try {\n                if (fileChannel != null) {\n                    fileChannel.close();\n                }\n            } catch (IOException e) {\n                // Log if unable to close the output stream\n                log.error(\"Unable to close file output stream\", e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/src/main/java/org/wso2/msf4j/examples/petstore/fileserver/Runner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.fileserver;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\n\n/**\n * Microservice runner for file server\n */\npublic class Runner {\n\n    public static void main(String[] args) {\n        HTTPMonitoringInterceptor httpMonitoringInterceptor = new HTTPMonitoringInterceptor();\n        MetricsInterceptor metricsInterceptor = new MetricsInterceptor();\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .addGlobalResponseInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .deploy(new FileServerService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/src/main/resources/http-monitoring.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\nenabled: true\n\ndas:\n  receiverURL: ${HTTP_MONITORING_DAS_RECEIVERURL}\n  # authURL: ssl://localhost:7711\n  type: thrift\n  username: admin\n  password: admin\n  dataAgentConfigPath: ${HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH}\n"
  },
  {
    "path": "samples/petstore/microservices/fileserver/src/main/resources/metrics.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nenabled: true\n\njmx:\n  registerMBean: true\n  name: org.wso2.msf4j:type=Metrics\n\ndas:\n  - &DAS01\n    receiverURL: ${METRICS_REPORTING_DAS_RECEIVERURL}\n    # authURL: ssl://localhost:7711\n    type: thrift\n    username: admin\n    password: admin\n    dataAgentConfigPath: ${METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH}\n\nreporting:\n  jmx:\n    - name: JMX\n      enabled: true\n\n  console:\n    - name: Console\n      enabled: false\n      pollingPeriod: 60\n\n  csv:\n    - name: CSV\n      enabled: false\n      location: metrics\n      pollingPeriod: 60\n\n  slf4j:\n    - name: SLF4J\n      enabled: false\n      loggerName: metrics\n      pollingPeriod: 60\n\n  das:\n    - name: DAS\n      enabled: true\n      das: *DAS01\n      pollingPeriod: 60\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/.gitignore",
    "content": "*.iml\n\n## Directory-based project format:\n.idea/\n\natlassian-ide-plugin.xml\nsoapui.log\nsoapui-errors.log\nglobal-groovy.log"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/README.md",
    "content": "# petstore-admin-fe\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/Dockerfile",
    "content": "From ubuntu:14.04\n\nRUN sudo apt-get update && apt-get install -y apache2 php5 php5-curl php5-redis curl\n\nRUN sudo apt-get install -y openssh-server git vim \nRUN mkdir -p /var/run/sshd\nRUN echo 'root:stratos' | chpasswd\nRUN sed -i \"s/PermitRootLogin without-password/#PermitRootLogin without-password/\" /etc/ssh/sshd_config\nEXPOSE 22\n\nexpose 80\n\nRUN rm -fr /var/www/html/*\nCOPY html /var/www/html/\n#COPY php.ini /etc/php5/apache2/\nCOPY init.sh /opt/\nRUN chmod 755 /opt/init.sh\nENTRYPOINT /opt/init.sh \n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/.htaccess",
    "content": ""
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/add-pet-types.php",
    "content": "<?php\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"pet-types.php\"=>'Pet Types', \"add-pet-types.php\"=>'Add');\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Administrator</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<?php\ninclude('includes/navbar.php');\n?>\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Add Pet Types</h1>\n        </div>\n        <div class=\"form-horizontal col-md-5\">\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <label for=\"input-name\" class=\"control-label\">Pet Type Name <span class=\"\">*</span></label>\n                    <input type=\"text\" class=\"form-control\" id=\"pet-type-name\" placeholder=\"add pet type\" required=\"\">\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <button type=\"button\" id=\"pet-type-btn\" class=\"btn btn-default btn-primary\">Add</button>\n                </div>\n            </div>\n        </div>\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n\n<script>\n    $(document).ready(function () {\n        var petCategoryName = $('#pet-type-name');\n        // handle the add pet type button click event\n        $('#pet-type-btn').click(function () {\n            var btn = $(this); //get current clicked button\n            if(petCategoryName.val() == ''){\n                var n = noty({text: 'Add proper pet category name', layout: 'bottomRight', type: 'error'});\n            }else{\n                addPetType(btn);\n            }\n\n        });\n\n        function addPetType(btn){\n            btn.button('loading');\n            $.ajax({\n                type: \"POST\",\n                url:  \"controllers/rest.php\",\n                dataType: 'json',\n                data: {api_type: 'addPetTypes', category_name: petCategoryName.val()},\n                success: function (data, textStatus, jqXHR) {\n                    if (data.status == 'error') {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                        window.setTimeout(function(){\n                            window.location.href = 'logout.php';\n                        }, 1500);\n                    } else if (data.status == 'warning') {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                    } else {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                        window.setTimeout(function(){\n                            window.location.href = 'pet-types.php';\n                        }, 1500);\n                    }\n                }\n            })\n                .always(function () {\n                    btn.button('reset');\n                });\n        }\n\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/add-pets.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"pets.php\"=>'Pets', \"add-pets.php\"=>'Add');\n\n$url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/category/all';\n$pet_catogories = callAuthAPIgetPetTypes($url,  preg_replace('/\\s+/', '', $_SESSION['authtoken']));\n\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Administrator</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<?php\ninclude('includes/navbar.php');\n?>\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Add Pets</h1>\n        </div>\n        <form class=\"form-horizontal col-md-5\" enctype=\"multipart/form-data\" method=\"post\" id=\"pet-target\" action=\"\">\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <label for=\"pet-category\" class=\"control-label\">Type</label>\n                    <select class=\"form-control\" id=\"pet-category\">\n                        <?php\n                        if(is_array($pet_catogories)) {\n                            foreach ($pet_catogories as $json) {\n                                echo '<option value=\"' . $json['name'] . '\">' . $json['name'] . '</option>';\n                            }\n                        }\n                        ?>\n                    </select>\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <label for=\"pet-age-months\" class=\"control-label\">Age </label>\n                    <input type=\"number\" class=\"form-control\" id=\"pet-age-months\" min=\"1\" max=\"1200\"\n                           placeholder=\"pet age\" required=\"\">\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <label for=\"pet-price\" class=\"control-label\">Price </label>\n                    <div class=\"input-group\">\n                        <div class=\"input-group-addon\">$</div>\n                        <input type=\"number\" min=\"1\" max=\"100000\" class=\"form-control form-control-md\" id=\"pet-price\"\n                               placeholder=\"pet price\">\n                    </div>\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <label for=\"pet-file-upload\" class=\"control-label\">Image </label>\n                    <input type=\"file\" name=\"file\" id=\"file\" class=\"form-control\" />\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-12\">\n                    <input type=\"submit\" id=\"pet-add-btn\" class=\"btn btn-default btn-primary\" value=\"Add\" />\n                </div>\n            </div>\n        </form>\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script>\n    $(document).ready(function () {\n        // handle the add pet type button click event\n        $('#pet-target').submit(function (e) {\n            e.preventDefault();\n            var btn = $(this); //get current clicked button\n            var formData = new FormData($('form')[0])\n            formData.append('api_type','addPets');\n            formData.append('pet-category', $('#pet-category').val());\n            formData.append('pet-age-months', $('#pet-age-months').val());\n            formData.append('pet-price', $('#pet-price').val());\n\n            $.ajax({\n                type: \"POST\",\n                url:  \"controllers/rest.php\",\n                data: formData,\n                cache: false,\n                processData:false,\n                contentType: false,\n                success: function (data, textStatus, jqXHR) {\n                    data = jQuery.parseJSON(data);\n                    if (data.status == 'error') {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                        window.setTimeout(function(){\n                            window.location.href = 'logout.php';\n                        }, 1500);\n                    } else if (data.status == 'warning') {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                    } else {\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                        window.setTimeout(function(){\n                         window.location.href = 'pets.php';\n                         }, 1500);\n                    }\n                }\n            })\n                .always(function () {\n                    btn.button('reset');\n                });\n        });\n\n        function addPets(btn){\n            btn.button('loading');\n            var formData = new FormData(this);\n\n        }\n\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/config/config.php",
    "content": "<?php\n\ndefine(\"SECURITY_SERVER\", getenv('SECURITY_SERVICE_HOST'));\ndefine(\"SECURITY_SERVER_PORT\", getenv('SECURITY_SERVICE_PORT'));\n\ndefine(\"PET_SERVICE\", getenv('PET_SERVICE_HOST'));\ndefine(\"PET_SERVICE_PORT\", getenv('PET_SERVICE_PORT'));\n\ndefine(\"FILE_SERVER\", getenv('FILE_SERVICE_HOST'));\ndefine(\"FILE_SERVER_PORT\", getenv('FILE_SERVICE_PORT'));\ndefine(\"FILE_SERVER_NODE_PORT\", getenv('FILE_SERVICE_NODE_PORT'));\n\n?>\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/controllers/API/curl_api.php",
    "content": "<?php\n/*\n * method for get API authentication\n */\nfunction callAuthApiLogin($url, $data){\n\n    $curl = curl_init($url);\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_POST, true);\n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            'Content-Length: ' . strlen($data))\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n\n    if($info['http_code'] === 200){\n        $response = explode(\"\\n\",$header);\n        $searchword = 'X-JWT-Assertion';\n        $matches = array_filter($response, function($var) use ($searchword) {\n            return preg_match(\"/\\b$searchword\\b/i\", $var); });\n\n        session_start();\n        $_SESSION['username'] = 'user';\n        $_SESSION['authtoken'] = trim(explode(\"X-JWT-Assertion:\", array_values($matches)[0])[1]);\n        echo json_encode(array('status' => 1));\n    }else if($info['http_code'] === 401){\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n\n}\n\n/*\n * method for Add Pet type categories\n */\nfunction callAuthApiAddPetTypes($url, $token, $data){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_POST, true);\n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200){\n        echo json_encode(array('status' => 'success', 'message' => 'Category added successfully'));\n    }else if($info['http_code'] === 401) {\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\n/*\n * method for delete Pet type categories\n */\nfunction callAuthApiDeletePetType($url, $token){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, \"DELETE\");\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200){\n        echo json_encode(array('status' => 'success', 'message' => 'Category deleted successfully'));\n    }else if($info['http_code'] === 401) {\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\nfunction callAuthApiAddPet($url, $token, $data){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_POST, true);\n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n\n    if($info['http_code'] === 200){\n        echo json_encode(array('status' => 'success', 'message' => 'Pet added successfully'));\n    }else if($info['http_code'] === 401) {\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\n\n/*\n * method for delete Pet\n */\nfunction callAuthApiDeletePet($url, $token){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, \"DELETE\");\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200){\n        echo json_encode(array('status' => 'success', 'message' => 'Pet deleted successfully'));\n    }else if($info['http_code'] === 401) {\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\nfunction callAuthApigetPets($url, $token){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200) {\n        return json_decode($body, true);\n    }else if($info['http_code'] === 401){\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\nfunction callAuthApigetPetTypes($url, $token){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200) {\n       return json_decode($body, true);\n    }else if($info['http_code'] === 401){\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\nfunction imageUpload($url, $files, $token){\n    $filePath = $files['file']['tmp_name'];\n    $fileName = $files['file']['name'];\n    exec(\"curl -X POST -H \\\"Transfer-Encoding: chunked\\\" -H \\\"Content-Type: application/octet-stream\\\" -H \\\"X-JWT-Assertion: {$token}\\\" --data-binary @{$filePath} {$url}/\".urlencode($fileName));\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/controllers/authentication/auth.php",
    "content": "<?php\ninclude('../API/curl_api.php');\ninclude('../../config/config.php');\n\n$username = htmlspecialchars($_POST[\"username\"]);\n$password = htmlspecialchars($_POST[\"password\"]);\n\n$auth_json = json_encode(array('name' => $username, 'password' => $password));\ncallAuthApiLogin('http://'.SECURITY_SERVER.':'.SECURITY_SERVER_PORT.'/user/login', $auth_json);\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/controllers/rest.php",
    "content": "<?php\n//ajax call base rest call handler\nsession_start();\ninclude('API/curl_api.php');\ninclude('../config/config.php');\n\n$api_type = htmlspecialchars($_POST[\"api_type\"]);\n\nif(isset($_SESSION['authtoken'])){\n    $token = preg_replace('/\\s+/', '', $_SESSION['authtoken']);\n}else{\n    echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    die;\n}\n\n\nswitch ($api_type) {\n    case \"addPetTypes\":\n        $category_name = htmlspecialchars($_POST[\"category_name\"]);\n        $category_name_json = json_encode(array('name' => $category_name));\n        $url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/category/';\n        callAuthApiAddPetTypes($url, $token, $category_name_json);\n        break;\n\n    case \"addPets\":\n        $url_image_upload= 'http://'.FILE_SERVER.':'.FILE_SERVER_PORT;\n        imageUpload($url_image_upload, $_FILES, $_SESSION['authtoken']);\n        $pet_category = htmlspecialchars($_POST[\"pet-category\"]);\n        $pet_age_months = htmlspecialchars($_POST[\"pet-age-months\"]);\n        $pet_price = htmlspecialchars($_POST[\"pet-price\"]);\n        $url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/pet/';\n        $data_json =json_encode(\n            array(\n                'category' => array('name'=>$pet_category),\n                'ageMonths' => $pet_age_months,\n                'price' => $pet_price,\n                'image'=> $_FILES['file']['name']\n            )\n        );\n        callAuthApiAddPet($url, $token, $data_json);\n        break;\n\n    case \"deletePetTypes\":\n        $category_name = htmlspecialchars($_POST[\"category_name\"]);\n        $url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/category/'.urlencode($category_name);\n        callAuthapiDeletePetType($url, $token);\n        break;\n\n    case \"deletePet\":\n        $pet_id = htmlspecialchars($_POST[\"pet_id\"]);\n        $url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/pet/'.$pet_id;\n        callAuthapiDeletePet($url, $token);\n        break;\n\n    default:\n        echo \"Invalid API call\";\n}"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/css/custom.css",
    "content": "* {\n    outline: none !important;\n}\n@font-face {\n    font-family: 'Roboto Light';\n    font-style: 'normal';\n    font-weight: 300;\n    src: url('../fonts/Roboto/Roboto-Light-webfont.eot');\n    src: local('Roboto Light'), local('Roboto-Light-webfont'),\n    url('../fonts/Roboto/Roboto-Light-webfont.eot') format('embedded-opentype'),\n    url('../fonts/Roboto/Roboto-Light-webfont.woff') format('woff'),\n    url('../fonts/Roboto/Roboto-Light-webfont.ttf') format('truetype'),\n    url('../fonts/Roboto/Roboto-Light-webfont.svg#Roboto Light') format('svg');\n}\nbody {\n    background: #f9f9f9;\n    font-family: 'Roboto Light', Arial, Helvetica, sans-serif;\n    font-weight: 300;\n}\nheader {\n    background: #222222;\n    min-height: 50px;\n    position: relative;\n}\nheader .brand {\n    padding: 10px 0;\n}\nheader .auth {\n    margin: 0 -15px;\n}\nheader .brand a {\n    min-height: 24px;\n}\nheader .brand img.logo {\n    height: 24px;\n}\nheader .brand h1 {\n    display: inline-block;\n    line-height: 1;\n    font-weight: 500;\n    font-size: 17px;\n    margin: 0 0 0 5px;\n    color: #ffffff;\n    padding: 6px 0 0 0;\n    font-style: normal;\n    text-transform: uppercase;\n}\nheader .dropdown {\n    display: inline-block;\n    color: #ffffff;\n    padding: 6px 0;\n}\n.dropdown-menu {\n    border: none;\n    background: #e4e4e4;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.navbar-wrapper {\n    min-height: 50px;\n}\n.navbar {\n     background: #2c313b;\n     border: none;\n     margin-bottom: 0;\n     -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n     border-radius: 0;\n    height: 50px;\n }\n.navbar .container-fluid {\n    padding: 0;\n}\n.navbar-toggle {\n    border: none;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n}\n.navbar-menu-toggle {\n    float: left;\n    height: 50px;\n    padding: 0 8px;\n    line-height: 50px;\n    font-size: 18px;\n    background: #007d85;\n    color: #ffffff;\n}\n.navbar-menu-toggle {\n    float: left;\n    height: 50px;\n    padding: 0 8px;\n    line-height: 50px;\n    font-size: 18px;\n    background: #007d85;\n    color: #ffffff;\n}\n.navbar-menu-toggle:hover, .navbar-menu-toggle:focus, .navbar-menu-toggle:active {\n    color: #ffffff;\n    background: #004d52;\n}\n.navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand {\n    color: #ffffff;\n    margin-left: 0;\n    padding: 0 15px;\n    line-height: 50px;\n    text-transform: uppercase;\n    background: #21252c;\n}\nnav .navbar-nav li:hover{\n    background-color: #575B64;\n}\n.breadcrumb>li {\n    display: inline-block;\n}\n.breadcrumb > li > a > .icon {\n    padding-bottom: 3px;\n}\n.navbar > .container .navbar-brand a, .navbar > .container-fluid .navbar-brand a {\n    color: #ffffff;\n    font-size: 16px;\n}\n.navbar .container-fluid > .navbar-collapse .icon, .navbar .container-fluid > .navbar-header .icon, .navbar .container > .navbar-collapse .icon, .navbar .container > .navbar-header .icon {\n    margin-bottom: 4px;\n}\n.navbar > .container .navbar-brand a, .navbar > .container-fluid .navbar-brand a {\n    color: #ffffff;\n    font-size: 16px;\n}\n.breadcrumb>li {\n    display: inline-block;\n}\n.breadcrumb > li + li:before {\n    padding: 0 1px;\n}\n.navbar-default .navbar-nav > li > a {\n    color: #ffffff;\n    text-transform: uppercase;\n    padding: 0 15px;\n    line-height: 50px;\n}\n.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus, .navbar-default .navbar-nav > li > a:active {\n    color: #ffffff;\n}\n.page-content-wrapper, .page-content-wrapper[data-container-behaviour=static] {\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n    transition: all 0.5s ease;\n    position: relative;\n    left: 0;\n    margin-left: 0;\n}\n\n.dropdown-menu.tiles {\n    padding: 4px;\n    max-width: 385px;\n}\n.dropdown-menu.dark {\n    background: #222222;\n    color: #ffffff;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.dropdown-menu.tiles > li {\n    padding: 0;\n    list-style: none;\n    display: inline-block;\n    float: left;\n}\n.dropdown-menu.tiles li a {\n    display: block;\n    margin: 4px;\n    padding: 5px;\n    list-style: none;\n    width: 85px;\n    height: 85px;\n    text-align: center;\n    vertical-align: text-bottom;\n    color: #ffffff;\n    text-decoration: none;\n    background: #444444;\n}\n.dropdown-menu.dark.arrow:before {\n    border-bottom-color: #222222;\n}\n.dropdown-menu.arrow:before, .dropdown-menu.arrow.arrow-top-left:before {\n    position: absolute;\n    top: -6px;\n    left: 15px;\n    right: auto;\n    display: inline-block;\n    border-right: 6px solid transparent;\n    border-bottom: 6px solid #e4e4e4;\n    border-left: 6px solid transparent;\n    content: '';\n}\n.dropdown-menu.tiles li a .icon {\n    display: block;\n    font-size: 35px;\n    margin: 3px 0 7px;\n    height: 35px;\n}\n.dropdown-menu.tiles li a .name {\n    display: block;\n    line-height: 14px;\n    font-size: 12px;\n    height: 28px;\n    overflow: hidden;\n}\n\nfooter {\n    position: fixed;\n    bottom: 0;\n    width: 100%;\n    min-height: 40px;\n    overflow: hidden;\n    color: #cbcbcb;\n    background: #222222;\n    z-index: 1000;\n}\nfooter > .container p, footer > .container-fluid p {\n    line-height: 40px;\n    margin-bottom: 0;\n}\nfooter a, footer a:hover {\n    color: #cbcbcb;\n}\n/*login page */\n.col-centered {\n    float: none;\n    margin: 0 auto;\n}\n.wr-login {\n    padding-top: 50px;\n}\n.uppercase {\n    text-transform: uppercase;\n}\n.blue-bg {\n    background-color: #3a9ecf !important;\n}\n.padding-double {\n    padding: 20px;\n}\n.boarder-bottom-blue {\n    border-bottom: 2px solid #006596;\n}\n.boarder-all {\n    border: 1px solid #d8d8d8;\n    background: #FFF;\n    margin-top: -10px;\n}\n.wr-login input[type=text], .wr-login input[type=password] {\n    border: 1px #d2d2d2 solid;\n    width: 100%;\n    height: 100%;\n    padding: 6px 10px;\n    z-index: 1;\n    -webkit-appearance: none;\n    line-height: 30px;\n    border-radius: 0px;\n}\nbutton.grey-bg:hover {\n    background-color: #3A9ECF;\n}\n.wr-btn {\n    font-weight: normal;\n    font-size: 13px;\n    color: #fff;\n    background: #5d81d2;\n    padding: 10px 10px;\n    display: inline-block;\n    border: none;\n}\nbutton.grey-bg {\n    background-color: #222222;\n}\n.white {\n    color: #FFF;\n}\n\n/* main page content */\n.thumbnail-overide{\n    border-radius: 0px;\n}\n.thumbnail-overide>.caption h3{\n    font-size: 1.2em;\n    text-align: center;\n}\na.thumbnail-overide:hover{\n   text-decoration: none;\n}\n.thumbnail-overide img{\n    margin-top: 1em;\n}\n\n.page-header {\n    margin: 0 0 20px;\n}\n\n.page-header > h1 {\n    margin-top: 0;\n    font-weight: 300;\n    font-size: 1.5em;\n}\n.form-control, .btn {\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.btn-primary {\n    color: #ffffff;\n    background-color: #2c313b;\n    border-color: #2c313b;\n}\n.btn-primary:hover {\n    background-color: #424958;\n}\na.btn:hover, .btn:hover, a.btn:focus, .btn:focus {\n    text-decoration: none;\n    background: #eee;\n}\n.invert-png{\n    -webkit-filter: invert(1);\n    filter: invert(1);\n    margin-bottom: 10px;\n    width: 50px;\n}\n.tb-preview {\n    width: 100px;\n    max-height: 100px;\n}"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/includes/header.php",
    "content": "<!-- header -->\n<header class=\"header header-default\">\n    <div class=\"container-fluid\">\n        <div class=\"pull-left brand float-remove-xs text-center-xs\">\n            <a href=\"#\">\n                <img src=\"images/logo-inverse.svg\" alt=\"wso2\" title=\"wso2\" class=\"logo\">\n                <h1>WSO2 Pet Store - backend</h1>\n            </a>\n        </div>\n        <div class=\"pull-right auth float-remove-xs text-center-xs\">\n            <a href=\"#\" class=\"dropdown\" data-toggle=\"dropdown\">\n                <span class=\"hidden-xs add-padding-left-3x\">administrator <span class=\"caret\"></span></span>\n               <span class=\"icon fw-stack fw-lg\">\n                   <i class=\"fw fw-user fw-stack-1x\"></i>\n               </span>\n            </a>\n            <ul class=\"dropdown-menu float-remove-xs position-static-xs text-center-xs remove-margin-xs slideInDown\" role=\"menu\">\n                <li class=\"dropdown-header visible-xs\">administrator <span class=\"caret\"></span></li>\n                <li class=\"divider visible-xs\"></li>\n                <li><a href=\"logout.php\">Sign out</a></li>\n            </ul>\n\n        </div>\n    </div>\n</header>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/includes/navbar.php",
    "content": "<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"pet-types.php\">\n                            <img src=\"images/list-pet-type.png\" class=\"invert-png\">\n                            <span class=\"name\">Pet Types</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"pets.php\">\n                            <img src=\"images/list-pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <?php\n                if(isset($action_buttons)){\n                ?>\n                <ul class=\"nav navbar-nav\">\n                    <?php\n                    if($action_buttons) {\n                        ?>\n                        <li>\n                            <a href=\"layout.html\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-laptop fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                                Main Wrapper\n                            </a>\n                        </li>\n                        <?php\n                    }\n                    ?>\n                </ul>\n                <?php\n                }\n                ?>\n\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/index.php",
    "content": "<?php\nsession_start();\nif(!isset($_SESSION['username'])){\n   header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"\");\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Administrator</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"pet-types.php\">\n                            <img src=\"images/list-pet-type.png\" class=\"invert-png\">\n                            <span class=\"name\">Pet Types</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"pets.php\">\n                            <img src=\"images/list-pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                    <ul class=\"nav navbar-nav\">\n                        <li>\n                                <a href=\"add-pet-types.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-add fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                                    Add pet types\n                                </a>\n                        </li>\n                        <li>\n                            <a href=\"add-pets.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-add fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                                Add pets\n                            </a>\n                        </li>\n                    </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"row\">\n            <div class=\"col-xs-6 col-md-2\">\n                <a href=\"add-pet-types.php\" class=\"thumbnail thumbnail-overide\">\n                    <img src=\"images/paw-pets.png\" alt=\"Add Pet Types\">\n                    <div class=\"caption\">\n                        <h3>Add Pet Types</h3>\n                    </div>\n                </a>\n            </div>\n            <div class=\"col-xs-6 col-md-2\">\n                <a href=\"pet-types.php\" class=\"thumbnail thumbnail-overide\">\n                    <img src=\"images/list-pet-type.png\" alt=\"List Pet Types\">\n                    <div class=\"caption\">\n                        <h3>List Pet Types</h3>\n                    </div>\n                </a>\n            </div>\n            <div class=\"col-xs-6 col-md-2\">\n                <a href=\"add-pets.php\" class=\"thumbnail thumbnail-overide\">\n                    <img src=\"images/pets.png\" alt=\"Add Pets\">\n                    <div class=\"caption\">\n                        <h3>Add Pets</h3>\n                    </div>\n                </a>\n            </div>\n            <div class=\"col-xs-6 col-md-2 \">\n                <a href=\"pets.php\" class=\"thumbnail thumbnail-overide\">\n                    <img src=\"images/list-pets.png\" alt=\"List Pets\">\n                    <div class=\"caption\">\n                        <h3>List Pets</h3>\n                    </div>\n                </a>\n            </div>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/js/custom.js",
    "content": ""
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/js/login.js",
    "content": "$(document).ready(function () {\n    $('#username').focus(); //set user cursor into username\n    var username = $('#username'), // Get the username field\n        password = $('#password'), // Get the password field\n        form_error = $('.form-error');\n\n    //handle form valiadation\n    var isValidForm = function () {\n        if (username.val() == \"\" || password.val() == \"\") {\n            var error = \"Enter your username\";\n            if (username.val() == \"\") {\n                username.parent().addClass('has-error has-feedback');\n                username.parent().append('<span class=\"glyphicon glyphicon-remove form-control-feedback\"></span>');\n            } else {\n                username.parent().removeClass('has-error has-feedback');\n                username.parent().find('span').empty().remove();\n                error = \"\";\n            }\n\n            if (password.val() == \"\") {\n                password.parent().addClass('has-error has-feedback');\n                password.parent().append('<span class=\"glyphicon glyphicon-remove form-control-feedback\"></span>');\n\n                if (error == \"\") {\n                    error = \"Enter your password\";\n                } else {\n                    error = \"Enter your username and password\";\n                }\n            } else {\n                password.parent().removeClass('has-error has-feedback');\n                password.parent().find('span').empty().remove();\n            }\n            form_error.html(error).show();\n            return false;\n        } else {\n            username.parent().removeClass('has-error has-feedback');\n            password.parent().removeClass('has-error has-feedback');\n            password.parent().find('span').empty().remove();\n            username.parent().find('span').empty().remove();\n            form_error.hide();\n            return true;\n        }\n    };\n\n    //handle login ajax request\n    function loginCheck(btn) {\n        btn.button('loading');\n        if (!isValidForm()) {\n            btn.button('reset');\n        } else {\n            $.ajax({\n                type: \"POST\",\n                url:  \"controllers/authentication/auth.php\",\n                dataType: 'json',\n                data: {username: username.val(), password: password.val()},\n                success: function (data) {\n                    if (data.status === 1) {\n                            window.location = 'index.php';\n                    }else if(data.status == \"error\"){\n                        var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                    } else {\n                        form_error.show().html(data.message);\n                    }\n                }\n            })\n                .always(function () {\n                    btn.button('reset');\n                });\n        }\n    }\n\n    username.keyup(function (e) {\n        if(e.keyCode == 13) {\n            return;\n        }\n        isValidForm();\n    });\n    password.keyup(function (e) {\n        if(e.keyCode == 13) {\n            return;\n        }\n        isValidForm();\n    });\n\n    // handle the submit button click event\n    $('#submit-btn').click(function () {\n        var btn = $(this); //get current clicked button\n        loginCheck(btn);\n    });// end of submit button\n\n    //handle key \"Enter\" press\n    $(document).keypress(function (e) {\n        if (e.keyCode == 13) {\n            var btn = $('#submit-btn');\n            loginCheck(btn);\n        }\n    });\n});"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/font-awesome_4.3.0/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.3.0');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  transform: translate(0, 0);\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-genderless:before,\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/font-wso2_1.2/css/font-wso2.css",
    "content": "@font-face {\n    font-family: 'font-wso2';\n    src:url('../fonts/font-wso2.eot?k4i0fx');\n    src:url('../fonts/font-wso2.eot?#iefixk4i0fx') format('embedded-opentype'),\n    url('../fonts/font-wso2.ttf?k4i0fx') format('truetype'),\n    url('../fonts/font-wso2.woff?k4i0fx') format('woff'),\n    url('../fonts/font-wso2.svg?k4i0fx#font-wso2') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n\n.fw, [class^=\"fw-\"], [class*=\" fw-\"] {\n    display: inline-block;\n    font: normal normal normal 14px/1 font-wso2;\n    font-size: inherit;\n    speak: none;\n    font-style: normal;\n    font-weight: normal;\n    font-variant: normal;\n    text-transform: none;\n    vertical-align: middle;\n\n    /* Better Font Rendering =========== */\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    text-rendering: auto;\n    transform: translate(0, 0);\n}\n\n/* ========================================================================\n * font options\n * ======================================================================== */\n\n.fw-lg {\n    font-size: 1.33333333em;\n    line-height: 0.75em;\n    vertical-align: -15%;\n}\n.fw-2x {\n    font-size: 2em;\n}\n.fw-3x {\n    font-size: 3em;\n}\n.fw-4x {\n    font-size: 4em;\n}\n.fw-5x {\n    font-size: 5em;\n}\n.fw-fw {\n    width: 1.28571429em;\n    text-align: center;\n}\n.fw-ul {\n    padding-left: 0;\n    margin-left: 2.14285714em;\n    list-style-type: none;\n}\n.fw-ul > li {\n    position: relative;\n}\n.fw-li {\n    position: absolute;\n    left: -2.14285714em;\n    width: 2.14285714em;\n    top: 0.14285714em;\n    text-align: center;\n}\n.fw-li.fw-lg {\n    left: -1.85714286em;\n}\n.fw-border {\n    padding: .2em .25em .15em;\n    border: solid 0.08em #eeeeee;\n    border-radius: .1em;\n}\n.fw-background {\n    background: #888;\n    border-radius: .3em;\n    padding: .4em .50em .45em;\n}\n.fw-pull-left {\n    float: left;\n}\n.fw-pull-right {\n    float: right;\n}\n.fw.fw-pull-left {\n    margin-right: .3em;\n}\n.fw.fw-pull-right {\n    margin-left: .3em;\n}\n.fw-spin {\n    -webkit-animation: fw-spin 2s infinite linear;\n    animation: fw-spin 2s infinite linear;\n}\n@-webkit-keyframes fw-spin {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}\n@keyframes fw-spin {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}\n.fw-pulse {\n    -webkit-animation: fw-pulse 2s ease-out infinite;\n    animation: fw-pulse 2s ease-out infinite;\n}\n@-webkit-keyframes fw-pulse {\n    0%, 30%  {\n        opacity: 0.3;\n    }\n    40% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0.3;\n    }\n}\n@keyframes fw-pulse {\n    0%, 30%  {\n        opacity: 0.3;\n    }\n    40% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0.3;\n    }\n}\n.fw-rotate-90 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n    -webkit-transform: rotate(90deg);\n    -ms-transform: rotate(90deg);\n    transform: rotate(90deg);\n}\n.fw-rotate-180 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n    -webkit-transform: rotate(180deg);\n    -ms-transform: rotate(180deg);\n    transform: rotate(180deg);\n}\n.fw-rotate-270 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n    -webkit-transform: rotate(270deg);\n    -ms-transform: rotate(270deg);\n    transform: rotate(270deg);\n}\n.fw-flip-horizontal {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n    -webkit-transform: scale(-1, 1);\n    -ms-transform: scale(-1, 1);\n    transform: scale(-1, 1);\n}\n.fw-flip-vertical {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n    -webkit-transform: scale(1, -1);\n    -ms-transform: scale(1, -1);\n    transform: scale(1, -1);\n}\n:root .fw-rotate-90,\n:root .fw-rotate-180,\n:root .fw-rotate-270,\n:root .fw-flip-horizontal,\n:root .fw-flip-vertical {\n    filter: none;\n}\n.fw-stack {\n    position: relative;\n    display: inline-block;\n    width: 2em;\n    height: 2em;\n    line-height: 2em;\n    vertical-align: middle;\n}\n.fw-stack-1x,\n.fw-stack-2x {\n    position: absolute;\n    left: 0;\n    width: 100%;\n    text-align: center;\n}\n.fw-stack-1x {\n    line-height: inherit;\n}\n.fw-stack-2x {\n    font-size: 2em;\n}\n.fw-inverse {\n    color: #ffffff;\n}\n.fw-number {\n    line-height: 1.8em;\n}\n\n/* ========================================================================\n * font icons\n * ======================================================================== */\n\n.fw-mouse-pointer:before {\n    content: \"\\e6b1\";\n}\n.fw-pointer:before {\n    content: \"\\e6b2\";\n}\n.fw-hand:before {\n    content: \"\\e6b3\";\n}\n.fw-question-mark:before {\n    content: \"\\e6b4\";\n}\n.fw-airplay:before {\n    content: \"\\e600\";\n}\n.fw-apn:before {\n    content: \"\\e602\";\n}\n.fw-vpn:before {\n    content: \"\\e603\";\n}\n.fw-apple:before {\n    content: \"\\e604\";\n}\n.fw-windows:before {\n    content: \"\\e605\";\n}\n.fw-android:before {\n    content: \"\\e606\";\n}\n.fw-wifi:before {\n    content: \"\\e607\";\n}\n.fw-battery:before {\n    content: \"\\e60a\";\n}\n.fw-camera:before {\n    content: \"\\e613\";\n}\n.fw-notification:before {\n    content: \"\\e60b\";\n}\n.fw-settings:before {\n    content: \"\\e66f\";\n}\n.fw-send:before {\n    content: \"\\e66a\";\n}\n.fw-bookmark:before {\n    content: \"\\e60d\";\n}\n.fw-bug:before {\n    content: \"\\e611\";\n}\n.fw-clock:before {\n    content: \"\\e61d\";\n}\n.fw-calendar:before {\n    content: \"\\e612\";\n}\n.fw-add:before {\n    content: \"\\e615\";\n}\n.fw-minus:before {\n    content: \"\\e616\";\n}\n.fw-check:before {\n    content: \"\\e617\";\n}\n.fw-cancel:before {\n    content: \"\\e618\";\n}\n.fw-list:before {\n    content: \"\\e64c\";\n}\n.fw-checklist:before {\n    content: \"\\e619\";\n}\n.fw-grid:before {\n    content: \"\\e638\";\n}\n.fw-dots:before {\n    content: \"\\e629\";\n}\n.fw-menu:before {\n    content: \"\\e651\";\n}\n.fw-tiles:before {\n    content: \"\\e681\";\n}\n.fw-clear:before {\n    content: \"\\e61b\";\n}\n.fw-clear-passcode:before {\n    content: \"\\e61c\";\n}\n.fw-enterprise-wipe:before {\n    content: \"\\e62f\";\n}\n.fw-cloud:before {\n    content: \"\\e61e\";\n}\n.fw-contact:before {\n    content: \"\\e620\";\n}\n.fw-copy:before {\n    content: \"\\e621\";\n}\n.fw-paste:before {\n    content: \"\\e658\";\n}\n.fw-undo:before {\n    content: \"\\e683\";\n}\n.fw-redo:before {\n    content: \"\\e65d\";\n}\n.fw-dashboard:before {\n    content: \"\\e622\";\n}\n.fw-view:before {\n    content: \"\\e691\";\n}\n.fw-focus:before {\n    content: \"\\e6b5\";\n}\n.fw-delete:before {\n    content: \"\\e624\";\n}\n.fw-save:before {\n    content: \"\\e665\";\n}\n.fw-register:before {\n    content: \"\\e65e\";\n}\n.fw-change-passcode:before {\n    content: \"\\e614\";\n}\n.fw-edit:before {\n    content: \"\\e62c\";\n}\n.fw-sign-up:before {\n    content: \"\\e671\";\n}\n.fw-deploy:before {\n    content: \"\\e625\";\n}\n.fw-dial-up:before {\n    content: \"\\e627\";\n}\n.fw-dss:before {\n    content: \"\\e62a\";\n}\n.fw-ebook:before {\n    content: \"\\e62b\";\n}\n.fw-import:before {\n    content: \"\\e63c\";\n}\n.fw-export:before {\n    content: \"\\e631\";\n}\n.fw-factory-reset:before {\n    content: \"\\e632\";\n}\n.fw-file-browse:before {\n    content: \"\\e633\";\n}\n.fw-grouping:before {\n    content: \"\\e6af\";\n}\n.fw-folder:before {\n    content: \"\\e6b6\";\n}\n.fw-filter:before {\n    content: \"\\e634\";\n}\n.fw-sort:before {\n    content: \"\\e673\";\n}\n.fw-sort-up:before {\n    content: \"\\e64b\";\n}\n.fw-sort-down:before {\n    content: \"\\e663\";\n}\n.fw-faq:before {\n    content: \"\\e6b7\";\n}\n.fw-message:before {\n    content: \"\\e635\";\n}\n.fw-forum:before {\n    content: \"\\e636\";\n}\n.fw-chat:before {\n    content: \"\\e6b8\";\n}\n.fw-mail:before {\n    content: \"\\e64f\";\n}\n.fw-invitation:before {\n    content: \"\\e63f\";\n}\n.fw-usb-drive:before {\n    content: \"\\e68e\";\n}\n.fw-hdd:before {\n    content: \"\\e639\";\n}\n.fw-home:before {\n    content: \"\\e63a\";\n}\n.fw-hour-glass:before {\n    content: \"\\e63b\";\n}\n.fw-incoming-call:before {\n    content: \"\\e63d\";\n}\n.fw-key:before {\n    content: \"\\e647\";\n}\n.fw-lifecycle:before {\n    content: \"\\e64a\";\n}\n.fw-list-sort:before {\n    content: \"\\e64d\";\n}\n.fw-lock:before {\n    content: \"\\e64e\";\n}\n.fw-map-location:before {\n    content: \"\\e650\";\n}\n.fw-laptop:before {\n    content: \"\\e648\";\n}\n.fw-mobile:before {\n    content: \"\\e652\";\n}\n.fw-ringing:before {\n    content: \"\\e694\";\n}\n.fw-computer:before {\n    content: \"\\e653\";\n}\n.fw-devices:before {\n    content: \"\\e626\";\n}\n.fw-mute:before {\n    content: \"\\e655\";\n}\n.fw-unmute:before {\n    content: \"\\e6ae\";\n}\n.fw-ok:before {\n    content: \"\\e657\";\n}\n.fw-error:before {\n    content: \"\\e630\";\n}\n.fw-circle:before {\n    content: \"\\e61a\";\n}\n.fw-ring:before {\n    content: \"\\e61f\";\n}\n.fw-pdf:before {\n    content: \"\\e659\";\n}\n.fw-ms-document:before {\n    content: \"\\e654\";\n}\n.fw-pie-chart:before {\n    content: \"\\e65a\";\n}\n.fw-bar-chart:before {\n    content: \"\\e6b0\";\n}\n.fw-publish:before {\n    content: \"\\e65c\";\n}\n.fw-resource:before {\n    content: \"\\e660\";\n}\n.fw-rules:before {\n    content: \"\\e664\";\n}\n.fw-scep:before {\n    content: \"\\e666\";\n}\n.fw-security:before {\n    content: \"\\e669\";\n}\n.fw-search:before {\n    content: \"\\e668\";\n}\n.fw-sequence:before {\n    content: \"\\e66b\";\n}\n.fw-servers:before {\n    content: \"\\e66c\";\n}\n.fw-ldap:before {\n    content: \"\\e649\";\n}\n.fw-database:before {\n    content: \"\\e623\";\n}\n.fw-hardware:before {\n    content: \"\\e6a9\";\n}\n.fw-signal:before {\n    content: \"\\e6b9\";\n}\n.fw-raspberry:before {\n    content: \"\\e6aa\";\n}\n.fw-arduino:before {\n    content: \"\\e6ab\";\n}\n.fw-share:before {\n    content: \"\\e670\";\n}\n.fw-star:before {\n    content: \"\\e674\";\n}\n.fw-coins:before {\n    content: \"\\e6ba\";\n}\n.fw-statistics:before {\n    content: \"\\e675\";\n}\n.fw-store:before {\n    content: \"\\e676\";\n}\n.fw-subscribe:before {\n    content: \"\\e677\";\n}\n.fw-fan:before {\n    content: \"\\e6bb\";\n}\n.fw-light:before {\n    content: \"\\e6bc\";\n}\n.fw-subscribed-calendar:before {\n    content: \"\\e678\";\n}\n.fw-tag:before {\n    content: \"\\e67a\";\n}\n.fw-tasks:before {\n    content: \"\\e67b\";\n}\n.fw-blank-document:before {\n    content: \"\\e60c\";\n}\n.fw-document:before {\n    content: \"\\e628\";\n}\n.fw-text:before {\n    content: \"\\e67c\";\n}\n.fw-policy:before {\n    content: \"\\e67d\";\n}\n.fw-security-policy:before {\n    content: \"\\e67e\";\n}\n.fw-throttling-policy:before {\n    content: \"\\e67f\";\n}\n.fw-ticked-box:before {\n    content: \"\\e680\";\n}\n.fw-uncheck:before {\n    content: \"\\e682\";\n}\n.fw-upload:before {\n    content: \"\\e68c\";\n}\n.fw-download:before {\n    content: \"\\e65f\";\n}\n.fw-up:before {\n    content: \"\\e684\";\n}\n.fw-down:before {\n    content: \"\\e685\";\n}\n.fw-left:before {\n    content: \"\\e686\";\n}\n.fw-right:before {\n    content: \"\\e687\";\n}\n.fw-up-arrow:before {\n    content: \"\\e688\";\n}\n.fw-down-arrow:before {\n    content: \"\\e689\";\n}\n.fw-left-arrow:before {\n    content: \"\\e68a\";\n}\n.fw-right-arrow:before {\n    content: \"\\e68b\";\n}\n.fw-endpoint:before {\n    content: \"\\e62d\";\n}\n.fw-uri:before {\n    content: \"\\e68d\";\n}\n.fw-broken-link:before {\n    content: \"\\e610\";\n}\n.fw-user:before {\n    content: \"\\e68f\";\n}\n.fw-add-user:before {\n    content: \"\\e690\";\n}\n.fw-refresh:before {\n    content: \"\\e692\";\n}\n.fw-warning:before {\n    content: \"\\e693\";\n}\n.fw-info:before {\n    content: \"\\e63e\";\n}\n.fw-block:before {\n    content: \"\\e695\";\n}\n.fw-bpmn:before {\n    content: \"\\e60f\";\n}\n.fw-schema:before {\n    content: \"\\e667\";\n}\n.fw-organization:before {\n    content: \"\\e6ac\";\n}\n.fw-public:before {\n    content: \"\\e6ad\";\n}\n.fw-bpel:before {\n    content: \"\\e60e\";\n}\n.fw-application:before {\n    content: \"\\e608\";\n}\n.fw-applications:before {\n    content: \"\\e609\";\n}\n.fw-public-app:before {\n    content: \"\\e65b\";\n}\n.fw-enterprise-app:before {\n    content: \"\\e62e\";\n}\n.fw-web-app:before {\n    content: \"\\e696\";\n}\n.fw-globe:before {\n    content: \"\\e697\";\n}\n.fw-webclip:before {\n    content: \"\\e698\";\n}\n.fw-proxy:before {\n    content: \"\\e699\";\n}\n.fw-web-service:before {\n    content: \"\\e69a\";\n}\n.fw-website:before {\n    content: \"\\e69b\";\n}\n.fw-gadget:before {\n    content: \"\\e637\";\n}\n.fw-api:before {\n    content: \"\\e601\";\n}\n.fw-rest-api:before {\n    content: \"\\e661\";\n}\n.fw-rest-service:before {\n    content: \"\\e662\";\n}\n.fw-jaxrs:before {\n    content: \"\\e645\";\n}\n.fw-service:before {\n    content: \"\\e66d\";\n}\n.fw-service-provider:before {\n    content: \"\\e66e\";\n}\n.fw-java-spring:before {\n    content: \"\\e644\";\n}\n.fw-jquery:before {\n    content: \"\\e646\";\n}\n.fw-swagger:before {\n    content: \"\\e679\";\n}\n.fw-java:before {\n    content: \"\\e641\";\n}\n.fw-javaee:before {\n    content: \"\\e642\";\n}\n.fw-javascript:before {\n    content: \"\\e643\";\n}\n.fw-jaggery:before {\n    content: \"\\e640\";\n}\n.fw-nodejs:before {\n    content: \"\\e656\";\n}\n.fw-xml:before {\n    content: \"\\e69c\";\n}\n.fw-soap:before {\n    content: \"\\e672\";\n}\n.fw-html:before {\n    content: \"\\e69d\";\n}\n.fw-war:before {\n    content: \"\\e69e\";\n}\n.fw-xacml:before {\n    content: \"\\e69f\";\n}\n.fw-wsdl:before {\n    content: \"\\e6a0\";\n}\n.fw-wadl:before {\n    content: \"\\e6a1\";\n}\n.fw-xq:before {\n    content: \"\\e6a2\";\n}\n.fw-xsd:before {\n    content: \"\\e6a3\";\n}\n.fw-xslt:before {\n    content: \"\\e6a4\";\n}\n.fw-zoom-in:before {\n    content: \"\\e6a5\";\n}\n.fw-zoom-out:before {\n    content: \"\\e6a6\";\n}\n.fw-wso2-logo:before {\n    content: \"\\e6a7\";\n}\n.fw-wso2:before {\n    content: \"\\e6a8\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/jquery_1.11.3/jquery-1.11.3.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/jquery.noty.js",
    "content": "/*!\n @package noty - jQuery Notification Plugin\n @version version: 2.3.5\n @contributors https://github.com/needim/noty/graphs/contributors\n\n @documentation Examples and Documentation - http://needim.github.com/noty/\n\n @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php\n */\n\n    if(typeof Object.create !== 'function') {\n        Object.create = function(o) {\n            function F() {\n            }\n\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    var NotyObject = {\n\n        init: function(options) {\n\n            // Mix in the passed in options with the default options\n            this.options = $.extend({}, $.noty.defaults, options);\n\n            this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];\n\n            if($.noty.themes[this.options.theme])\n                this.options.theme = $.noty.themes[this.options.theme];\n            else\n                options.themeClassName = this.options.theme;\n\n            delete options.layout;\n            delete options.theme;\n\n            this.options = $.extend({}, this.options, this.options.layout.options);\n            this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));\n\n            this.options = $.extend({}, this.options, options);\n\n            // Build the noty dom initial structure\n            this._build();\n\n            // return this so we can chain/use the bridge with less code.\n            return this;\n        }, // end init\n\n        _build: function() {\n\n            // Generating noty bar\n            var $bar = $('<div class=\"noty_bar noty_type_' + this.options.type + '\"></div>').attr('id', this.options.id);\n            $bar.append(this.options.template).find('.noty_text').html(this.options.text);\n\n            this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;\n\n            if(this.options.themeClassName)\n                this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type);\n\n            // Set buttons if available\n            if(this.options.buttons) {\n\n                // If we have button disable closeWith & timeout options\n                this.options.closeWith = [];\n                this.options.timeout = false;\n\n                var $buttons = $('<div/>').addClass('noty_buttons');\n\n                (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);\n\n                var self = this;\n\n                $.each(this.options.buttons, function(i, button) {\n                    var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text).attr('id', button.id ? button.id : 'button-' + i)\n                        .appendTo(self.$bar.find('.noty_buttons'))\n                        .on('click', function(event) {\n                            if($.isFunction(button.onClick)) {\n                                button.onClick.call($button, self, event);\n                            }\n                        });\n                });\n            }\n\n            // For easy access\n            this.$message = this.$bar.find('.noty_message');\n            this.$closeButton = this.$bar.find('.noty_close');\n            this.$buttons = this.$bar.find('.noty_buttons');\n\n            $.noty.store[this.options.id] = this; // store noty for api\n\n        }, // end _build\n\n        show: function() {\n\n            var self = this;\n\n            (self.options.custom) ? self.options.custom.find(self.options.layout.container.selector).append(self.$bar) : $(self.options.layout.container.selector).append(self.$bar);\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.style.apply(self);\n\n            ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});\n\n            self.$bar.addClass(self.options.layout.addClass);\n\n            self.options.layout.container.style.apply($(self.options.layout.container.selector));\n\n            self.showing = true;\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.callback.onShow.apply(this);\n\n            if($.inArray('click', self.options.closeWith) > -1)\n                self.$bar.css('cursor', 'pointer').one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    if(self.options.callback.onCloseClick) {\n                        self.options.callback.onCloseClick.apply(self);\n                    }\n                    self.close();\n                });\n\n            if($.inArray('hover', self.options.closeWith) > -1)\n                self.$bar.one('mouseenter', function() {\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) > -1)\n                self.$closeButton.one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) == -1)\n                self.$closeButton.remove();\n\n            if(self.options.callback.onShow)\n                self.options.callback.onShow.apply(self);\n\n            if (typeof self.options.animation.open == 'string') {\n                self.$bar.css('height', self.$bar.innerHeight());\n                self.$bar.show().addClass(self.options.animation.open).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                    self.showing = false;\n                    self.shown = true;\n                });\n\n            } else {\n                self.$bar.animate(\n                    self.options.animation.open,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                        self.showing = false;\n                        self.shown = true;\n                    });\n            }\n\n            // If noty is have a timeout option\n            if(self.options.timeout)\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n\n            return this;\n\n        }, // end show\n\n        close: function() {\n\n            if(this.closed) return;\n            if(this.$bar && this.$bar.hasClass('i-am-closing-now')) return;\n\n            var self = this;\n\n            if(this.showing) {\n                self.$bar.queue(\n                    function() {\n                        self.close.apply(self);\n                    }\n                );\n                return;\n            }\n\n            if(!this.shown && !this.showing) { // If we are still waiting in the queue just delete from queue\n                var queue = [];\n                $.each($.noty.queue, function(i, n) {\n                    if(n.options.id != self.options.id) {\n                        queue.push(n);\n                    }\n                });\n                $.noty.queue = queue;\n                return;\n            }\n\n            self.$bar.addClass('i-am-closing-now');\n\n            if(self.options.callback.onClose) {\n                self.options.callback.onClose.apply(self);\n            }\n\n            if (typeof self.options.animation.close == 'string') {\n                self.$bar.addClass(self.options.animation.close).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    self.closeCleanUp();\n                });\n            } else {\n                self.$bar.clearQueue().stop().animate(\n                    self.options.animation.close,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    })\n                    .promise().done(function() {\n                        self.closeCleanUp();\n                    });\n            }\n\n        }, // end close\n\n        closeCleanUp: function() {\n\n            var self = this;\n\n            // Modal Cleaning\n            if(self.options.modal) {\n                $.notyRenderer.setModalCount(-1);\n                if($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function() {\n                    $(this).remove();\n                });\n            }\n\n            // Layout Cleaning\n            $.notyRenderer.setLayoutCountFor(self, -1);\n            if($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();\n\n            // Make sure self.$bar has not been removed before attempting to remove it\n            if(typeof self.$bar !== 'undefined' && self.$bar !== null) {\n\n                if (typeof self.options.animation.close == 'string') {\n                    self.$bar.css('transition', 'all 100ms ease').css('border', 0).css('margin', 0).height(0);\n                    self.$bar.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {\n                        self.$bar.remove();\n                        self.$bar = null;\n                        self.closed = true;\n\n                        if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                            self.options.theme.callback.onClose.apply(self);\n                        }\n                    });\n                } else {\n                    self.$bar.remove();\n                    self.$bar = null;\n                    self.closed = true;\n                }\n            }\n\n            delete $.noty.store[self.options.id]; // deleting noty from store\n\n            if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                self.options.theme.callback.onClose.apply(self);\n            }\n\n            if(!self.options.dismissQueue) {\n                // Queue render\n                $.noty.ontap = true;\n\n                $.notyRenderer.render();\n            }\n\n            if(self.options.maxVisible > 0 && self.options.dismissQueue) {\n                $.notyRenderer.render();\n            }\n\n        }, // end close clean up\n\n        setText: function(text) {\n            if(!this.closed) {\n                this.options.text = text;\n                this.$bar.find('.noty_text').html(text);\n            }\n            return this;\n        },\n\n        setType: function(type) {\n            if(!this.closed) {\n                this.options.type = type;\n                this.options.theme.style.apply(this);\n                this.options.theme.callback.onShow.apply(this);\n            }\n            return this;\n        },\n\n        setTimeout: function(time) {\n            if(!this.closed) {\n                var self = this;\n                this.options.timeout = time;\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n            }\n            return this;\n        },\n\n        stopPropagation: function(evt) {\n            evt = evt || window.event;\n            if(typeof evt.stopPropagation !== \"undefined\") {\n                evt.stopPropagation();\n            }\n            else {\n                evt.cancelBubble = true;\n            }\n        },\n\n        closed : false,\n        showing: false,\n        shown  : false\n\n    }; // end NotyObject\n\n    $.notyRenderer = {};\n\n    $.notyRenderer.init = function(options) {\n\n        // Renderer creates a new noty\n        var notification = Object.create(NotyObject).init(options);\n\n        if(notification.options.killer)\n            $.noty.closeAll();\n\n        (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);\n\n        $.notyRenderer.render();\n\n        return ($.noty.returns == 'object') ? notification : notification.options.id;\n    };\n\n    $.notyRenderer.render = function() {\n\n        var instance = $.noty.queue[0];\n\n        if($.type(instance) === 'object') {\n            if(instance.options.dismissQueue) {\n                if(instance.options.maxVisible > 0) {\n                    if($(instance.options.layout.container.selector + ' li').length < instance.options.maxVisible) {\n                        $.notyRenderer.show($.noty.queue.shift());\n                    }\n                    else {\n\n                    }\n                }\n                else {\n                    $.notyRenderer.show($.noty.queue.shift());\n                }\n            }\n            else {\n                if($.noty.ontap) {\n                    $.notyRenderer.show($.noty.queue.shift());\n                    $.noty.ontap = false;\n                }\n            }\n        }\n        else {\n            $.noty.ontap = true; // Queue is over\n        }\n\n    };\n\n    $.notyRenderer.show = function(notification) {\n\n        if(notification.options.modal) {\n            $.notyRenderer.createModalFor(notification);\n            $.notyRenderer.setModalCount(+1);\n        }\n\n        // Where is the container?\n        if(notification.options.custom) {\n            if(notification.options.custom.find(notification.options.layout.container.selector).length == 0) {\n                notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                notification.options.custom.find(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n        else {\n            if($(notification.options.layout.container.selector).length == 0) {\n                $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                $(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n\n        $.notyRenderer.setLayoutCountFor(notification, +1);\n\n        notification.show();\n    };\n\n    $.notyRenderer.createModalFor = function(notification) {\n        if($('.noty_modal').length == 0) {\n            var modal = $('<div/>').addClass('noty_modal').addClass(notification.options.theme).data('noty_modal_count', 0);\n\n            if(notification.options.theme.modal && notification.options.theme.modal.css)\n                modal.css(notification.options.theme.modal.css);\n\n            modal.prependTo($('body')).fadeIn('fast');\n\n            if($.inArray('backdrop', notification.options.closeWith) > -1)\n                modal.on('click', function(e) {\n                    $.noty.closeAll();\n                });\n        }\n    };\n\n    $.notyRenderer.getLayoutCountFor = function(notification) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;\n    };\n\n    $.notyRenderer.setLayoutCountFor = function(notification, arg) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);\n    };\n\n    $.notyRenderer.getModalCount = function() {\n        return $('.noty_modal').data('noty_modal_count') || 0;\n    };\n\n    $.notyRenderer.setModalCount = function(arg) {\n        return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);\n    };\n\n    // This is for custom container\n    $.fn.noty = function(options) {\n        options.custom = $(this);\n        return $.notyRenderer.init(options);\n    };\n\n    $.noty = {};\n    $.noty.queue = [];\n    $.noty.ontap = true;\n    $.noty.layouts = {};\n    $.noty.themes = {};\n    $.noty.returns = 'object';\n    $.noty.store = {};\n\n    $.noty.get = function(id) {\n        return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;\n    };\n\n    $.noty.close = function(id) {\n        return $.noty.get(id) ? $.noty.get(id).close() : false;\n    };\n\n    $.noty.setText = function(id, text) {\n        return $.noty.get(id) ? $.noty.get(id).setText(text) : false;\n    };\n\n    $.noty.setType = function(id, type) {\n        return $.noty.get(id) ? $.noty.get(id).setType(type) : false;\n    };\n\n    $.noty.clearQueue = function() {\n        $.noty.queue = [];\n    };\n\n    $.noty.closeAll = function() {\n        $.noty.clearQueue();\n        $.each($.noty.store, function(id, noty) {\n            noty.close();\n        });\n    };\n\n    var windowAlert = window.alert;\n\n    $.noty.consumeAlert = function(options) {\n        window.alert = function(text) {\n            if(options)\n                options.text = text;\n            else\n                options = {text: text};\n\n            $.notyRenderer.init(options);\n        };\n    };\n\n    $.noty.stopConsumeAlert = function() {\n        window.alert = windowAlert;\n    };\n\n    $.noty.defaults = {\n        layout      : 'top',\n        theme       : 'defaultTheme',\n        type        : 'alert',\n        text        : '',\n        dismissQueue: true,\n        template    : '<div class=\"noty_message\"><span class=\"noty_text\"></span><div class=\"noty_close\"></div></div>',\n        animation   : {\n            open  : {height: 'toggle'},\n            close : {height: 'toggle'},\n            easing: 'swing',\n            speed : 500\n        },\n        timeout     : false,\n        force       : false,\n        modal       : false,\n        maxVisible  : 5,\n        killer      : false,\n        closeWith   : ['click'],\n        callback    : {\n            onShow      : function() {\n            },\n            afterShow   : function() {\n            },\n            onClose     : function() {\n            },\n            afterClose  : function() {\n            },\n            onCloseClick: function() {\n            }\n        },\n        buttons     : false\n    };\n\n    $(window).on('resize', function() {\n        $.each($.noty.layouts, function(index, layout) {\n            layout.container.style.apply($(layout.container.selector));\n        });\n    });\n\n    // Helpers\n    window.noty = function noty(options) {\n        return $.notyRenderer.init(options);\n    };\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/bottom.js",
    "content": "$.noty.layouts.bottom = {\n    name     : 'bottom',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_bottom_layout_container\" />',\n        selector: 'ul#noty_bottom_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/bottomCenter.js",
    "content": "$.noty.layouts.bottomCenter = {\n    name     : 'bottomCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomCenter_layout_container\" />',\n        selector: 'ul#noty_bottomCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/bottomLeft.js",
    "content": "$.noty.layouts.bottomLeft = {\n    name     : 'bottomLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomLeft_layout_container\" />',\n        selector: 'ul#noty_bottomLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/bottomRight.js",
    "content": "$.noty.layouts.bottomRight = {\n    name     : 'bottomRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomRight_layout_container\" />',\n        selector: 'ul#noty_bottomRight_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/center.js",
    "content": "$.noty.layouts.center = {\n    name     : 'center',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_center_layout_container\" />',\n        selector: 'ul#noty_center_layout_container',\n        style   : function() {\n            $(this).css({\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/centerLeft.js",
    "content": "$.noty.layouts.centerLeft = {\n    name     : 'centerLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerLeft_layout_container\" />',\n        selector: 'ul#noty_centerLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/centerRight.js",
    "content": "$.noty.layouts.centerRight = {\n    name     : 'centerRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerRight_layout_container\" />',\n        selector: 'ul#noty_centerRight_layout_container',\n        style   : function() {\n            $(this).css({\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/inline.js",
    "content": "$.noty.layouts.inline = {\n    name     : 'inline',\n    options  : {},\n    container: {\n        object  : '<ul class=\"noty_inline_layout_container\" />',\n        selector: 'ul.noty_inline_layout_container',\n        style   : function() {\n            $(this).css({\n                width        : '100%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/top.js",
    "content": "$.noty.layouts.top = {\n    name     : 'top',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_top_layout_container\" />',\n        selector: 'ul#noty_top_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/topCenter.js",
    "content": "$.noty.layouts.topCenter = {\n    name     : 'topCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topCenter_layout_container\" />',\n        selector: 'ul#noty_topCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/topLeft.js",
    "content": "$.noty.layouts.topLeft = {\n    name     : 'topLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topLeft_layout_container\" />',\n        selector: 'ul#noty_topLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/layouts/topRight.js",
    "content": "$.noty.layouts.topRight = {\n    name     : 'topRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topRight_layout_container\" />',\n        selector: 'ul#noty_topRight_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/packaged/jquery.noty.packaged.js",
    "content": "!function(root, factory) {\n\t if (typeof define === 'function' && define.amd) {\n\t\t define(['jquery.noty.packaged'], factory);\n\t } else if (typeof exports === 'object') {\n\t\t module.exports = factory(require('jquery'));\n\t } else {\n\t\t factory(root.jQuery);\n\t }\n}(this, function($) {\n\n/*!\n @package noty - jQuery Notification Plugin\n @version version: 2.3.5\n @contributors https://github.com/needim/noty/graphs/contributors\n\n @documentation Examples and Documentation - http://needim.github.com/noty/\n\n @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php\n */\n\n    if(typeof Object.create !== 'function') {\n        Object.create = function(o) {\n            function F() {\n            }\n\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    var NotyObject = {\n\n        init: function(options) {\n\n            // Mix in the passed in options with the default options\n            this.options = $.extend({}, $.noty.defaults, options);\n\n            this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];\n\n            if($.noty.themes[this.options.theme])\n                this.options.theme = $.noty.themes[this.options.theme];\n            else\n                options.themeClassName = this.options.theme;\n\n            delete options.layout;\n            delete options.theme;\n\n            this.options = $.extend({}, this.options, this.options.layout.options);\n            this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));\n\n            this.options = $.extend({}, this.options, options);\n\n            // Build the noty dom initial structure\n            this._build();\n\n            // return this so we can chain/use the bridge with less code.\n            return this;\n        }, // end init\n\n        _build: function() {\n\n            // Generating noty bar\n            var $bar = $('<div class=\"noty_bar noty_type_' + this.options.type + '\"></div>').attr('id', this.options.id);\n            $bar.append(this.options.template).find('.noty_text').html(this.options.text);\n\n            this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;\n\n            if(this.options.themeClassName)\n                this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type);\n\n            // Set buttons if available\n            if(this.options.buttons) {\n\n                // If we have button disable closeWith & timeout options\n                this.options.closeWith = [];\n                this.options.timeout = false;\n\n                var $buttons = $('<div/>').addClass('noty_buttons');\n\n                (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);\n\n                var self = this;\n\n                $.each(this.options.buttons, function(i, button) {\n                    var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text).attr('id', button.id ? button.id : 'button-' + i)\n                        .appendTo(self.$bar.find('.noty_buttons'))\n                        .on('click', function(event) {\n                            if($.isFunction(button.onClick)) {\n                                button.onClick.call($button, self, event);\n                            }\n                        });\n                });\n            }\n\n            // For easy access\n            this.$message = this.$bar.find('.noty_message');\n            this.$closeButton = this.$bar.find('.noty_close');\n            this.$buttons = this.$bar.find('.noty_buttons');\n\n            $.noty.store[this.options.id] = this; // store noty for api\n\n        }, // end _build\n\n        show: function() {\n\n            var self = this;\n\n            (self.options.custom) ? self.options.custom.find(self.options.layout.container.selector).append(self.$bar) : $(self.options.layout.container.selector).append(self.$bar);\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.style.apply(self);\n\n            ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});\n\n            self.$bar.addClass(self.options.layout.addClass);\n\n            self.options.layout.container.style.apply($(self.options.layout.container.selector));\n\n            self.showing = true;\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.callback.onShow.apply(this);\n\n            if($.inArray('click', self.options.closeWith) > -1)\n                self.$bar.css('cursor', 'pointer').one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    if(self.options.callback.onCloseClick) {\n                        self.options.callback.onCloseClick.apply(self);\n                    }\n                    self.close();\n                });\n\n            if($.inArray('hover', self.options.closeWith) > -1)\n                self.$bar.one('mouseenter', function() {\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) > -1)\n                self.$closeButton.one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) == -1)\n                self.$closeButton.remove();\n\n            if(self.options.callback.onShow)\n                self.options.callback.onShow.apply(self);\n\n            if (typeof self.options.animation.open == 'string') {\n                self.$bar.css('height', self.$bar.innerHeight());\n                self.$bar.show().addClass(self.options.animation.open).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                    self.showing = false;\n                    self.shown = true;\n                });\n\n            } else {\n                self.$bar.animate(\n                    self.options.animation.open,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                        self.showing = false;\n                        self.shown = true;\n                    });\n            }\n\n            // If noty is have a timeout option\n            if(self.options.timeout)\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n\n            return this;\n\n        }, // end show\n\n        close: function() {\n\n            if(this.closed) return;\n            if(this.$bar && this.$bar.hasClass('i-am-closing-now')) return;\n\n            var self = this;\n\n            if(this.showing) {\n                self.$bar.queue(\n                    function() {\n                        self.close.apply(self);\n                    }\n                );\n                return;\n            }\n\n            if(!this.shown && !this.showing) { // If we are still waiting in the queue just delete from queue\n                var queue = [];\n                $.each($.noty.queue, function(i, n) {\n                    if(n.options.id != self.options.id) {\n                        queue.push(n);\n                    }\n                });\n                $.noty.queue = queue;\n                return;\n            }\n\n            self.$bar.addClass('i-am-closing-now');\n\n            if(self.options.callback.onClose) {\n                self.options.callback.onClose.apply(self);\n            }\n\n            if (typeof self.options.animation.close == 'string') {\n                self.$bar.addClass(self.options.animation.close).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    self.closeCleanUp();\n                });\n            } else {\n                self.$bar.clearQueue().stop().animate(\n                    self.options.animation.close,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    })\n                    .promise().done(function() {\n                        self.closeCleanUp();\n                    });\n            }\n\n        }, // end close\n\n        closeCleanUp: function() {\n\n            var self = this;\n\n            // Modal Cleaning\n            if(self.options.modal) {\n                $.notyRenderer.setModalCount(-1);\n                if($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function() {\n                    $(this).remove();\n                });\n            }\n\n            // Layout Cleaning\n            $.notyRenderer.setLayoutCountFor(self, -1);\n            if($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();\n\n            // Make sure self.$bar has not been removed before attempting to remove it\n            if(typeof self.$bar !== 'undefined' && self.$bar !== null) {\n\n                if (typeof self.options.animation.close == 'string') {\n                    self.$bar.css('transition', 'all 100ms ease').css('border', 0).css('margin', 0).height(0);\n                    self.$bar.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {\n                        self.$bar.remove();\n                        self.$bar = null;\n                        self.closed = true;\n\n                        if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                            self.options.theme.callback.onClose.apply(self);\n                        }\n                    });\n                } else {\n                    self.$bar.remove();\n                    self.$bar = null;\n                    self.closed = true;\n                }\n            }\n\n            delete $.noty.store[self.options.id]; // deleting noty from store\n\n            if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                self.options.theme.callback.onClose.apply(self);\n            }\n\n            if(!self.options.dismissQueue) {\n                // Queue render\n                $.noty.ontap = true;\n\n                $.notyRenderer.render();\n            }\n\n            if(self.options.maxVisible > 0 && self.options.dismissQueue) {\n                $.notyRenderer.render();\n            }\n\n        }, // end close clean up\n\n        setText: function(text) {\n            if(!this.closed) {\n                this.options.text = text;\n                this.$bar.find('.noty_text').html(text);\n            }\n            return this;\n        },\n\n        setType: function(type) {\n            if(!this.closed) {\n                this.options.type = type;\n                this.options.theme.style.apply(this);\n                this.options.theme.callback.onShow.apply(this);\n            }\n            return this;\n        },\n\n        setTimeout: function(time) {\n            if(!this.closed) {\n                var self = this;\n                this.options.timeout = time;\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n            }\n            return this;\n        },\n\n        stopPropagation: function(evt) {\n            evt = evt || window.event;\n            if(typeof evt.stopPropagation !== \"undefined\") {\n                evt.stopPropagation();\n            }\n            else {\n                evt.cancelBubble = true;\n            }\n        },\n\n        closed : false,\n        showing: false,\n        shown  : false\n\n    }; // end NotyObject\n\n    $.notyRenderer = {};\n\n    $.notyRenderer.init = function(options) {\n\n        // Renderer creates a new noty\n        var notification = Object.create(NotyObject).init(options);\n\n        if(notification.options.killer)\n            $.noty.closeAll();\n\n        (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);\n\n        $.notyRenderer.render();\n\n        return ($.noty.returns == 'object') ? notification : notification.options.id;\n    };\n\n    $.notyRenderer.render = function() {\n\n        var instance = $.noty.queue[0];\n\n        if($.type(instance) === 'object') {\n            if(instance.options.dismissQueue) {\n                if(instance.options.maxVisible > 0) {\n                    if($(instance.options.layout.container.selector + ' li').length < instance.options.maxVisible) {\n                        $.notyRenderer.show($.noty.queue.shift());\n                    }\n                    else {\n\n                    }\n                }\n                else {\n                    $.notyRenderer.show($.noty.queue.shift());\n                }\n            }\n            else {\n                if($.noty.ontap) {\n                    $.notyRenderer.show($.noty.queue.shift());\n                    $.noty.ontap = false;\n                }\n            }\n        }\n        else {\n            $.noty.ontap = true; // Queue is over\n        }\n\n    };\n\n    $.notyRenderer.show = function(notification) {\n\n        if(notification.options.modal) {\n            $.notyRenderer.createModalFor(notification);\n            $.notyRenderer.setModalCount(+1);\n        }\n\n        // Where is the container?\n        if(notification.options.custom) {\n            if(notification.options.custom.find(notification.options.layout.container.selector).length == 0) {\n                notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                notification.options.custom.find(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n        else {\n            if($(notification.options.layout.container.selector).length == 0) {\n                $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                $(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n\n        $.notyRenderer.setLayoutCountFor(notification, +1);\n\n        notification.show();\n    };\n\n    $.notyRenderer.createModalFor = function(notification) {\n        if($('.noty_modal').length == 0) {\n            var modal = $('<div/>').addClass('noty_modal').addClass(notification.options.theme).data('noty_modal_count', 0);\n\n            if(notification.options.theme.modal && notification.options.theme.modal.css)\n                modal.css(notification.options.theme.modal.css);\n\n            modal.prependTo($('body')).fadeIn('fast');\n\n            if($.inArray('backdrop', notification.options.closeWith) > -1)\n                modal.on('click', function(e) {\n                    $.noty.closeAll();\n                });\n        }\n    };\n\n    $.notyRenderer.getLayoutCountFor = function(notification) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;\n    };\n\n    $.notyRenderer.setLayoutCountFor = function(notification, arg) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);\n    };\n\n    $.notyRenderer.getModalCount = function() {\n        return $('.noty_modal').data('noty_modal_count') || 0;\n    };\n\n    $.notyRenderer.setModalCount = function(arg) {\n        return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);\n    };\n\n    // This is for custom container\n    $.fn.noty = function(options) {\n        options.custom = $(this);\n        return $.notyRenderer.init(options);\n    };\n\n    $.noty = {};\n    $.noty.queue = [];\n    $.noty.ontap = true;\n    $.noty.layouts = {};\n    $.noty.themes = {};\n    $.noty.returns = 'object';\n    $.noty.store = {};\n\n    $.noty.get = function(id) {\n        return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;\n    };\n\n    $.noty.close = function(id) {\n        return $.noty.get(id) ? $.noty.get(id).close() : false;\n    };\n\n    $.noty.setText = function(id, text) {\n        return $.noty.get(id) ? $.noty.get(id).setText(text) : false;\n    };\n\n    $.noty.setType = function(id, type) {\n        return $.noty.get(id) ? $.noty.get(id).setType(type) : false;\n    };\n\n    $.noty.clearQueue = function() {\n        $.noty.queue = [];\n    };\n\n    $.noty.closeAll = function() {\n        $.noty.clearQueue();\n        $.each($.noty.store, function(id, noty) {\n            noty.close();\n        });\n    };\n\n    var windowAlert = window.alert;\n\n    $.noty.consumeAlert = function(options) {\n        window.alert = function(text) {\n            if(options)\n                options.text = text;\n            else\n                options = {text: text};\n\n            $.notyRenderer.init(options);\n        };\n    };\n\n    $.noty.stopConsumeAlert = function() {\n        window.alert = windowAlert;\n    };\n\n    $.noty.defaults = {\n        layout      : 'top',\n        theme       : 'defaultTheme',\n        type        : 'alert',\n        text        : '',\n        dismissQueue: true,\n        template    : '<div class=\"noty_message\"><span class=\"noty_text\"></span><div class=\"noty_close\"></div></div>',\n        animation   : {\n            open  : {height: 'toggle'},\n            close : {height: 'toggle'},\n            easing: 'swing',\n            speed : 500\n        },\n        timeout     : false,\n        force       : false,\n        modal       : false,\n        maxVisible  : 5,\n        killer      : false,\n        closeWith   : ['click'],\n        callback    : {\n            onShow      : function() {\n            },\n            afterShow   : function() {\n            },\n            onClose     : function() {\n            },\n            afterClose  : function() {\n            },\n            onCloseClick: function() {\n            }\n        },\n        buttons     : false\n    };\n\n    $(window).on('resize', function() {\n        $.each($.noty.layouts, function(index, layout) {\n            layout.container.style.apply($(layout.container.selector));\n        });\n    });\n\n    // Helpers\n    window.noty = function noty(options) {\n        return $.notyRenderer.init(options);\n    };\n\n$.noty.layouts.bottom = {\n    name     : 'bottom',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_bottom_layout_container\" />',\n        selector: 'ul#noty_bottom_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.bottomCenter = {\n    name     : 'bottomCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomCenter_layout_container\" />',\n        selector: 'ul#noty_bottomCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n\n$.noty.layouts.bottomLeft = {\n    name     : 'bottomLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomLeft_layout_container\" />',\n        selector: 'ul#noty_bottomLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.bottomRight = {\n    name     : 'bottomRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomRight_layout_container\" />',\n        selector: 'ul#noty_bottomRight_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.center = {\n    name     : 'center',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_center_layout_container\" />',\n        selector: 'ul#noty_center_layout_container',\n        style   : function() {\n            $(this).css({\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.centerLeft = {\n    name     : 'centerLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerLeft_layout_container\" />',\n        selector: 'ul#noty_centerLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.centerRight = {\n    name     : 'centerRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerRight_layout_container\" />',\n        selector: 'ul#noty_centerRight_layout_container',\n        style   : function() {\n            $(this).css({\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.inline = {\n    name     : 'inline',\n    options  : {},\n    container: {\n        object  : '<ul class=\"noty_inline_layout_container\" />',\n        selector: 'ul.noty_inline_layout_container',\n        style   : function() {\n            $(this).css({\n                width        : '100%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n$.noty.layouts.top = {\n    name     : 'top',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_top_layout_container\" />',\n        selector: 'ul#noty_top_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n$.noty.layouts.topCenter = {\n    name     : 'topCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topCenter_layout_container\" />',\n        selector: 'ul#noty_topCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.topLeft = {\n    name     : 'topLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topLeft_layout_container\" />',\n        selector: 'ul#noty_topLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.topRight = {\n    name     : 'topRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topRight_layout_container\" />',\n        selector: 'ul#noty_topRight_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.themes.bootstrapTheme = {\n    name: 'bootstrapTheme',\n    modal: {\n        css: {\n            position: 'fixed',\n            width: '100%',\n            height: '100%',\n            backgroundColor: '#000',\n            zIndex: 10000,\n            opacity: 0.6,\n            display: 'none',\n            left: 0,\n            top: 0\n        }\n    },\n    style: function() {\n\n        var containerSelector = this.options.layout.container.selector;\n        $(containerSelector).addClass('list-group');\n\n        this.$closeButton.append('<span aria-hidden=\"true\">&times;</span><span class=\"sr-only\">Close</span>');\n        this.$closeButton.addClass('close');\n\n        this.$bar.addClass( \"list-group-item\" ).css('padding', '0px');\n\n        switch (this.options.type) {\n            case 'alert': case 'notification':\n                this.$bar.addClass( \"list-group-item-info\" );\n                break;\n            case 'warning':\n                this.$bar.addClass( \"list-group-item-warning\" );\n                break;\n            case 'error':\n                this.$bar.addClass( \"list-group-item-danger\" );\n                break;\n            case 'information':\n                this.$bar.addClass(\"list-group-item-info\");\n                break;\n            case 'success':\n                this.$bar.addClass( \"list-group-item-success\" );\n                break;\n        }\n\n        this.$message.css({\n            fontSize: '13px',\n            lineHeight: '16px',\n            textAlign: 'center',\n            padding: '8px 10px 9px',\n            width: 'auto',\n            position: 'relative'\n        });\n    },\n    callback: {\n        onShow: function() {  },\n        onClose: function() {  }\n    }\n};\n\n\n$.noty.themes.defaultTheme = {\n    name    : 'defaultTheme',\n    helpers : {\n        borderFix: function() {\n            if(this.options.dismissQueue) {\n                var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;\n                switch(this.options.layout.name) {\n                    case 'top':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).last().css({borderRadius: '0px 0px 5px 5px'});\n                        break;\n                    case 'topCenter':\n                    case 'topLeft':\n                    case 'topRight':\n                    case 'bottomCenter':\n                    case 'bottomLeft':\n                    case 'bottomRight':\n                    case 'center':\n                    case 'centerLeft':\n                    case 'centerRight':\n                    case 'inline':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});\n                        $(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'});\n                        break;\n                    case 'bottom':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({borderRadius: '5px 5px 0px 0px'});\n                        break;\n                    default:\n                        break;\n                }\n            }\n        }\n    },\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow  : 'hidden',\n            background: \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAQAAAClM0ndAAAAhklEQVR4AdXO0QrCMBBE0bttkk38/w8WRERpdyjzVOc+HxhIHqJGMQcFFkpYRQotLLSw0IJ5aBdovruMYDA/kT8plF9ZKLFQcgF18hDj1SbQOMlCA4kao0iiXmah7qBWPdxpohsgVZyj7e5I9KcID+EhiDI5gxBYKLBQYKHAQoGFAoEks/YEGHYKB7hFxf0AAAAASUVORK5CYII=') repeat-x scroll left top #fff\"\n        });\n\n        this.$message.css({\n            fontSize  : '13px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '8px 10px 9px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderRadius: '0px 0px 5px 5px',\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderRadius: '5px 5px 0px 0px',\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        },\n        onClose: function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        }\n    }\n};\n\n$.noty.themes.relax = {\n    name    : 'relax',\n    helpers : {},\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow    : 'hidden',\n            margin      : '4px 0',\n            borderRadius: '2px'\n        });\n\n        this.$message.css({\n            fontSize  : '14px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '10px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderTop   : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderBottom: '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#dedede', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: '#FF8181', borderColor: '#e25353', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#78C5E7', borderColor: '#3badd6', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: '#BCF5BC', borderColor: '#7cdd77', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n\n        },\n        onClose: function() {\n\n        }\n    }\n};\n\n\nreturn window.noty;\n\n});"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/promise.js",
    "content": "/*!\n * Noty Helpers Javascript From JQuery Javascript Library\n *\n * Ported by Maksim Pecherskiy.  Original Licensing:\n *\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n * Copyright 2011, The Dojo Foundation\n * Released under the MIT, BSD, and GPL Licenses.\n *\n * Date: Mon Nov 21 21:11:03 2011 -0500\n */\n\n\n(function(){\n\n  // String to Object flags format cache\nvar flagsCache = {};\n\n// Convert String-formatted flags into Object-formatted ones and store in cache\nfunction createFlags( flags ) {\n  var object = flagsCache[ flags ] = {},\n    i, length;\n  flags = flags.split( /\\s+/ );\n  for ( i = 0, length = flags.length; i < length; i++ ) {\n    object[ flags[i] ] = true;\n  }\n  return object;\n}\n\njQuery.extend({\n\n  _mark: function( elem, type ) {\n    if ( elem ) {\n      type = (type || \"fx\") + \"mark\";\n      jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );\n    }\n  },\n\n  _unmark: function( force, elem, type ) {\n    if ( force !== true ) {\n      type = elem;\n      elem = force;\n      force = false;\n    }\n    if ( elem ) {\n      type = type || \"fx\";\n      var key = type + \"mark\",\n        count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );\n      if ( count ) {\n        jQuery.data( elem, key, count, true );\n      } else {\n        jQuery.removeData( elem, key, true );\n        handleQueueMarkDefer( elem, type, \"mark\" );\n      }\n    }\n  },\n\n  queue: function( elem, type, data ) {\n    if ( elem ) {\n      type = (type || \"fx\") + \"queue\";\n      var q = jQuery.data( elem, type, undefined, true );\n      // Speed up dequeue by getting out quickly if this is just a lookup\n      if ( data ) {\n        if ( !q || jQuery.isArray(data) ) {\n          q = jQuery.data( elem, type, jQuery.makeArray(data), true );\n        } else {\n          q.push( data );\n        }\n      }\n      return q || [];\n    }\n  },\n\n  dequeue: function( elem, type ) {\n    type = type || \"fx\";\n\n    var queue = jQuery.queue( elem, type ),\n      fn = queue.shift(),\n      defer;\n\n    // If the fx queue is dequeued, always remove the progress sentinel\n    if ( fn === \"inprogress\" ) {\n      fn = queue.shift();\n    }\n\n    if ( fn ) {\n      // Add a progress sentinel to prevent the fx queue from being\n      // automatically dequeued\n      if ( type === \"fx\" ) {\n        queue.unshift(\"inprogress\");\n      }\n\n      fn.call(elem, function() {\n        jQuery.dequeue(elem, type);\n      });\n    }\n\n    if ( !queue.length ) {\n      jQuery.removeData( elem, type + \"queue\", true );\n      handleQueueMarkDefer( elem, type, \"queue\" );\n    }\n  }\n});\n\njQuery.fn.extend({\n  queue: function( type, data ) {\n    if ( typeof type !== \"string\" ) {\n      data = type;\n      type = \"fx\";\n    }\n\n    if ( data === undefined ) {\n      return jQuery.queue( this[0], type );\n    }\n    return this.each(function() {\n      var queue = jQuery.queue( this, type, data );\n\n      if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n        jQuery.dequeue( this, type );\n      }\n    });\n  },\n  dequeue: function( type ) {\n    return this.each(function() {\n      jQuery.dequeue( this, type );\n    });\n  },\n  // Based off of the plugin by Clint Helfers, with permission.\n  // http://blindsignals.com/index.php/2009/07/jquery-delay/\n  delay: function( time, type ) {\n    time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n    type = type || \"fx\";\n\n    return this.queue( type, function() {\n      var elem = this;\n      setTimeout(function() {\n        jQuery.dequeue( elem, type );\n      }, time );\n    });\n  },\n  clearQueue: function( type ) {\n    return this.queue( type || \"fx\", [] );\n  },\n  // Get a promise resolved when queues of a certain type\n  // are emptied (fx is the type by default)\n  promise: function( type, object ) {\n    if ( typeof type !== \"string\" ) {\n      object = type;\n      type = undefined;\n    }\n    type = type || \"fx\";\n    var defer = jQuery.Deferred(),\n      elements = this,\n      i = elements.length,\n      count = 1,\n      deferDataKey = type + \"defer\",\n      queueDataKey = type + \"queue\",\n      markDataKey = type + \"mark\",\n      tmp;\n    function resolve() {\n      if ( !( --count ) ) {\n        defer.resolveWith( elements, [ elements ] );\n      }\n    }\n    while( i-- ) {\n      if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n          ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n            jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n          jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {\n        count++;\n        tmp.done( resolve );\n      }\n    }\n    resolve();\n    return defer.promise();\n  }\n});\n\nfunction handleQueueMarkDefer( elem, type, src ) {\n  var deferDataKey = type + \"defer\",\n    queueDataKey = type + \"queue\",\n    markDataKey = type + \"mark\",\n    defer = jQuery._data( elem, deferDataKey );\n  if ( defer &&\n    ( src === \"queue\" || !jQuery._data(elem, queueDataKey) ) &&\n    ( src === \"mark\" || !jQuery._data(elem, markDataKey) ) ) {\n    // Give room for hard-coded callbacks to fire first\n    // and eventually mark/queue something else on the element\n    setTimeout( function() {\n      if ( !jQuery._data( elem, queueDataKey ) &&\n        !jQuery._data( elem, markDataKey ) ) {\n        jQuery.removeData( elem, deferDataKey, true );\n        defer.fire();\n      }\n    }, 0 );\n  }\n}\n\n\n\njQuery.Callbacks = function( flags ) {\n\n  // Convert flags from String-formatted to Object-formatted\n  // (we check in cache first)\n  flags = flags ? ( /*flagsCache[ flags ] || */createFlags( flags ) ) : {};\n\n  var // Actual callback list\n    list = [],\n    // Stack of fire calls for repeatable lists\n    stack = [],\n    // Last fire value (for non-forgettable lists)\n    memory,\n    // Flag to know if list is currently firing\n    firing,\n    // First callback to fire (used internally by add and fireWith)\n    firingStart,\n    // End of the loop when firing\n    firingLength,\n    // Index of currently firing callback (modified by remove if needed)\n    firingIndex,\n    // Add one or several callbacks to the list\n    add = function( args ) {\n      var i,\n        length,\n        elem,\n        type,\n        actual;\n      for ( i = 0, length = args.length; i < length; i++ ) {\n        elem = args[ i ];\n        type = jQuery.type( elem );\n        if ( type === \"array\" ) {\n          // Inspect recursively\n          add( elem );\n        } else if ( type === \"function\" ) {\n          // Add if not in unique mode and callback is not in\n          if ( !flags.unique || !self.has( elem ) ) {\n            list.push( elem );\n          }\n        }\n      }\n    },\n    // Fire callbacks\n    fire = function( context, args ) {\n      args = args || [];\n      memory = !flags.memory || [ context, args ];\n      firing = true;\n      firingIndex = firingStart || 0;\n      firingStart = 0;\n      firingLength = list.length;\n      for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n        if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {\n          memory = true; // Mark as halted\n          break;\n        }\n      }\n      firing = false;\n      if ( list ) {\n        if ( !flags.once ) {\n          if ( stack && stack.length ) {\n            memory = stack.shift();\n            self.fireWith( memory[ 0 ], memory[ 1 ] );\n          }\n        } else if ( memory === true ) {\n          self.disable();\n        } else {\n          list = [];\n        }\n      }\n    },\n    // Actual Callbacks object\n    self = {\n      // Add a callback or a collection of callbacks to the list\n      add: function() {\n        if ( list ) {\n          var length = list.length;\n          add( arguments );\n          // Do we need to add the callbacks to the\n          // current firing batch?\n          if ( firing ) {\n            firingLength = list.length;\n          // With memory, if we're not firing then\n          // we should call right away, unless previous\n          // firing was halted (stopOnFalse)\n          } else if ( memory && memory !== true ) {\n            firingStart = length;\n            fire( memory[ 0 ], memory[ 1 ] );\n          }\n        }\n        return this;\n      },\n      // Remove a callback from the list\n      remove: function() {\n        if ( list ) {\n          var args = arguments,\n            argIndex = 0,\n            argLength = args.length;\n          for ( ; argIndex < argLength ; argIndex++ ) {\n            for ( var i = 0; i < list.length; i++ ) {\n              if ( args[ argIndex ] === list[ i ] ) {\n                // Handle firingIndex and firingLength\n                if ( firing ) {\n                  if ( i <= firingLength ) {\n                    firingLength--;\n                    if ( i <= firingIndex ) {\n                      firingIndex--;\n                    }\n                  }\n                }\n                // Remove the element\n                list.splice( i--, 1 );\n                // If we have some unicity property then\n                // we only need to do this once\n                if ( flags.unique ) {\n                  break;\n                }\n              }\n            }\n          }\n        }\n        return this;\n      },\n      // Control if a given callback is in the list\n      has: function( fn ) {\n        if ( list ) {\n          var i = 0,\n            length = list.length;\n          for ( ; i < length; i++ ) {\n            if ( fn === list[ i ] ) {\n              return true;\n            }\n          }\n        }\n        return false;\n      },\n      // Remove all callbacks from the list\n      empty: function() {\n        list = [];\n        return this;\n      },\n      // Have the list do nothing anymore\n      disable: function() {\n        list = stack = memory = undefined;\n        return this;\n      },\n      // Is it disabled?\n      disabled: function() {\n        return !list;\n      },\n      // Lock the list in its current state\n      lock: function() {\n        stack = undefined;\n        if ( !memory || memory === true ) {\n          self.disable();\n        }\n        return this;\n      },\n      // Is it locked?\n      locked: function() {\n        return !stack;\n      },\n      // Call all callbacks with the given context and arguments\n      fireWith: function( context, args ) {\n        if ( stack ) {\n          if ( firing ) {\n            if ( !flags.once ) {\n              stack.push( [ context, args ] );\n            }\n          } else if ( !( flags.once && memory ) ) {\n            fire( context, args );\n          }\n        }\n        return this;\n      },\n      // Call all the callbacks with the given arguments\n      fire: function() {\n        self.fireWith( this, arguments );\n        return this;\n      },\n      // To know if the callbacks have already been called at least once\n      fired: function() {\n        return !!memory;\n      }\n    };\n\n  return self;\n};\n\n\n\njQuery.fn.extend({\n  // Get a promise resolved when queues of a certain type\n  // are emptied (fx is the type by default)\n  promise: function( type, object ) {\n    if ( typeof type !== \"string\" ) {\n      object = type;\n      type = undefined;\n    }\n    type = type || \"fx\";\n    var defer = jQuery.Deferred(),\n      elements = this,\n      i = elements.length,\n      count = 1,\n      deferDataKey = type + \"defer\",\n      queueDataKey = type + \"queue\",\n      markDataKey = type + \"mark\",\n      tmp;\n    function resolve() {\n      if ( !( --count ) ) {\n        defer.resolveWith( elements, [ elements ] );\n      }\n    }\n    while( i-- ) {\n      if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n          ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n            jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n          jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( \"once memory\" ), true ) )) {\n        count++;\n        tmp.add( resolve );\n      }\n    }\n    resolve();\n    return defer.promise();\n  }\n});\n})();"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/themes/bootstrap.js",
    "content": "$.noty.themes.bootstrapTheme = {\n    name: 'bootstrapTheme',\n    modal: {\n        css: {\n            position: 'fixed',\n            width: '100%',\n            height: '100%',\n            backgroundColor: '#000',\n            zIndex: 10000,\n            opacity: 0.6,\n            display: 'none',\n            left: 0,\n            top: 0\n        }\n    },\n    style: function() {\n\n        var containerSelector = this.options.layout.container.selector;\n        $(containerSelector).addClass('list-group');\n\n        this.$closeButton.append('<span aria-hidden=\"true\">&times;</span><span class=\"sr-only\">Close</span>');\n        this.$closeButton.addClass('close');\n\n        this.$bar.addClass( \"list-group-item\" ).css('padding', '0px');\n\n        switch (this.options.type) {\n            case 'alert': case 'notification':\n                this.$bar.addClass( \"list-group-item-info\" );\n                break;\n            case 'warning':\n                this.$bar.addClass( \"list-group-item-warning\" );\n                break;\n            case 'error':\n                this.$bar.addClass( \"list-group-item-danger\" );\n                break;\n            case 'information':\n                this.$bar.addClass(\"list-group-item-info\");\n                break;\n            case 'success':\n                this.$bar.addClass( \"list-group-item-success\" );\n                break;\n        }\n\n        this.$message.css({\n            fontSize: '13px',\n            lineHeight: '16px',\n            textAlign: 'center',\n            padding: '8px 10px 9px',\n            width: 'auto',\n            position: 'relative'\n        });\n    },\n    callback: {\n        onShow: function() {  },\n        onClose: function() {  }\n    }\n};\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/themes/default.js",
    "content": "$.noty.themes.defaultTheme = {\n    name    : 'defaultTheme',\n    helpers : {\n        borderFix: function() {\n            if(this.options.dismissQueue) {\n                var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;\n                switch(this.options.layout.name) {\n                    case 'top':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).last().css({borderRadius: '0px 0px 5px 5px'});\n                        break;\n                    case 'topCenter':\n                    case 'topLeft':\n                    case 'topRight':\n                    case 'bottomCenter':\n                    case 'bottomLeft':\n                    case 'bottomRight':\n                    case 'center':\n                    case 'centerLeft':\n                    case 'centerRight':\n                    case 'inline':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});\n                        $(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'});\n                        break;\n                    case 'bottom':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({borderRadius: '5px 5px 0px 0px'});\n                        break;\n                    default:\n                        break;\n                }\n            }\n        }\n    },\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow  : 'hidden',\n            background: \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAQAAAClM0ndAAAAhklEQVR4AdXO0QrCMBBE0bttkk38/w8WRERpdyjzVOc+HxhIHqJGMQcFFkpYRQotLLSw0IJ5aBdovruMYDA/kT8plF9ZKLFQcgF18hDj1SbQOMlCA4kao0iiXmah7qBWPdxpohsgVZyj7e5I9KcID+EhiDI5gxBYKLBQYKHAQoGFAoEks/YEGHYKB7hFxf0AAAAASUVORK5CYII=') repeat-x scroll left top #fff\"\n        });\n\n        this.$message.css({\n            fontSize  : '13px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '8px 10px 9px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderRadius: '0px 0px 5px 5px',\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderRadius: '5px 5px 0px 0px',\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        },\n        onClose: function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        }\n    }\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/libs/noty_2.3.5/themes/relax.js",
    "content": "$.noty.themes.relax = {\n    name    : 'relax',\n    helpers : {},\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow    : 'hidden',\n            margin      : '4px 0',\n            borderRadius: '2px'\n        });\n\n        this.$message.css({\n            fontSize  : '14px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '10px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderTop   : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderBottom: '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#dedede', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: '#FF8181', borderColor: '#e25353', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#78C5E7', borderColor: '#3badd6', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: '#BCF5BC', borderColor: '#7cdd77', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n\n        },\n        onClose: function() {\n\n        }\n    }\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/login.php",
    "content": "<?php\ninclude_once('config/config.php')\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Login</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<header class=\"header header-default\">\n    <div class=\"container-fluid\">\n        <div class=\"pull-left brand float-remove-xs text-center-xs\">\n            <a href=\"#\">\n                <img src=\"images/logo-inverse.svg\" alt=\"wso2\" title=\"wso2\" class=\"logo\">\n                <h1>WSO2 Pet Store - login</h1>\n            </a>\n        </div>\n    </div>\n</header>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\n                <!-- content -->\n                <div class=\"container col-xs-10 col-sm-6 col-md-6 col-lg-3 col-centered wr-content wr-login col-centered\">\n                    <div>\n                        <h2 class=\"wr-title uppercase blue-bg padding-double white boarder-bottom-blue margin-none\">Sign in </h2>\n\n\n                    </div>\n                    <div class=\"boarder-all \">\n                        <div class=\"clearfix\"></div>\n\n                        <div class=\"padding-double login-form\">\n                            <div class=\"error-msg\" id=\"error-msg\" style=\"display:none;\">Username or password is invalid</div>\n\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <input id=\"username\" name=\"username\" type=\"text\" class=\"form-control\" tabindex=\"0\"\n                                       placeholder=\"Username\">\n                            </div>\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <input id=\"password\" name=\"password\" type=\"password\" class=\"form-control\"\n                                       placeholder=\"Password\">\n                            </div>\n\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <button class=\"wr-btn grey-bg col-xs-12 col-md-12 col-lg-12 uppercase font-extra-large\" type=\"submit\" id=\"submit-btn\"> Sign in</button>\n                            </div>\n                            <div class=\"clearfix\"></div>\n                        </div>\n\n                    </div>\n                </div>\n                <!-- /content -->\n\n            </div>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script src=\"js/login.js\"></script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/logout.php",
    "content": "<?php\nsession_start();\nsession_destroy();\nheader('Location: login.php');\n?>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/pet-types.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"pet-types.php\"=>'Pet Types');\n$url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/category/all';\n$pet_catogories = callAuthAPIgetPetTypes($url,  preg_replace('/\\s+/', '', $_SESSION['authtoken']));\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Administrator</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"pet-types.php\">\n                            <img src=\"images/list-pet-type.png\" class=\"invert-png\">\n                            <span class=\"name\">Pet Types</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"pets.php\">\n                            <img src=\"images/list-pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li>\n                        <a href=\"add-pet-types.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-add fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                            Add pet type\n                        </a>\n                    </li>\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Pet Types</h1>\n        </div>\n        <div class=\"row\">\n            <div class=\"col-md-6\">\n                <table class=\"table table-striped\">\n                    <?php\n                    if(is_array($pet_catogories) && (count($pet_catogories) > 0)) {\n                    ?>\n                    <thead>\n                    <tr>\n                        <th>Category Name</th>\n                        <th></th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    <?php\n                        foreach ($pet_catogories as $json) {\n                    ?>\n                    <tr>\n                        <td><?php echo $json['name'] ?></td>\n                        <td>\n                            <a href=\"#\" class=\"btn padding-reduce-on-grid-view remove-cat\"\n                               data-category=\"<?php echo $json['name'] ?>\">\n                                <span class=\"fw-stack\">\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                    <i class=\"fw fw-delete fw-stack-1x\"></i>\n                                </span>\n                                <span class=\"hidden-xs\">Delete</span>\n                            </a>\n                        </td>\n                    </tr>\n                    <?php\n                        }\n                    }else{\n                        echo '<div class=\"alert alert-info\" role=\"alert\">No Pet Types added yet. Click <a href=\"add-pet-types.php\">here to add new pet type</a></div>';\n                    }\n                    ?>\n\n                    </tbody>\n                </table>\n            </div>\n        </div>\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script>\n   $(document).on('click', '.remove-cat', function(){\n       var pet_category = $(this).attr('data-category');\n       noty({\n           layout: 'bottomRight',\n           type: 'warning',\n           text: 'Are you sure you want to delete : <strong>'+ pet_category + \"</strong> ?\",\n           buttons: [\n               {addClass: 'btn btn-primary', text: 'Yes', onClick: function($noty) {\n                   $noty.close();\n                   $.ajax({\n                       type: \"POST\",\n                       url:  \"controllers/rest.php\",\n                       dataType: 'json',\n                       data: {api_type: 'deletePetTypes', category_name: pet_category},\n                       success: function (data, textStatus, jqXHR) {\n                           if (data.status == 'error') {\n                               var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                               window.setTimeout(function(){\n                                   window.location.href = 'logout.php';\n                               }, 1500);\n                           } else if (data.status == 'warning') {\n                               var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                           } else {\n                               var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                               window.setTimeout(function(){\n                                   window.location.href = 'pet-types.php';\n                               }, 1500);\n                           }\n                       }\n                   });\n\n               }\n               },\n               {addClass: 'btn btn-danger', text: 'No', onClick: function($noty) {\n                   $noty.close();\n               }\n               }\n           ]\n       });\n\n\n   });\n</script>\n\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/html/pets.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\n\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"pets.php\"=>'Pets');\n\n$url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/pet/all';\n$get_pets = callAuthApigetPets($url,  preg_replace('/\\s+/', '', $_SESSION['authtoken']));\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Administrator</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"pet-types.php\">\n                            <img src=\"images/list-pet-type.png\" class=\"invert-png\">\n                            <span class=\"name\">Pet Types</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"pets.php\">\n                            <img src=\"images/list-pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li>\n                        <a href=\"add-pets.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-add fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                            Add pet\n                        </a>\n                    </li>\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Pets</h1>\n        </div>\n        <div class=\"row\">\n            <div class=\"col-md-6\">\n                <table class=\"table table-striped\">\n                    <?php\n                    if(is_array($get_pets) && (count($get_pets) > 0)) {\n                    ?>\n                    <thead>\n                    <tr>\n                        <th>Pet Id</th>\n                        <th>Image</th>\n                        <th>Category</th>\n                        <th>Age</th>\n                        <th>Price</th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    <?php\n                        foreach ($get_pets as $json) {\n                            ?>\n                            <tr>\n                                <td><?php echo $json['id'] ?></td>\n                                <td><img src=\"<?php echo 'http://'.$_SERVER[\"SERVER_NAME\"].':'.FILE_SERVER_NODE_PORT.'/'.$json['image'] ?>\" class=\"tb-preview\"/></td>\n                                <td><?php echo $json['category']['name'] ?></td>\n                                <td><?php echo $json['ageMonths'] ?></td>\n                                <td><?php echo $json['price'] ?></td>\n                                <td>\n                                    <a href=\"#\" class=\"btn padding-reduce-on-grid-view remove-pet\"\n                                       data-petid=\"<?php echo $json['id'] ?>\">\n                                <span class=\"fw-stack\">\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                    <i class=\"fw fw-delete fw-stack-1x\"></i>\n                                </span>\n                                        <span class=\"hidden-xs\">Delete</span>\n                                    </a>\n                                </td>\n                            </tr>\n                            <?php\n                        }\n                    }else{\n                        echo '<div class=\"alert alert-info\" role=\"alert\">No Pets added yet. Click <a href=\"add-pets.php\">here to add new pet</a></div>';\n                    }\n                    ?>\n\n                    </tbody>\n                </table>\n            </div>\n        </div>\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script>\n    $(document).on('click', '.remove-pet', function(){\n        var pet_id = $(this).attr('data-petid');\n        noty({\n            layout: 'bottomRight',\n            type: 'warning',\n            text: 'Are you sure you want to delete : <strong>'+ pet_id + \"</strong> ?\",\n            buttons: [\n                {addClass: 'btn btn-primary', text: 'Yes', onClick: function($noty) {\n                    $noty.close();\n                    $.ajax({\n                        type: \"POST\",\n                        url:  \"controllers/rest.php\",\n                        dataType: 'json',\n                        data: {api_type: 'deletePet', pet_id: pet_id},\n                        success: function (data, textStatus, jqXHR) {\n                            if (data.status == 'error') {\n                                var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                                window.setTimeout(function(){\n                                    window.location.href = 'logout.php';\n                                }, 1500);\n                            } else if (data.status == 'warning') {\n                                var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                            } else {\n                                var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                                window.setTimeout(function(){\n                                    window.location.href = 'pets.php';\n                                }, 1500);\n                            }\n                        }\n                    });\n\n                }\n                },\n                {addClass: 'btn btn-danger', text: 'No', onClick: function($noty) {\n                    $noty.close();\n                }\n                }\n            ]\n        });\n\n\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/docker/init.sh",
    "content": "#!/bin/bash\n\nenv >> /etc/environment\necho \". /etc/environment\" >> /etc/apache2/envvars\n/usr/sbin/apache2ctl -D FOREGROUND\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/kubernetes/admin-fe-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: admin-fe\n  labels:\n    name: admin-fe\nspec:\n  replicas: 1\n  selector:\n    name: admin-fe\n  template:\n    metadata:\n      labels:\n        name: admin-fe\n    spec:\n      containers:\n      - name: admin-fe\n        image: wso2msf4j/petstore-admin-fe:2.0.0\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n        - name: FE_FILE_SERVICE_HOST\n          value: fileserver\n        - name: FE_FILE_SERVICE_PORT\n          value: \"80\"\n        - name: FE_PET_SERVICE_HOST\n          value: pet\n        - name: FE_PET_SERVICE_PORT\n          value: \"80\"\n        - name: FE_USER_SERVICE_HOST\n          value: security\n        - name: FE_USER_SERVICE_PORT\n          value: \"80\"\n        - name: FE_FILE_SERVICE_NODE_PORT\n          value: \"31111\"\n        ports:\n        - containerPort: 80\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/kubernetes/admin-fe-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: admin-fe\n  labels:\n    name: admin-fe\nspec:\n  sessionAffinity: ClientIP\n  ports:\n    # the port that this service should serve on\n    - port: 80\n      targetPort: 80\n  type: NodePort\n  selector:\n    name: admin-fe\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/kubernetes/redis-master-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: redis-master\n  labels:\n    name: redis-master\nspec:\n  replicas: 1\n  selector:\n    name: redis-master\n  template:\n    metadata:\n      labels:\n        name: redis-master\n    spec:\n      containers:\n      - name: master\n        image: redis\n        ports:\n        - containerPort: 6379\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-admin/container/kubernetes/redis-master-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: redis-master\n  labels:\n    name: redis-master\nspec:\n  ports:\n    # the port that this service should serve on\n  - port: 6379\n    targetPort: 6379\n  selector:\n    name: redis-master\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/.gitignore",
    "content": "*.iml\n\n## Directory-based project format:\n.idea/\n\natlassian-ide-plugin.xml\nsoapui.log\nsoapui-errors.log\nglobal-groovy.log"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/README.md",
    "content": "# petstore-store-fe\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/Dockerfile",
    "content": "From ubuntu:14.04\n\nRUN sudo apt-get update && apt-get install -y apache2 php5 php5-curl php5-redis\n\nRUN sudo apt-get install -y openssh-server git vim \nRUN mkdir -p /var/run/sshd\nRUN echo 'root:stratos' | chpasswd\nRUN sed -i \"s/PermitRootLogin without-password/#PermitRootLogin without-password/\" /etc/ssh/sshd_config\nEXPOSE 22\n\nexpose 80\n\nRUN rm -fr /var/www/html/*\nCOPY html /var/www/html/\n#COPY php.ini /etc/php5/apache2/\nCOPY init.sh /opt/\nRUN chmod 755 /opt/init.sh\nENTRYPOINT /opt/init.sh \n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/cart.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"cart.php\"=>\"cart\");\n$cart = [];\nif(isset($_SESSION['cart'])){\n    $cart = $_SESSION['cart'];\n}\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"index.php\">\n                            <img src=\"images/pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"cart.php\">\n                            <img src=\"images/cart.png\" class=\"invert-png\">\n                            <span class=\"name\">My Cart</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <ul class=\"nav navbar-nav navbar-right\">\n                    <li class=\"visible-inline-block\">\n                        <a href=\"cart.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fa fa-shopping-cart fa-stack-1x\"></i>\n                                </span>\n                            Cart\n                            <span class=\"badge\"><?php\n                                if(isset($_SESSION['cart'])) {\n                                    echo count($_SESSION['cart']);\n                                }\n                                ?></span>\n                        </a>\n                    </li>\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Cart</h1>\n        </div>\n        <div class=\"row\">\n            <div class=\"col-md-6\">\n                <table class=\"table table-striped\">\n                    <?php\n                    if(is_array($cart) && (count($cart) > 0)) {\n                    ?>\n                    <thead>\n                    <tr>\n                        <th>Pet Id</th>\n                        <th>Image</th>\n                        <th>Price($)</th>\n                        <th></th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    <?php\n                    $total_price = 0;\n                    foreach ($cart as $json) {\n                        $total_price += $json['price'];\n                        $_SESSION['carttotal'] = $total_price;\n                        ?>\n                        <tr>\n                            <td><?php echo $json['id'] ?></td>\n                            <td><img src=\"<?php echo $json['image'] ?>\" /></td>\n                            <td><?php echo $json['price'] ?></td>\n                            <td>\n                                <a href=\"#\" class=\"btn padding-reduce-on-grid-view remove-pet\"\n                                   data-petid=\"<?php echo $json['id'] ?>\">\n                                <span class=\"fw-stack\">\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                    <i class=\"fw fw-delete fw-stack-1x\"></i>\n                                </span>\n                                </a>\n                            </td>\n                        </tr>\n                        <?php\n                    }\n                    ?>\n                     <tr>\n                         <td colspan=\"2\"><strong>Total Amount</strong></td>\n                         <td><strong><?php echo  $total_price; ?></strong></td>\n                         <td></td>\n                     </tr>\n                     <tr>\n                         <td colspan=\"2\"></td>\n                         <td colspan=\"2\">\n                             <a type=\"button\" id=\"pet-type-btn\" class=\"btn btn-default btn-primary\" href=\"checkout.php\">Proceed to Checkout</a>\n                         </td>\n                     </tr>\n                    <?php\n                    }else{\n                        echo '<div class=\"alert alert-info\" role=\"alert\">No Pets added yet. Click <a href=\"index.php\">here to add new pet</a></div>';\n                    }\n                    ?>\n\n                    </tbody>\n                </table>\n\n            </div>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n\n<script>\n    $(document).on('click', '.remove-pet', function(){\n       var petId = $(this).attr('data-petid');\n\n        $.ajax({\n            type: \"POST\",\n            url:  \"controllers/cart/cart.php\",\n            dataType: 'json',\n            data: {\n                cart_action: 'removeFromcart',\n                pet_id: petId\n            },\n            success: function (data, textStatus, jqXHR) {\n                if (data.status == 'error') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                    window.setTimeout(function(){\n                        window.location.href = 'logout.php';\n                    }, 1500);\n                } else if (data.status == 'warning') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                } else {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                    window.setTimeout(function(){\n                        window.location.href = 'cart.php';\n                    }, 1500);\n                }\n            }\n        });\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/checkout.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\nsession_start();\nif(!isset($_SESSION['username'])){\n    header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"checkout.php\"=>\"checkout\");\nif(isset($_SESSION['cart'])){\n    $cart = $_SESSION['cart'];\n}\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Checkout</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"index.php\">\n                            <img src=\"images/pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"cart.php\">\n                            <img src=\"images/cart.png\" class=\"invert-png\">\n                            <span class=\"name\">My Cart</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <ul class=\"nav navbar-nav navbar-right\">\n                    <li class=\"visible-inline-block\">\n                        <a href=\"cart.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fa fa-shopping-cart fa-stack-1x\"></i>\n                                </span>\n                            Cart\n                            <span class=\"badge\"><?php\n                                if(isset($_SESSION['cart'])) {\n                                    echo count($_SESSION['cart']);\n                                }\n                                ?></span>\n                        </a>\n                    </li>\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"page-header\" id=\"loading\">\n            <h1>Checkout</h1>\n        </div>\n        <div class=\"row\">\n            <div class=\"form-horizontal col-md-5\"\n                <div class=\"form-group\">\n                    <div class=\"col-sm-12\">\n                        <label for=\"card-number\" class=\"control-label\">Cart Number </label>\n                        <input type=\"text\" class=\"form-control\" id=\"card-number\" min=\"1\" max=\"1200\"\n                               placeholder=\"Card Number\" required=\"\" inputmode=\"numeric\" autocomplete=\"cc-number\">\n                    </div>\n                    <div class=\"col-sm-12\">\n                        <label for=\"card-holder-name\" class=\"control-label\">Cart Holder Name </label>\n                        <input type=\"text\" class=\"form-control\" id=\"card-holder-name\" min=\"1\" max=\"1200\"\n                               placeholder=\"Card Holder Name\" required=\"\">\n                    </div>\n                    <div class=\"col-sm-6\">\n                        <label for=\"card-holder-cvc\" class=\"control-label\">Cart Holder CVC </label>\n                        <input type=\"text\" class=\"form-control\" id=\"card-holder-cvc\" min=\"1\" max=\"1200\"\n                               placeholder=\"Card Holder CVC\" required=\"\">\n                    </div>\n                    <div class=\"clearfix\"></div>\n                    <div class=\"col-sm-6\">\n                        <br/>\n                        <a type=\"button\" id=\"place-order-btn\" class=\"btn btn-default btn-primary\">Place Order</a>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script>\n    $('#place-order-btn').click(function(){\n        var cardNumber = $('#card-number').val(),\n            cardHolderName = $('#card-holder-name').val(),\n            cardCvc = $('#card-holder-cvc').val();\n\n        $.ajax({\n            type: \"POST\",\n            url:  \"controllers/cart/cart.php\",\n            dataType: 'json',\n            data: {\n                cart_action: 'placeOrder',\n                card_number: cardNumber,\n                card_holder_name: cardHolderName,\n                card_cvc: cardCvc\n            },\n            success: function (data, textStatus, jqXHR) {\n                if (data.status == 'error') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                } else if (data.status == 'warning') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                } else {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                    window.setTimeout(function(){\n                        window.location.href = 'index.php';\n                    }, 1500);\n                }\n            }\n        });\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/config/config.php",
    "content": "<?php\n\ndefine(\"SECURITY_SERVER\", getenv('SECURITY_SERVICE_HOST'));\ndefine(\"SECURITY_SERVER_PORT\", getenv('SECURITY_SERVICE_PORT'));\n\ndefine(\"PET_SERVICE\", getenv('PET_SERVICE_HOST'));\ndefine(\"PET_SERVICE_PORT\", getenv('PET_SERVICE_PORT'));\n\ndefine(\"FILE_SERVER\", getenv('FILE_SERVICE_HOST'));\ndefine(\"FILE_SERVER_PORT\", getenv('FILE_SERVICE_PORT'));\ndefine(\"FILE_SERVER_NODE_PORT\", getenv('FILE_SERVICE_NODE_PORT'));\n\ndefine(\"TRANSACTION_SERVICE\", getenv('TXN_SERVICE_HOST'));\ndefine(\"TRANSACTION_SERVICE_PORT\", getenv('TXN_SERVICE_PORT'));\n\n?>\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/controllers/API/curl_api.php",
    "content": "<?php\n\n/*\n * method for get API authentication\n */\nfunction callAuthApiLogin($url, $data){\n\n    $curl = curl_init($url);\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_POST, true);\n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            'Content-Length: ' . strlen($data))\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n\n    if($info['http_code'] === 200){\n        $response = explode(\"\\n\",$header);\n        $searchword = 'X-JWT-Assertion';\n        $matches = array_filter($response, function($var) use ($searchword) {\n            return preg_match(\"/\\b$searchword\\b/i\", $var); });\n\n        session_start();\n        $_SESSION['username'] = 'user';\n        $_SESSION['authtoken'] = trim(explode(\"X-JWT-Assertion:\", array_values($matches)[0])[1]);\n        echo json_encode(array('status' => 1));\n    }else if($info['http_code'] === 401){\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n\n}\n\nfunction callAuthApigetPets($url, $token){\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200) {\n        return json_decode($body, true);\n    }else if($info['http_code'] === 401){\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n\nfunction addToCart($pet_id, $pet_price, $pet_image){\n    $pet_array = array(\n        'id' => $pet_id,\n        'price' => $pet_price,\n        'image' => $pet_image\n    );\n    if(isset($_SESSION['cart'])){\n        if(!in_array($pet_array, $_SESSION['cart'], true)){\n            array_push($_SESSION['cart'], $pet_array);\n            echo json_encode(array('status' => 'success', 'message' => 'Pet added to your cart successfully'));\n        }else{\n            echo json_encode(array('status' => 'warning', 'message' => 'Pet is already in your cart'));\n        }\n\n    }else{\n        $_SESSION['cart'] = array();\n    }\n\n}\n\nfunction removeFromCart($pet_id, $cart){\n\n    for($i = count($cart)-1; $i >= 0; $i--){\n        if(isset($cart[$i][\"id\"]) && ($cart[$i][\"id\"] == $pet_id)){\n            unset($cart[$i]);\n        }\n    }\n    $_SESSION['cart'] = $cart;\n    echo json_encode(array('status' => 'success', 'message' => 'Pet remove from your cart successfully'));\n}\n\nfunction placeOrder($url, $token, $data){\n\n    $curl = curl_init($url);\n    $token_assertion = 'X-JWT-Assertion: '.$token;\n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($curl, CURLOPT_POST, true);\n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);\n    curl_setopt($curl, CURLOPT_HTTPHEADER, array(\n            'Content-Type: application/json',\n            $token_assertion)\n    );\n    curl_setopt($curl, CURLOPT_HEADER, true);\n    $curl_response = curl_exec($curl);\n    $info = curl_getinfo($curl);\n    if ($curl_response === false) {\n        curl_close($curl);\n        die('error occured during curl exec. Additioanl info: ' . var_export($info));\n    }\n\n    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);\n    $header = substr($curl_response, 0, $header_size);\n    $body = substr($curl_response, $header_size);\n\n    if($info['http_code'] === 200){\n        unset($_SESSION['cart']);\n        echo json_encode(array('status' => 'success', 'message' => 'Your Order has been placed successfully..! Your transaction ID: '.$body));\n\n    }else if($info['http_code'] === 401) {\n        echo json_encode(array('status' => 'error', 'message' => 'User unauthorized'));\n    }else{\n        echo json_encode(array('status' => 'error', 'message' => 'Something went wrong'));\n    }\n}\n?>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/controllers/authentication/auth.php",
    "content": "<?php\ninclude('../API/curl_api.php');\ninclude('../../config/config.php');\n\n$username = htmlspecialchars($_POST[\"username\"]);\n$password = htmlspecialchars($_POST[\"password\"]);\n\n$auth_json = json_encode(array('name' => $username, 'password' => $password));\ncallAuthApiLogin('http://'.SECURITY_SERVER.':'.SECURITY_SERVER_PORT.'/user/login', $auth_json);\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/controllers/cart/cart.php",
    "content": "<?php\n//ajax call base rest call handler\nsession_start();\ninclude('../API/curl_api.php');\ninclude('../../config/config.php');\n\n$cart_action = htmlspecialchars($_POST[\"cart_action\"]);\n$token = preg_replace('/\\s+/', '', $_SESSION['authtoken']);\n\nswitch ($cart_action) {\n    case \"addTocart\":\n        $pet_id = htmlspecialchars($_POST[\"pet_id\"]);\n        $pet_price = htmlspecialchars($_POST[\"pet_price\"]);\n        $pet_image = htmlspecialchars($_POST[\"pet_image\"]);\n        addToCart($pet_id, $pet_price, $pet_image);\n        break;\n\n    case \"removeFromcart\":\n        $pet_id = htmlspecialchars($_POST[\"pet_id\"]);\n        $cart = $_SESSION['cart'];\n        removeFromCart($pet_id, $cart);\n        break;\n\n    case \"placeOrder\":\n        $url = 'http://'.TRANSACTION_SERVICE.':'.TRANSACTION_SERVICE_PORT.'/transaction/';\n        $cart = $_SESSION['cart'];\n        $cart_ids = array();\n        foreach($cart as $json ){\n            array_push($cart_ids, $json['id']);\n        }\n        $card_number = htmlspecialchars($_POST[\"card_number\"]);\n        $card_holder_name = htmlspecialchars($_POST[\"card_holder_name\"]);\n        $card_cvc = htmlspecialchars($_POST[\"card_cvc\"]);\n        $cart_total = $_SESSION['carttotal'];\n        $data = array(\n            \"pets\" => $cart_ids,\n            'total' => $cart_total,\n            'creditCard'=>array(\n                \"number\"=> $card_number,\n                \"name\"=>$card_holder_name,\n                \"cvc\"=>$card_cvc\n            )\n        );\n        placeOrder($url, $token, json_encode($data));\n        break;\n\n    default:\n        echo \"Invalid API call\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/css/custom.css",
    "content": "* {\n    outline: none !important;\n}\n@font-face {\n    font-family: 'Roboto Light';\n    font-style: 'normal';\n    font-weight: 300;\n    src: url('../fonts/Roboto/Roboto-Light-webfont.eot');\n    src: local('Roboto Light'), local('Roboto-Light-webfont'),\n    url('../fonts/Roboto/Roboto-Light-webfont.eot') format('embedded-opentype'),\n    url('../fonts/Roboto/Roboto-Light-webfont.woff') format('woff'),\n    url('../fonts/Roboto/Roboto-Light-webfont.ttf') format('truetype'),\n    url('../fonts/Roboto/Roboto-Light-webfont.svg#Roboto Light') format('svg');\n}\nbody {\n    background: #f9f9f9;\n    font-family: 'Roboto Light', Arial, Helvetica, sans-serif;\n    font-weight: 300;\n}\nheader {\n    background: #222222;\n    min-height: 50px;\n    position: relative;\n}\nheader .brand {\n    padding: 10px 0;\n}\nheader .auth {\n    margin: 0 -15px;\n}\nheader .brand a {\n    min-height: 24px;\n}\nheader .brand img.logo {\n    height: 24px;\n}\nheader .brand h1 {\n    display: inline-block;\n    line-height: 1;\n    font-weight: 500;\n    font-size: 17px;\n    margin: 0 0 0 5px;\n    color: #ffffff;\n    padding: 6px 0 0 0;\n    font-style: normal;\n    text-transform: uppercase;\n}\nheader .dropdown {\n    display: inline-block;\n    color: #ffffff;\n    padding: 6px 0;\n}\n.dropdown-menu {\n    border: none;\n    background: #e4e4e4;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.navbar-wrapper {\n    min-height: 50px;\n}\n.navbar {\n     background: #2c313b;\n     border: none;\n     margin-bottom: 0;\n     -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n     border-radius: 0;\n    height: 50px;\n }\n.navbar .container-fluid {\n    padding: 0;\n}\n.navbar-toggle {\n    border: none;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n}\n.navbar-menu-toggle {\n    float: left;\n    height: 50px;\n    padding: 0 8px;\n    line-height: 50px;\n    font-size: 18px;\n    background: #007d85;\n    color: #ffffff;\n}\n.navbar-menu-toggle {\n    float: left;\n    height: 50px;\n    padding: 0 8px;\n    line-height: 50px;\n    font-size: 18px;\n    background: #007d85;\n    color: #ffffff;\n}\n.navbar-menu-toggle:hover, .navbar-menu-toggle:focus, .navbar-menu-toggle:active {\n    color: #ffffff;\n    background: #004d52;\n}\n.navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand {\n    color: #ffffff;\n    margin-left: 0;\n    padding: 0 15px;\n    line-height: 50px;\n    text-transform: uppercase;\n    background: #21252c;\n}\nnav .navbar-nav li:hover{\n    background-color: #575B64;\n}\n.breadcrumb>li {\n    display: inline-block;\n}\n.breadcrumb > li > a > .icon {\n    padding-bottom: 3px;\n}\n.navbar > .container .navbar-brand a, .navbar > .container-fluid .navbar-brand a {\n    color: #ffffff;\n    font-size: 16px;\n}\n.navbar .container-fluid > .navbar-collapse .icon, .navbar .container-fluid > .navbar-header .icon, .navbar .container > .navbar-collapse .icon, .navbar .container > .navbar-header .icon {\n    margin-bottom: 4px;\n}\n.navbar > .container .navbar-brand a, .navbar > .container-fluid .navbar-brand a {\n    color: #ffffff;\n    font-size: 16px;\n}\n.breadcrumb>li {\n    display: inline-block;\n}\n.breadcrumb > li + li:before {\n    padding: 0 1px;\n}\n.navbar-default .navbar-nav > li > a {\n    color: #ffffff;\n    text-transform: uppercase;\n    padding: 0 15px;\n    line-height: 50px;\n}\n.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus, .navbar-default .navbar-nav > li > a:active {\n    color: #ffffff;\n}\n.page-content-wrapper, .page-content-wrapper[data-container-behaviour=static] {\n    -webkit-transition: all 0.5s ease;\n    -moz-transition: all 0.5s ease;\n    -ms-transition: all 0.5s ease;\n    -o-transition: all 0.5s ease;\n    transition: all 0.5s ease;\n    position: relative;\n    left: 0;\n    margin-left: 0;\n}\n\n.dropdown-menu.tiles {\n    padding: 4px;\n    max-width: 385px;\n}\n.dropdown-menu.dark {\n    background: #222222;\n    color: #ffffff;\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.dropdown-menu.tiles > li {\n    padding: 0;\n    list-style: none;\n    display: inline-block;\n    float: left;\n}\n.dropdown-menu.tiles li a {\n    display: block;\n    margin: 4px;\n    padding: 5px;\n    list-style: none;\n    width: 85px;\n    height: 85px;\n    text-align: center;\n    vertical-align: text-bottom;\n    color: #ffffff;\n    text-decoration: none;\n    background: #444444;\n}\n.dropdown-menu.dark.arrow:before {\n    border-bottom-color: #222222;\n}\n.dropdown-menu.arrow:before, .dropdown-menu.arrow.arrow-top-left:before {\n    position: absolute;\n    top: -6px;\n    left: 15px;\n    right: auto;\n    display: inline-block;\n    border-right: 6px solid transparent;\n    border-bottom: 6px solid #e4e4e4;\n    border-left: 6px solid transparent;\n    content: '';\n}\n.dropdown-menu.tiles li a .icon {\n    display: block;\n    font-size: 35px;\n    margin: 3px 0 7px;\n    height: 35px;\n}\n.dropdown-menu.tiles li a .name {\n    display: block;\n    line-height: 14px;\n    font-size: 12px;\n    height: 28px;\n    overflow: hidden;\n}\n\nfooter {\n    position: fixed;\n    bottom: 0;\n    width: 100%;\n    min-height: 40px;\n    overflow: hidden;\n    color: #cbcbcb;\n    background: #222222;\n    z-index: 1000;\n}\nfooter > .container p, footer > .container-fluid p {\n    line-height: 40px;\n    margin-bottom: 0;\n}\nfooter a, footer a:hover {\n    color: #cbcbcb;\n}\n/*login page */\n.col-centered {\n    float: none;\n    margin: 0 auto;\n}\n.wr-login {\n    padding-top: 50px;\n}\n.uppercase {\n    text-transform: uppercase;\n}\n.blue-bg {\n    background-color: #3a9ecf !important;\n}\n.padding-double {\n    padding: 20px;\n}\n.boarder-bottom-blue {\n    border-bottom: 2px solid #006596;\n}\n.boarder-all {\n    border: 1px solid #d8d8d8;\n    background: #FFF;\n    margin-top: -10px;\n}\n.wr-login input[type=text], .wr-login input[type=password] {\n    border: 1px #d2d2d2 solid;\n    width: 100%;\n    height: 100%;\n    padding: 6px 10px;\n    z-index: 1;\n    -webkit-appearance: none;\n    line-height: 30px;\n    border-radius: 0px;\n}\nbutton.grey-bg:hover {\n    background-color: #3A9ECF;\n}\n.wr-btn {\n    font-weight: normal;\n    font-size: 13px;\n    color: #fff;\n    background: #5d81d2;\n    padding: 10px 10px;\n    display: inline-block;\n    border: none;\n}\nbutton.grey-bg {\n    background-color: #222222;\n}\n.white {\n    color: #FFF;\n}\n\n/* main page content */\n.thumbnail-overide{\n    border-radius: 0px;\n}\n.thumbnail-overide>.caption h3{\n    font-size: 1.2em;\n    text-align: center;\n}\na.thumbnail-overide:hover{\n   text-decoration: none;\n}\n.thumbnail-overide img{\n    margin-top: 1em;\n}\n\n.page-header {\n    margin: 0 0 20px;\n}\n\n.page-header > h1 {\n    margin-top: 0;\n    font-weight: 300;\n    font-size: 1.5em;\n}\n.form-control, .btn {\n    -webkit-border-radius: 0;\n    -moz-border-radius: 0;\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n}\n.btn-primary {\n    color: #ffffff;\n    background-color: #2c313b;\n    border-color: #2c313b;\n}\n.btn-primary:hover {\n    background-color: #424958;\n}\na.btn:hover, .btn:hover, a.btn:focus, .btn:focus {\n    text-decoration: none;\n    background: #7B7B7B;\n}\n.invert-png{\n    -webkit-filter: invert(1);\n    filter: invert(1);\n    margin-bottom: 10px;\n    width: 50px;\n}\n\n.thumbnail:hover .ct-product-meta {\n    bottom: 0;\n}\n\n.thumbnail .ct-product-meta {\n    -webkit-transition: all 0.2s ease-in-out;\n    transition: all 0.2s ease-in-out;\n    position: absolute;\n    height: 50px;\n    width: 100%;\n    left: 0px;\n    bottom: -50px;\n    text-align: center;\n    background: #2b8be9;\n}\n.thumbnail .ct-product-meta .ct-product-button {\n    height: 50px;\n    width: 100%;\n    line-height: 50px;\n    padding: 0;\n    color: #fff;\n}\n.thumbnail{\n    overflow: hidden;\n    min-height: 200px;\n    max-height: 200px;\n    position: relative;\n    border-radius: 0px;\n\n}\n\n.ct-product-button:hover, a.ct-product-button:focus, .ct-product-button:focus {\n    text-decoration: none;\n    background: #6BABEA !important;\n}\n.pet-price{\n    font-size: 1.3em;\n}\n.pet-image{\n    width:100%;\n}"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/includes/header.php",
    "content": "<!-- header -->\n<header class=\"header header-default\">\n    <div class=\"container-fluid\">\n        <div class=\"pull-left brand float-remove-xs text-center-xs\">\n            <a href=\"#\">\n                <img src=\"images/logo-inverse.svg\" alt=\"wso2\" title=\"wso2\" class=\"logo\">\n                <h1>WSO2 Pet Store</h1>\n            </a>\n        </div>\n        <div class=\"pull-right auth float-remove-xs text-center-xs\">\n            <a href=\"#\" class=\"dropdown\" data-toggle=\"dropdown\">\n                <span class=\"hidden-xs add-padding-left-3x\">User <span class=\"caret\"></span></span>\n               <span class=\"icon fw-stack fw-lg\">\n                   <i class=\"fw fw-user fw-stack-1x\"></i>\n               </span>\n            </a>\n            <ul class=\"dropdown-menu float-remove-xs position-static-xs text-center-xs remove-margin-xs slideInDown\" role=\"menu\">\n                <li class=\"dropdown-header visible-xs\">User <span class=\"caret\"></span></li>\n                <li class=\"divider visible-xs\"></li>\n                <li><a href=\"logout.php\">Sign out</a></li>\n            </ul>\n\n        </div>\n    </div>\n</header>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/includes/navbar.php",
    "content": "<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"pet-types.php\">\n                            <img src=\"images/list-pet-type.png\" class=\"invert-png\">\n                            <span class=\"name\">Pet Types</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"pets.php\">\n                            <img src=\"images/list-pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <?php\n                if(isset($action_buttons)){\n                ?>\n                <ul class=\"nav navbar-nav\">\n                    <?php\n                    if($action_buttons) {\n                        ?>\n                        <li>\n                            <a href=\"layout.html\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fw fw-laptop fw-stack-1x\"></i>\n                                    <i class=\"fw fw-ring fw-stack-2x\"></i>\n                                </span>\n                                Main Wrapper\n                            </a>\n                        </li>\n                        <?php\n                    }\n                    ?>\n                </ul>\n                <?php\n                }\n                ?>\n\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/index.php",
    "content": "<?php\ninclude('controllers/API/curl_api.php');\ninclude('config/config.php');\nsession_start();\nif(!isset($_SESSION['username'])){\n   header(\"location:login.php\");\n}\n//return page breadcrumbs\n$breadcrumbs = array(\"\");\n$url = 'http://'.PET_SERVICE.':'.PET_SERVICE_PORT.'/pet/all';\n$get_pets = callAuthApigetPets($url, preg_replace('/\\s+/', '', $_SESSION['authtoken']));\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<?php\ninclude('includes/header.php');\n?>\n\n<!-- navbar -->\n<div class=\"navbar-wrapper\">\n    <nav class=\"navbar navbar-default\" data-spy=\"affix\" data-offset-top=\"50\" data-offset-bottom=\"40\">\n        <div class=\"container-fluid\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-menu-toggle\" data-toggle=\"dropdown\">\n                        <span class=\"icon fw-stack\">\n                            <i class=\"fw fw-tiles fw-stack-1x\"></i>\n                        </span>\n                </a>\n                <ul class=\"dropdown-menu tiles arrow dark add-margin-1x\" role=\"menu\">\n                    <li>\n                        <a href=\"index.php\">\n                            <img src=\"images/pets.png\" class=\"invert-png\">\n                            <span class=\"name\">Pets</span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"cart.php\">\n                            <img src=\"images/cart.png\" class=\"invert-png\">\n                            <span class=\"name\">My Cart</span>\n                        </a>\n                    </li>\n                </ul>\n                <ol class=\"breadcrumb navbar-brand\">\n                    <li><a href=\"index.php\"><i class=\"icon fw fw-home\"></i></a></li>\n                    <?php\n                    if($breadcrumbs){\n                        foreach ($breadcrumbs as $key => $value) {\n                            echo '<li><a href=\"'.$key.'\">'.$value.'</a></li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <div id=\"navbar\" class=\"collapse navbar-collapse\">\n                <ul class=\"nav navbar-nav navbar-right\">\n                    <li class=\"visible-inline-block\">\n                        <a href=\"cart.php\">\n                                <span class=\"icon fw-stack\">\n                                    <i class=\"fa fa-shopping-cart fa-stack-1x\"></i>\n                                </span>\n                            Cart\n                            <span class=\"badge\"><?php\n                                if(isset($_SESSION['cart'])) {\n                                   echo count($_SESSION['cart']);\n                                }\n                                ?></span>\n                        </a>\n                    </li>\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n</div>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n        <div class=\"clearfix\"></div>\n        <div class=\"row\">\n            <?php\n            foreach ($get_pets as $json) {\n                ?>\n                <div class=\"col-xs-6 col-md-2\">\n                    <div class=\"thumbnail\">\n                        <img src=\"<?php echo 'http://'.$_SERVER[\"SERVER_NAME\"].':'.FILE_SERVER_NODE_PORT.'/'.$json['image'] ?>\"\n                             alt=\"<?php echo $json['image'] ?>\" class=\"pet-image\">\n\n                        <div class=\"caption\">\n                            <h3 class=\"pet-price\">Price: $<?php echo $json['price'] ?></h3>\n\n                            <!--<p>\n                                <a href=\"#\" class=\"btn btn-primary\" role=\"button\">More</a>\n                                <a href=\"#\" class=\"btn btn-default\" role=\"button\">Add to cart</a>\n                            </p>-->\n                            <div class=\"ct-product-meta\">\n                                <a href=\"#\" class=\"btn btn-motive ct-product-button\"\n                                   data-id=\"<?php echo $json['id'] ?>\"\n                                   data-price=\"<?php echo $json['price'] ?>\">\n                                    <i class=\"fa fa-shopping-cart\"></i> Add to Cart\n                                </a>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <?php\n            }\n            ?>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script>\n    $(document).on('click', '.ct-product-button', function(){\n        var petId = $(this).attr('data-id'),\n            petPrice = $(this).attr('data-price'),\n            petImage = $(this).parent().parent().parent().find('img').attr('src');\n\n        $.ajax({\n            type: \"POST\",\n            url:  \"controllers/cart/cart.php\",\n            dataType: 'json',\n            data: {\n                cart_action: 'addTocart',\n                pet_id: petId,\n                pet_price: petPrice,\n                pet_image: petImage\n\n            },\n            success: function (data, textStatus, jqXHR) {\n                if (data.status == 'error') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'error'});\n                    window.setTimeout(function(){\n                        window.location.href = 'logout.php';\n                    }, 1500);\n                } else if (data.status == 'warning') {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'warning'});\n                } else {\n                    var n = noty({text: data.message, layout: 'bottomRight', type: 'success'});\n                    window.setTimeout(function(){\n                        window.location.href = 'index.php';\n                    }, 1500);\n                }\n            }\n        });\n    });\n</script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/js/custom.js",
    "content": ""
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/js/login.js",
    "content": "$(document).ready(function () {\n    $('#username').focus(); //set user cursor into username\n    var username = $('#username'), // Get the username field\n        password = $('#password'), // Get the password field\n        form_error = $('.form-error');\n\n    //handle form valiadation\n    var isValidForm = function () {\n        if (username.val() == \"\" || password.val() == \"\") {\n            var error = \"Enter your username\";\n            if (username.val() == \"\") {\n                username.parent().addClass('has-error has-feedback');\n                username.parent().append('<span class=\"glyphicon glyphicon-remove form-control-feedback\"></span>');\n            } else {\n                username.parent().removeClass('has-error has-feedback');\n                username.parent().find('span').empty().remove();\n                error = \"\";\n            }\n\n            if (password.val() == \"\") {\n                password.parent().addClass('has-error has-feedback');\n                password.parent().append('<span class=\"glyphicon glyphicon-remove form-control-feedback\"></span>');\n\n                if (error == \"\") {\n                    error = \"Enter your password\";\n                } else {\n                    error = \"Enter your username and password\";\n                }\n            } else {\n                password.parent().removeClass('has-error has-feedback');\n                password.parent().find('span').empty().remove();\n            }\n            form_error.html(error).show();\n            return false;\n        } else {\n            username.parent().removeClass('has-error has-feedback');\n            password.parent().removeClass('has-error has-feedback');\n            password.parent().find('span').empty().remove();\n            username.parent().find('span').empty().remove();\n            form_error.hide();\n            return true;\n        }\n    };\n\n    //handle login ajax request\n    function loginCheck(btn) {\n        btn.button('loading');\n        if (!isValidForm()) {\n            btn.button('reset');\n        } else {\n            $.ajax({\n                type: \"POST\",\n                url:  \"controllers/authentication/auth.php\",\n                dataType: 'json',\n                data: {username: username.val(), password: password.val()},\n                success: function (data) {\n                    if (data.status === 1) {\n                            window.location = 'index.php';\n                    } else {\n                        form_error.show().html(data.message);\n                    }\n                }\n            })\n                .always(function () {\n                    btn.button('reset');\n                });\n        }\n    }\n\n    username.keyup(function (e) {\n        if(e.keyCode == 13) {\n            return;\n        }\n        isValidForm();\n    });\n    password.keyup(function (e) {\n        if(e.keyCode == 13) {\n            return;\n        }\n        isValidForm();\n    });\n\n    // handle the submit button click event\n    $('#submit-btn').click(function () {\n        var btn = $(this); //get current clicked button\n        loginCheck(btn);\n    });// end of submit button\n\n    //handle key \"Enter\" press\n    $(document).keypress(function (e) {\n        if (e.keyCode == 13) {\n            var btn = $('#submit-btn');\n            loginCheck(btn);\n        }\n    });\n});"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/font-awesome_4.3.0/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.3.0');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  transform: translate(0, 0);\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-genderless:before,\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/font-wso2_1.2/css/font-wso2.css",
    "content": "@font-face {\n    font-family: 'font-wso2';\n    src:url('../fonts/font-wso2.eot?k4i0fx');\n    src:url('../fonts/font-wso2.eot?#iefixk4i0fx') format('embedded-opentype'),\n    url('../fonts/font-wso2.ttf?k4i0fx') format('truetype'),\n    url('../fonts/font-wso2.woff?k4i0fx') format('woff'),\n    url('../fonts/font-wso2.svg?k4i0fx#font-wso2') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n\n.fw, [class^=\"fw-\"], [class*=\" fw-\"] {\n    display: inline-block;\n    font: normal normal normal 14px/1 font-wso2;\n    font-size: inherit;\n    speak: none;\n    font-style: normal;\n    font-weight: normal;\n    font-variant: normal;\n    text-transform: none;\n    vertical-align: middle;\n\n    /* Better Font Rendering =========== */\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    text-rendering: auto;\n    transform: translate(0, 0);\n}\n\n/* ========================================================================\n * font options\n * ======================================================================== */\n\n.fw-lg {\n    font-size: 1.33333333em;\n    line-height: 0.75em;\n    vertical-align: -15%;\n}\n.fw-2x {\n    font-size: 2em;\n}\n.fw-3x {\n    font-size: 3em;\n}\n.fw-4x {\n    font-size: 4em;\n}\n.fw-5x {\n    font-size: 5em;\n}\n.fw-fw {\n    width: 1.28571429em;\n    text-align: center;\n}\n.fw-ul {\n    padding-left: 0;\n    margin-left: 2.14285714em;\n    list-style-type: none;\n}\n.fw-ul > li {\n    position: relative;\n}\n.fw-li {\n    position: absolute;\n    left: -2.14285714em;\n    width: 2.14285714em;\n    top: 0.14285714em;\n    text-align: center;\n}\n.fw-li.fw-lg {\n    left: -1.85714286em;\n}\n.fw-border {\n    padding: .2em .25em .15em;\n    border: solid 0.08em #eeeeee;\n    border-radius: .1em;\n}\n.fw-background {\n    background: #888;\n    border-radius: .3em;\n    padding: .4em .50em .45em;\n}\n.fw-pull-left {\n    float: left;\n}\n.fw-pull-right {\n    float: right;\n}\n.fw.fw-pull-left {\n    margin-right: .3em;\n}\n.fw.fw-pull-right {\n    margin-left: .3em;\n}\n.fw-spin {\n    -webkit-animation: fw-spin 2s infinite linear;\n    animation: fw-spin 2s infinite linear;\n}\n@-webkit-keyframes fw-spin {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}\n@keyframes fw-spin {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    100% {\n        -webkit-transform: rotate(359deg);\n        transform: rotate(359deg);\n    }\n}\n.fw-pulse {\n    -webkit-animation: fw-pulse 2s ease-out infinite;\n    animation: fw-pulse 2s ease-out infinite;\n}\n@-webkit-keyframes fw-pulse {\n    0%, 30%  {\n        opacity: 0.3;\n    }\n    40% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0.3;\n    }\n}\n@keyframes fw-pulse {\n    0%, 30%  {\n        opacity: 0.3;\n    }\n    40% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0.3;\n    }\n}\n.fw-rotate-90 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n    -webkit-transform: rotate(90deg);\n    -ms-transform: rotate(90deg);\n    transform: rotate(90deg);\n}\n.fw-rotate-180 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n    -webkit-transform: rotate(180deg);\n    -ms-transform: rotate(180deg);\n    transform: rotate(180deg);\n}\n.fw-rotate-270 {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n    -webkit-transform: rotate(270deg);\n    -ms-transform: rotate(270deg);\n    transform: rotate(270deg);\n}\n.fw-flip-horizontal {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n    -webkit-transform: scale(-1, 1);\n    -ms-transform: scale(-1, 1);\n    transform: scale(-1, 1);\n}\n.fw-flip-vertical {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n    -webkit-transform: scale(1, -1);\n    -ms-transform: scale(1, -1);\n    transform: scale(1, -1);\n}\n:root .fw-rotate-90,\n:root .fw-rotate-180,\n:root .fw-rotate-270,\n:root .fw-flip-horizontal,\n:root .fw-flip-vertical {\n    filter: none;\n}\n.fw-stack {\n    position: relative;\n    display: inline-block;\n    width: 2em;\n    height: 2em;\n    line-height: 2em;\n    vertical-align: middle;\n}\n.fw-stack-1x,\n.fw-stack-2x {\n    position: absolute;\n    left: 0;\n    width: 100%;\n    text-align: center;\n}\n.fw-stack-1x {\n    line-height: inherit;\n}\n.fw-stack-2x {\n    font-size: 2em;\n}\n.fw-inverse {\n    color: #ffffff;\n}\n.fw-number {\n    line-height: 1.8em;\n}\n\n/* ========================================================================\n * font icons\n * ======================================================================== */\n\n.fw-mouse-pointer:before {\n    content: \"\\e6b1\";\n}\n.fw-pointer:before {\n    content: \"\\e6b2\";\n}\n.fw-hand:before {\n    content: \"\\e6b3\";\n}\n.fw-question-mark:before {\n    content: \"\\e6b4\";\n}\n.fw-airplay:before {\n    content: \"\\e600\";\n}\n.fw-apn:before {\n    content: \"\\e602\";\n}\n.fw-vpn:before {\n    content: \"\\e603\";\n}\n.fw-apple:before {\n    content: \"\\e604\";\n}\n.fw-windows:before {\n    content: \"\\e605\";\n}\n.fw-android:before {\n    content: \"\\e606\";\n}\n.fw-wifi:before {\n    content: \"\\e607\";\n}\n.fw-battery:before {\n    content: \"\\e60a\";\n}\n.fw-camera:before {\n    content: \"\\e613\";\n}\n.fw-notification:before {\n    content: \"\\e60b\";\n}\n.fw-settings:before {\n    content: \"\\e66f\";\n}\n.fw-send:before {\n    content: \"\\e66a\";\n}\n.fw-bookmark:before {\n    content: \"\\e60d\";\n}\n.fw-bug:before {\n    content: \"\\e611\";\n}\n.fw-clock:before {\n    content: \"\\e61d\";\n}\n.fw-calendar:before {\n    content: \"\\e612\";\n}\n.fw-add:before {\n    content: \"\\e615\";\n}\n.fw-minus:before {\n    content: \"\\e616\";\n}\n.fw-check:before {\n    content: \"\\e617\";\n}\n.fw-cancel:before {\n    content: \"\\e618\";\n}\n.fw-list:before {\n    content: \"\\e64c\";\n}\n.fw-checklist:before {\n    content: \"\\e619\";\n}\n.fw-grid:before {\n    content: \"\\e638\";\n}\n.fw-dots:before {\n    content: \"\\e629\";\n}\n.fw-menu:before {\n    content: \"\\e651\";\n}\n.fw-tiles:before {\n    content: \"\\e681\";\n}\n.fw-clear:before {\n    content: \"\\e61b\";\n}\n.fw-clear-passcode:before {\n    content: \"\\e61c\";\n}\n.fw-enterprise-wipe:before {\n    content: \"\\e62f\";\n}\n.fw-cloud:before {\n    content: \"\\e61e\";\n}\n.fw-contact:before {\n    content: \"\\e620\";\n}\n.fw-copy:before {\n    content: \"\\e621\";\n}\n.fw-paste:before {\n    content: \"\\e658\";\n}\n.fw-undo:before {\n    content: \"\\e683\";\n}\n.fw-redo:before {\n    content: \"\\e65d\";\n}\n.fw-dashboard:before {\n    content: \"\\e622\";\n}\n.fw-view:before {\n    content: \"\\e691\";\n}\n.fw-focus:before {\n    content: \"\\e6b5\";\n}\n.fw-delete:before {\n    content: \"\\e624\";\n}\n.fw-save:before {\n    content: \"\\e665\";\n}\n.fw-register:before {\n    content: \"\\e65e\";\n}\n.fw-change-passcode:before {\n    content: \"\\e614\";\n}\n.fw-edit:before {\n    content: \"\\e62c\";\n}\n.fw-sign-up:before {\n    content: \"\\e671\";\n}\n.fw-deploy:before {\n    content: \"\\e625\";\n}\n.fw-dial-up:before {\n    content: \"\\e627\";\n}\n.fw-dss:before {\n    content: \"\\e62a\";\n}\n.fw-ebook:before {\n    content: \"\\e62b\";\n}\n.fw-import:before {\n    content: \"\\e63c\";\n}\n.fw-export:before {\n    content: \"\\e631\";\n}\n.fw-factory-reset:before {\n    content: \"\\e632\";\n}\n.fw-file-browse:before {\n    content: \"\\e633\";\n}\n.fw-grouping:before {\n    content: \"\\e6af\";\n}\n.fw-folder:before {\n    content: \"\\e6b6\";\n}\n.fw-filter:before {\n    content: \"\\e634\";\n}\n.fw-sort:before {\n    content: \"\\e673\";\n}\n.fw-sort-up:before {\n    content: \"\\e64b\";\n}\n.fw-sort-down:before {\n    content: \"\\e663\";\n}\n.fw-faq:before {\n    content: \"\\e6b7\";\n}\n.fw-message:before {\n    content: \"\\e635\";\n}\n.fw-forum:before {\n    content: \"\\e636\";\n}\n.fw-chat:before {\n    content: \"\\e6b8\";\n}\n.fw-mail:before {\n    content: \"\\e64f\";\n}\n.fw-invitation:before {\n    content: \"\\e63f\";\n}\n.fw-usb-drive:before {\n    content: \"\\e68e\";\n}\n.fw-hdd:before {\n    content: \"\\e639\";\n}\n.fw-home:before {\n    content: \"\\e63a\";\n}\n.fw-hour-glass:before {\n    content: \"\\e63b\";\n}\n.fw-incoming-call:before {\n    content: \"\\e63d\";\n}\n.fw-key:before {\n    content: \"\\e647\";\n}\n.fw-lifecycle:before {\n    content: \"\\e64a\";\n}\n.fw-list-sort:before {\n    content: \"\\e64d\";\n}\n.fw-lock:before {\n    content: \"\\e64e\";\n}\n.fw-map-location:before {\n    content: \"\\e650\";\n}\n.fw-laptop:before {\n    content: \"\\e648\";\n}\n.fw-mobile:before {\n    content: \"\\e652\";\n}\n.fw-ringing:before {\n    content: \"\\e694\";\n}\n.fw-computer:before {\n    content: \"\\e653\";\n}\n.fw-devices:before {\n    content: \"\\e626\";\n}\n.fw-mute:before {\n    content: \"\\e655\";\n}\n.fw-unmute:before {\n    content: \"\\e6ae\";\n}\n.fw-ok:before {\n    content: \"\\e657\";\n}\n.fw-error:before {\n    content: \"\\e630\";\n}\n.fw-circle:before {\n    content: \"\\e61a\";\n}\n.fw-ring:before {\n    content: \"\\e61f\";\n}\n.fw-pdf:before {\n    content: \"\\e659\";\n}\n.fw-ms-document:before {\n    content: \"\\e654\";\n}\n.fw-pie-chart:before {\n    content: \"\\e65a\";\n}\n.fw-bar-chart:before {\n    content: \"\\e6b0\";\n}\n.fw-publish:before {\n    content: \"\\e65c\";\n}\n.fw-resource:before {\n    content: \"\\e660\";\n}\n.fw-rules:before {\n    content: \"\\e664\";\n}\n.fw-scep:before {\n    content: \"\\e666\";\n}\n.fw-security:before {\n    content: \"\\e669\";\n}\n.fw-search:before {\n    content: \"\\e668\";\n}\n.fw-sequence:before {\n    content: \"\\e66b\";\n}\n.fw-servers:before {\n    content: \"\\e66c\";\n}\n.fw-ldap:before {\n    content: \"\\e649\";\n}\n.fw-database:before {\n    content: \"\\e623\";\n}\n.fw-hardware:before {\n    content: \"\\e6a9\";\n}\n.fw-signal:before {\n    content: \"\\e6b9\";\n}\n.fw-raspberry:before {\n    content: \"\\e6aa\";\n}\n.fw-arduino:before {\n    content: \"\\e6ab\";\n}\n.fw-share:before {\n    content: \"\\e670\";\n}\n.fw-star:before {\n    content: \"\\e674\";\n}\n.fw-coins:before {\n    content: \"\\e6ba\";\n}\n.fw-statistics:before {\n    content: \"\\e675\";\n}\n.fw-store:before {\n    content: \"\\e676\";\n}\n.fw-subscribe:before {\n    content: \"\\e677\";\n}\n.fw-fan:before {\n    content: \"\\e6bb\";\n}\n.fw-light:before {\n    content: \"\\e6bc\";\n}\n.fw-subscribed-calendar:before {\n    content: \"\\e678\";\n}\n.fw-tag:before {\n    content: \"\\e67a\";\n}\n.fw-tasks:before {\n    content: \"\\e67b\";\n}\n.fw-blank-document:before {\n    content: \"\\e60c\";\n}\n.fw-document:before {\n    content: \"\\e628\";\n}\n.fw-text:before {\n    content: \"\\e67c\";\n}\n.fw-policy:before {\n    content: \"\\e67d\";\n}\n.fw-security-policy:before {\n    content: \"\\e67e\";\n}\n.fw-throttling-policy:before {\n    content: \"\\e67f\";\n}\n.fw-ticked-box:before {\n    content: \"\\e680\";\n}\n.fw-uncheck:before {\n    content: \"\\e682\";\n}\n.fw-upload:before {\n    content: \"\\e68c\";\n}\n.fw-download:before {\n    content: \"\\e65f\";\n}\n.fw-up:before {\n    content: \"\\e684\";\n}\n.fw-down:before {\n    content: \"\\e685\";\n}\n.fw-left:before {\n    content: \"\\e686\";\n}\n.fw-right:before {\n    content: \"\\e687\";\n}\n.fw-up-arrow:before {\n    content: \"\\e688\";\n}\n.fw-down-arrow:before {\n    content: \"\\e689\";\n}\n.fw-left-arrow:before {\n    content: \"\\e68a\";\n}\n.fw-right-arrow:before {\n    content: \"\\e68b\";\n}\n.fw-endpoint:before {\n    content: \"\\e62d\";\n}\n.fw-uri:before {\n    content: \"\\e68d\";\n}\n.fw-broken-link:before {\n    content: \"\\e610\";\n}\n.fw-user:before {\n    content: \"\\e68f\";\n}\n.fw-add-user:before {\n    content: \"\\e690\";\n}\n.fw-refresh:before {\n    content: \"\\e692\";\n}\n.fw-warning:before {\n    content: \"\\e693\";\n}\n.fw-info:before {\n    content: \"\\e63e\";\n}\n.fw-block:before {\n    content: \"\\e695\";\n}\n.fw-bpmn:before {\n    content: \"\\e60f\";\n}\n.fw-schema:before {\n    content: \"\\e667\";\n}\n.fw-organization:before {\n    content: \"\\e6ac\";\n}\n.fw-public:before {\n    content: \"\\e6ad\";\n}\n.fw-bpel:before {\n    content: \"\\e60e\";\n}\n.fw-application:before {\n    content: \"\\e608\";\n}\n.fw-applications:before {\n    content: \"\\e609\";\n}\n.fw-public-app:before {\n    content: \"\\e65b\";\n}\n.fw-enterprise-app:before {\n    content: \"\\e62e\";\n}\n.fw-web-app:before {\n    content: \"\\e696\";\n}\n.fw-globe:before {\n    content: \"\\e697\";\n}\n.fw-webclip:before {\n    content: \"\\e698\";\n}\n.fw-proxy:before {\n    content: \"\\e699\";\n}\n.fw-web-service:before {\n    content: \"\\e69a\";\n}\n.fw-website:before {\n    content: \"\\e69b\";\n}\n.fw-gadget:before {\n    content: \"\\e637\";\n}\n.fw-api:before {\n    content: \"\\e601\";\n}\n.fw-rest-api:before {\n    content: \"\\e661\";\n}\n.fw-rest-service:before {\n    content: \"\\e662\";\n}\n.fw-jaxrs:before {\n    content: \"\\e645\";\n}\n.fw-service:before {\n    content: \"\\e66d\";\n}\n.fw-service-provider:before {\n    content: \"\\e66e\";\n}\n.fw-java-spring:before {\n    content: \"\\e644\";\n}\n.fw-jquery:before {\n    content: \"\\e646\";\n}\n.fw-swagger:before {\n    content: \"\\e679\";\n}\n.fw-java:before {\n    content: \"\\e641\";\n}\n.fw-javaee:before {\n    content: \"\\e642\";\n}\n.fw-javascript:before {\n    content: \"\\e643\";\n}\n.fw-jaggery:before {\n    content: \"\\e640\";\n}\n.fw-nodejs:before {\n    content: \"\\e656\";\n}\n.fw-xml:before {\n    content: \"\\e69c\";\n}\n.fw-soap:before {\n    content: \"\\e672\";\n}\n.fw-html:before {\n    content: \"\\e69d\";\n}\n.fw-war:before {\n    content: \"\\e69e\";\n}\n.fw-xacml:before {\n    content: \"\\e69f\";\n}\n.fw-wsdl:before {\n    content: \"\\e6a0\";\n}\n.fw-wadl:before {\n    content: \"\\e6a1\";\n}\n.fw-xq:before {\n    content: \"\\e6a2\";\n}\n.fw-xsd:before {\n    content: \"\\e6a3\";\n}\n.fw-xslt:before {\n    content: \"\\e6a4\";\n}\n.fw-zoom-in:before {\n    content: \"\\e6a5\";\n}\n.fw-zoom-out:before {\n    content: \"\\e6a6\";\n}\n.fw-wso2-logo:before {\n    content: \"\\e6a7\";\n}\n.fw-wso2:before {\n    content: \"\\e6a8\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/jquery_1.11.3/jquery-1.11.3.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/jquery.noty.js",
    "content": "/*!\n @package noty - jQuery Notification Plugin\n @version version: 2.3.5\n @contributors https://github.com/needim/noty/graphs/contributors\n\n @documentation Examples and Documentation - http://needim.github.com/noty/\n\n @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php\n */\n\n    if(typeof Object.create !== 'function') {\n        Object.create = function(o) {\n            function F() {\n            }\n\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    var NotyObject = {\n\n        init: function(options) {\n\n            // Mix in the passed in options with the default options\n            this.options = $.extend({}, $.noty.defaults, options);\n\n            this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];\n\n            if($.noty.themes[this.options.theme])\n                this.options.theme = $.noty.themes[this.options.theme];\n            else\n                options.themeClassName = this.options.theme;\n\n            delete options.layout;\n            delete options.theme;\n\n            this.options = $.extend({}, this.options, this.options.layout.options);\n            this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));\n\n            this.options = $.extend({}, this.options, options);\n\n            // Build the noty dom initial structure\n            this._build();\n\n            // return this so we can chain/use the bridge with less code.\n            return this;\n        }, // end init\n\n        _build: function() {\n\n            // Generating noty bar\n            var $bar = $('<div class=\"noty_bar noty_type_' + this.options.type + '\"></div>').attr('id', this.options.id);\n            $bar.append(this.options.template).find('.noty_text').html(this.options.text);\n\n            this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;\n\n            if(this.options.themeClassName)\n                this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type);\n\n            // Set buttons if available\n            if(this.options.buttons) {\n\n                // If we have button disable closeWith & timeout options\n                this.options.closeWith = [];\n                this.options.timeout = false;\n\n                var $buttons = $('<div/>').addClass('noty_buttons');\n\n                (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);\n\n                var self = this;\n\n                $.each(this.options.buttons, function(i, button) {\n                    var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text).attr('id', button.id ? button.id : 'button-' + i)\n                        .appendTo(self.$bar.find('.noty_buttons'))\n                        .on('click', function(event) {\n                            if($.isFunction(button.onClick)) {\n                                button.onClick.call($button, self, event);\n                            }\n                        });\n                });\n            }\n\n            // For easy access\n            this.$message = this.$bar.find('.noty_message');\n            this.$closeButton = this.$bar.find('.noty_close');\n            this.$buttons = this.$bar.find('.noty_buttons');\n\n            $.noty.store[this.options.id] = this; // store noty for api\n\n        }, // end _build\n\n        show: function() {\n\n            var self = this;\n\n            (self.options.custom) ? self.options.custom.find(self.options.layout.container.selector).append(self.$bar) : $(self.options.layout.container.selector).append(self.$bar);\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.style.apply(self);\n\n            ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});\n\n            self.$bar.addClass(self.options.layout.addClass);\n\n            self.options.layout.container.style.apply($(self.options.layout.container.selector));\n\n            self.showing = true;\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.callback.onShow.apply(this);\n\n            if($.inArray('click', self.options.closeWith) > -1)\n                self.$bar.css('cursor', 'pointer').one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    if(self.options.callback.onCloseClick) {\n                        self.options.callback.onCloseClick.apply(self);\n                    }\n                    self.close();\n                });\n\n            if($.inArray('hover', self.options.closeWith) > -1)\n                self.$bar.one('mouseenter', function() {\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) > -1)\n                self.$closeButton.one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) == -1)\n                self.$closeButton.remove();\n\n            if(self.options.callback.onShow)\n                self.options.callback.onShow.apply(self);\n\n            if (typeof self.options.animation.open == 'string') {\n                self.$bar.css('height', self.$bar.innerHeight());\n                self.$bar.show().addClass(self.options.animation.open).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                    self.showing = false;\n                    self.shown = true;\n                });\n\n            } else {\n                self.$bar.animate(\n                    self.options.animation.open,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                        self.showing = false;\n                        self.shown = true;\n                    });\n            }\n\n            // If noty is have a timeout option\n            if(self.options.timeout)\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n\n            return this;\n\n        }, // end show\n\n        close: function() {\n\n            if(this.closed) return;\n            if(this.$bar && this.$bar.hasClass('i-am-closing-now')) return;\n\n            var self = this;\n\n            if(this.showing) {\n                self.$bar.queue(\n                    function() {\n                        self.close.apply(self);\n                    }\n                );\n                return;\n            }\n\n            if(!this.shown && !this.showing) { // If we are still waiting in the queue just delete from queue\n                var queue = [];\n                $.each($.noty.queue, function(i, n) {\n                    if(n.options.id != self.options.id) {\n                        queue.push(n);\n                    }\n                });\n                $.noty.queue = queue;\n                return;\n            }\n\n            self.$bar.addClass('i-am-closing-now');\n\n            if(self.options.callback.onClose) {\n                self.options.callback.onClose.apply(self);\n            }\n\n            if (typeof self.options.animation.close == 'string') {\n                self.$bar.addClass(self.options.animation.close).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    self.closeCleanUp();\n                });\n            } else {\n                self.$bar.clearQueue().stop().animate(\n                    self.options.animation.close,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    })\n                    .promise().done(function() {\n                        self.closeCleanUp();\n                    });\n            }\n\n        }, // end close\n\n        closeCleanUp: function() {\n\n            var self = this;\n\n            // Modal Cleaning\n            if(self.options.modal) {\n                $.notyRenderer.setModalCount(-1);\n                if($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function() {\n                    $(this).remove();\n                });\n            }\n\n            // Layout Cleaning\n            $.notyRenderer.setLayoutCountFor(self, -1);\n            if($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();\n\n            // Make sure self.$bar has not been removed before attempting to remove it\n            if(typeof self.$bar !== 'undefined' && self.$bar !== null) {\n\n                if (typeof self.options.animation.close == 'string') {\n                    self.$bar.css('transition', 'all 100ms ease').css('border', 0).css('margin', 0).height(0);\n                    self.$bar.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {\n                        self.$bar.remove();\n                        self.$bar = null;\n                        self.closed = true;\n\n                        if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                            self.options.theme.callback.onClose.apply(self);\n                        }\n                    });\n                } else {\n                    self.$bar.remove();\n                    self.$bar = null;\n                    self.closed = true;\n                }\n            }\n\n            delete $.noty.store[self.options.id]; // deleting noty from store\n\n            if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                self.options.theme.callback.onClose.apply(self);\n            }\n\n            if(!self.options.dismissQueue) {\n                // Queue render\n                $.noty.ontap = true;\n\n                $.notyRenderer.render();\n            }\n\n            if(self.options.maxVisible > 0 && self.options.dismissQueue) {\n                $.notyRenderer.render();\n            }\n\n        }, // end close clean up\n\n        setText: function(text) {\n            if(!this.closed) {\n                this.options.text = text;\n                this.$bar.find('.noty_text').html(text);\n            }\n            return this;\n        },\n\n        setType: function(type) {\n            if(!this.closed) {\n                this.options.type = type;\n                this.options.theme.style.apply(this);\n                this.options.theme.callback.onShow.apply(this);\n            }\n            return this;\n        },\n\n        setTimeout: function(time) {\n            if(!this.closed) {\n                var self = this;\n                this.options.timeout = time;\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n            }\n            return this;\n        },\n\n        stopPropagation: function(evt) {\n            evt = evt || window.event;\n            if(typeof evt.stopPropagation !== \"undefined\") {\n                evt.stopPropagation();\n            }\n            else {\n                evt.cancelBubble = true;\n            }\n        },\n\n        closed : false,\n        showing: false,\n        shown  : false\n\n    }; // end NotyObject\n\n    $.notyRenderer = {};\n\n    $.notyRenderer.init = function(options) {\n\n        // Renderer creates a new noty\n        var notification = Object.create(NotyObject).init(options);\n\n        if(notification.options.killer)\n            $.noty.closeAll();\n\n        (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);\n\n        $.notyRenderer.render();\n\n        return ($.noty.returns == 'object') ? notification : notification.options.id;\n    };\n\n    $.notyRenderer.render = function() {\n\n        var instance = $.noty.queue[0];\n\n        if($.type(instance) === 'object') {\n            if(instance.options.dismissQueue) {\n                if(instance.options.maxVisible > 0) {\n                    if($(instance.options.layout.container.selector + ' li').length < instance.options.maxVisible) {\n                        $.notyRenderer.show($.noty.queue.shift());\n                    }\n                    else {\n\n                    }\n                }\n                else {\n                    $.notyRenderer.show($.noty.queue.shift());\n                }\n            }\n            else {\n                if($.noty.ontap) {\n                    $.notyRenderer.show($.noty.queue.shift());\n                    $.noty.ontap = false;\n                }\n            }\n        }\n        else {\n            $.noty.ontap = true; // Queue is over\n        }\n\n    };\n\n    $.notyRenderer.show = function(notification) {\n\n        if(notification.options.modal) {\n            $.notyRenderer.createModalFor(notification);\n            $.notyRenderer.setModalCount(+1);\n        }\n\n        // Where is the container?\n        if(notification.options.custom) {\n            if(notification.options.custom.find(notification.options.layout.container.selector).length == 0) {\n                notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                notification.options.custom.find(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n        else {\n            if($(notification.options.layout.container.selector).length == 0) {\n                $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                $(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n\n        $.notyRenderer.setLayoutCountFor(notification, +1);\n\n        notification.show();\n    };\n\n    $.notyRenderer.createModalFor = function(notification) {\n        if($('.noty_modal').length == 0) {\n            var modal = $('<div/>').addClass('noty_modal').addClass(notification.options.theme).data('noty_modal_count', 0);\n\n            if(notification.options.theme.modal && notification.options.theme.modal.css)\n                modal.css(notification.options.theme.modal.css);\n\n            modal.prependTo($('body')).fadeIn('fast');\n\n            if($.inArray('backdrop', notification.options.closeWith) > -1)\n                modal.on('click', function(e) {\n                    $.noty.closeAll();\n                });\n        }\n    };\n\n    $.notyRenderer.getLayoutCountFor = function(notification) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;\n    };\n\n    $.notyRenderer.setLayoutCountFor = function(notification, arg) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);\n    };\n\n    $.notyRenderer.getModalCount = function() {\n        return $('.noty_modal').data('noty_modal_count') || 0;\n    };\n\n    $.notyRenderer.setModalCount = function(arg) {\n        return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);\n    };\n\n    // This is for custom container\n    $.fn.noty = function(options) {\n        options.custom = $(this);\n        return $.notyRenderer.init(options);\n    };\n\n    $.noty = {};\n    $.noty.queue = [];\n    $.noty.ontap = true;\n    $.noty.layouts = {};\n    $.noty.themes = {};\n    $.noty.returns = 'object';\n    $.noty.store = {};\n\n    $.noty.get = function(id) {\n        return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;\n    };\n\n    $.noty.close = function(id) {\n        return $.noty.get(id) ? $.noty.get(id).close() : false;\n    };\n\n    $.noty.setText = function(id, text) {\n        return $.noty.get(id) ? $.noty.get(id).setText(text) : false;\n    };\n\n    $.noty.setType = function(id, type) {\n        return $.noty.get(id) ? $.noty.get(id).setType(type) : false;\n    };\n\n    $.noty.clearQueue = function() {\n        $.noty.queue = [];\n    };\n\n    $.noty.closeAll = function() {\n        $.noty.clearQueue();\n        $.each($.noty.store, function(id, noty) {\n            noty.close();\n        });\n    };\n\n    var windowAlert = window.alert;\n\n    $.noty.consumeAlert = function(options) {\n        window.alert = function(text) {\n            if(options)\n                options.text = text;\n            else\n                options = {text: text};\n\n            $.notyRenderer.init(options);\n        };\n    };\n\n    $.noty.stopConsumeAlert = function() {\n        window.alert = windowAlert;\n    };\n\n    $.noty.defaults = {\n        layout      : 'top',\n        theme       : 'defaultTheme',\n        type        : 'alert',\n        text        : '',\n        dismissQueue: true,\n        template    : '<div class=\"noty_message\"><span class=\"noty_text\"></span><div class=\"noty_close\"></div></div>',\n        animation   : {\n            open  : {height: 'toggle'},\n            close : {height: 'toggle'},\n            easing: 'swing',\n            speed : 500\n        },\n        timeout     : false,\n        force       : false,\n        modal       : false,\n        maxVisible  : 5,\n        killer      : false,\n        closeWith   : ['click'],\n        callback    : {\n            onShow      : function() {\n            },\n            afterShow   : function() {\n            },\n            onClose     : function() {\n            },\n            afterClose  : function() {\n            },\n            onCloseClick: function() {\n            }\n        },\n        buttons     : false\n    };\n\n    $(window).on('resize', function() {\n        $.each($.noty.layouts, function(index, layout) {\n            layout.container.style.apply($(layout.container.selector));\n        });\n    });\n\n    // Helpers\n    window.noty = function noty(options) {\n        return $.notyRenderer.init(options);\n    };\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/bottom.js",
    "content": "$.noty.layouts.bottom = {\n    name     : 'bottom',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_bottom_layout_container\" />',\n        selector: 'ul#noty_bottom_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/bottomCenter.js",
    "content": "$.noty.layouts.bottomCenter = {\n    name     : 'bottomCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomCenter_layout_container\" />',\n        selector: 'ul#noty_bottomCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/bottomLeft.js",
    "content": "$.noty.layouts.bottomLeft = {\n    name     : 'bottomLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomLeft_layout_container\" />',\n        selector: 'ul#noty_bottomLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/bottomRight.js",
    "content": "$.noty.layouts.bottomRight = {\n    name     : 'bottomRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomRight_layout_container\" />',\n        selector: 'ul#noty_bottomRight_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/center.js",
    "content": "$.noty.layouts.center = {\n    name     : 'center',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_center_layout_container\" />',\n        selector: 'ul#noty_center_layout_container',\n        style   : function() {\n            $(this).css({\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/centerLeft.js",
    "content": "$.noty.layouts.centerLeft = {\n    name     : 'centerLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerLeft_layout_container\" />',\n        selector: 'ul#noty_centerLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/centerRight.js",
    "content": "$.noty.layouts.centerRight = {\n    name     : 'centerRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerRight_layout_container\" />',\n        selector: 'ul#noty_centerRight_layout_container',\n        style   : function() {\n            $(this).css({\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/inline.js",
    "content": "$.noty.layouts.inline = {\n    name     : 'inline',\n    options  : {},\n    container: {\n        object  : '<ul class=\"noty_inline_layout_container\" />',\n        selector: 'ul.noty_inline_layout_container',\n        style   : function() {\n            $(this).css({\n                width        : '100%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/top.js",
    "content": "$.noty.layouts.top = {\n    name     : 'top',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_top_layout_container\" />',\n        selector: 'ul#noty_top_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/topCenter.js",
    "content": "$.noty.layouts.topCenter = {\n    name     : 'topCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topCenter_layout_container\" />',\n        selector: 'ul#noty_topCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/topLeft.js",
    "content": "$.noty.layouts.topLeft = {\n    name     : 'topLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topLeft_layout_container\" />',\n        selector: 'ul#noty_topLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/layouts/topRight.js",
    "content": "$.noty.layouts.topRight = {\n    name     : 'topRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topRight_layout_container\" />',\n        selector: 'ul#noty_topRight_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/packaged/jquery.noty.packaged.js",
    "content": "!function(root, factory) {\n\t if (typeof define === 'function' && define.amd) {\n\t\t define(['jquery.noty.packaged'], factory);\n\t } else if (typeof exports === 'object') {\n\t\t module.exports = factory(require('jquery'));\n\t } else {\n\t\t factory(root.jQuery);\n\t }\n}(this, function($) {\n\n/*!\n @package noty - jQuery Notification Plugin\n @version version: 2.3.5\n @contributors https://github.com/needim/noty/graphs/contributors\n\n @documentation Examples and Documentation - http://needim.github.com/noty/\n\n @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php\n */\n\n    if(typeof Object.create !== 'function') {\n        Object.create = function(o) {\n            function F() {\n            }\n\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    var NotyObject = {\n\n        init: function(options) {\n\n            // Mix in the passed in options with the default options\n            this.options = $.extend({}, $.noty.defaults, options);\n\n            this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];\n\n            if($.noty.themes[this.options.theme])\n                this.options.theme = $.noty.themes[this.options.theme];\n            else\n                options.themeClassName = this.options.theme;\n\n            delete options.layout;\n            delete options.theme;\n\n            this.options = $.extend({}, this.options, this.options.layout.options);\n            this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));\n\n            this.options = $.extend({}, this.options, options);\n\n            // Build the noty dom initial structure\n            this._build();\n\n            // return this so we can chain/use the bridge with less code.\n            return this;\n        }, // end init\n\n        _build: function() {\n\n            // Generating noty bar\n            var $bar = $('<div class=\"noty_bar noty_type_' + this.options.type + '\"></div>').attr('id', this.options.id);\n            $bar.append(this.options.template).find('.noty_text').html(this.options.text);\n\n            this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;\n\n            if(this.options.themeClassName)\n                this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type);\n\n            // Set buttons if available\n            if(this.options.buttons) {\n\n                // If we have button disable closeWith & timeout options\n                this.options.closeWith = [];\n                this.options.timeout = false;\n\n                var $buttons = $('<div/>').addClass('noty_buttons');\n\n                (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);\n\n                var self = this;\n\n                $.each(this.options.buttons, function(i, button) {\n                    var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text).attr('id', button.id ? button.id : 'button-' + i)\n                        .appendTo(self.$bar.find('.noty_buttons'))\n                        .on('click', function(event) {\n                            if($.isFunction(button.onClick)) {\n                                button.onClick.call($button, self, event);\n                            }\n                        });\n                });\n            }\n\n            // For easy access\n            this.$message = this.$bar.find('.noty_message');\n            this.$closeButton = this.$bar.find('.noty_close');\n            this.$buttons = this.$bar.find('.noty_buttons');\n\n            $.noty.store[this.options.id] = this; // store noty for api\n\n        }, // end _build\n\n        show: function() {\n\n            var self = this;\n\n            (self.options.custom) ? self.options.custom.find(self.options.layout.container.selector).append(self.$bar) : $(self.options.layout.container.selector).append(self.$bar);\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.style.apply(self);\n\n            ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});\n\n            self.$bar.addClass(self.options.layout.addClass);\n\n            self.options.layout.container.style.apply($(self.options.layout.container.selector));\n\n            self.showing = true;\n\n            if(self.options.theme && self.options.theme.style)\n                self.options.theme.callback.onShow.apply(this);\n\n            if($.inArray('click', self.options.closeWith) > -1)\n                self.$bar.css('cursor', 'pointer').one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    if(self.options.callback.onCloseClick) {\n                        self.options.callback.onCloseClick.apply(self);\n                    }\n                    self.close();\n                });\n\n            if($.inArray('hover', self.options.closeWith) > -1)\n                self.$bar.one('mouseenter', function() {\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) > -1)\n                self.$closeButton.one('click', function(evt) {\n                    self.stopPropagation(evt);\n                    self.close();\n                });\n\n            if($.inArray('button', self.options.closeWith) == -1)\n                self.$closeButton.remove();\n\n            if(self.options.callback.onShow)\n                self.options.callback.onShow.apply(self);\n\n            if (typeof self.options.animation.open == 'string') {\n                self.$bar.css('height', self.$bar.innerHeight());\n                self.$bar.show().addClass(self.options.animation.open).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                    self.showing = false;\n                    self.shown = true;\n                });\n\n            } else {\n                self.$bar.animate(\n                    self.options.animation.open,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);\n                        self.showing = false;\n                        self.shown = true;\n                    });\n            }\n\n            // If noty is have a timeout option\n            if(self.options.timeout)\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n\n            return this;\n\n        }, // end show\n\n        close: function() {\n\n            if(this.closed) return;\n            if(this.$bar && this.$bar.hasClass('i-am-closing-now')) return;\n\n            var self = this;\n\n            if(this.showing) {\n                self.$bar.queue(\n                    function() {\n                        self.close.apply(self);\n                    }\n                );\n                return;\n            }\n\n            if(!this.shown && !this.showing) { // If we are still waiting in the queue just delete from queue\n                var queue = [];\n                $.each($.noty.queue, function(i, n) {\n                    if(n.options.id != self.options.id) {\n                        queue.push(n);\n                    }\n                });\n                $.noty.queue = queue;\n                return;\n            }\n\n            self.$bar.addClass('i-am-closing-now');\n\n            if(self.options.callback.onClose) {\n                self.options.callback.onClose.apply(self);\n            }\n\n            if (typeof self.options.animation.close == 'string') {\n                self.$bar.addClass(self.options.animation.close).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {\n                    if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    self.closeCleanUp();\n                });\n            } else {\n                self.$bar.clearQueue().stop().animate(\n                    self.options.animation.close,\n                    self.options.animation.speed,\n                    self.options.animation.easing,\n                    function() {\n                        if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);\n                    })\n                    .promise().done(function() {\n                        self.closeCleanUp();\n                    });\n            }\n\n        }, // end close\n\n        closeCleanUp: function() {\n\n            var self = this;\n\n            // Modal Cleaning\n            if(self.options.modal) {\n                $.notyRenderer.setModalCount(-1);\n                if($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function() {\n                    $(this).remove();\n                });\n            }\n\n            // Layout Cleaning\n            $.notyRenderer.setLayoutCountFor(self, -1);\n            if($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();\n\n            // Make sure self.$bar has not been removed before attempting to remove it\n            if(typeof self.$bar !== 'undefined' && self.$bar !== null) {\n\n                if (typeof self.options.animation.close == 'string') {\n                    self.$bar.css('transition', 'all 100ms ease').css('border', 0).css('margin', 0).height(0);\n                    self.$bar.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {\n                        self.$bar.remove();\n                        self.$bar = null;\n                        self.closed = true;\n\n                        if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                            self.options.theme.callback.onClose.apply(self);\n                        }\n                    });\n                } else {\n                    self.$bar.remove();\n                    self.$bar = null;\n                    self.closed = true;\n                }\n            }\n\n            delete $.noty.store[self.options.id]; // deleting noty from store\n\n            if(self.options.theme.callback && self.options.theme.callback.onClose) {\n                self.options.theme.callback.onClose.apply(self);\n            }\n\n            if(!self.options.dismissQueue) {\n                // Queue render\n                $.noty.ontap = true;\n\n                $.notyRenderer.render();\n            }\n\n            if(self.options.maxVisible > 0 && self.options.dismissQueue) {\n                $.notyRenderer.render();\n            }\n\n        }, // end close clean up\n\n        setText: function(text) {\n            if(!this.closed) {\n                this.options.text = text;\n                this.$bar.find('.noty_text').html(text);\n            }\n            return this;\n        },\n\n        setType: function(type) {\n            if(!this.closed) {\n                this.options.type = type;\n                this.options.theme.style.apply(this);\n                this.options.theme.callback.onShow.apply(this);\n            }\n            return this;\n        },\n\n        setTimeout: function(time) {\n            if(!this.closed) {\n                var self = this;\n                this.options.timeout = time;\n                self.$bar.delay(self.options.timeout).promise().done(function() {\n                    self.close();\n                });\n            }\n            return this;\n        },\n\n        stopPropagation: function(evt) {\n            evt = evt || window.event;\n            if(typeof evt.stopPropagation !== \"undefined\") {\n                evt.stopPropagation();\n            }\n            else {\n                evt.cancelBubble = true;\n            }\n        },\n\n        closed : false,\n        showing: false,\n        shown  : false\n\n    }; // end NotyObject\n\n    $.notyRenderer = {};\n\n    $.notyRenderer.init = function(options) {\n\n        // Renderer creates a new noty\n        var notification = Object.create(NotyObject).init(options);\n\n        if(notification.options.killer)\n            $.noty.closeAll();\n\n        (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);\n\n        $.notyRenderer.render();\n\n        return ($.noty.returns == 'object') ? notification : notification.options.id;\n    };\n\n    $.notyRenderer.render = function() {\n\n        var instance = $.noty.queue[0];\n\n        if($.type(instance) === 'object') {\n            if(instance.options.dismissQueue) {\n                if(instance.options.maxVisible > 0) {\n                    if($(instance.options.layout.container.selector + ' li').length < instance.options.maxVisible) {\n                        $.notyRenderer.show($.noty.queue.shift());\n                    }\n                    else {\n\n                    }\n                }\n                else {\n                    $.notyRenderer.show($.noty.queue.shift());\n                }\n            }\n            else {\n                if($.noty.ontap) {\n                    $.notyRenderer.show($.noty.queue.shift());\n                    $.noty.ontap = false;\n                }\n            }\n        }\n        else {\n            $.noty.ontap = true; // Queue is over\n        }\n\n    };\n\n    $.notyRenderer.show = function(notification) {\n\n        if(notification.options.modal) {\n            $.notyRenderer.createModalFor(notification);\n            $.notyRenderer.setModalCount(+1);\n        }\n\n        // Where is the container?\n        if(notification.options.custom) {\n            if(notification.options.custom.find(notification.options.layout.container.selector).length == 0) {\n                notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                notification.options.custom.find(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n        else {\n            if($(notification.options.layout.container.selector).length == 0) {\n                $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));\n            }\n            else {\n                $(notification.options.layout.container.selector).removeClass('i-am-new');\n            }\n        }\n\n        $.notyRenderer.setLayoutCountFor(notification, +1);\n\n        notification.show();\n    };\n\n    $.notyRenderer.createModalFor = function(notification) {\n        if($('.noty_modal').length == 0) {\n            var modal = $('<div/>').addClass('noty_modal').addClass(notification.options.theme).data('noty_modal_count', 0);\n\n            if(notification.options.theme.modal && notification.options.theme.modal.css)\n                modal.css(notification.options.theme.modal.css);\n\n            modal.prependTo($('body')).fadeIn('fast');\n\n            if($.inArray('backdrop', notification.options.closeWith) > -1)\n                modal.on('click', function(e) {\n                    $.noty.closeAll();\n                });\n        }\n    };\n\n    $.notyRenderer.getLayoutCountFor = function(notification) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;\n    };\n\n    $.notyRenderer.setLayoutCountFor = function(notification, arg) {\n        return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);\n    };\n\n    $.notyRenderer.getModalCount = function() {\n        return $('.noty_modal').data('noty_modal_count') || 0;\n    };\n\n    $.notyRenderer.setModalCount = function(arg) {\n        return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);\n    };\n\n    // This is for custom container\n    $.fn.noty = function(options) {\n        options.custom = $(this);\n        return $.notyRenderer.init(options);\n    };\n\n    $.noty = {};\n    $.noty.queue = [];\n    $.noty.ontap = true;\n    $.noty.layouts = {};\n    $.noty.themes = {};\n    $.noty.returns = 'object';\n    $.noty.store = {};\n\n    $.noty.get = function(id) {\n        return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;\n    };\n\n    $.noty.close = function(id) {\n        return $.noty.get(id) ? $.noty.get(id).close() : false;\n    };\n\n    $.noty.setText = function(id, text) {\n        return $.noty.get(id) ? $.noty.get(id).setText(text) : false;\n    };\n\n    $.noty.setType = function(id, type) {\n        return $.noty.get(id) ? $.noty.get(id).setType(type) : false;\n    };\n\n    $.noty.clearQueue = function() {\n        $.noty.queue = [];\n    };\n\n    $.noty.closeAll = function() {\n        $.noty.clearQueue();\n        $.each($.noty.store, function(id, noty) {\n            noty.close();\n        });\n    };\n\n    var windowAlert = window.alert;\n\n    $.noty.consumeAlert = function(options) {\n        window.alert = function(text) {\n            if(options)\n                options.text = text;\n            else\n                options = {text: text};\n\n            $.notyRenderer.init(options);\n        };\n    };\n\n    $.noty.stopConsumeAlert = function() {\n        window.alert = windowAlert;\n    };\n\n    $.noty.defaults = {\n        layout      : 'top',\n        theme       : 'defaultTheme',\n        type        : 'alert',\n        text        : '',\n        dismissQueue: true,\n        template    : '<div class=\"noty_message\"><span class=\"noty_text\"></span><div class=\"noty_close\"></div></div>',\n        animation   : {\n            open  : {height: 'toggle'},\n            close : {height: 'toggle'},\n            easing: 'swing',\n            speed : 500\n        },\n        timeout     : false,\n        force       : false,\n        modal       : false,\n        maxVisible  : 5,\n        killer      : false,\n        closeWith   : ['click'],\n        callback    : {\n            onShow      : function() {\n            },\n            afterShow   : function() {\n            },\n            onClose     : function() {\n            },\n            afterClose  : function() {\n            },\n            onCloseClick: function() {\n            }\n        },\n        buttons     : false\n    };\n\n    $(window).on('resize', function() {\n        $.each($.noty.layouts, function(index, layout) {\n            layout.container.style.apply($(layout.container.selector));\n        });\n    });\n\n    // Helpers\n    window.noty = function noty(options) {\n        return $.notyRenderer.init(options);\n    };\n\n$.noty.layouts.bottom = {\n    name     : 'bottom',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_bottom_layout_container\" />',\n        selector: 'ul#noty_bottom_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.bottomCenter = {\n    name     : 'bottomCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomCenter_layout_container\" />',\n        selector: 'ul#noty_bottomCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n\n$.noty.layouts.bottomLeft = {\n    name     : 'bottomLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomLeft_layout_container\" />',\n        selector: 'ul#noty_bottomLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.bottomRight = {\n    name     : 'bottomRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_bottomRight_layout_container\" />',\n        selector: 'ul#noty_bottomRight_layout_container',\n        style   : function() {\n            $(this).css({\n                bottom       : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.center = {\n    name     : 'center',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_center_layout_container\" />',\n        selector: 'ul#noty_center_layout_container',\n        style   : function() {\n            $(this).css({\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px',\n                    top : ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.centerLeft = {\n    name     : 'centerLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerLeft_layout_container\" />',\n        selector: 'ul#noty_centerLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.centerRight = {\n    name     : 'centerRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_centerRight_layout_container\" />',\n        selector: 'ul#noty_centerRight_layout_container',\n        style   : function() {\n            $(this).css({\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            // getting hidden height\n            var dupe = $(this).clone().css({visibility: \"hidden\", display: \"block\", position: \"absolute\", top: 0, left: 0}).attr('id', 'dupe');\n            $(\"body\").append(dupe);\n            dupe.find('.i-am-closing-now').remove();\n            dupe.find('li').css('display', 'block');\n            var actual_height = dupe.height();\n            dupe.remove();\n\n            if($(this).hasClass('i-am-new')) {\n                $(this).css({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                });\n            }\n            else {\n                $(this).animate({\n                    top: ($(window).height() - actual_height) / 2 + 'px'\n                }, 500);\n            }\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.inline = {\n    name     : 'inline',\n    options  : {},\n    container: {\n        object  : '<ul class=\"noty_inline_layout_container\" />',\n        selector: 'ul.noty_inline_layout_container',\n        style   : function() {\n            $(this).css({\n                width        : '100%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n$.noty.layouts.top = {\n    name     : 'top',\n    options  : {},\n    container: {\n        object  : '<ul id=\"noty_top_layout_container\" />',\n        selector: 'ul#noty_top_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 0,\n                left         : '5%',\n                position     : 'fixed',\n                width        : '90%',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 9999999\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none'\n    },\n    addClass : ''\n};\n$.noty.layouts.topCenter = {\n    name     : 'topCenter',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topCenter_layout_container\" />',\n        selector: 'ul#noty_topCenter_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 0,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            $(this).css({\n                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'\n            });\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n\n$.noty.layouts.topLeft = {\n    name     : 'topLeft',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topLeft_layout_container\" />',\n        selector: 'ul#noty_topLeft_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                left         : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    left: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.layouts.topRight = {\n    name     : 'topRight',\n    options  : { // overrides options\n\n    },\n    container: {\n        object  : '<ul id=\"noty_topRight_layout_container\" />',\n        selector: 'ul#noty_topRight_layout_container',\n        style   : function() {\n            $(this).css({\n                top          : 20,\n                right        : 20,\n                position     : 'fixed',\n                width        : '310px',\n                height       : 'auto',\n                margin       : 0,\n                padding      : 0,\n                listStyleType: 'none',\n                zIndex       : 10000000\n            });\n\n            if(window.innerWidth < 600) {\n                $(this).css({\n                    right: 5\n                });\n            }\n        }\n    },\n    parent   : {\n        object  : '<li />',\n        selector: 'li',\n        css     : {}\n    },\n    css      : {\n        display: 'none',\n        width  : '310px'\n    },\n    addClass : ''\n};\n$.noty.themes.bootstrapTheme = {\n    name: 'bootstrapTheme',\n    modal: {\n        css: {\n            position: 'fixed',\n            width: '100%',\n            height: '100%',\n            backgroundColor: '#000',\n            zIndex: 10000,\n            opacity: 0.6,\n            display: 'none',\n            left: 0,\n            top: 0\n        }\n    },\n    style: function() {\n\n        var containerSelector = this.options.layout.container.selector;\n        $(containerSelector).addClass('list-group');\n\n        this.$closeButton.append('<span aria-hidden=\"true\">&times;</span><span class=\"sr-only\">Close</span>');\n        this.$closeButton.addClass('close');\n\n        this.$bar.addClass( \"list-group-item\" ).css('padding', '0px');\n\n        switch (this.options.type) {\n            case 'alert': case 'notification':\n                this.$bar.addClass( \"list-group-item-info\" );\n                break;\n            case 'warning':\n                this.$bar.addClass( \"list-group-item-warning\" );\n                break;\n            case 'error':\n                this.$bar.addClass( \"list-group-item-danger\" );\n                break;\n            case 'information':\n                this.$bar.addClass(\"list-group-item-info\");\n                break;\n            case 'success':\n                this.$bar.addClass( \"list-group-item-success\" );\n                break;\n        }\n\n        this.$message.css({\n            fontSize: '13px',\n            lineHeight: '16px',\n            textAlign: 'center',\n            padding: '8px 10px 9px',\n            width: 'auto',\n            position: 'relative'\n        });\n    },\n    callback: {\n        onShow: function() {  },\n        onClose: function() {  }\n    }\n};\n\n\n$.noty.themes.defaultTheme = {\n    name    : 'defaultTheme',\n    helpers : {\n        borderFix: function() {\n            if(this.options.dismissQueue) {\n                var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;\n                switch(this.options.layout.name) {\n                    case 'top':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).last().css({borderRadius: '0px 0px 5px 5px'});\n                        break;\n                    case 'topCenter':\n                    case 'topLeft':\n                    case 'topRight':\n                    case 'bottomCenter':\n                    case 'bottomLeft':\n                    case 'bottomRight':\n                    case 'center':\n                    case 'centerLeft':\n                    case 'centerRight':\n                    case 'inline':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});\n                        $(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'});\n                        break;\n                    case 'bottom':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({borderRadius: '5px 5px 0px 0px'});\n                        break;\n                    default:\n                        break;\n                }\n            }\n        }\n    },\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow  : 'hidden',\n            background: \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAQAAAClM0ndAAAAhklEQVR4AdXO0QrCMBBE0bttkk38/w8WRERpdyjzVOc+HxhIHqJGMQcFFkpYRQotLLSw0IJ5aBdovruMYDA/kT8plF9ZKLFQcgF18hDj1SbQOMlCA4kao0iiXmah7qBWPdxpohsgVZyj7e5I9KcID+EhiDI5gxBYKLBQYKHAQoGFAoEks/YEGHYKB7hFxf0AAAAASUVORK5CYII=') repeat-x scroll left top #fff\"\n        });\n\n        this.$message.css({\n            fontSize  : '13px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '8px 10px 9px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderRadius: '0px 0px 5px 5px',\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderRadius: '5px 5px 0px 0px',\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        },\n        onClose: function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        }\n    }\n};\n\n$.noty.themes.relax = {\n    name    : 'relax',\n    helpers : {},\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow    : 'hidden',\n            margin      : '4px 0',\n            borderRadius: '2px'\n        });\n\n        this.$message.css({\n            fontSize  : '14px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '10px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderTop   : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderBottom: '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#dedede', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: '#FF8181', borderColor: '#e25353', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#78C5E7', borderColor: '#3badd6', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: '#BCF5BC', borderColor: '#7cdd77', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n\n        },\n        onClose: function() {\n\n        }\n    }\n};\n\n\nreturn window.noty;\n\n});"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/promise.js",
    "content": "/*!\n * Noty Helpers Javascript From JQuery Javascript Library\n *\n * Ported by Maksim Pecherskiy.  Original Licensing:\n *\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n * Copyright 2011, The Dojo Foundation\n * Released under the MIT, BSD, and GPL Licenses.\n *\n * Date: Mon Nov 21 21:11:03 2011 -0500\n */\n\n\n(function(){\n\n  // String to Object flags format cache\nvar flagsCache = {};\n\n// Convert String-formatted flags into Object-formatted ones and store in cache\nfunction createFlags( flags ) {\n  var object = flagsCache[ flags ] = {},\n    i, length;\n  flags = flags.split( /\\s+/ );\n  for ( i = 0, length = flags.length; i < length; i++ ) {\n    object[ flags[i] ] = true;\n  }\n  return object;\n}\n\njQuery.extend({\n\n  _mark: function( elem, type ) {\n    if ( elem ) {\n      type = (type || \"fx\") + \"mark\";\n      jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );\n    }\n  },\n\n  _unmark: function( force, elem, type ) {\n    if ( force !== true ) {\n      type = elem;\n      elem = force;\n      force = false;\n    }\n    if ( elem ) {\n      type = type || \"fx\";\n      var key = type + \"mark\",\n        count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );\n      if ( count ) {\n        jQuery.data( elem, key, count, true );\n      } else {\n        jQuery.removeData( elem, key, true );\n        handleQueueMarkDefer( elem, type, \"mark\" );\n      }\n    }\n  },\n\n  queue: function( elem, type, data ) {\n    if ( elem ) {\n      type = (type || \"fx\") + \"queue\";\n      var q = jQuery.data( elem, type, undefined, true );\n      // Speed up dequeue by getting out quickly if this is just a lookup\n      if ( data ) {\n        if ( !q || jQuery.isArray(data) ) {\n          q = jQuery.data( elem, type, jQuery.makeArray(data), true );\n        } else {\n          q.push( data );\n        }\n      }\n      return q || [];\n    }\n  },\n\n  dequeue: function( elem, type ) {\n    type = type || \"fx\";\n\n    var queue = jQuery.queue( elem, type ),\n      fn = queue.shift(),\n      defer;\n\n    // If the fx queue is dequeued, always remove the progress sentinel\n    if ( fn === \"inprogress\" ) {\n      fn = queue.shift();\n    }\n\n    if ( fn ) {\n      // Add a progress sentinel to prevent the fx queue from being\n      // automatically dequeued\n      if ( type === \"fx\" ) {\n        queue.unshift(\"inprogress\");\n      }\n\n      fn.call(elem, function() {\n        jQuery.dequeue(elem, type);\n      });\n    }\n\n    if ( !queue.length ) {\n      jQuery.removeData( elem, type + \"queue\", true );\n      handleQueueMarkDefer( elem, type, \"queue\" );\n    }\n  }\n});\n\njQuery.fn.extend({\n  queue: function( type, data ) {\n    if ( typeof type !== \"string\" ) {\n      data = type;\n      type = \"fx\";\n    }\n\n    if ( data === undefined ) {\n      return jQuery.queue( this[0], type );\n    }\n    return this.each(function() {\n      var queue = jQuery.queue( this, type, data );\n\n      if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n        jQuery.dequeue( this, type );\n      }\n    });\n  },\n  dequeue: function( type ) {\n    return this.each(function() {\n      jQuery.dequeue( this, type );\n    });\n  },\n  // Based off of the plugin by Clint Helfers, with permission.\n  // http://blindsignals.com/index.php/2009/07/jquery-delay/\n  delay: function( time, type ) {\n    time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n    type = type || \"fx\";\n\n    return this.queue( type, function() {\n      var elem = this;\n      setTimeout(function() {\n        jQuery.dequeue( elem, type );\n      }, time );\n    });\n  },\n  clearQueue: function( type ) {\n    return this.queue( type || \"fx\", [] );\n  },\n  // Get a promise resolved when queues of a certain type\n  // are emptied (fx is the type by default)\n  promise: function( type, object ) {\n    if ( typeof type !== \"string\" ) {\n      object = type;\n      type = undefined;\n    }\n    type = type || \"fx\";\n    var defer = jQuery.Deferred(),\n      elements = this,\n      i = elements.length,\n      count = 1,\n      deferDataKey = type + \"defer\",\n      queueDataKey = type + \"queue\",\n      markDataKey = type + \"mark\",\n      tmp;\n    function resolve() {\n      if ( !( --count ) ) {\n        defer.resolveWith( elements, [ elements ] );\n      }\n    }\n    while( i-- ) {\n      if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n          ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n            jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n          jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {\n        count++;\n        tmp.done( resolve );\n      }\n    }\n    resolve();\n    return defer.promise();\n  }\n});\n\nfunction handleQueueMarkDefer( elem, type, src ) {\n  var deferDataKey = type + \"defer\",\n    queueDataKey = type + \"queue\",\n    markDataKey = type + \"mark\",\n    defer = jQuery._data( elem, deferDataKey );\n  if ( defer &&\n    ( src === \"queue\" || !jQuery._data(elem, queueDataKey) ) &&\n    ( src === \"mark\" || !jQuery._data(elem, markDataKey) ) ) {\n    // Give room for hard-coded callbacks to fire first\n    // and eventually mark/queue something else on the element\n    setTimeout( function() {\n      if ( !jQuery._data( elem, queueDataKey ) &&\n        !jQuery._data( elem, markDataKey ) ) {\n        jQuery.removeData( elem, deferDataKey, true );\n        defer.fire();\n      }\n    }, 0 );\n  }\n}\n\n\n\njQuery.Callbacks = function( flags ) {\n\n  // Convert flags from String-formatted to Object-formatted\n  // (we check in cache first)\n  flags = flags ? ( /*flagsCache[ flags ] || */createFlags( flags ) ) : {};\n\n  var // Actual callback list\n    list = [],\n    // Stack of fire calls for repeatable lists\n    stack = [],\n    // Last fire value (for non-forgettable lists)\n    memory,\n    // Flag to know if list is currently firing\n    firing,\n    // First callback to fire (used internally by add and fireWith)\n    firingStart,\n    // End of the loop when firing\n    firingLength,\n    // Index of currently firing callback (modified by remove if needed)\n    firingIndex,\n    // Add one or several callbacks to the list\n    add = function( args ) {\n      var i,\n        length,\n        elem,\n        type,\n        actual;\n      for ( i = 0, length = args.length; i < length; i++ ) {\n        elem = args[ i ];\n        type = jQuery.type( elem );\n        if ( type === \"array\" ) {\n          // Inspect recursively\n          add( elem );\n        } else if ( type === \"function\" ) {\n          // Add if not in unique mode and callback is not in\n          if ( !flags.unique || !self.has( elem ) ) {\n            list.push( elem );\n          }\n        }\n      }\n    },\n    // Fire callbacks\n    fire = function( context, args ) {\n      args = args || [];\n      memory = !flags.memory || [ context, args ];\n      firing = true;\n      firingIndex = firingStart || 0;\n      firingStart = 0;\n      firingLength = list.length;\n      for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n        if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {\n          memory = true; // Mark as halted\n          break;\n        }\n      }\n      firing = false;\n      if ( list ) {\n        if ( !flags.once ) {\n          if ( stack && stack.length ) {\n            memory = stack.shift();\n            self.fireWith( memory[ 0 ], memory[ 1 ] );\n          }\n        } else if ( memory === true ) {\n          self.disable();\n        } else {\n          list = [];\n        }\n      }\n    },\n    // Actual Callbacks object\n    self = {\n      // Add a callback or a collection of callbacks to the list\n      add: function() {\n        if ( list ) {\n          var length = list.length;\n          add( arguments );\n          // Do we need to add the callbacks to the\n          // current firing batch?\n          if ( firing ) {\n            firingLength = list.length;\n          // With memory, if we're not firing then\n          // we should call right away, unless previous\n          // firing was halted (stopOnFalse)\n          } else if ( memory && memory !== true ) {\n            firingStart = length;\n            fire( memory[ 0 ], memory[ 1 ] );\n          }\n        }\n        return this;\n      },\n      // Remove a callback from the list\n      remove: function() {\n        if ( list ) {\n          var args = arguments,\n            argIndex = 0,\n            argLength = args.length;\n          for ( ; argIndex < argLength ; argIndex++ ) {\n            for ( var i = 0; i < list.length; i++ ) {\n              if ( args[ argIndex ] === list[ i ] ) {\n                // Handle firingIndex and firingLength\n                if ( firing ) {\n                  if ( i <= firingLength ) {\n                    firingLength--;\n                    if ( i <= firingIndex ) {\n                      firingIndex--;\n                    }\n                  }\n                }\n                // Remove the element\n                list.splice( i--, 1 );\n                // If we have some unicity property then\n                // we only need to do this once\n                if ( flags.unique ) {\n                  break;\n                }\n              }\n            }\n          }\n        }\n        return this;\n      },\n      // Control if a given callback is in the list\n      has: function( fn ) {\n        if ( list ) {\n          var i = 0,\n            length = list.length;\n          for ( ; i < length; i++ ) {\n            if ( fn === list[ i ] ) {\n              return true;\n            }\n          }\n        }\n        return false;\n      },\n      // Remove all callbacks from the list\n      empty: function() {\n        list = [];\n        return this;\n      },\n      // Have the list do nothing anymore\n      disable: function() {\n        list = stack = memory = undefined;\n        return this;\n      },\n      // Is it disabled?\n      disabled: function() {\n        return !list;\n      },\n      // Lock the list in its current state\n      lock: function() {\n        stack = undefined;\n        if ( !memory || memory === true ) {\n          self.disable();\n        }\n        return this;\n      },\n      // Is it locked?\n      locked: function() {\n        return !stack;\n      },\n      // Call all callbacks with the given context and arguments\n      fireWith: function( context, args ) {\n        if ( stack ) {\n          if ( firing ) {\n            if ( !flags.once ) {\n              stack.push( [ context, args ] );\n            }\n          } else if ( !( flags.once && memory ) ) {\n            fire( context, args );\n          }\n        }\n        return this;\n      },\n      // Call all the callbacks with the given arguments\n      fire: function() {\n        self.fireWith( this, arguments );\n        return this;\n      },\n      // To know if the callbacks have already been called at least once\n      fired: function() {\n        return !!memory;\n      }\n    };\n\n  return self;\n};\n\n\n\njQuery.fn.extend({\n  // Get a promise resolved when queues of a certain type\n  // are emptied (fx is the type by default)\n  promise: function( type, object ) {\n    if ( typeof type !== \"string\" ) {\n      object = type;\n      type = undefined;\n    }\n    type = type || \"fx\";\n    var defer = jQuery.Deferred(),\n      elements = this,\n      i = elements.length,\n      count = 1,\n      deferDataKey = type + \"defer\",\n      queueDataKey = type + \"queue\",\n      markDataKey = type + \"mark\",\n      tmp;\n    function resolve() {\n      if ( !( --count ) ) {\n        defer.resolveWith( elements, [ elements ] );\n      }\n    }\n    while( i-- ) {\n      if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n          ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n            jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n          jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( \"once memory\" ), true ) )) {\n        count++;\n        tmp.add( resolve );\n      }\n    }\n    resolve();\n    return defer.promise();\n  }\n});\n})();"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/themes/bootstrap.js",
    "content": "$.noty.themes.bootstrapTheme = {\n    name: 'bootstrapTheme',\n    modal: {\n        css: {\n            position: 'fixed',\n            width: '100%',\n            height: '100%',\n            backgroundColor: '#000',\n            zIndex: 10000,\n            opacity: 0.6,\n            display: 'none',\n            left: 0,\n            top: 0\n        }\n    },\n    style: function() {\n\n        var containerSelector = this.options.layout.container.selector;\n        $(containerSelector).addClass('list-group');\n\n        this.$closeButton.append('<span aria-hidden=\"true\">&times;</span><span class=\"sr-only\">Close</span>');\n        this.$closeButton.addClass('close');\n\n        this.$bar.addClass( \"list-group-item\" ).css('padding', '0px');\n\n        switch (this.options.type) {\n            case 'alert': case 'notification':\n                this.$bar.addClass( \"list-group-item-info\" );\n                break;\n            case 'warning':\n                this.$bar.addClass( \"list-group-item-warning\" );\n                break;\n            case 'error':\n                this.$bar.addClass( \"list-group-item-danger\" );\n                break;\n            case 'information':\n                this.$bar.addClass(\"list-group-item-info\");\n                break;\n            case 'success':\n                this.$bar.addClass( \"list-group-item-success\" );\n                break;\n        }\n\n        this.$message.css({\n            fontSize: '13px',\n            lineHeight: '16px',\n            textAlign: 'center',\n            padding: '8px 10px 9px',\n            width: 'auto',\n            position: 'relative'\n        });\n    },\n    callback: {\n        onShow: function() {  },\n        onClose: function() {  }\n    }\n};\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/themes/default.js",
    "content": "$.noty.themes.defaultTheme = {\n    name    : 'defaultTheme',\n    helpers : {\n        borderFix: function() {\n            if(this.options.dismissQueue) {\n                var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;\n                switch(this.options.layout.name) {\n                    case 'top':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).last().css({borderRadius: '0px 0px 5px 5px'});\n                        break;\n                    case 'topCenter':\n                    case 'topLeft':\n                    case 'topRight':\n                    case 'bottomCenter':\n                    case 'bottomLeft':\n                    case 'bottomRight':\n                    case 'center':\n                    case 'centerLeft':\n                    case 'centerRight':\n                    case 'inline':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});\n                        $(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'});\n                        break;\n                    case 'bottom':\n                        $(selector).css({borderRadius: '0px 0px 0px 0px'});\n                        $(selector).first().css({borderRadius: '5px 5px 0px 0px'});\n                        break;\n                    default:\n                        break;\n                }\n            }\n        }\n    },\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow  : 'hidden',\n            background: \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAQAAAClM0ndAAAAhklEQVR4AdXO0QrCMBBE0bttkk38/w8WRERpdyjzVOc+HxhIHqJGMQcFFkpYRQotLLSw0IJ5aBdovruMYDA/kT8plF9ZKLFQcgF18hDj1SbQOMlCA4kao0iiXmah7qBWPdxpohsgVZyj7e5I9KcID+EhiDI5gxBYKLBQYKHAQoGFAoEks/YEGHYKB7hFxf0AAAAASUVORK5CYII=') repeat-x scroll left top #fff\"\n        });\n\n        this.$message.css({\n            fontSize  : '13px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '8px 10px 9px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderRadius: '0px 0px 5px 5px',\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    borderRadius: '5px',\n                    border      : '1px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderRadius: '5px 5px 0px 0px',\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        },\n        onClose: function() {\n            $.noty.themes.defaultTheme.helpers.borderFix.apply(this);\n        }\n    }\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/libs/noty_2.3.5/themes/relax.js",
    "content": "$.noty.themes.relax = {\n    name    : 'relax',\n    helpers : {},\n    modal   : {\n        css: {\n            position       : 'fixed',\n            width          : '100%',\n            height         : '100%',\n            backgroundColor: '#000',\n            zIndex         : 10000,\n            opacity        : 0.6,\n            display        : 'none',\n            left           : 0,\n            top            : 0\n        }\n    },\n    style   : function() {\n\n        this.$bar.css({\n            overflow    : 'hidden',\n            margin      : '4px 0',\n            borderRadius: '2px'\n        });\n\n        this.$message.css({\n            fontSize  : '14px',\n            lineHeight: '16px',\n            textAlign : 'center',\n            padding   : '10px',\n            width     : 'auto',\n            position  : 'relative'\n        });\n\n        this.$closeButton.css({\n            position  : 'absolute',\n            top       : 4, right: 4,\n            width     : 10, height: 10,\n            background: \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)\",\n            display   : 'none',\n            cursor    : 'pointer'\n        });\n\n        this.$buttons.css({\n            padding        : 5,\n            textAlign      : 'right',\n            borderTop      : '1px solid #ccc',\n            backgroundColor: '#fff'\n        });\n\n        this.$buttons.find('button').css({\n            marginLeft: 5\n        });\n\n        this.$buttons.find('button:first').css({\n            marginLeft: 0\n        });\n\n        this.$bar.on({\n            mouseenter: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 1);\n            },\n            mouseleave: function() {\n                $(this).find('.noty_close').stop().fadeTo('normal', 0);\n            }\n        });\n\n        switch(this.options.layout.name) {\n            case 'top':\n                this.$bar.css({\n                    borderBottom: '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderTop   : '2px solid #eee',\n                    boxShadow   : \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            case 'topCenter':\n            case 'center':\n            case 'bottomCenter':\n            case 'inline':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'center'});\n                break;\n            case 'topLeft':\n            case 'topRight':\n            case 'bottomLeft':\n            case 'bottomRight':\n            case 'centerLeft':\n            case 'centerRight':\n                this.$bar.css({\n                    border   : '1px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                this.$message.css({fontSize: '13px', textAlign: 'left'});\n                break;\n            case 'bottom':\n                this.$bar.css({\n                    borderTop   : '2px solid #eee',\n                    borderLeft  : '2px solid #eee',\n                    borderRight : '2px solid #eee',\n                    borderBottom: '2px solid #eee',\n                    boxShadow   : \"0 -2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n            default:\n                this.$bar.css({\n                    border   : '2px solid #eee',\n                    boxShadow: \"0 2px 4px rgba(0, 0, 0, 0.1)\"\n                });\n                break;\n        }\n\n        switch(this.options.type) {\n            case 'alert':\n            case 'notification':\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#dedede', color: '#444'});\n                break;\n            case 'warning':\n                this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});\n                this.$buttons.css({borderTop: '1px solid #FFC237'});\n                break;\n            case 'error':\n                this.$bar.css({backgroundColor: '#FF8181', borderColor: '#e25353', color: '#FFF'});\n                this.$message.css({fontWeight: 'bold'});\n                this.$buttons.css({borderTop: '1px solid darkred'});\n                break;\n            case 'information':\n                this.$bar.css({backgroundColor: '#78C5E7', borderColor: '#3badd6', color: '#FFF'});\n                this.$buttons.css({borderTop: '1px solid #0B90C4'});\n                break;\n            case 'success':\n                this.$bar.css({backgroundColor: '#BCF5BC', borderColor: '#7cdd77', color: 'darkgreen'});\n                this.$buttons.css({borderTop: '1px solid #50C24E'});\n                break;\n            default:\n                this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'});\n                break;\n        }\n    },\n    callback: {\n        onShow : function() {\n\n        },\n        onClose: function() {\n\n        }\n    }\n};\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/login.php",
    "content": "<?php\ninclude_once('config/config.php')\n?>\n<!--\n~   Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>WSO2 Pet Store - Login</title>\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.png\" />\n\n    <!-- Bootstrap CSS -->\n    <link href=\"libs/bootstrap_3.2.0/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font Awesome CSS -->\n    <link href=\"libs/font-awesome_4.3.0/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <!-- Font WSO2 CSS -->\n    <link href=\"libs/font-wso2_1.2/css/font-wso2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"libs/html5shiv_3.7.2/html5shiv.min.js\"></script>\n    <script src=\"libs/respond_1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n<body>\n<!-- header -->\n<header class=\"header header-default\">\n    <div class=\"container-fluid\">\n        <div class=\"pull-left brand float-remove-xs text-center-xs\">\n            <a href=\"#\">\n                <img src=\"images/logo-inverse.svg\" alt=\"wso2\" title=\"wso2\" class=\"logo\">\n                <h1>WSO2 Pet Store - login</h1>\n            </a>\n        </div>\n    </div>\n</header>\n\n<!-- #page-content-wrapper -->\n<div class=\"page-content-wrapper\">\n\n    <!-- page content -->\n    <div class=\"container-fluid body-wrapper\">\n\n        <div class=\"row\">\n            <div class=\"col-md-12\">\n\n                <!-- content -->\n                <div class=\"container col-xs-10 col-sm-6 col-md-6 col-lg-3 col-centered wr-content wr-login col-centered\">\n                    <div>\n                        <h2 class=\"wr-title uppercase blue-bg padding-double white boarder-bottom-blue margin-none\">Sign in </h2>\n\n\n                    </div>\n                    <div class=\"boarder-all \">\n                        <div class=\"clearfix\"></div>\n\n                        <div class=\"padding-double login-form\">\n                            <div class=\"error-msg\" id=\"error-msg\" style=\"display:none;\">Username or password is invalid</div>\n\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <input id=\"username\" name=\"username\" type=\"text\" class=\"form-control\" tabindex=\"0\"\n                                       placeholder=\"Username\">\n                            </div>\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <input id=\"password\" name=\"password\" type=\"password\" class=\"form-control\"\n                                       placeholder=\"Password\">\n                            </div>\n\n                            <div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group\">\n                                <button class=\"wr-btn grey-bg col-xs-12 col-md-12 col-lg-12 uppercase font-extra-large\" type=\"submit\" id=\"submit-btn\"> Sign in</button>\n                            </div>\n                            <div class=\"clearfix\"></div>\n                        </div>\n\n                    </div>\n                </div>\n                <!-- /content -->\n\n            </div>\n        </div>\n\n    </div>\n\n</div><!-- /#page-content-wrapper -->\n\n\n<!-- footer -->\n<footer class=\"footer\">\n    <div class=\"container-fluid\">\n        <p>&copy; <script>document.write(new Date().getFullYear());</script> <a href=\"http://wso2.com/\" target=\"_blank\"><i class=\"icon fw fw-wso2\"></i> Inc</a>. All Rights Reserved.</p>\n    </div>\n</footer>\n\n<!-- Jquery/Jquery UI JS -->\n<script src=\"libs/jquery_1.11.3/jquery-1.11.3.js\"></script>\n<!-- Bootstrap JS -->\n<script src=\"libs/bootstrap_3.2.0/js/bootstrap.min.js\"></script>\n\n<!-- Noty JS -->\n<script src=\"libs/noty_2.3.5/packaged/jquery.noty.packaged.min.js\"></script>\n<script src=\"js/login.js\"></script>\n<script src=\"js/custom.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/html/logout.php",
    "content": "<?php\nsession_start();\nsession_destroy();\nheader('Location: login.php');\n?>"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/docker/init.sh",
    "content": "#!/bin/bash\n\nenv >> /etc/environment\necho \". /etc/environment\" >> /etc/apache2/envvars\n/usr/sbin/apache2ctl -D FOREGROUND\n\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/kubernetes/user-fe-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: store-fe\n  labels:\n    name: store-fe\nspec:\n  replicas: 1\n  selector:\n    name: store-fe\n  template:\n    metadata:\n      labels:\n        name: store-fe\n    spec:\n      containers:\n      - name: store-fe\n        image: wso2msf4j/petstore-store-fe:2.0.0\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n        - name: FE_FILE_SERVICE_HOST\n          value: fileserver\n        - name: FE_FILE_SERVICE_PORT\n          value: \"80\"\n        - name: FE_PET_SERVICE_HOST\n          value: pet\n        - name: FE_PET_SERVICE_PORT\n          value: \"80\"\n        - name: FE_USER_SERVICE_HOST\n          value: security\n        - name: FE_USER_SERVICE_PORT\n          value: \"80\"\n        - name: FE_TXN_SERVICE_HOST\n          value: txn\n        - name: FE_TXN_SERVICE_PORT\n          value: \"80\"\n        - name: FE_FILE_SERVICE_NODE_PORT\n          value: \"31111\"\n        ports:\n        - containerPort: 80\n"
  },
  {
    "path": "samples/petstore/microservices/frontend-user/container/kubernetes/user-fe-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: store-fe\n  labels:\n    name: store-fe\nspec:\n  sessionAffinity: ClientIP\n  ports:\n    # the port that this service should serve on\n    - port: 80\n      targetPort: 80\n  type: NodePort\n  selector:\n    name: store-fe\n"
  },
  {
    "path": "samples/petstore/microservices/pet/README.md",
    "content": "Pet Microservice in the Pet store sample"
  },
  {
    "path": "samples/petstore/microservices/pet/container/docker/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM java:8-jre\nMAINTAINER architecture@wso2.org\n\nWORKDIR /opt\n\n# --------------------------------\n# Copy scripts, packages & plugins\n# --------------------------------\nCOPY packages/petstore-pet.jar /opt/\nCOPY packages/client-truststore.jks /opt/\nCOPY packages/data-agent-conf.xml /opt/\n\n# --------------------------------\n# HTTP Monitoring and metrics specific config\n# --------------------------------\nENV METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV METRICS_REPORTING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\nENV HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV HTTP_MONITORING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\n\n#----------------------\n# Expose container ports\n# ----------------------\nEXPOSE 8080\n\nENTRYPOINT java -jar /opt/petstore-pet.jar\n"
  },
  {
    "path": "samples/petstore/microservices/pet/container/docker/README.md",
    "content": "# How to Build the Docker Image\n\n1. Copy target/petstore-pet-1.0.0.jar to the docker/packages directory\n2. Download jdk-8u60-linux-x64.gz to  the docker/packages directory\n3. From this directory, run:\n\n```\ndocker build -t wso2msf4j/petstore-pet .\n```\n\n4. From the ssh directory, run\n```\ndocker build -t wso2msf4j/ssh .\n```"
  },
  {
    "path": "samples/petstore/microservices/pet/container/docker/ssh/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM ubuntu:14.04\nMAINTAINER architecture@wso2.org\n\nRUN apt-get update && apt-get install -y openssh-server dnsutils\nRUN mkdir -p /var/run/sshd\nRUN echo 'root:wso2' | chpasswd\nRUN sed -i \"s/PermitRootLogin without-password/#PermitRootLogin without-password/\" /etc/ssh/sshd_config\nEXPOSE 22\n\nENTRYPOINT /usr/sbin/sshd -D\n"
  },
  {
    "path": "samples/petstore/microservices/pet/container/kubernetes/pet-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: pet\n  labels:\n    name: pet\nspec:\n  replicas: 1\n  selector:\n    name: pet\n  template:\n    metadata:\n      labels:\n        name: pet\n    spec:\n      containers:\n      - name: pet\n        image: wso2msf4j/petstore-pet:2.0.0\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n          # If your cluster config does not include a dns service, then to\n          # instead access environment variables to find service host\n          # info, comment out the 'value: dns' line above, and uncomment the\n          # line below.\n          # value: env\n        - name: SENTINEL1_HOST\n          value: redis-sentinel\n        - name: SENTINEL1_PORT\n          value: \"26379\"\n        ports:\n        - containerPort: 8080\n"
  },
  {
    "path": "samples/petstore/microservices/pet/container/kubernetes/pet-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: pet\n  labels:\n    name: pet\nspec:\n  # if your cluster supports it, uncomment the following to automatically create\n  # an external load-balanced IP for the frontend service.\n  # type: LoadBalancer\n  ports:\n    # the port that this service should serve on\n    - port: 80\n      targetPort: 8080\n\n  type: NodePort\n  selector:\n    name: pet"
  },
  {
    "path": "samples/petstore/microservices/pet/data-agent-conf.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<DataAgentsConfiguration>\n    <Agent>\n        <Name>Thrift</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.thrift.ThriftDataEndpoint</DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n\n    <Agent>\n        <Name>Binary</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.binary.BinaryDataEndpoint\n        </DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n</DataAgentsConfiguration>\n\n"
  },
  {
    "path": "samples/petstore/microservices/pet/etc/init.sh",
    "content": "#!/bin/sh\n\nif [ -z \"$1\" ] || [ -z \"$2\" ]; then\n    echo \"Usage: init.sh <host> <port>\"\n    exit 1\nfi\n\nfor i in {0..10}\ndo\n  age=$((1+$i))\n  price=`echo 100.99 + $i | bc`\n\n  curl -v -X POST -H \"Content-Type:application/json\" \\\n  -d '{\"category\":{\"name\":\"cat\"},\"ageMonths\":\"'\"$age\"'\",\"price\":\"'\"$price\"'\",\"image\":\"http://foo.com/cat'\"$i\"'.png\"}' \\\n  http://$1:$2/pet/\ndone\n\ncurl http://$1:$2/pet/all\n\n#172.17.4.201:31485"
  },
  {
    "path": "samples/petstore/microservices/pet/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore-pet</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: [Pet Store] - Pet store microservices example - pet microservice</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n            <version>2.25</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>petstore-util</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.examples.petstore.pet.Runner</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/java/org/wso2/msf4j/examples/petstore/pet/PetCategoryService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.pet;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\nimport org.wso2.msf4j.examples.petstore.util.model.Category;\nimport redis.clients.jedis.Jedis;\nimport redis.clients.jedis.JedisPool;\nimport redis.clients.jedis.JedisPoolConfig;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * Pet category microservice.\n */\n@HTTPMonitored\n@Path(\"/category\")\npublic class PetCategoryService {\n    private static final Logger log = LoggerFactory.getLogger(PetCategoryService.class);\n    private static String REDIS_MASTER_HOST = System.getenv(\"REDIS_MASTER_HOST\");\n    private static int REDIS_MASTER_PORT = Integer.parseInt(System.getenv(\"REDIS_MASTER_PORT\"));\n\n    static {\n        log.info(\"Using Redis master:\" + REDIS_MASTER_HOST + \":\" + REDIS_MASTER_PORT);\n    }\n\n    private static final JedisPool pool =\n            new JedisPool(new JedisPoolConfig(), REDIS_MASTER_HOST, REDIS_MASTER_PORT);\n\n    @POST\n    @Consumes(\"application/json\")\n    @Timed\n    public Response addCategory(Category category) {\n        String name = category.getName();\n        log.info(\"Using Redis master:\" + REDIS_MASTER_HOST + \":\" + REDIS_MASTER_PORT);\n        try (Jedis jedis = pool.getResource()) {\n            jedis.sadd(org.wso2.msf4j.examples.petstore.pet.PetConstants.CATEGORIES_KEY, name);\n            log.info(\"Added category\");\n        }\n        return Response.status(Response.Status.OK).entity(\"Category with name \" + name + \" successfully added\").build();\n    }\n\n    @DELETE\n    @Path(\"/{name}\")\n    @Timed\n    public Response deleteCategory(@PathParam(\"name\") String name) {\n        try (Jedis jedis = pool.getResource()) {\n            if (!jedis.smembers(PetConstants.CATEGORIES_KEY).contains(name)) {\n                return Response.status(Response.Status.NOT_FOUND).build();\n            }\n            String categoryKey = PetConstants.CATEGORY_KEY_PREFIX + name;\n            jedis.srem(PetConstants.CATEGORIES_KEY, name);\n            jedis.del(categoryKey);\n            log.info(\"Deleted category: \" + name);\n        }\n        return Response.status(Response.Status.OK).entity(\"OK\").build();\n    }\n\n    @GET\n    @Produces(\"application/json\")\n    @Path(\"/{name}\")\n    @Timed\n    public Response getCategory(@PathParam(\"name\") String name) {\n        try (Jedis jedis = pool.getResource()) {\n            if (!jedis.smembers(PetConstants.CATEGORIES_KEY).contains(name)) {\n                return Response.status(Response.Status.NOT_FOUND).build();\n            }\n            log.info(\"Got category\");\n        }\n        return Response.status(Response.Status.OK).entity(new Category(name)).build();\n    }\n\n    @GET\n    @Path(\"/all\")\n    @Produces(\"application/json\")\n    @Timed\n    public Set<Category> getAllCategories() {\n        try (Jedis jedis = pool.getResource()) {\n            Set<String> smembers = jedis.smembers(PetConstants.CATEGORIES_KEY);\n            Set<Category> categories = new HashSet<>(smembers.size());\n            for (String smember : smembers) {\n                categories.add(new Category(smember));\n            }\n            return categories;\n        }\n    }\n\n}\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/java/org/wso2/msf4j/examples/petstore/pet/PetConstants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.pet;\n\n/**\n * Pet store - pet microservice constants.\n */\npublic final class PetConstants {\n\n    public static final String CATEGORIES_KEY = \"petstore:pet:categories\";\n\n    public static final String CATEGORY_KEY_PREFIX = \"petstore:pet:category.\";\n\n    public static final String PET_ID_KEY_PREFIX = \"petstore:pet:id.\";\n}\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/java/org/wso2/msf4j/examples/petstore/pet/PetService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.pet;\n\nimport com.google.gson.Gson;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\nimport org.wso2.msf4j.examples.petstore.util.model.Pet;\nimport redis.clients.jedis.Jedis;\nimport redis.clients.jedis.JedisPool;\nimport redis.clients.jedis.JedisPoolConfig;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.DELETE;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.PUT;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * Pet microservice.\n */\n@HTTPMonitored\n@Path(\"/pet\")\npublic class PetService {\n    private static final Logger log = LoggerFactory.getLogger(PetService.class);\n\n    private static String REDIS_MASTER_HOST = System.getenv(\"REDIS_MASTER_HOST\");\n    private static int REDIS_MASTER_PORT = Integer.parseInt(System.getenv(\"REDIS_MASTER_PORT\"));\n\n    static {\n        log.info(\"Using Redis master:\" + REDIS_MASTER_HOST + \":\" + REDIS_MASTER_PORT);\n    }\n\n    private static final JedisPool pool =\n            new JedisPool(new JedisPoolConfig(), REDIS_MASTER_HOST, REDIS_MASTER_PORT);\n\n    @POST\n    @Consumes(\"application/json\")\n    @Timed\n    public Response addPet(Pet pet) {\n        log.info(\"Adding pet\");\n        String categoryName = pet.getCategory().getName();\n        try (Jedis jedis = pool.getResource()) {\n            if (!jedis.smembers(PetConstants.CATEGORIES_KEY).contains(categoryName)) {\n                jedis.sadd(PetConstants.CATEGORIES_KEY, categoryName);\n            }\n            String categoryKey = PetConstants.CATEGORY_KEY_PREFIX + categoryName;\n            jedis.sadd(categoryKey, pet.getId());\n            String id = pet.getId();\n            String petKey = PetConstants.PET_ID_KEY_PREFIX + id;\n            if (jedis.get(petKey) != null) {\n                return Response.status(Response.Status.CONFLICT).\n                        entity(\"Pet with ID \" + id + \" already exists\").build();\n            } else {\n                jedis.set(petKey, new Gson().toJson(pet));\n                log.info(\"Added pet\");\n            }\n            return Response.status(Response.Status.OK).entity(\"Pet with ID \" + id + \" successfully added\").build();\n        }\n    }\n\n    @DELETE\n    @Path(\"/{id}\")\n    @Timed\n    public Response deletePet(@PathParam(\"id\") String id) {\n        String petKey = PetConstants.PET_ID_KEY_PREFIX + id;\n        try (Jedis jedis = pool.getResource()) {\n            String petValue = jedis.get(petKey);\n            if (petValue == null || petValue.isEmpty()) {\n                return Response.status(Response.Status.NOT_FOUND).build();\n            }\n            Pet pet = new Gson().fromJson(petValue, Pet.class);\n            String categoryKey = PetConstants.CATEGORY_KEY_PREFIX + pet.getCategory().getName();\n            jedis.srem(categoryKey, pet.getId());\n            jedis.del(petKey);\n            log.info(\"Deleted pet\");\n            return Response.status(Response.Status.OK).entity(\"OK\").build();\n        }\n    }\n\n    @PUT\n    @Consumes(\"application/json\")\n    @Timed\n    public Response updatePet(Pet pet) {\n        String id = pet.getId();\n        String petKey = PetConstants.PET_ID_KEY_PREFIX + id;\n        try (Jedis jedis = pool.getResource()) {\n            String json = jedis.get(petKey);\n            if (json == null || json.isEmpty()) {\n                return Response.status(Response.Status.NOT_FOUND).build();\n            } else {\n                jedis.set(petKey, new Gson().toJson(pet));\n                log.info(\"Updated pet\");\n                return Response.status(Response.Status.OK).entity(\"Pet with ID \" + id + \" successfully updated\").build();\n            }\n        }\n    }\n\n    @GET\n    @Produces(\"application/json\")\n    @Path(\"/{id}\")\n    @Timed\n    public Response getPet(@PathParam(\"id\") String id) {\n        try (Jedis jedis = pool.getResource()) {\n            String json = jedis.get(PetConstants.PET_ID_KEY_PREFIX + id);\n            if (json == null || json.isEmpty()) {\n                return Response.status(Response.Status.NOT_FOUND).build();\n            }\n            log.info(\"Got pet\");\n            return Response.status(Response.Status.OK).entity(new Gson().fromJson(json, Pet.class)).build();\n        }\n    }\n\n    @GET\n    @Path(\"/all\")\n    @Produces(\"application/json\")\n    @Timed\n    public List<Pet> getAllPets() {\n        List<Pet> result = new ArrayList<>();\n        try (Jedis jedis = pool.getResource()) {\n            Set<String> categories = jedis.smembers(PetConstants.CATEGORIES_KEY);\n            for (String category : categories) {\n                Set<String> pets = jedis.smembers(PetConstants.CATEGORY_KEY_PREFIX + category);\n                for (String petID : pets) {\n                    String petValue = jedis.get(PetConstants.PET_ID_KEY_PREFIX + petID);\n                    result.add(new Gson().fromJson(petValue, Pet.class));\n                }\n            }\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/java/org/wso2/msf4j/examples/petstore/pet/Runner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.pet;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\nimport org.wso2.msf4j.security.JWTSecurityInterceptor;\n\n/**\n * Microservice runner for the pet microservices.\n */\npublic class Runner {\n\n    public static void main(String[] args) {\n        JWTSecurityInterceptor jwtSecurityInterceptor = new JWTSecurityInterceptor();\n        HTTPMonitoringInterceptor httpMonitoringInterceptor = new HTTPMonitoringInterceptor();\n        MetricsInterceptor metricsInterceptor = new MetricsInterceptor();\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(jwtSecurityInterceptor, httpMonitoringInterceptor, metricsInterceptor)\n                .addGlobalResponseInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .deploy(new PetService())\n                .deploy(new PetCategoryService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/resources/http-monitoring.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\nenabled: true\n\ndas:\n  receiverURL: ${HTTP_MONITORING_DAS_RECEIVERURL}\n  # authURL: ssl://localhost:7711\n  type: thrift\n  username: admin\n  password: admin\n  dataAgentConfigPath: ${HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH}\n"
  },
  {
    "path": "samples/petstore/microservices/pet/src/main/resources/metrics.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nenabled: true\n\njmx:\n  registerMBean: true\n  name: org.wso2.msf4j:type=Metrics\n\ndas:\n  - &DAS01\n    receiverURL: ${METRICS_REPORTING_DAS_RECEIVERURL}\n    # authURL: ssl://localhost:7711\n    type: thrift\n    username: admin\n    password: admin\n    dataAgentConfigPath: ${METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH}\n\nreporting:\n  jmx:\n    - name: JMX\n      enabled: true\n\n  console:\n    - name: Console\n      enabled: false\n      pollingPeriod: 60\n\n  csv:\n    - name: CSV\n      enabled: false\n      location: metrics\n      pollingPeriod: 60\n\n  slf4j:\n    - name: SLF4J\n      enabled: false\n      loggerName: metrics\n      pollingPeriod: 60\n\n  das:\n    - name: DAS\n      enabled: true\n      das: *DAS01\n      pollingPeriod: 60\n"
  },
  {
    "path": "samples/petstore/microservices/redis/container/kubernetes/README.md",
    "content": "## Reliable, Scalable Redis on Kubernetes\n\nThe following document describes the deployment of a reliable, multi-node Redis on Kubernetes.  It deploys a master with replicated slaves, as well as replicated redis sentinels which are use for health checking and failover.\n\n\nA [_Pod_](../../docs/user-guide/pods.md) is one or more containers that _must_ be scheduled onto the same host.  All containers in a pod share a network namespace, and may optionally share mounted volumes.\n\nWe will used the shared network namespace to bootstrap our Redis cluster.  In particular, the very first sentinel needs to know how to find the master (subsequent sentinels just ask the first sentinel).  Because all containers in a Pod share a network namespace, the sentinel can simply look at ```$(hostname -i):6379```.\n\n\nCreate this master as follows:\n\n```sh\nkubectl create -f redis-master.yaml\n```\n\nIn Redis, we will use a Kubernetes Service to provide a discoverable endpoints for the Redis sentinels in the cluster.  From the sentinels Redis clients can find the master, and then the slaves and other relevant info for the cluster.  This enables new members to join the cluster when failures occur.\n\nCreate this service:\n\n```sh\nkubectl create -f redis-sentinel-service.yaml\n```\n\nCreating replication controllers for both master and the sentinel\n\n```sh\nkubectl create -f examples/redis/redis-controller.yaml\nkubectl create -f examples/redis/redis-sentinel-controller.yaml\n```\n\nInitially creating those pods didn't actually do anything, since we only asked for one sentinel and one redis server, and they already existed, nothing changed.  Now we will add more replicas:\n\n```sh\nkubectl scale rc redis --replicas=3\n```\n\n```sh\nkubectl scale rc redis-sentinel --replicas=3\n```\n\nThis will create two additional replicas of the redis server and two additional replicas of the redis sentinel.\n\nUnlike our original redis-master pod, these pods exist independently, and they use the ```redis-sentinel-service``` that we defined above to discover and join the cluster.\n\nThe final step in the cluster turn up is to delete the original redis-master pod that we created manually.  While it was useful for bootstrapping discovery in the cluster, we really don't want the lifespan of our sentinel to be tied to the lifespan of one of our redis servers, and now that we have a successful, replicated redis sentinel service up and running, the binding is unnecessary.\n\nDelete the master as follows:\n\n```sh\nkubectl delete pods redis-master\n```\n\nNow let's take a close look at what happens after this pod is deleted.  There are three things that happen:\n\n  1. The redis replication controller notices that its desired state is 3 replicas, but there are currently only 2 replicas, and so it creates a new redis server to bring the replica count back up to 3\n  2. The redis-sentinel replication controller likewise notices the missing sentinel, and also creates a new sentinel.\n  3. The redis sentinels themselves, realize that the master has disappeared from the cluster, and begin the election procedure for selecting a new master.  They perform this election and selection, and chose one of the existing redis server replicas to be the new master.\n\n\nhere is the summary of commands:\n\n```\n# Create a bootstrap master\nkubectl create -f redis-master.yaml\n\n# Check whether the pods are up & running and wait until they are up\n\nkubectl get pods\n\n# Create a service to track the sentinels\nkubectl create -f redis-sentinel-service.yaml\n\n# Create a replication controller for redis servers\nkubectl create -f redis-controller.yaml\n\n# Create a replication controller for redis sentinels\nkubectl create -f redis-sentinel-controller.yaml\n\n# Scale both replication controllers\nkubectl scale rc redis --replicas=3\nkubectl scale rc redis-sentinel --replicas=3\n\n# Delete the original master pod\nkubectl delete pods redis-master\n```\n\nMore information please see https://github.com/kubernetes/kubernetes/tree/release-1.0/examples/redis\n\n\n"
  },
  {
    "path": "samples/petstore/microservices/redis/container/kubernetes/redis-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: redis\nspec:\n  replicas: 1\n  selector:\n    name: redis\n  template:\n    metadata:\n      labels:\n        name: redis\n    spec:\n      containers:\n      - name: redis\n        image: kubernetes/redis:v1\n        ports:\n        - containerPort: 6379\n        resources:\n          limits:\n            cpu: \"0.1\"\n        volumeMounts:\n        - mountPath: /redis-master-data\n          name: data\n      volumes:\n        - name: data\n          emptyDir: {}\n"
  },
  {
    "path": "samples/petstore/microservices/redis/container/kubernetes/redis-master.yaml",
    "content": "apiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    name: redis\n    redis-sentinel: \"true\"\n    role: master\n  name: redis-master\nspec:\n  containers:\n    - name: master\n      image: kubernetes/redis:v1\n      env:\n        - name: MASTER\n          value: \"true\"\n      ports:\n        - containerPort: 6379\n      resources:\n        limits:\n          cpu: \"0.1\"\n      volumeMounts:\n        - mountPath: /redis-master-data\n          name: data\n    - name: sentinel\n      image: kubernetes/redis:v1\n      env:\n        - name: SENTINEL\n          value: \"true\"\n      ports:\n        - containerPort: 26379\n  volumes:\n    - name: data\n      emptyDir: {}\n"
  },
  {
    "path": "samples/petstore/microservices/redis/container/kubernetes/redis-sentinel-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: redis-sentinel\nspec:\n  replicas: 1\n  selector:\n    redis-sentinel: \"true\"\n  template:\n    metadata:\n      labels:\n        name: redis-sentinel\n        redis-sentinel: \"true\"\n        role: sentinel\n    spec:\n      containers:\n      - name: sentinel\n        image: kubernetes/redis:v1\n        env:\n          - name: SENTINEL\n            value: \"true\"\n        ports:\n          - containerPort: 26379\n"
  },
  {
    "path": "samples/petstore/microservices/redis/container/kubernetes/redis-sentinel-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    name: sentinel\n    role: service\n  name: redis-sentinel\nspec:\n  ports:\n    - port: 26379\n      targetPort: 26379\n  type: NodePort\n  selector:\n    redis-sentinel: \"true\"\n"
  },
  {
    "path": "samples/petstore/microservices/security/container/docker/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM java:8-jre\nMAINTAINER architecture@wso2.org\n\nWORKDIR /opt\n\n# --------------------------------\n# Copy scripts, packages & plugins\n# --------------------------------\nCOPY packages/petstore-security.jar /opt/\nCOPY packages/client-truststore.jks /opt/\nCOPY packages/data-agent-conf.xml /opt/\n\n# --------------------------------\n# HTTP Monitoring and metrics specific config\n# --------------------------------\nENV METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV METRICS_REPORTING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\nENV HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV HTTP_MONITORING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\n\n# ----------------------\n# Expose container ports\n# ----------------------\nEXPOSE 8080\n\nENTRYPOINT java -jar /opt/petstore-security.jar\n"
  },
  {
    "path": "samples/petstore/microservices/security/container/kubernetes/README.md",
    "content": ""
  },
  {
    "path": "samples/petstore/microservices/security/container/kubernetes/security-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: security\n  labels:\n    name: security\nspec:\n  replicas: 1\n  selector:\n    name: security\n  template:\n    metadata:\n      labels:\n        name: security\n    spec:\n      containers:\n      - name: security\n        image: wso2msf4j/petstore-security:2.0.0\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n        ports:\n        - containerPort: 8080\n"
  },
  {
    "path": "samples/petstore/microservices/security/container/kubernetes/security-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: security\n  labels:\n    name: security\nspec:\n  # if your cluster supports it, uncomment the following to automatically create\n  # an external load-balanced IP for the frontend service.\n  # type: LoadBalancer\n  ports:\n    # the port that this service should serve on\n    - port: 80\n      targetPort: 8080\n  type: NodePort\n  selector:\n    name: security\n"
  },
  {
    "path": "samples/petstore/microservices/security/data-agent-conf.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<DataAgentsConfiguration>\n    <Agent>\n        <Name>Thrift</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.thrift.ThriftDataEndpoint</DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n\n    <Agent>\n        <Name>Binary</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.binary.BinaryDataEndpoint\n        </DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n</DataAgentsConfiguration>\n\n"
  },
  {
    "path": "samples/petstore/microservices/security/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore-security</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: [Pet Store] - Pet store microservices example - security microservice</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>commons-io.wso2</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>2.4.0.wso2v1</version>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n            <version>3.0.1</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>petstore-util</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n            <version>2.25</version>\n        </dependency>\n\n        <dependency>\n            <groupId>org.apache.ws.commons.axiom</groupId>\n            <artifactId>axiom-impl</artifactId>\n            <version>1.2.11</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.identity</groupId>\n            <artifactId>org.wso2.carbon.ldap.server</artifactId>\n            <version>5.0.0</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.core</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>bouncycastle</groupId>\n                    <artifactId>bcprov-jdk15</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.examples.petstore.security.Runner</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/README.md",
    "content": ""
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/JWTGenerator.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.security;\n\nimport com.nimbusds.jose.JWSAlgorithm;\nimport com.nimbusds.jose.JWSHeader;\nimport com.nimbusds.jose.JWSSigner;\nimport com.nimbusds.jose.crypto.RSASSASigner;\nimport com.nimbusds.jwt.JWTClaimsSet;\nimport com.nimbusds.jwt.SignedJWT;\nimport org.wso2.msf4j.examples.petstore.util.model.User;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.KeyStore;\nimport java.security.KeyStoreException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.UnrecoverableKeyException;\nimport java.security.cert.CertificateException;\nimport java.security.interfaces.RSAPrivateKey;\nimport java.util.Date;\n\n/**\n * Generates JWT.\n */\npublic class JWTGenerator {\n\n    private static String keyStore = \"wso2carbon.jks\";\n    private String alias = \"wso2carbon\";\n    private String keyStorePassword = \"wso2carbon\";\n\n    protected String generateJWT(User user) throws Exception {\n\n        RSAPrivateKey privateKey = getPrivateKey(keyStore, keyStorePassword, alias);\n        // Create RSA-signer with the private key\n        JWSSigner signer = new RSASSASigner(privateKey);\n\n        // Prepare JWT with claims set\n        JWTClaimsSet claimsSet = new JWTClaimsSet();\n        claimsSet.setSubject(user.getName());\n        claimsSet.setClaim(\"email\", user.getEmail());\n        claimsSet.setClaim(\"roles\", user.getRoles());\n        claimsSet.setIssuer(\"wso2.org/products/msf4j\");\n        claimsSet.setExpirationTime(new Date(new Date().getTime() + 60 * 60 * 1000)); //60 min\n\n        SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);\n\n        // Compute the RSA signature\n        signedJWT.sign(signer);\n\n        // To serialize to compact form, produces something like\n        // eyJhbGciOiJSUzI1NiJ9.SW4gUlNBIHdlIHRydXN0IQ.IRMQENi4nJyp4er2L\n        // mZq3ivwoAjqa1uUkSBKFIX7ATndFF5ivnt-m8uApHO4kfIFOrW7w2Ezmlg3Qd\n        // maXlS9DhN0nUk_hGI3amEjkKd0BWYCB8vfUbUv0XGjQip78AI4z1PrFRNidm7\n        // -jPDm5Iq0SZnjKjCNS5Q15fokXZc8u0A\n\n        return signedJWT.serialize();\n    }\n\n    private RSAPrivateKey getPrivateKey(String keyStorePath, String keyStorePassword, String alias)\n            throws IOException, KeyStoreException, CertificateException,\n            NoSuchAlgorithmException, UnrecoverableKeyException {\n\n        InputStream inputStream = null;\n        try {\n            inputStream = this.getClass().getClassLoader().getResourceAsStream(keyStorePath);\n            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());\n            keystore.load(inputStream, keyStorePassword.toCharArray());\n\n            RSAPrivateKey privateKey = (RSAPrivateKey) keystore.getKey(alias, keyStorePassword.toCharArray());\n            return privateKey;\n\n        } finally {\n            if (inputStream != null) {\n                inputStream.close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/Runner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.security;\n\nimport org.wso2.carbon.ldap.server.util.EmbeddingLDAPException;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\nimport org.wso2.msf4j.examples.petstore.security.ldap.server.ApacheDirectoryServerActivator;\n\nimport java.io.IOException;\n\n/**\n * Microservice runner for the userAuthentication microservice.\n */\npublic class Runner {\n\n    public static void main(String[] args) throws IOException, EmbeddingLDAPException {\n        ApacheDirectoryServerActivator apacheDS = new ApacheDirectoryServerActivator();\n        apacheDS.start();\n        HTTPMonitoringInterceptor httpMonitoringInterceptor = new HTTPMonitoringInterceptor();\n        MetricsInterceptor metricsInterceptor = new MetricsInterceptor();\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .addGlobalResponseInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .deploy(new UserAuthenticationService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/UserAuthenticationService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.security;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\nimport org.wso2.msf4j.examples.petstore.security.ldap.LDAPUserStoreManager;\nimport org.wso2.msf4j.examples.petstore.util.model.User;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport javax.naming.NamingException;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.Response;\n\n/**\n * UserAuthentication micro service.\n */\n@HTTPMonitored\n@Path(\"/user\")\npublic class UserAuthenticationService {\n\n    private static final Logger log = LoggerFactory.getLogger(UserAuthenticationService.class);\n    private static final String JWT_HEADER = \"X-JWT-Assertion\";\n    private String host = SystemVariableUtil.getValue(\"LDAP_HOST\", \"localhost\");\n    private int port = Integer.parseInt(SystemVariableUtil.getValue(\"LDAP_PORT\", \"10389\"));\n    private String connectionName = SystemVariableUtil.getValue(\"LDAP_CONNECTION_NAME\", \"uid=admin,ou=system\");\n    private String connectionPassword = SystemVariableUtil.getValue(\"LDAP_CONNECTION_PASSWORD\", \"admin\");\n\n    @POST\n    @Consumes(\"application/json\")\n    @Path(\"/login\")\n    @Timed\n    public Response authenticate(User user) {\n        String name = user.getName();\n        log.info(\"Authenticating user \" + name + \" ..\");\n        String jwt;\n        boolean isAuthenticated;\n        try {\n            LDAPUserStoreManager ldapUserStoreManager = LDAPUserStoreManager.\n                    getInstance(host, port, connectionName, connectionPassword);\n            isAuthenticated = ldapUserStoreManager.isValidUser(name, user.getPassword());\n            if (isAuthenticated) {\n                User userFromUserStore = new User();\n                userFromUserStore.setName(name);\n                userFromUserStore.setEmail(ldapUserStoreManager.getAttributeValue(name, \"mail\"));\n                userFromUserStore.setLastName(ldapUserStoreManager.getAttributeValue(name, \"sn\"));\n\n                JWTGenerator jwtGenerator = new JWTGenerator();\n                jwt = jwtGenerator.generateJWT(userFromUserStore);\n                String msg = \"User \" + name + \" authenticated successfully\";\n                log.info(msg + \". JWT=\" + jwt);\n                return Response.ok(msg).header(JWT_HEADER, jwt).build();\n            }\n        } catch (Exception e) {\n            log.error(\"Exception occurred while trying to authenticate user \" + name, e);\n            return Response.status(Response.Status.EXPECTATION_FAILED).build();\n        }\n        log.warn(\"Failed login attempt by user \" + name);\n        return Response.status(Response.Status.UNAUTHORIZED).entity(\"Invalid login attempt.\").build();\n    }\n\n    @POST\n    @Consumes(\"application/json\")\n    @Path(\"/add\")\n    @Timed\n    public Response addUser(User user) {\n        String name = user.getName();\n        log.info(\"Adding new user \" + name + \" ..\");\n        LDAPUserStoreManager ldapUserStoreManager;\n\n        try {\n            ldapUserStoreManager = LDAPUserStoreManager\n                    .getInstance(host, port, connectionName, connectionPassword);\n\n            //Create groups\n            if (user.getRoles() != null && user.getRoles().size() > 0) {\n                for (String role : user.getRoles()) {\n                    ldapUserStoreManager.addGroup(role, role);\n                }\n            }\n\n            ldapUserStoreManager.addUserAndAssignGroups(user.getName(), user.getFirstName(), user.getLastName(),\n                    user.getPassword(), user.getEmail(), user.getRoles());\n            log.info(\"User \" + name + \" successfully added ..\");\n        } catch (NamingException e) {\n            log.error(\"Exception occurred while adding user \" + name, e);\n            return Response.status(Response.Status.EXPECTATION_FAILED).build();\n        }\n        return Response.status(Response.Status.OK).entity(\"User \" + name + \" successfully added\").build();\n    }\n\n    @POST\n    @Consumes(\"application/json\")\n    @Path(\"/ldapgroup/{name}/{description}\")\n    @Timed\n    public Response addLDAPGroup(@PathParam(\"name\") String name, @PathParam(\"description\") String description) {\n        log.info(\"Adding new ldap group \" + name + \" ..\");\n        LDAPUserStoreManager ldapUserStoreManager;\n        try {\n            ldapUserStoreManager = LDAPUserStoreManager\n                    .getInstance(host, port, connectionName, connectionPassword);\n            ldapUserStoreManager.addGroup(name, description);\n        } catch (NamingException e) {\n            log.error(\"Error occurred while adding LDAP group \" + name, e);\n            return Response.status(Response.Status.EXPECTATION_FAILED).build();\n        }\n        return Response.status(Response.Status.OK).entity(\"LDAP group \" + name + \" successfully added\").build();\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/ldap/LDAPUserStoreManager.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.security.ldap;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport javax.naming.Context;\nimport javax.naming.NameAlreadyBoundException;\nimport javax.naming.NameNotFoundException;\nimport javax.naming.NamingException;\nimport javax.naming.directory.Attribute;\nimport javax.naming.directory.AttributeInUseException;\nimport javax.naming.directory.Attributes;\nimport javax.naming.directory.BasicAttribute;\nimport javax.naming.directory.BasicAttributes;\nimport javax.naming.directory.DirContext;\nimport javax.naming.directory.InitialDirContext;\nimport javax.naming.directory.ModificationItem;\nimport javax.naming.directory.NoSuchAttributeException;\n\n\n/**\n * Perform user management operations for LDAP. OrganizationUnit (OU) for Users and Groups\n * should have defined in system variables \"LDAP_USER_OU\" and \"LDAP_GROUPS_OU\" correspondingly.\n * If not default OU/s are used.\n */\npublic class LDAPUserStoreManager {\n\n    private static final Logger log = LoggerFactory.getLogger(LDAPUserStoreManager.class);\n\n    //The OU (organizational unit) to add users to\n    private static final String USERS_OU = SystemVariableUtil.getValue(\"LDAP_USER_OU\",\n                                                                       \"ou=Users,dc=WSO2,dc=ORG\");\n\n    //The OU (organizational unit) to add groups to\n    private static final String GROUPS_OU = SystemVariableUtil.getValue(\"LDAP_GROUPS_OU\",\n                                                                        \"ou=Groups,dc=WSO2,dc=ORG\");\n\n    //The default LDAP port\n    private static final int DEFAULT_PORT = 389;\n\n    //The LDAPManager instance object\n    private static Map instances = new HashMap();\n\n    //The connection, through a <code>DirContext</code>, to LDAP\n    private DirContext context;\n\n    //The hostname connected to\n    private String hostname;\n\n    //The port connected to\n    private int port;\n\n    protected LDAPUserStoreManager(String hostname, int port, String username, String password)\n            throws NamingException {\n\n        context = getInitialContext(hostname, port, username, password);\n\n        // Only save data if we got connected\n        this.hostname = hostname;\n        this.port = port;\n    }\n\n    public static LDAPUserStoreManager getInstance(String hostname, int port,\n                                                   String username, String password)\n            throws NamingException {\n\n        // Construct the key for the supplied information\n        String key = hostname + \":\" + port + \"|\" +\n                (username == null ? \"\" : username) + \"|\" +\n                (password == null ? \"\" : password);\n\n        if (!instances.containsKey(key)) {\n            synchronized (LDAPUserStoreManager.class) {\n                if (!instances.containsKey(key)) {\n                    LDAPUserStoreManager instance = new LDAPUserStoreManager(hostname, port,\n                                                                             username, password);\n                    instances.put(key, instance);\n                    return instance;\n                }\n            }\n        }\n\n        return (LDAPUserStoreManager) instances.get(key);\n    }\n\n    public static LDAPUserStoreManager getInstance(String hostname)\n            throws NamingException {\n\n        return getInstance(hostname, DEFAULT_PORT, null, null);\n    }\n\n    public void addUser(String username, String firstName, String lastName, String password,\n                        String email) throws NamingException {\n\n        // Create a container set of attributes\n        Attributes container = new BasicAttributes();\n\n        // Create the objectclass to add\n        Attribute objClasses = new BasicAttribute(\"objectClass\");\n        objClasses.add(\"top\");\n        objClasses.add(\"person\");\n        objClasses.add(\"organizationalPerson\");\n        objClasses.add(\"inetOrgPerson\");\n\n        // Assign the username, first name, and last name\n        String cnValue;\n        Attribute givenName;\n        Attribute sn;\n        if (firstName == null || lastName == null) {\n            cnValue = username;\n            givenName = new BasicAttribute(\"givenName\", username);\n            sn = new BasicAttribute(\"sn\", username);\n        } else {\n            cnValue = firstName + \" \" + lastName;\n            givenName = new BasicAttribute(\"givenName\", firstName);\n            sn = new BasicAttribute(\"sn\", lastName);\n        }\n        Attribute cn = new BasicAttribute(\"cn\", cnValue);\n        Attribute uid = new BasicAttribute(\"uid\", username);\n        Attribute mail = new BasicAttribute(\"mail\", email);\n\n        // Add password\n        Attribute userPassword = new BasicAttribute(\"userpassword\", password);\n        \n        // Add these to the container\n        container.put(objClasses);\n        container.put(cn);\n        container.put(sn);\n        container.put(givenName);\n        container.put(uid);\n        container.put(mail);\n        container.put(userPassword);\n\n        // Create the entry\n        context.createSubcontext(getUserDN(username), container);\n    }\n\n    public void deleteUser(String username) throws NamingException {\n        try {\n            context.destroySubcontext(getUserDN(username));\n        } catch (NameNotFoundException e) {\n            // If the user is not found, ignore the error\n        }\n    }\n\n    public boolean isValidUser(String username, String password)\n            throws Exception {\n\n        try {\n            getInitialContext(hostname, port, getUserDN(username), password);\n            return true;\n        } catch (javax.naming.NameNotFoundException e) {\n            throw new Exception(\"Authentication failed \" + username);\n        } catch (NamingException e) {\n            log.error(\"error\", e);\n            // Any other error indicates couldn't log user in\n            return false;\n        }\n    }\n\n    public void addGroup(String name, String description)\n            throws NamingException {\n\n        // Create a container set of attributes\n        Attributes container = new BasicAttributes();\n\n        // Create the objectclass to add\n        Attribute objClasses = new BasicAttribute(\"objectClass\");\n        objClasses.add(\"top\");\n        objClasses.add(\"groupOfNames\");\n\n        // Assign the name and description to the group\n        Attribute cn = new BasicAttribute(\"cn\", name);\n        Attribute desc = new BasicAttribute(\"description\", description);\n\n        // Add these to the container\n        container.put(objClasses);\n        container.put(cn);\n        container.put(desc);\n\n        try {\n            // Create the entry\n            context.createSubcontext(getGroupDN(name), container);\n        } catch (NameAlreadyBoundException e) {\n            log.info(\"Group already exist ..\");\n            // Group already added. ignore exception.\n        }\n    }\n\n    public void deleteGroup(String name) throws NamingException {\n        try {\n            context.destroySubcontext(getGroupDN(name));\n        } catch (NameNotFoundException e) {\n            // If the group is not found, ignore the error\n        }\n    }\n\n    public void assignUser(String username, String groupName) throws NamingException {\n\n        try {\n            ModificationItem[] mods = new ModificationItem[1];\n            Attribute mod = new BasicAttribute(\"member\", getUserDN(username));\n            mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, mod);\n            context.modifyAttributes(getGroupDN(groupName), mods);\n        } catch (AttributeInUseException e) {\n            // If user is already added, ignore exception\n        }\n    }\n\n    public void removeUser(String username, String groupName) throws NamingException {\n\n        try {\n            ModificationItem[] mods = new ModificationItem[1];\n            Attribute mod = new BasicAttribute(\"member\", getUserDN(username));\n            mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod);\n            context.modifyAttributes(getGroupDN(groupName), mods);\n        } catch (NoSuchAttributeException e) {\n            // If user is not assigned, ignore the error\n        }\n    }\n\n    public String getAttributeValue(String username, String attributeName) throws NamingException {\n\n        String attributeValue = null;\n\n        // Set up attributes to search for\n        String[] searchAttributes = new String[1];\n        searchAttributes[0] = attributeName;\n        Attributes attributes = context.getAttributes(getUserDN(username), searchAttributes);\n\n        if (attributes != null) {\n           attributeValue = attributes.get(attributeName).get().toString();\n        }\n\n        return attributeValue;\n    }\n\n    public void addUserAndAssignGroups(String username, String firstName, String lastName,\n                                       String password, String email, List<String> groups)\n            throws NamingException {\n\n        addUser(username, firstName, lastName, password, email);\n        if (groups != null) {\n            for (String group : groups) {\n                assignUser(username, group);\n\n            }\n        }\n    }\n\n\n    private String getUserDN(String username) {\n        return \"uid=\" + username + \",\" + USERS_OU;\n    }\n\n    private String getGroupDN(String name) {\n        return \"cn=\" + name + \",\" + GROUPS_OU;\n    }\n\n    private DirContext getInitialContext(String hostname, int port,\n                                         String username, String password)\n            throws NamingException {\n\n        String providerURL = \"ldap://\" + hostname + \":\" + port;\n\n        Properties props = new Properties();\n        props.put(Context.INITIAL_CONTEXT_FACTORY, \"com.sun.jndi.ldap.LdapCtxFactory\");\n        props.put(Context.PROVIDER_URL, providerURL);\n\n        if ((username != null) && (!username.equals(\"\"))) {\n            props.put(Context.SECURITY_AUTHENTICATION, \"simple\");\n            props.put(Context.SECURITY_PRINCIPAL, username);\n            props.put(Context.SECURITY_CREDENTIALS, (password == null) ? \"\" : password);\n        }\n\n        return new InitialDirContext(props);\n    }\n\n}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/ldap/server/ApacheDirectoryServerActivator.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.security.ldap.server;\n\nimport org.apache.commons.io.IOUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.apacheds.DirectoryServiceFactory;\nimport org.wso2.carbon.apacheds.KDCServer;\nimport org.wso2.carbon.apacheds.KdcConfiguration;\nimport org.wso2.carbon.apacheds.LDAPConfiguration;\nimport org.wso2.carbon.apacheds.LDAPServer;\nimport org.wso2.carbon.apacheds.PartitionInfo;\nimport org.wso2.carbon.apacheds.PartitionManager;\nimport org.wso2.carbon.ldap.server.exception.DirectoryServerException;\nimport org.wso2.carbon.ldap.server.util.EmbeddingLDAPException;\nimport org.wso2.msf4j.util.SystemVariableUtil;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Enumeration;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\n\n/**\n * This start the EmbeddedLDAP-server. Needs to have \"MSF4J_HOME\" system variable configured by\n * pointing to the directory that ldap data and config files get stored. If the \"MSF4J_HOME\" is not set\n * current working directory will use as the MSF4J_HOME\".\n */\npublic class ApacheDirectoryServerActivator {\n\n    private static final Logger log = LoggerFactory.getLogger(ApacheDirectoryServerActivator.class);\n\n    private String msf4jHome = SystemVariableUtil.getValue(\"MSF4J_HOME\", System.getProperty(\"user.dir\"));\n    private LDAPServer ldapServer;\n    private KDCServer kdcServer;\n\n    /**\n     * Starts EmbeddedLDAP-server.\n     */\n    public void start() {\n\n        try {\n            /*Configure embedded-ldap.xml and  default ldap schema, if those are not defined.*/\n            copyResources();\n\n            /*Read the embedded-ldap configuration file.*/\n            LDAPServerConfigurationBuilder configurationBuilder = new LDAPServerConfigurationBuilder(\n                    getLdapConfigurationFile());\n            /*Make relevant objects that encapsulate different parts of config file.*/\n            configurationBuilder.buildConfigurations();\n\n            boolean embeddedLDAPEnabled = configurationBuilder.isEmbeddedLDAPEnabled();\n            //start LDAPServer only if embedded-ldap is enabled.\n            if (embeddedLDAPEnabled) {\n\n                LDAPConfiguration ldapConfiguration = configurationBuilder.getLdapConfiguration();\n                /*set the embedded-apacheds's schema location which is: carbon-home/repository/data/\n                is-default-schema.zip\n                */\n                setSchemaLocation();\n\n                /* Set working directory where schema directory and ldap partitions are created*/\n                setWorkingDirectory(ldapConfiguration);\n\n                startLdapServer(ldapConfiguration);\n\n                /* replace default password with that is provided in the configuration file.*/\n                this.ldapServer.changeConnectionUserPassword(\n                        configurationBuilder.getConnectionPassword());\n\n                // Add admin (default)partition if it is not already created.\n                PartitionManager partitionManager = this.ldapServer.getPartitionManager();\n                PartitionInfo defaultPartitionInfo = configurationBuilder.getPartitionConfigurations();\n                boolean defaultPartitionAlreadyExisted =\n                        partitionManager.partitionDirectoryExists(defaultPartitionInfo.getPartitionId());\n\n                if (!defaultPartitionAlreadyExisted) {\n                    partitionManager.addPartition(defaultPartitionInfo);\n                    if (kdcServer == null) {\n                        kdcServer = DirectoryServiceFactory.createKDCServer(DirectoryServiceFactory.LDAPServerType.\n                                APACHE_DIRECTORY_SERVICE);\n                    }\n                    kdcServer.kerberizePartition(configurationBuilder.\n                            getPartitionConfigurations(), this.ldapServer);\n                } else {\n                    partitionManager.initializeExistingPartition(defaultPartitionInfo);\n                }\n\n                // Start KDC if enabled\n                if (configurationBuilder.isKdcEnabled()) {\n                    startKDC(configurationBuilder.getKdcConfigurations());\n                }\n\n                if (log.isDebugEnabled()) {\n                    log.debug(\"apacheds-server started.\");\n                }\n\n            } else {\n                //if needed, create a dummy tenant manager service and register it.\n                log.info(\"Embedded LDAP is disabled.\");\n            }\n\n        } catch (FileNotFoundException e) {\n            String errorMessage = \"Could not start the embedded-ldap. \";\n            log.error(errorMessage, e);\n\n        } catch (DirectoryServerException e) {\n            String errorMessage = \"Could not start the embedded-ldap. \";\n            log.error(errorMessage, e);\n\n        } catch (EmbeddingLDAPException e) {\n            String errorMessage = \"Could not start the embedded-ldap. \";\n            log.error(errorMessage, e);\n        } catch (Exception e) {\n            String errorMessage = \"An unknown exception occurred while starting LDAP server. \";\n            log.error(errorMessage, e);\n        } catch (Throwable e) {\n            String errorMessage = \"An unknown error occurred while starting LDAP server. \";\n            log.error(errorMessage, e);\n        }\n\n    }\n\n    private void setSchemaLocation() throws EmbeddingLDAPException {\n\n        String schemaLocation = \"repository\" + File.separator + \"data\" + File.separator +\n                \"is-default-schema.zip\";\n        File dataDir = new File(getCarbonHome(), schemaLocation);\n\n        // Set schema location\n        System.setProperty(\"schema.zip.store.location\", dataDir.getAbsolutePath());\n    }\n\n    private String getCarbonHome() throws EmbeddingLDAPException {\n        return msf4jHome;\n    }\n\n    private File getLdapConfigurationFile() throws EmbeddingLDAPException {\n\n        String configurationFilePath = \"repository\" + File.separator + \"conf\" + File.separator +\n                \"embedded-ldap.xml\";\n        return new File(getCarbonHome(), configurationFilePath);\n    }\n\n    private void setWorkingDirectory(LDAPConfiguration ldapConfiguration)\n            throws EmbeddingLDAPException {\n\n        if (ldapConfiguration.getWorkingDirectory().equals(\".\")) {\n            File dataDir = new File(getCarbonHome(), \"repository\" + File.separator + \"data\");\n            if (!dataDir.exists()) {\n                if (!dataDir.mkdir()) {\n                    String msg = \"Unable to create data directory at \" + dataDir.getAbsolutePath();\n                    log.error(msg);\n                    throw new EmbeddingLDAPException(msg);\n                }\n            }\n\n            File bundleDataDir = new File(dataDir, \"org.wso2.carbon.directory\");\n            if (!bundleDataDir.exists()) {\n                if (!bundleDataDir.mkdirs()) {\n                    String msg = \"Unable to create schema data directory at \" + bundleDataDir.\n                            getAbsolutePath();\n                    log.error(msg);\n                    throw new EmbeddingLDAPException(msg);\n\n                }\n            }\n\n            ldapConfiguration.setWorkingDirectory(bundleDataDir.getAbsolutePath());\n        }\n    }\n\n    private void startLdapServer(LDAPConfiguration ldapConfiguration)\n            throws DirectoryServerException {\n\n        this.ldapServer = DirectoryServiceFactory.createLDAPServer(DirectoryServiceFactory.\n                LDAPServerType.APACHE_DIRECTORY_SERVICE);\n\n        log.info(\"Initializing Directory Server with working directory \" + ldapConfiguration.\n                getWorkingDirectory() + \" and port \" + ldapConfiguration.getLdapPort());\n\n        this.ldapServer.init(ldapConfiguration);\n\n        this.ldapServer.start();\n    }\n\n    private void startKDC(KdcConfiguration kdcConfiguration)\n            throws DirectoryServerException {\n\n        if (kdcServer == null) {\n            kdcServer = DirectoryServiceFactory\n                    .createKDCServer(DirectoryServiceFactory.LDAPServerType.APACHE_DIRECTORY_SERVICE);\n        }\n        kdcServer.init(kdcConfiguration, this.ldapServer);\n\n        kdcServer.start();\n\n    }\n\n    public void stop() throws Exception {\n\n        if (this.kdcServer != null) {\n            this.kdcServer.stop();\n        }\n\n        if (this.ldapServer != null) {\n\n            this.ldapServer.stop();\n        }\n    }\n\n    private void copyResources() throws IOException, EmbeddingLDAPException {\n\n        final File jarFile = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());\n\n        final String repositoryDirectory = \"repository\";\n        final File destinationRoot = new File(getCarbonHome());\n\n        //Check whether ladap configs are already configured\n        File repository = new File(getCarbonHome() + File.separator + repositoryDirectory);\n\n        if (!repository.exists()) {\n            JarFile jar = null;\n\n            try {\n                jar = new JarFile(jarFile);\n\n                final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar\n\n                while (entries.hasMoreElements()) {\n                    JarEntry entry = entries.nextElement();\n\n                    // Skip if the entry is not about the 'repository' directory.\n                    if (!entry.getName().startsWith(repositoryDirectory)) {\n                        continue;\n                    }\n\n                    // If the entry is a directory create the relevant directory in the destination.\n                    File destination = new File(destinationRoot, entry.getName());\n                    if (entry.isDirectory()) {\n                        if (destination.mkdirs()) {\n                            continue;\n                        }\n                    }\n\n                    InputStream in = null;\n                    OutputStream out = null;\n\n                    try {\n                        // If the entry is a file, copy the file to the destination\n                        in = jar.getInputStream(entry);\n                        out = new FileOutputStream(destination);\n                        IOUtils.copy(in, out);\n                        IOUtils.closeQuietly(in);\n                    } finally {\n                        if (out != null) {\n                            out.close();\n                        }\n                        if (in != null) {\n                            in.close();\n                        }\n                    }\n                }\n            } finally {\n                if (jar != null) {\n                    jar.close();\n\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/java/org/wso2/msf4j/examples/petstore/security/ldap/server/LDAPServerConfigurationBuilder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.security.ldap.server;\n\nimport org.apache.axiom.om.OMElement;\nimport org.apache.axiom.om.impl.builder.StAXOMBuilder;\nimport org.apache.log4j.Logger;\nimport org.wso2.carbon.apacheds.AdminGroupInfo;\nimport org.wso2.carbon.apacheds.AdminInfo;\nimport org.wso2.carbon.apacheds.KdcConfiguration;\nimport org.wso2.carbon.apacheds.LDAPConfiguration;\nimport org.wso2.carbon.apacheds.PartitionInfo;\nimport org.wso2.carbon.apacheds.PasswordAlgorithm;\nimport org.wso2.carbon.ldap.server.exception.DirectoryServerException;\nimport org.wso2.carbon.ldap.server.util.EmbeddingLDAPException;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.InputStream;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport javax.xml.namespace.QName;\nimport javax.xml.stream.XMLStreamException;\n\n/**\n * This class is responsible for building LDAP and KDC configurations. Given a file\n * name this will read configuration values and populate them into configuration classes.\n * Related configuration file is embedded-ldap.xml.\n */\npublic class LDAPServerConfigurationBuilder {\n\n    private Logger logger = Logger.getLogger(LDAPServerConfigurationBuilder.class);\n\n    public static final java.lang.String LOCAL_NAME_PROPERTY = \"Property\";\n\n    public static final java.lang.String ATTR_NAME_PROP_NAME = \"name\";\n\n    private InputStream configurationFileStream;\n    /*Password to connect with the embedded-ldap server*/\n    private String connectionPassword;\n    /*contains embedded-ldap server configurations*/\n    private LDAPConfiguration ldapConfiguration;\n    /*contains default partition's configurations*/\n    private PartitionInfo partitionConfigurations;\n    /*contains KDC server configurations*/\n    private KdcConfiguration kdcConfigurations;\n\n    private boolean kdcEnabled = false;\n\n    private static final String CARBON_KDC_PORT_CONFIG_SECTION = \"Ports.EmbeddedLDAP.KDCServerPort\";\n    private static final int DEFAULT_KDC_SERVER_PORT = 8000;\n\n    /**\n     * Constructor with the configuration file as input that reads the file into an InputStream.\n     *\n     * @param file that includes embedded-ldap server configurations.\n     * @throws FileNotFoundException\n     */\n    public LDAPServerConfigurationBuilder(File file) throws FileNotFoundException {\n\n        if (!file.exists()) {\n            String msg = \"File not found. - \" + file.getAbsolutePath();\n            logger.error(msg);\n            throw new FileNotFoundException(msg);\n        }\n\n        try {\n            configurationFileStream = new FileInputStream(file);\n        } catch (FileNotFoundException e) {\n            String msg = \"Could not open file - \" + file.getAbsolutePath();\n            logger.error(msg);\n            throw new FileNotFoundException(msg);\n        }\n\n    }\n\n    /**\n     * Build separate sections of the configuration file and the configuration file as a whole, as\n     * OMElements.\n     *\n     * @throws org.wso2.carbon.ldap.server.util.EmbeddingLDAPException\n     */\n    public void buildConfigurations() throws EmbeddingLDAPException {\n\n        StAXOMBuilder builder;\n\n        try {\n            builder = new StAXOMBuilder(configurationFileStream);\n        } catch (XMLStreamException e) {\n            logger.error(\"Unable to build LDAP configurations.\", e);\n            throw new EmbeddingLDAPException(\"Unable to build LDAP configurations\", e);\n        }\n        /*Read the whole config file as an OMElement*/\n        OMElement documentElement = builder.getDocumentElement();\n\n        /*Extract the part that contains embedded-ldap specific configurations*/\n        OMElement embeddedLdap = documentElement.getFirstChildWithName(new QName(\"EmbeddedLDAP\"));\n        /*Set properties in ldapConfiguration object from those read from the config element.*/\n        buildLDAPConfigurations(embeddedLdap);\n\n        if (ldapConfiguration.isEnable()) {\n            /*Set properties in partitionConfigurations object from those read from the config file.*/\n            buildPartitionConfigurations(documentElement);\n\n            /*Extract the part that contains kdc-server specific configurations*/\n            OMElement kdcConfigElement = documentElement.getFirstChildWithName(new QName(\"KDCServer\"));\n            /*Set properties in kdcConfiguration object from those read from the config element.*/\n            buildKDCConfigurations(kdcConfigElement);\n\n            /*Says root partition that KDC is enabled. Root partition admin should have KDC object\n          attributes in LDAP*/\n            this.partitionConfigurations.setKdcEnabled(this.kdcEnabled);\n\n            // Do some cross checking\n            if (this.kdcEnabled) {\n\n                this.kdcConfigurations.setSystemAdminPassword(this.getConnectionPassword());\n\n                // Set admin partition for KDC\n                this.kdcConfigurations.setPartitionInfo(this.getPartitionConfigurations());\n\n            }\n        }\n    }\n\n    public String getConnectionPassword() throws EmbeddingLDAPException {\n        if (connectionPassword == null) {\n            buildConfigurations();\n        }\n        return connectionPassword;\n    }\n\n    public LDAPConfiguration getLdapConfiguration() throws EmbeddingLDAPException {\n        if (ldapConfiguration == null) {\n            buildConfigurations();\n        }\n        return ldapConfiguration;\n    }\n\n    /**\n     * Read and set the connection password from the property map.\n     *\n     * @param propertyMap : containing properties of EmbeddedLDAP Element.\n     * @throws org.wso2.carbon.ldap.server.util.EmbeddingLDAPException\n     */\n    private void buildConnectionPassword(Map<String, String> propertyMap)\n            throws EmbeddingLDAPException {\n\n        connectionPassword = propertyMap.get(\"connectionPassword\");\n        if (connectionPassword == null) {\n            throw new EmbeddingLDAPException(\"Connection password not specified in the \" +\n                    \"configuration file.\");\n        }\n\n    }\n\n    /**\n     * Read properties from EmbeddedLDAP element in configuration and set them in the\n     * ldapConfiguration object.\n     *\n     * @param embeddedLDAP: part of the XML config file named: EmbeddedLDAP\n     * @throws org.wso2.carbon.ldap.server.util.EmbeddingLDAPException\n     */\n    private void buildLDAPConfigurations(OMElement embeddedLDAP) throws EmbeddingLDAPException {\n        /*Read the properties of EmbeddedLDAP XML element.*/\n        Map<String, String> propertyMap = getChildPropertyElements(embeddedLDAP);\n\n        ldapConfiguration = new LDAPConfiguration();\n        /*set connectionPassword*/\n        buildConnectionPassword(propertyMap);\n        String booleanString;\n\n        if ((booleanString = propertyMap.get(\"accessControlEnabled\")) != null) {\n            ldapConfiguration.setAccessControlOn(Boolean.parseBoolean(booleanString));\n        }\n\n        if ((booleanString = propertyMap.get(\"allowAnonymousAccess\")) != null) {\n            ldapConfiguration.setAllowAnonymousAccess(Boolean.parseBoolean(booleanString));\n        }\n\n        if ((booleanString = propertyMap.get(\"changedLogEnabled\")) != null) {\n            ldapConfiguration.setChangeLogEnabled(Boolean.parseBoolean(booleanString));\n        }\n\n        if ((booleanString = propertyMap.get(\"denormalizeOpAttrsEnabled\")) != null) {\n            ldapConfiguration.setDeNormalizedAttributesEnabled(Boolean.parseBoolean(booleanString));\n        }\n        //check and set whether embedded ldap is enabled.\n        String enableInfo = propertyMap.get(\"enable\");\n\n        if ((\"true\").equals(enableInfo)) {\n            ldapConfiguration.setEnable(true);\n        } else {\n            ldapConfiguration.setEnable(false);\n        }\n        ldapConfiguration.setInstanceId(propertyMap.get(\"instanceId\"));\n\n        //Set LDAP server port\n        ldapConfiguration.setLdapPort(Integer.parseInt(propertyMap.get(\"port\")));\n\n        ldapConfiguration.setWorkingDirectory(propertyMap.get(\"workingDirectory\"));\n        ldapConfiguration.setAdminEntryObjectClass(propertyMap.get(\"AdminEntryObjectClass\"));\n        ldapConfiguration.setMaxPDUSize(getIntegerValue(propertyMap.get(\"maxPDUSize\")));\n        ldapConfiguration.setSaslHostName(propertyMap.get(\"saslHostName\"));\n        ldapConfiguration.setSaslPrincipalName(propertyMap.get(\"saslPrincipalName\"));\n    }\n\n    private int getIntegerValue(String value) {\n        if (value != null) {\n            return Integer.parseInt(value);\n        }\n\n        return -1;\n\n    }\n\n    /**\n     * Reads the properties mentioned under the XML Element in the config file, which is passed\n     * as an OMElement to the method.\n     *\n     * @param omElement : main XML element whose properties should be read\n     * @return : the map containing property names and the values.\n     */\n    private Map<String, String> getChildPropertyElements(OMElement omElement) {\n        Map<String, String> map = new HashMap<String, String>();\n        Iterator<?> ite = omElement.getChildrenWithName(new QName(LOCAL_NAME_PROPERTY));\n        while (ite.hasNext()) {\n            OMElement propElem = (OMElement) ite.next();\n            String propName = propElem.getAttributeValue(new QName(ATTR_NAME_PROP_NAME));\n            String propValue = propElem.getText();\n            map.put(propName, propValue);\n        }\n        return map;\n    }\n\n    /**\n     * Read properties related to default partition and set them in partitionConfigurations object.\n     *\n     * @param documentElement: whole config file read as an OMElement.\n     *                         Following parts are read from the config file:\n     *                         <p>\n     *                         Default partition configurations\n     *                         <p>\n     *                         &lt;DefaultPartition&gt;\n     *                         &lt;Property name=\"id\"&gt;root &lt;/Property&gt;\n     *                         &lt;Property name=\"realm\"&gt;wso2.com &lt;/Property&gt;\n     *                         &lt;Property name=\"kdcPassword\"&gt;secret &lt;/Property&gt;\n     *                         &lt;Property name=\"ldapServerPrinciplePassword\"&gt;randall &lt;/Property&gt;\n     *                         &lt;/DefaultPartition&gt;\n     *                         <p>\n     *                         Default partition admin configurations\n     *                         <p>\n     *                         &lt;PartitionAdmin&gt;\n     *                         &lt;Property name=\"uid\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"commonName\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"lastName\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"email\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"password\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"passwordType\"&gt;SHA&lt;/Property&gt;\n     *                         &lt;/PartitionAdmin>\n     *                         <p>\n     *                         Default partition admin's group configuration\n     *                         <p>\n     *                         &lt;PartitionAdminGroup&gt;\n     *                         &lt;Property name=\"adminRoleName\"&gt;admin&lt;/Property&gt;\n     *                         &lt;Property name=\"groupNameAttribute\"&gt;cn&lt;/Property&gt;\n     *                         &lt;Property name=\"memberNameAttribute\"&gt;member&lt;/Property&gt;\n     *                         &lt;/PartitionAdminGroup&gt;\n     */\n    private void buildPartitionConfigurations(OMElement documentElement) {\n\n        this.partitionConfigurations = new PartitionInfo();\n\n        OMElement defaultPartition = documentElement.getFirstChildWithName(new QName(\"DefaultPartition\"));\n        Map<String, String> propertyMap = getChildPropertyElements(defaultPartition);\n\n        this.partitionConfigurations.setPartitionId(propertyMap.get(\"id\"));\n        this.partitionConfigurations.setRealm(propertyMap.get(\"realm\"));\n\n        this.partitionConfigurations.setPartitionKdcPassword(propertyMap.get(\"kdcPassword\"));\n        this.partitionConfigurations.setLdapServerPrinciplePassword(propertyMap.get(\"ldapServerPrinciplePassword\"));\n        this.partitionConfigurations.setRootDN(getDomainNameForRealm(propertyMap.get(\"realm\")));\n\n        // Admin user config\n        OMElement partitionAdmin = documentElement.getFirstChildWithName(new QName(\"PartitionAdmin\"));\n        propertyMap = getChildPropertyElements(partitionAdmin);\n        AdminInfo defaultPartitionAdmin = buildPartitionAdminConfigurations(propertyMap);\n\n        // Admin role config\n        OMElement partitionAdminRole = documentElement.getFirstChildWithName(new QName(\"PartitionAdminGroup\"));\n        propertyMap = getChildPropertyElements(partitionAdminRole);\n        AdminGroupInfo adminGroupInfo = buildPartitionAdminGroupConfigurations(propertyMap);\n\n        defaultPartitionAdmin.setGroupInformation(adminGroupInfo);\n        this.partitionConfigurations.setPartitionAdministrator(defaultPartitionAdmin);\n\n    }\n\n    private AdminInfo buildPartitionAdminConfigurations(Map<String, String> propertyMap) {\n        AdminInfo adminInfo = new AdminInfo();\n\n        adminInfo.setAdminUserName(propertyMap.get(\"uid\"));\n        adminInfo.setAdminCommonName(propertyMap.get(\"firstName\"));\n        adminInfo.setAdminLastName(propertyMap.get(\"lastName\"));\n        adminInfo.setAdminEmail(propertyMap.get(\"email\"));\n        adminInfo.setAdminPassword(propertyMap.get(\"password\"));\n        adminInfo.setPasswordAlgorithm(PasswordAlgorithm.valueOf(propertyMap.get(\"passwordType\")));\n        adminInfo.addObjectClass(ldapConfiguration.getAdminEntryObjectClass());\n        adminInfo.setUsernameAttribute(\"uid\");\n\n        return adminInfo;\n    }\n\n    private AdminGroupInfo buildPartitionAdminGroupConfigurations(Map<String, String> propertyMap) {\n        AdminGroupInfo adminGroupInfo = new AdminGroupInfo();\n        adminGroupInfo.setAdminRoleName(propertyMap.get(\"adminRoleName\"));\n        adminGroupInfo.setGroupNameAttribute(propertyMap.get(\"groupNameAttribute\"));\n        adminGroupInfo.setMemberNameAttribute(propertyMap.get(\"memberNameAttribute\"));\n        return adminGroupInfo;\n    }\n\n    private String getDomainNameForRealm(String realm) {\n\n        if (realm == null) {\n            return null;\n        }\n\n        String[] components = realm.split(\"\\\\.\");\n\n        if (components.length == 0) {\n            return \"dc=\" + realm;\n        }\n\n        StringBuilder domainName = new StringBuilder();\n\n        for (int i = 0; i < components.length; ++i) {\n            domainName.append(\"dc=\");\n            domainName.append(components[i]);\n\n            if (i != (components.length - 1)) {\n                domainName.append(\",\");\n            }\n        }\n\n        return domainName.toString();\n    }\n\n    public PartitionInfo getPartitionConfigurations() throws EmbeddingLDAPException {\n        if (partitionConfigurations == null) {\n            buildConfigurations();\n        }\n        return partitionConfigurations;\n    }\n\n    public KdcConfiguration getKdcConfigurations() throws EmbeddingLDAPException {\n        if (kdcConfigurations == null) {\n            buildConfigurations();\n        }\n        return kdcConfigurations;\n    }\n\n    public boolean isKdcEnabled() {\n        return kdcEnabled;\n    }\n\n    /**\n     * Read properties from KDCConfiguration element in configuration and set them in the\n     * kdcConfigurations object.\n     * KDC configurations\n     * <p>\n     * &lt;KDCServer&gt;\n     * &lt;Property name=\"name\"&gt;defaultKDC&lt;/Property&gt;\n     * &lt;Property name=\"enabled\"&gt;false&lt;/Property&gt;\n     * &lt;Property name=\"protocol\"&gt;UDP&lt;/Property&gt;\n     * &lt;Property name=\"host\"&gt;localhost&lt;/Property&gt;\n     * &lt;Property name=\"maximumTicketLifeTime\"&gt;8640000&lt;/Property&gt;\n     * &lt;Property name=\"maximumRenewableLifeTime\"&gt;604800000&lt;/Property&gt;\n     * &lt;Property name=\"preAuthenticationTimeStampEnabled\"&gt;true&lt;/Property&gt;\n     * &lt;/KDCServer&gt;\n     *\n     * @param kdcConfigElement\n     * @throws org.wso2.carbon.ldap.server.util.EmbeddingLDAPException\n     */\n    private void buildKDCConfigurations(OMElement kdcConfigElement)\n            throws EmbeddingLDAPException {\n        Map<String, String> propertyMap = getChildPropertyElements(kdcConfigElement);\n        String booleanString;\n        if ((booleanString = propertyMap.get(\"enabled\")) != null) {\n            this.kdcEnabled = Boolean.parseBoolean(booleanString);\n            if (!this.kdcEnabled) {\n                logger.info(\"KDC server is disabled.\");\n                return;\n            }\n        } else {\n            logger.info(\"KDC server is disabled.\");\n            return;\n        }\n        this.kdcConfigurations = new KdcConfiguration();\n        this.kdcConfigurations.setKdcName(propertyMap.get(\"name\"));\n        try {\n            this.kdcConfigurations.setKdcCommunicationProtocol(propertyMap.get(\"protocol\"));\n        } catch (DirectoryServerException e) {\n            String errorMessage = \"Can not read/set protocol parameter in KDCConfig.\";\n            logger.error(errorMessage, e);\n            throw new EmbeddingLDAPException(errorMessage, e);\n        }\n        this.kdcConfigurations.setKdcHostAddress(propertyMap.get(\"host\"));\n\n        //Read KDC port from carbon.xml and set it\n        int port = Integer.parseInt(propertyMap.get(\"port\"));\n        if (port == -1) {\n            logger.warn(\"KDC port defined in carbon.xml's \" + CARBON_KDC_PORT_CONFIG_SECTION +\n                    \" config section or embedded-ldap.xml is invalid. \" +\n                    \"Setting KDC server port to default - \" + DEFAULT_KDC_SERVER_PORT);\n            port = DEFAULT_KDC_SERVER_PORT;\n        }\n\n        this.kdcConfigurations.setKdcCommunicationPort(port);\n\n        this.kdcConfigurations.setMaxTicketLifeTime(getIntegerValue(propertyMap.get(\n                \"maximumTicketLifeTime\")));\n        this.kdcConfigurations.setMaxRenewableLifeTime(getIntegerValue(propertyMap.get(\n                \"maximumRenewableLifeTime\")));\n\n        if ((booleanString = propertyMap.get(\"preAuthenticationTimeStampEnabled\")) != null) {\n            boolean preAuthenticationTSEnabled = Boolean.parseBoolean(booleanString);\n            this.kdcConfigurations.setPreAuthenticateTimeStampRequired(preAuthenticationTSEnabled);\n        }\n    }\n\n    public boolean isEmbeddedLDAPEnabled() {\n        return ldapConfiguration.isEnable();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/resources/http-monitoring.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\nenabled: true\n\ndas:\n  receiverURL: ${HTTP_MONITORING_DAS_RECEIVERURL}\n  # authURL: ssl://localhost:7711\n  type: thrift\n  username: admin\n  password: admin\n  dataAgentConfigPath: ${HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH}\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/resources/metrics.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nenabled: true\n\njmx:\n  registerMBean: true\n  name: org.wso2.msf4j:type=Metrics\n\ndas:\n  - &DAS01\n    receiverURL: ${METRICS_REPORTING_DAS_RECEIVERURL}\n    # authURL: ssl://localhost:7711\n    type: thrift\n    username: admin\n    password: admin\n    dataAgentConfigPath: ${METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH}\n\nreporting:\n  jmx:\n    - name: JMX\n      enabled: true\n\n  console:\n    - name: Console\n      enabled: false\n      pollingPeriod: 60\n\n  csv:\n    - name: CSV\n      enabled: false\n      location: metrics\n      pollingPeriod: 60\n\n  slf4j:\n    - name: SLF4J\n      enabled: false\n      loggerName: metrics\n      pollingPeriod: 60\n\n  das:\n    - name: DAS\n      enabled: true\n      das: *DAS01\n      pollingPeriod: 60\n"
  },
  {
    "path": "samples/petstore/microservices/security/src/main/resources/repository/conf/embedded-ldap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\tAll carbon based products comes with a LDAP user store. \n\tFor this we use an embedded LDAP in carbon based products. \n\tThis file contains necessary configurations to control the behavior of embedded LDAP.\n\tYou may use this file to enable, disable LDAP server, configure connection admin password, etc ...\n\tIn addition to embedded-ldap server configurations this file also has Kerberos KDC (Key Distribution Center) \n\tspecific configurations.\n-->\n\n<EmbeddedLDAPConfig>\n\n  <!-- \n\tLDAP server configurations \n\t==========================\n\tThis section contains LDAP server specific configurations.\n\n\tProperty                Usage\n\t=======                 ====\n\tenable                  If true the embedded LDAP server will start when server starts up.\n\t\t\t\t            Else embedded LDAP server will not start. Thus user has to use a different\n\t\t\t\t            user store.\n\tinstanceid              An id given to the LDAP server instance.\n\tconnectionPassword      The password of the admin. (uid=admin,ou=system)\n\tworkingDirectory        Location where LDAP will store its schema files.\n\tAdminEntryObjectClass   Object class which encapsulate attributes needed by claims.\n\tallowAnonymousAccess    Should allow users to access LDAP server without credentials. Default false.\n\taccessControlEnabled    Should access control be enabled among partitions. Default true.\n\tsaslHostName            Default host name to be used in SASL (Simple Authentication and Security Layer).\n\t\t\t\t            This property comes from apacheds implementation itself.\n\tsaslPrincipalName       Default SASL principal name. Again this property also comes from apacheds implementation\n\t\t\t\t            itself.\n  -->\n  <EmbeddedLDAP>\n    <Property name=\"enable\">true</Property>\n    <Property name=\"port\">10389</Property>\n    <Property name=\"instanceId\">default</Property>\n    <Property name=\"connectionPassword\">admin</Property>\n    <Property name=\"workingDirectory\">.</Property>\n    <Property name=\"AdminEntryObjectClass\">identityPerson</Property>\n    <Property name=\"allowAnonymousAccess\">false</Property>\n    <Property name=\"accessControlEnabled\">true</Property>\n    <Property name=\"denormalizeOpAttrsEnabled\">false</Property>\n    <Property name=\"maxPDUSize\">2000000</Property>\n    <Property name=\"saslHostName\">localhost</Property>\n    <Property name=\"saslPrincipalName\">ldap/localhost@EXAMPLE.COM</Property>\n  </EmbeddedLDAP>\n\n  <!-- \n\tDefault partition configurations\n\t================================ \n\tWhen embedded LDAP server starts for the first time it will create a default partition. \n\tFollowing properties configure values for the default partition.\n\t\n\tProperty                        Usage\n\t=======                         =====\n\tid                              Each partition is given an id. The id given to the default paritition.\n\trealm                           Realm is the place where we store user principals and service principals.\n                                        The name of the realm for default partition.\n\tkdcPassword                     This parameter is used when KDC (Key Distribution Center) is enabled. In apacheds\n                                        KDC also has a server principal. This defines a password for KDC server principal.\n\tldapServerPrinciplePassword     If LDAP server is also defined as a server principal, this will be the password.\n\t\n  -->\n  <DefaultPartition>\n    <Property name=\"id\">root</Property>\n    <Property name=\"realm\">WSO2.ORG</Property>    \n    <Property name=\"kdcPassword\">secret</Property>\n    <Property name=\"ldapServerPrinciplePassword\">randall</Property>\n  </DefaultPartition>\n\n  <!-- \n\tDefault partition admin configurations\n\t======================================\n\tIn a multi-tenant scenario each tenant will have a separate partition. Thus tenant admin will be the partition admin.\n\tFollowing configurations define admin attributes for above created default partition.\n\n\tProperty            Usage\n\t========            =====\n\tuid                 UID attribute for partition admin.\n\tcommonName          The cn attribute for admin\n\tlastName            The sn attribute for admin\n\temail               The email attribute for admin\n\tpasswordType        The password hashing mechanism. Following hashing mechanisms are available, \"SHA\", \"MD5\".\n                        \"PLAIN_TEXT\" is also a valid value. If KDC is enabled password type will be enforced to be\n                        plain text.\n  -->\n  <PartitionAdmin>\n    <Property name=\"uid\">admin</Property>\n    <Property name=\"firstName\">admin</Property>\n    <Property name=\"lastName\">admin</Property>\n    <Property name=\"email\">admin@wso2.com</Property>\n    <Property name=\"password\">admin</Property>\n    <Property name=\"passwordType\">PLAIN_TEXT</Property>\n  </PartitionAdmin>\n\n  <!-- \n\tDefault partition admin's group configuration \n\t=============================================\n\tEmbedded LDAP is capable of keeping group information also.\n\tIf LDAP groups are enabled in user store (usr-mgt.xml) group information will be\n\trecorded in a separate sub-context. Following configuration defines the group\n\tproperties.\n\n\tProperty                Usage\n\t=======                 =====\n\tadminRoleName\t\t    The name of the role/group that admin should be included.\n\tgroupNameAttribute\t    The attribute which group name will be recorded.\n\tmemberNameAttribute\t    The attribute which memebers are recorded.\n  -->\n  <PartitionAdminGroup>\n    <Property name=\"adminRoleName\">admin</Property>\n    <Property name=\"groupNameAttribute\">cn</Property>\n    <Property name=\"memberNameAttribute\">member</Property>\n  </PartitionAdminGroup>\n\n    <!--\n      KDC configurations\n      =================\n      Following configurations are applicable to KDC server. Generally, the KDC is only enabled in\n      Identity Server. You may enable KDC server if you wish to do so. But if you dont have any Kerberos specific\n      programs, it is recommended to disable KDC server.\n\n      Property                          Usage\n      =======                           =====\n      name                              Name given to default KDC server.\n      enabled                           If true a KDC server will start when starting LDAP server.\n                                          Else a KDC server will not start with a LDAP server.\n      protocol                          Default protocol to be used in KDC communication. Default is UDP.\n      maximumTicketLifeTime             The maximum life time of a ticket issued by the KDC.\n      maximumRenewableLifeTime          Life time which a ticket can be used by renewing it several times.\n      preAuthenticationTimeStampEnabled Pre-authentication is a feature in latest Kerberos protocol.\n                                          This property says whether to enable it or disable it.\n    -->\n  <KDCServer>\n    <Property name=\"name\">defaultKDC</Property>\n    <Property name=\"enabled\">false</Property>\n    <Property name=\"protocol\">UDP</Property>\n    <Property name=\"host\">localhost</Property>\n    <Property name=\"port\">10389</Property>\n    <Property name=\"maximumTicketLifeTime\">8640000</Property>\n    <Property name=\"maximumRenewableLifeTime\">604800000</Property>\n    <Property name=\"preAuthenticationTimeStampEnabled\">true</Property>\n  </KDCServer>\n\n</EmbeddedLDAPConfig>\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/README.md",
    "content": "Transaction Microservice in the Pet store sample"
  },
  {
    "path": "samples/petstore/microservices/transaction/container/docker/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM java:8-jre\nMAINTAINER architecture@wso2.org\n\nWORKDIR /opt\n\n# --------------------------------\n# Copy scripts, packages & plugins\n# --------------------------------\nCOPY packages/petstore-txn.jar /opt/\nCOPY packages/client-truststore.jks /opt/\nCOPY packages/data-agent-conf.xml /opt/\n\n# --------------------------------\n# HTTP Monitoring and metrics specific config\n# --------------------------------\nENV METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV METRICS_REPORTING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\nENV HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH data-agent-conf.xml\nENV HTTP_MONITORING_DAS_RECEIVERURL \"tcp://172.17.8.1:7612\"\n\n# ----------------------\n# Expose container ports\n# ----------------------\nEXPOSE 8080\n\nENTRYPOINT java -jar /opt/petstore-txn.jar\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/container/kubernetes/txn-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: txn\n  labels:\n    name: txn\nspec:\n  replicas: 1\n  selector:\n    name: txn\n  template:\n    metadata:\n      labels:\n        name: txn\n    spec:\n      containers:\n      - name: txn\n        image: wso2msf4j/petstore-txn:2.0.0\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n          # If your cluster config does not include a dns service, then to\n          # instead access environment variables to find service host\n          # info, comment out the 'value: dns' line above, and uncomment the\n          # line below.\n          # value: env\n        - name: SENTINEL1_HOST\n          value: redis-sentinel\n        - name: SENTINEL1_PORT\n          value: \"26379\"\n        ports:\n        - containerPort: 8080\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/container/kubernetes/txn-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: txn\n  labels:\n    name: txn\nspec:\n  # if your cluster supports it, uncomment the following to automatically create\n  # an external load-balanced IP for the frontend service.\n  # type: LoadBalancer\n  ports:\n    # the port that this service should serve on\n    - port: 80\n      targetPort: 8080\n\n  type: NodePort\n  selector:\n    name: txn"
  },
  {
    "path": "samples/petstore/microservices/transaction/data-agent-conf.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<DataAgentsConfiguration>\n    <Agent>\n        <Name>Thrift</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.thrift.ThriftDataEndpoint</DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n\n    <Agent>\n        <Name>Binary</Name>\n        <DataEndpointClass>org.wso2.carbon.databridge.agent.endpoint.binary.BinaryDataEndpoint\n        </DataEndpointClass>\n        <TrustSore>client-truststore.jks</TrustSore>\n        <TrustSorePassword>wso2carbon</TrustSorePassword>\n        <QueueSize>32768</QueueSize>\n        <BatchSize>200</BatchSize>\n        <CorePoolSize>5</CorePoolSize>\n        <MaxPoolSize>10</MaxPoolSize>\n        <KeepAliveTimeInPool>20</KeepAliveTimeInPool>\n        <ReconnectionInterval>30</ReconnectionInterval>\n        <MaxTransportPoolSize>250</MaxTransportPoolSize>\n        <MaxIdleConnections>250</MaxIdleConnections>\n        <EvictionTimePeriod>5500</EvictionTimePeriod>\n        <MinIdleTimeInPool>5000</MinIdleTimeInPool>\n        <SecureMaxTransportPoolSize>250</SecureMaxTransportPoolSize>\n        <SecureMaxIdleConnections>250</SecureMaxIdleConnections>\n        <SecureEvictionTimePeriod>5500</SecureEvictionTimePeriod>\n        <SecureMinIdleTimeInPool>5000</SecureMinIdleTimeInPool>\n    </Agent>\n</DataAgentsConfiguration>\n\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore-txn</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: [Pet Store] - Pet store microservices example - transaction microservice</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-analytics</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.nimbusds</groupId>\n            <artifactId>nimbus-jose-jwt</artifactId>\n            <version>2.25</version>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>petstore-util</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.examples.petstore.transaction.Runner</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/src/main/java/org/wso2/msf4j/examples/petstore/transaction/Runner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.transaction;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitoringInterceptor;\nimport org.wso2.msf4j.analytics.metrics.MetricsInterceptor;\nimport org.wso2.msf4j.security.JWTSecurityInterceptor;\n\n/**\n * Microservice runner for the pet microservices.\n */\npublic class Runner {\n    public static void main(String[] args) {\n        JWTSecurityInterceptor jwtSecurityInterceptor = new JWTSecurityInterceptor();\n        HTTPMonitoringInterceptor httpMonitoringInterceptor = new HTTPMonitoringInterceptor();\n        MetricsInterceptor metricsInterceptor = new MetricsInterceptor();\n\n        new MicroservicesRunner()\n                .addGlobalRequestInterceptor(jwtSecurityInterceptor, httpMonitoringInterceptor, metricsInterceptor)\n                .addGlobalResponseInterceptor(httpMonitoringInterceptor, metricsInterceptor)\n                .deploy(new TxnService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/src/main/java/org/wso2/msf4j/examples/petstore/transaction/TxnConstants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.transaction;\n\n/**\n * Constants used in the transaction service.\n */\npublic final class TxnConstants {\n\n    public static final String ORDERS_KEY = \"petstore:transaction:orders\";\n\n    public static final String ORDER_KEY_PREFIX = \"petstore:transaction:order.\";\n\n}\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/src/main/java/org/wso2/msf4j/examples/petstore/transaction/TxnService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.transaction;\n\nimport com.google.gson.Gson;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.carbon.metrics.core.annotation.Timed;\nimport org.wso2.msf4j.analytics.httpmonitoring.HTTPMonitored;\nimport org.wso2.msf4j.examples.petstore.util.model.Order;\nimport redis.clients.jedis.Jedis;\nimport redis.clients.jedis.JedisPool;\nimport redis.clients.jedis.JedisPoolConfig;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Response;\n\n/**\n * Transaction microservice.\n */\n@HTTPMonitored\n@Path(\"/transaction\")\npublic class TxnService {\n    private static final Logger log = LoggerFactory.getLogger(TxnService.class);\n    private static String REDIS_MASTER_HOST = System.getenv(\"REDIS_MASTER_HOST\");\n    private static int REDIS_MASTER_PORT = Integer.parseInt(System.getenv(\"REDIS_MASTER_PORT\"));\n\n    static {\n        log.info(\"Using Redis master:\" + REDIS_MASTER_HOST + \":\" + REDIS_MASTER_PORT);\n    }\n\n    private static final JedisPool pool =\n            new JedisPool(new JedisPoolConfig(), REDIS_MASTER_HOST, REDIS_MASTER_PORT);\n\n    @POST\n    @Consumes(\"application/json\")\n    @Timed\n    public Response addOrder(Order order) {\n        String orderId = order.getId();\n        try (Jedis jedis = pool.getResource()) {\n            if (!jedis.smembers(TxnConstants.ORDERS_KEY).contains(orderId)) {\n                jedis.sadd(TxnConstants.ORDERS_KEY, orderId);\n            }\n            String orderKey = TxnConstants.ORDER_KEY_PREFIX + orderId;\n            if (jedis.get(orderKey) != null) {\n                return Response.status(Response.Status.CONFLICT).\n                        entity(\"Order with ID \" + orderId + \" already exists\").build();\n            } else {\n                jedis.set(orderKey, new Gson().toJson(order));\n                log.info(\"Added order\");\n            }\n            // We are ignoring the credit card details. In the real world, this is where we would make a call to the\n            // payment gateway\n            return Response.status(Response.Status.OK).entity(new Gson().toJson(orderId)).build();\n        }\n    }\n\n    @GET\n    @Path(\"/all\")\n    @Produces(\"application/json\")\n    @Timed\n    public List<Order> getOrders(String txnId) {\n        try (Jedis jedis = pool.getResource()) {\n            Set<String> orderKeys = jedis.smembers(TxnConstants.ORDERS_KEY);\n            List<Order> result = new ArrayList<>(orderKeys.size());\n            for (String orderKey : orderKeys) {\n                String orderValue = jedis.get(orderKey);\n                result.add(new Gson().fromJson(orderValue, Order.class));\n            }\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/src/main/resources/http-monitoring.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for HTTP Monitoring\n\nenabled: true\n\ndas:\n  receiverURL: ${HTTP_MONITORING_DAS_RECEIVERURL}\n  # authURL: ssl://localhost:7711\n  type: thrift\n  username: admin\n  password: admin\n  dataAgentConfigPath: ${HTTP_MONITORING_DAS_DATAAGENTCONFIGPATH}\n"
  },
  {
    "path": "samples/petstore/microservices/transaction/src/main/resources/metrics.yml",
    "content": "# Copyright 2016 WSO2 Inc. (http://wso2.org)\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# This is the main configuration file for metrics\n\nenabled: true\n\njmx:\n  registerMBean: true\n  name: org.wso2.msf4j:type=Metrics\n\ndas:\n  - &DAS01\n    receiverURL: ${METRICS_REPORTING_DAS_RECEIVERURL}\n    # authURL: ssl://localhost:7711\n    type: thrift\n    username: admin\n    password: admin\n    dataAgentConfigPath: ${METRICS_REPORTING_DAS_DATAAGENTCONFIGPATH}\n\nreporting:\n  jmx:\n    - name: JMX\n      enabled: true\n\n  console:\n    - name: Console\n      enabled: false\n      pollingPeriod: 60\n\n  csv:\n    - name: CSV\n      enabled: false\n      location: metrics\n      pollingPeriod: 60\n\n  slf4j:\n    - name: SLF4J\n      enabled: false\n      loggerName: metrics\n      pollingPeriod: 60\n\n  das:\n    - name: DAS\n      enabled: true\n      das: *DAS01\n      pollingPeriod: 60\n"
  },
  {
    "path": "samples/petstore/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore</artifactId>\n    <packaging>pom</packaging>\n\n    <name>Sample: [Pet Store] - Pet Store Microservices Solution</name>\n    <url>http://wso2.org</url>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>redis.clients</groupId>\n                <artifactId>jedis</artifactId>\n                <version>2.7.2</version>\n                <type>jar</type>\n                <scope>compile</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <modules>\n        <module>util</module>\n        <!--<module>frontend-util</module>-->\n        <module>microservices/pet</module>\n        <module>microservices/transaction</module>\n        <module>microservices/security</module>\n        <module>microservices/fileserver</module>\n    </modules>\n\n</project>\n"
  },
  {
    "path": "samples/petstore/util/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>petstore</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <artifactId>petstore-util</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: [Pet Store] - Pet store microservices example - utils</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>redis.clients</groupId>\n            <artifactId>jedis</artifactId>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/JedisUtil.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.util;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.util.SystemVariableUtil;\nimport redis.clients.jedis.Jedis;\nimport redis.clients.jedis.exceptions.JedisConnectionException;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.locks.ReentrantLock;\nimport java.util.stream.Collectors;\n\n/**\n * Utility class for connecting to Redis &amp; handling Redis calls.\n */\npublic class JedisUtil {\n    private static final Logger log = LoggerFactory.getLogger(JedisUtil.class);\n\n    private static final String SENTINEL1_HOST;\n    private static final String SENTINEL2_HOST;\n\n    private static final int SENTINEL1_PORT;\n    private static final int SENTINEL2_PORT;\n\n    private static final String MASTER_NAME = \"mymaster\";\n\n    private static Jedis sentinel1;\n    private static Jedis sentinel2;\n\n    private static ReentrantLock lock = new ReentrantLock();\n\n    static {\n        SENTINEL1_HOST = SystemVariableUtil.getValue(\"SENTINEL1_HOST\", \"127.0.0.1\");\n        SENTINEL2_HOST = SystemVariableUtil.getValue(\"SENTINEL2_HOST\", \"127.0.0.1\");\n        SENTINEL1_PORT = Integer.parseInt(SystemVariableUtil.getValue(\"SENTINEL1_PORT\", \"5000\"));\n        SENTINEL2_PORT = Integer.parseInt(SystemVariableUtil.getValue(\"SENTINEL2_PORT\", \"5001\"));\n\n        sentinel1 = new Jedis(SENTINEL1_HOST, SENTINEL1_PORT);\n        sentinel2 = new Jedis(SENTINEL2_HOST, SENTINEL2_PORT);\n\n        log.info(\"Sentinel 1: \" + SENTINEL1_HOST + \":\" + SENTINEL1_PORT);\n        log.info(\"Sentinel 2: \" + SENTINEL2_HOST + \":\" + SENTINEL2_PORT);\n    }\n\n    private static Jedis master = getJedis();\n\n    public static String getSentinelHost() {\n        return SENTINEL1_HOST;\n    }\n\n    public static int getSentinelPort() {\n        return SENTINEL1_PORT;\n    }\n\n    public static void set(String key, String value) {\n        fetchMaster();\n        try {\n            master.set(key, value);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            master.set(key, value);\n        }\n    }\n\n    public static String get(String key) {\n        fetchMaster();\n        try {\n            return master.get(key);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            return master.get(key);\n        }\n    }\n\n    public static void del(String key) {\n        fetchMaster();\n        try {\n            master.del(key);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            master.del(key);\n        }\n    }\n\n    public static void sadd(String key, String value) {\n        fetchMaster();\n        try {\n            master.sadd(key, value);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            master.sadd(key, value);\n        }\n    }\n\n    public static Set<String> smembers(String key) {\n        fetchMaster();\n        try {\n            return master.smembers(key);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            return master.smembers(key);\n        }\n    }\n\n    public static void srem(String key, String value) {\n        fetchMaster();\n        try {\n            master.srem(key, value);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            master.sadd(key, value);\n        }\n    }\n\n    public static List<String> getValues(String keyPattern) {\n        fetchMaster();\n        List<String> values = new ArrayList<>();\n        try {\n            getValuesInternal(keyPattern, values);\n        } catch (JedisConnectionException e) {\n            master = getJedis();\n            getValuesInternal(keyPattern, values);\n        }\n        return values;\n    }\n\n    private static void getValuesInternal(String keyPattern, List<String> values) {\n        Set<String> keys = master.keys(keyPattern);\n        values.addAll(keys.stream().map(master::get).collect(Collectors.toList()));\n    }\n\n    private static void fetchMaster() {\n        if (master == null) {\n            lock.lock();\n            if (master == null) {\n                master = getJedis();\n            }\n        }\n    }\n\n    private static Jedis getJedis() {\n        try {\n            log.info(\"Using sentinel: \" + sentinel1);\n            return getJedisInternal(sentinel1);\n        } catch (JedisConnectionException e) {\n            sentinel1.close();\n            Jedis tempSentinel = sentinel1;\n            sentinel1 = sentinel2;\n            sentinel2 = tempSentinel;\n            log.info(\"Using sentinel: \" + sentinel1);\n            return getJedisInternal(sentinel1);\n        }\n    }\n\n    private static Jedis getJedisInternal(Jedis sentinel) {\n        List<Map<String, String>> masters = sentinel.sentinelMasters();\n        for (Map<String, String> master : masters) {\n            if (MASTER_NAME.equals(master.get(\"name\"))) {\n                String masterIP = master.get(\"ip\");\n                int masterPort = Integer.parseInt(master.get(\"port\"));\n                log.info(\"Redis master : {}:{}\", masterIP, masterPort);\n                return new Jedis(masterIP, masterPort);\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/model/Category.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.util.model;\n\n/**\n * The pet category; such as dog, cat, bird, reptile, fish etc.\n */\npublic class Category {\n\n    private String name;\n\n    public Category() {}\n\n    public Category(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n}\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/model/CreditCard.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.util.model;\n\n/**\n * Represents a credit card.\n */\n@SuppressWarnings(\"unused\")\npublic class CreditCard {\n\n    private String number;\n    private String name;\n    private String cvc;\n\n    public String getCvc() {\n        return cvc;\n    }\n\n    public void setCvc(String cvc) {\n        this.cvc = cvc;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getNumber() {\n        return number;\n    }\n\n    public void setNumber(String number) {\n        this.number = number;\n    }\n}\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/model/Order.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.util.model;\n\nimport java.util.List;\nimport java.util.UUID;\n\n/**\n * Represents an order.\n */\n@SuppressWarnings(\"unused\")\npublic class Order {\n    private String id = UUID.randomUUID().toString();\n    private long dateAdded = System.currentTimeMillis();\n\n    /**\n     * IDs of the pets purchased.\n     */\n    private List<String> pets;\n    private double total;\n    private CreditCard creditCard;\n\n    // TODO: store the customer ID\n\n    public long getDateAdded() {\n        return dateAdded;\n    }\n\n    public void setDateAdded(long dateAdded) {\n        this.dateAdded = dateAdded;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public CreditCard getCreditCard() {\n        return creditCard;\n    }\n\n    public void setCreditCard(CreditCard creditCard) {\n        this.creditCard = creditCard;\n    }\n\n    public List<String> getPets() {\n        return pets;\n    }\n\n    public void setPets(List<String> pets) {\n        this.pets = pets;\n    }\n\n    public double getTotal() {\n        return total;\n    }\n\n    public void setTotal(double total) {\n        this.total = total;\n    }\n}\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/model/Pet.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.examples.petstore.util.model;\n\nimport java.util.UUID;\n\n/**\n * Represents a pet.\n */\npublic class Pet {\n\n    private String id = UUID.randomUUID().toString();\n    private Category category;\n    private int ageMonths;\n    private String details;\n    private float price;\n    private long dateAdded = System.currentTimeMillis();\n    private String image;\n\n    public Pet() {\n    }\n\n    public int getAgeMonths() {\n        return ageMonths;\n    }\n\n    public void setAgeMonths(int ageMonths) {\n        this.ageMonths = ageMonths;\n    }\n\n    public Category getCategory() {\n        return category;\n    }\n\n    public void setCategory(Category category) {\n        this.category = category;\n    }\n\n    public long getDateAdded() {\n        return dateAdded;\n    }\n\n    public String getDetails() {\n        return details;\n    }\n\n    public void setDetails(String details) {\n        this.details = details;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getImage() {\n        return image;\n    }\n\n    public void setImage(String image) {\n        this.image = image;\n    }\n\n    public float getPrice() {\n        return price;\n    }\n\n    public void setPrice(float price) {\n        this.price = price;\n    }\n\n    public void setDateAdded(long dateAdded) {\n        this.dateAdded = dateAdded;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n}\n"
  },
  {
    "path": "samples/petstore/util/src/main/java/org/wso2/msf4j/examples/petstore/util/model/User.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.examples.petstore.util.model;\n\nimport java.util.List;\nimport javax.xml.bind.annotation.XmlAttribute;\n\n/**\n * Bean class used for populating user.\n */\npublic class User {\n\n    private String name;\n    private String password;\n    private String email;\n\n    @XmlAttribute(required = false)\n    private List<String> roles;\n\n    @XmlAttribute(required = false)\n    private String firstName;\n\n    @XmlAttribute(required = false)\n    private String lastName;\n\n    public String getName() {\n        return name;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public List<String> getRoles() {\n        return roles;\n    }\n\n    public void setRoles(List<String> roles) {\n        this.roles = roles;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    public String getPassword() {\n        return password;\n\n    }\n\n    public void setPassword(String password) {\n        this.password = password;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n}\n"
  },
  {
    "path": "samples/regex-pathparam/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>regex-pathparam</artifactId>\n\n    <name>Sample: PathParam with Regex</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/regex-pathparam/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner().deploy(new RegexPathParam()).start();\n    }\n}\n"
  },
  {
    "path": "samples/regex-pathparam/src/main/java/org/wso2/msf4j/example/RegexPathParam.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.Response;\n\n@Path(\"/PathParamWithRegex\")\npublic class RegexPathParam {\n\n    @GET\n    @Path(\"{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}/states\")\n    public Response getAssetState(@PathParam(\"assetType\") String assetType, @PathParam(\"id\") String id) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"Asset Type = \").append(assetType).append(\", Asset Id = \").append(id);\n        return Response.ok().entity(sb.toString()).build();\n    }\n\n    @GET\n    @Path(\"/endpoints/{assetType : [a-zA-Z][a-zA-Z_0-9]*}/{id}\")\n    public Response createEndpoint(@PathParam(\"assetType\") String assetType, @PathParam(\"id\") String id) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"Asset Type = \").append(assetType).append(\", Asset Id = \").append(id);\n        return Response.ok().entity(sb.toString()).build();\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/README.md",
    "content": "# Spring Helloworld Sample\n\nThis is the MSF4J Hello World sample based on Spring that reponds to you saying hello.\n\nFollowing example illustrates how to use Spring annotations together with MSF4J annotations to build a RESTful service. \n\n```java\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n@Component\n@Path(\"/greeting\")\npublic class Hello {\n\n    @Autowired\n    private HelloService helloService;\n\n    @GET\n    public String message() {\n        return helloService.hello(\" World\");\n    }\n}\n\n``` \n\nHere an instance of HelloService class will be injected to the Hello service class by Spring framework,  to enable \nSpring to discover  HelloService bean it is possible to use @Component annotation within HelloService class as shown \nbelow.  \n\n```java\n@Component\npublic class HelloService {\n\n   public String hello(String name) throws InvalidNameException {\n       if (isNumericValue(name)) {\n           throw new InvalidNameException(name + \" is an invalid name\");\n       }\n       return \"Hello \" + name;\n   }\n\n }\n \n``` \n\nIn addition to above service classes a special class called MSF4JSpringApplication is used to run Spring based MSF4J \nservices.  When specific Spring Configuration is not present, MSF4J use Spring’s auto-scan feature to discover service \nbeans, any class  with @Path and Spring’s @Component  annotations will be deploy as services. \n\n```java\nimport org.wso2.msf4j.spring.MSF4JSpringApplication;\n\npublic class Application {\n\n    public static void main(String[] args) {\n        MSF4JSpringApplication.run(Application.class, args);\n    }\n}\n```\n\n### Deploying interceptors using Spring.  \n\nIt is possible to configure and deploy MSF4J Interceptors through Spring. Adding @Component  annotation to any \nimplementation class of MSF4J Interceptor enables Spring to auto-discover and deploy above class as \nan MSF4J Interceptor.  \n\n```java\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\n@Component\npublic class LogHeadersInterceptor implements Interceptor {\n\n    @Override\n    public boolean preCall(HttpRequest httpRequest, HttpResponder httpResponder, \n                           ServiceMethodInfo serviceMethodInfo) {\n        // preCall implementation code goes here \n    }\n\n    @Override\n    public void postCall(HttpRequest httpRequest, HttpResponseStatus httpResponseStatus,\n                         ServiceMethodInfo serviceMethodInfo) {\n        // postCall implementation code goes here \n    }\n}\n```\n\n### Configuring ExceptionMappers using Spring. \n\nAdding  @Component  annotations into ExceptionMapper classes enable Spring framework to discover and register \nExceptionMappers with MSF4J.\n\n```java\n@Component\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n```\n\n### Configuring MSF4J through Spring\nIt’s possible to provide alternative or additional Spring configuration by annotating configuration classes \nusing @Configuration annotation. For more details refer following examples. \n\n\n### 1. Changing HTTP port \n\n```java\n@Configuration\npublic class TransportConfiguration {\n\n    @Bean\n    public HTTPTransportConfig http(){\n         return new HTTPTransportConfig(9090);\n     }\n\n}\n```\nIn above example it overrides default HTTPTransportConfig bean with user configured  HTTPTransportConfig bean mentioned in TransportConfiguration class so that service will run on HTTP port 9090 instead of default 8080 port. Here adding @Configuration annotation into above class enables Spring to identify underlying class as a Spring configuration.  Also note that, here default HTTPTransportConfig bean name is “http”, it’s required to use same bean name as default HTTPTransportConfig bean name in order to override default HTTP configurations.    \n\nAlternatively it’s possible to use one of the following approach to change the HTTP port through configuration. \n\n1. Provide port number as a command line argument\n    * Example:   --http.port=9090\n\n2. Provide port number as a system variable \n    *  Example:  -Dhttp.port=9090\n\n3. Provide port number through application.properties file \n    *  Example: create a application.properties in the classpath and  include http.port=9090 property. \n \nFollowing are the list of configuration options supported by HTTP transport.  \n \nOption | Description \n--- | --- |\nenabled | Enable or disable the transport \nport  | HTTP port \nhost | Host to be bind with HTTP transport \n\n\n\n### 2. Configuring HTTPS transport  \n\nBy default HTTPSTransportConfig is disabled, it is possible to configure HTTPSTransportConfig bean as below \nby providing required key store details. \n\n```java\n@Configuration\npublic class TransportConfiguration {\n\n    @Bean\n    public HTTPSTransportConfig https() {\n        return new HTTPSTransportConfig().port(7070).keyStore(\"wso2carbon\")\n                .keyStorePass(\"wso2carbon\").certPass(\"wso2carbon\").enabled();\n\n    }\n}\n```\n\nFollowing are the list of configuration options supported by HTTPS transport.  \n\nOption | Description \n--- | --- |\nenabled | Enable or disable the transport \nport  | HTTP port \nhost | Host to be bind with HTTP transport \nkeyStore | Key store file to be used with HTTPS transport \nkeyStorePass | Key store password \ncertPass | Certificate password \n\n\n# How to build and run the sample\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom the target directory, run\n```\njava -jar spring-helloworld-*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\n\n```\ncurl http://localhost:9090/hello/wso2\n```\n\nYou should get a response similar to the following:\n\n```\nHello wso2\n```\n"
  },
  {
    "path": "samples/spring-helloworld/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>spring-helloworld</artifactId>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-spring</artifactId>\n        </dependency>\n    </dependencies>\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.spring.MSF4JSpringApplication;\n\n/**\n * Main Application class to run this sample.\n */\npublic class Application {\n\n    public static void main(String[] args) {\n        MSF4JSpringApplication.run(Application.class, args);\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/Hello.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * MSF4J service class annotated with MSF4J and Spring annotations.\n */\n\n@Component\n@Path(\"/hello\")\npublic class Hello {\n\n    @Autowired\n    private HelloService helloService;\n\n    @GET\n    @Path(\"/{name}\")\n    public String hello(@PathParam(\"name\") String name) throws InvalidNameException {\n        return helloService.hello(name);\n    }\n\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/HelloService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.springframework.stereotype.Component;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * HelloService class to be injected to Hello resource through Spring\n */\n@Component\npublic class HelloService {\n\n    public String hello(String name) throws InvalidNameException {\n        if (isNumericValue(name)) {\n            throw new InvalidNameException(name + \" is an invalid name\");\n        }\n        return \"Hello \" + name;\n    }\n\n    private boolean isNumericValue(String value) {\n        Pattern pattern = Pattern.compile(\"^(0|[1-9][0-9]*)$\");\n        Matcher matcher = pattern.matcher(value);\n        return matcher.matches();\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/InvalidNameException.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\n/**\n * InvalidNameException class to demonstrate ExceptionMapper feature .\n */\npublic class InvalidNameException extends Exception {\n\n    public InvalidNameException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/InvalidNameExceptionMapper.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * MSF4J ExceptionMapper for InvalidNameExceptionMapper  Exception.\n */\n@Component\npublic class InvalidNameExceptionMapper implements ExceptionMapper<InvalidNameException> {\n    @Override\n    public Response toResponse(InvalidNameException exception) {\n        return Response.status(500).\n                entity(exception.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/LogHeadersInterceptor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.Response;\nimport org.wso2.msf4j.interceptor.RequestInterceptor;\n\n/**\n * Spring based MSF4J Interceptor class which print HTTP headers from incoming messages.\n */\n@Component\npublic class LogHeadersInterceptor implements RequestInterceptor {\n\n    private final Log log = LogFactory.getLog(LogHeadersInterceptor.class);\n\n    @Override\n    public boolean interceptRequest(Request request, Response response) throws Exception {\n        request.getHeaders().getRequestHeaders().entrySet()\n                .forEach(header -> log.info(\"Header - \" + header.getKey() + \" : \" + header.getValue()));\n        return true;\n    }\n}\n"
  },
  {
    "path": "samples/spring-helloworld/src/main/java/org/wso2/msf4j/example/TransportConfiguration.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.wso2.msf4j.spring.transport.HTTPTransportConfig;\n\n@Configuration\npublic class TransportConfiguration {\n\n    @Bean\n    public HTTPTransportConfig http() {\n        return new HTTPTransportConfig(9090);\n    }\n\n}\n"
  },
  {
    "path": "samples/spring-profile/README.md",
    "content": "# How to build and run the sample\n\n## About this sample\n\nThis sample demonstrates how to configure MSF4J transport related properties using application.yml file.\nThe service will be run on port 10000 instead of default 8080 port or the 6060 which is hard coded. This is because\nwe have set http].port property in the application.yml file.\n\n```java\n@Configuration\npublic class TransportConfiguration {\n\n    @Bean\n    public HTTPTransportConfig http() {\n        return new HTTPTransportConfig(6060);\n    }\n\n}\n\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom the target directory, run\n```\njava -jar target/spring-profile*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\n\n```\ncurl -v http://localhost:10000/hello/wso2\n```\n\nYou should get a response similar to the following:\n\n```\nHello wso2\n```\n\n## How to use Spring profiles\n\n```\ndev profile - java -Dspring.profiles.active=dev -jar target/spring-profile*.jar\n\nprod profile - java -Dspring.profiles.active=prod -jar target/spring-profile*.jar\n```\nBased on the profile that set, you will see the port the application start get change."
  },
  {
    "path": "samples/spring-profile/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>spring-profile</artifactId>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-spring</artifactId>\n        </dependency>\n    </dependencies>\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/spring-profile/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.spring.MSF4JSpringApplication;\n\n/**\n * Main Application class to run this sample.\n */\npublic class Application {\n\n    public static void main(String[] args) {\n        MSF4JSpringApplication.run(Application.class, args);\n    }\n}\n"
  },
  {
    "path": "samples/spring-profile/src/main/java/org/wso2/msf4j/example/Hello.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n/**\n * Hello Resource class.\n */\n\n@Component\n@Path(\"/hello\")\npublic class Hello {\n\n    @Autowired\n    private HelloService helloService;\n\n    @GET\n    @Path(\"/{name}\")\n    public String hello(@PathParam(\"name\") String name) {\n        return helloService.hello(name);\n    }\n\n}"
  },
  {
    "path": "samples/spring-profile/src/main/java/org/wso2/msf4j/example/HelloService.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example;\n\nimport org.springframework.stereotype.Component;\n\n/**\n * HelloService class to be injected to Hello resource through Spring\n */\n@Component\npublic class HelloService {\n\n    public String hello(String name) {\n        return \"Hello \" + name;\n    }\n}"
  },
  {
    "path": "samples/spring-profile/src/main/java/org/wso2/msf4j/example/TransportConfig.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.wso2.msf4j.spring.transport.HTTPTransportConfig;\n\n@Configuration\npublic class TransportConfig {\n    \n    @Bean\n    public HTTPTransportConfig http() {\n        return new HTTPTransportConfig(6060);\n    }\n}\n"
  },
  {
    "path": "samples/spring-profile/src/main/resources/application.yml",
    "content": "http.port: 10000\n---\nspring:\n profiles: dev\nhttp.port: 15000\n---\nspring:\n profiles: prod\nhttp.port: 20000\n"
  },
  {
    "path": "samples/stockquote/bundle/README.md",
    "content": "# SimpleStockQuote MSF4J OSGi Bundle Sample\n\nThis sample demonstrates how to create a microservice as an OSGi bundle.\nSee also; [msf4j fatjar](../fatjar)\n\nIn this sample we have exposed the StockQuoteService as an OSGi service that implements \norg.wso2.msf4j.Microservice interface as shown in the following code.\n\n```java\n@Component(\n        name = \"org.wso2.msf4j.stockquote.StockQuoteService\",\n        service = Microservice.class,\n        immediate = true\n)\n@Path(\"/stockquote\")\npublic class StockQuoteService implements Microservice {\n\n    @Activate\n    protected void activate(BundleContext bundleContext){\n        // Nothing to do\n    }\n\n    @Deactivate\n    protected void deactivate(BundleContext bundleContext){\n        // Nothing to do\n    }\n    \n    // resource methods are here..\n}\n```\nNote the empty @Activate and @Deactivate methods that are required to properly generate the bundle headers that are \nrequired by the framework.\n\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n### Using OSGi Console\n\nCopy and extract the wso2-msf4j-*.zip file in tests/test-distribution to some location.\nGo to the wso2-msf4j-*/wso2/default/bin directory\nThen run the following command to start the MSF4J server.\n```\n./carbon.sh\n```\n\nInstall the target/stockquote-bundle-*.jar as an OSGi bundle to WSO2 MSF4J product using it's \nOSGi console with the following command.\n\n```\ninstall file://<path to target directory>/stockquote-bundle-2.0.0.jar\n```\n\nWhen the installation of the bundle is successful, use the bundle ID of the installed bundle to start  \nit. Use the following command in the OSGi console for that.\n\n```\nstart <bundle ID>\n```\n\nWhen the bundle is started, the microservice that is exposed as an OSGi service will be picked by the runtime and \nwill be exposed as a REST service.\n\n### Using dropins directory\nUnzip wso2 MSF4J product and copy target/stockquote-bundle-*.jar bundle to the \n\"[SERVER-HOME]/lib\" directory.\n\nThen navigate to the bin directory and run the following command to start WSO2 MSF4J server.\n```\n./carbon.sh\n```\nWhen the server is being started, the bundle in the dropins directory will be automatically \nloaded and it's microservices that are there as OSGi services will be exposed as REST services.\n\n## Changing transport configuration\nBy default microservices server starts with all IPv4 addresses on the local machine and port 8080. If you need to \nchange properties, you can do it using deployment.yaml. You need to copy below configuration to deployment.yaml in \nserver conf directory and change the configuration.\n\n````yaml\nwso2.transport.http:\n  transportProperties:\n   - name: \"latency.metrics.enabled\"\n     value: true\n   - name: \"server.bootstrap.socket.timeout\"\n     value: 60\n   - name: \"client.bootstrap.socket.timeout\"\n     value: 60\n\n  listenerConfigurations:\n   - id: \"default\"\n     host: \"0.0.0.0\"\n     port: 8080\n\n  senderConfigurations:\n   - id: \"http-sender\"\n````\n\n## How to test the sample\n\nUse following cURL commands.\n```\ncurl http://localhost:9090/stockquote/IBM\n```"
  },
  {
    "path": "samples/stockquote/bundle/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>stockquote-bundle</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>Sample: Stockquote microservice (OSGi Bundle)</name>\n    <url>http://maven.apache.org</url>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-swagger</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <private.package>org.wso2.msf4j.stockquote.*</private.package>\n        <import.package>\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.wso2.msf4j.*,\n            javax.ws.rs.*,\n            javax.xml.bind*,\n            org.slf4j.*,\n            io.swagger.annotations.*,\n            org.wso2.carbon.messaging.*\n        </import.package>\n        <carbon.component>\n            osgi.service; objectClass=\"org.wso2.msf4j.Microservice\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/Stock.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.stockquote;\n\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a stock item. @XmlRootElement is used to support xml conversion.\n */\n@SuppressWarnings(\"unused\")\n@XmlRootElement\npublic class Stock {\n\n    private String symbol;\n    private String name;\n    private double last;\n    private double low;\n    private double high;\n\n    /**\n     * No arg constructor is required for xml marshalling\n     */\n    public Stock() {\n    }\n\n    public Stock(String symbol, String name) {\n        this.symbol = symbol;\n        this.name = name;\n    }\n\n    public Stock(String symbol, String name, double last, double low, double high) {\n        this(symbol, name);\n        this.last = last;\n        this.low = low;\n        this.high = high;\n    }\n\n    public String getSymbol() {\n        return symbol;\n    }\n\n    public void setSymbol(String symbol) {\n        this.symbol = symbol;\n    }\n\n    public void setHigh(double high) {\n        this.high = high;\n    }\n\n    public void setLast(double last) {\n        this.last = last;\n    }\n\n    public void setLow(double low) {\n        this.low = low;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public double getHigh() {\n        return high;\n    }\n\n    public double getLast() {\n        return last;\n    }\n\n    public double getLow() {\n        return low;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/StockQuoteService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.stockquote;\n\nimport io.swagger.annotations.ApiOperation;\nimport io.swagger.annotations.ApiParam;\nimport io.swagger.annotations.ApiResponse;\nimport io.swagger.annotations.ApiResponses;\nimport io.swagger.annotations.Contact;\nimport io.swagger.annotations.Info;\nimport io.swagger.annotations.License;\nimport io.swagger.annotations.SwaggerDefinition;\nimport org.osgi.framework.BundleContext;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Deactivate;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.stockquote.exception.DuplicateSymbolException;\nimport org.wso2.msf4j.stockquote.exception.SymbolNotFoundException;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.Response;\n\n/**\n * StockQuote microservice.\n */\n@Component(\n        name = \"org.wso2.msf4j.stockquote.StockQuoteService\",\n        service = Microservice.class,\n        immediate = true\n)\n@SwaggerDefinition(\n        info = @Info(\n                title = \"Stockquote Swagger Definition\", version = \"1.0\",\n                description = \"Stock quote service\",\n                license = @License(name = \"Apache 2.0\", url = \"http://www.apache.org/licenses/LICENSE-2.0\"),\n                contact = @Contact(\n                        name = \"Afkham Azeez\",\n                        email = \"azeez@wso2.com\",\n                        url = \"http://wso2.com\"\n                ))\n)\n@Path(\"/stockquote\")\npublic class StockQuoteService implements Microservice {\n    private static final Logger log = LoggerFactory.getLogger(StockQuoteService.class);\n\n    private Map<String, Stock> stockQuotes = new HashMap<>();\n\n    /**\n     * Add initial stocks IBM, GOOG, AMZN.\n     */\n    public StockQuoteService() {\n        stockQuotes.put(\"IBM\", new Stock(\"IBM\", \"International Business Machines\", 149.62, 150.78, 149.18));\n        stockQuotes.put(\"GOOG\", new Stock(\"GOOG\", \"Alphabet Inc.\", 652.30, 657.81, 643.15));\n        stockQuotes.put(\"AMZN\", new Stock(\"AMZN\", \"Amazon.com\", 548.90, 553.20, 543.10));\n    }\n\n    @Activate\n    protected void activate(BundleContext bundleContext) {\n        // Nothing to do\n    }\n\n    @Deactivate\n    protected void deactivate(BundleContext bundleContext) {\n        // Nothing to do\n    }\n\n\n    /**\n     * Retrieve a stock for a given symbol.\n     * http://localhost:8080/stockquote/IBM\n     *\n     * @param symbol Stock symbol will be taken from the path parameter.\n     * @return\n     */\n    @GET\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Return stock quote corresponding to the symbol\",\n            notes = \"Returns HTTP 404 if the symbol is not found\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Valid stock item found\"),\n            @ApiResponse(code = 404, message = \"Stock item not found\")})\n    public Response getQuote(@PathParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException(\"Symbol \" + symbol + \" not found\");\n        }\n        return Response.status(Response.Status.OK).entity(stock).build();\n    }\n\n    /**\n     * Add a new stock.\n     * curl -v -X POST -H \"Content-Type:application/json\" \\\n     * -d '{\"symbol\":\"BAR\",\"name\": \"Bar Inc.\", \\\n     * \"last\":149.62,\"low\":150.78,\"high\":149.18,\n     * \"createdByHost\":\"10.100.1.192\"}' \\\n     * http://localhost:8080/stockquote\n     *\n     * @param stock Stock object will be created from the request Json body.\n     */\n    @POST\n    @Consumes(\"application/json\")\n    @ApiOperation(\n            value = \"Add a stock item\",\n            notes = \"Add a valid stock item\")\n    public void addStock(@ApiParam(value = \"Stock object\", required = true) Stock stock)\n            throws DuplicateSymbolException {\n        String symbol = stock.getSymbol();\n        if (stockQuotes.containsKey(symbol)) {\n            throw new DuplicateSymbolException(\"Symbol \" + symbol + \" already exists\");\n        }\n        stockQuotes.put(symbol, stock);\n    }\n\n    /**\n     * Retrieve all stocks.\n     * http://localhost:8080/stockquote/all\n     *\n     * @return All stocks will be sent to the client as Json/xml\n     * according to the Accept header of the request.\n     */\n    @GET\n    @Path(\"/all\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Get all stocks\",\n            notes = \"Returns all stock items\",\n            response = Stocks.class,\n            responseContainer = \"List\")\n    public Stocks getAllStocks(@Context Request request) {\n        request.getHeaders().getRequestHeaders().entrySet().forEach(entry -> log.info(entry.getKey() + \"=\" + entry\n                .getValue()));\n        return new Stocks(stockQuotes.values());\n    }\n\n    @Override\n    public String toString() {\n        return \"StockQuoteService-OSGi-bundle\";\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/Stocks.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.stockquote;\n\nimport java.util.Collection;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a list of Stock objects. This wrapper is\n * required for proper xml list marshaling.\n */\n@XmlRootElement\npublic class Stocks {\n\n    @XmlElement(name = \"stock\")\n    private Collection<Stock> stocks;\n\n    /**\n     * No arg constructor is required for xml marshalling\n     */\n    public Stocks() {\n    }\n\n    public Stocks(Collection<Stock> stocks) {\n        this.stocks = stocks;\n    }\n\n    public Collection<Stock> getStocks() {\n        return stocks;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/DuplicateSymbolException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\n/**\n * DuplicateSymbolException.\n */\npublic class DuplicateSymbolException extends Exception {\n    public DuplicateSymbolException(String msg) {\n        super(msg);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/DuplicateSymbolMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\nimport org.osgi.service.component.annotations.Component;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * DuplicateSymbolMapper.\n */\n@Component(\n        name = \"org.wso2.msf4j.stockquote.exception.DuplicateSymbolMapper\",\n        service = ExceptionMapper.class,\n        immediate = true\n)\npublic class DuplicateSymbolMapper implements ExceptionMapper<DuplicateSymbolException> {\n\n    @Override\n    public Response toResponse(DuplicateSymbolException e) {\n        return Response.status(Response.Status.CONFLICT).\n                entity(e.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/EntityNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\n/**\n * EntityNotFoundException.\n */\npublic class EntityNotFoundException extends Exception {\n    public EntityNotFoundException() {\n        super();\n    }\n\n    public EntityNotFoundException(String message) {\n        super(message);\n    }\n\n    public EntityNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public EntityNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected EntityNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/EntityNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\nimport org.osgi.service.component.annotations.Component;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * EntityNotFoundMapper.\n */\n@Component(\n        name = \"org.wso2.msf4j.stockquote.exception.EntityNotFoundMapper\",\n        service = ExceptionMapper.class,\n        immediate = true\n)\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/SymbolNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\n/**\n * Thrown when a Symbol is not found.\n */\npublic class SymbolNotFoundException extends EntityNotFoundException {\n    public SymbolNotFoundException() {\n        super();\n    }\n\n    public SymbolNotFoundException(String message) {\n        super(message);\n    }\n\n    public SymbolNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public SymbolNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected SymbolNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/bundle/src/main/java/org/wso2/msf4j/stockquote/exception/SymbolNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.exception;\n\nimport org.osgi.service.component.annotations.Component;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handled SymbolNotFoundException.\n */\n@Component(\n        name = \"org.wso2.msf4j.stockquote.exception.SymbolNotFoundMapper\",\n        service = ExceptionMapper.class,\n        immediate = true\n)\npublic class SymbolNotFoundMapper implements ExceptionMapper<SymbolNotFoundException> {\n\n    public Response toResponse(SymbolNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from SymbolNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/README.md",
    "content": "# SimpleStockQuote Deployable jar Sample\n\nThis sample demonstrates how to create a deployable microservice for hot deployment.\n\nIn this sample we have exposed the StockQuoteService as an deployable microservice that implements\norg.wso2.msf4j.Microservice interface as shown in the following code.\n See also [msf4j bundle](../bundle), [msf4j fatjar](../fatjar)\n\n```java\n@Path(\"/stockquote\")\npublic class StockQuoteService implements Microservice {\n\n    // resource methods are here..\n\n}\n```\n\nYou have to add full classpath of the microservice class in <microservice.resourceClasses> under properties in the pom\n.xml of deployable jar as shown in the following code.\n\n```xml\n    <properties>\n        <microservice.resourceClasses>org.wso2.msf4j.stockquote.example.StockQuoteService</microservice.resourceClasses>\n    </properties>\n```\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nCopy and extract the wso2-msf4j-*.zip file in tests/test-distribution to some location.\nGo to the wso2-msf4j-*/wso2/default/bin directory\nThen run the following command to start the MSF4J server.\n```\n./carbon.sh\n```\n\nThe copy the target/stockquote-deployable-jar-<-version->.jar to deployment/microservices directory of MSF4J server.\nThen the jar will be automatically deployed to the server runtime.\n\n## How to test the sample\n\nUse following cURL commands.\n```\ncurl http://localhost:9090/stockquote/IBM\n```"
  },
  {
    "path": "samples/stockquote/deployable-jar/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>stockquote-deployable-jar</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: Stockquote microservice (Deployable Jar)</name>\n    <url>http://maven.apache.org</url>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-annotations</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.resourceClasses>org.wso2.msf4j.stockquote.example.StockQuoteService</microservice.resourceClasses>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/Stock.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.stockquote.example;\n\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a stock item. @XmlRootElement is used to support xml conversion.\n */\n@SuppressWarnings(\"unused\")\n@XmlRootElement\npublic class Stock {\n\n    private String symbol;\n    private String name;\n    private double last;\n    private double low;\n    private double high;\n\n    /**\n     * No arg constructor is required for xml marshalling.\n     */\n    public Stock() {\n    }\n\n    public Stock(String symbol, String name) {\n        this.symbol = symbol;\n        this.name = name;\n    }\n\n    public Stock(String symbol, String name, double last, double low, double high) {\n        this(symbol, name);\n        this.last = last;\n        this.low = low;\n        this.high = high;\n    }\n\n    public String getSymbol() {\n        return symbol;\n    }\n\n    public void setSymbol(String symbol) {\n        this.symbol = symbol;\n    }\n\n    public void setHigh(double high) {\n        this.high = high;\n    }\n\n    public void setLast(double last) {\n        this.last = last;\n    }\n\n    public void setLow(double low) {\n        this.low = low;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public double getHigh() {\n        return high;\n    }\n\n    public double getLast() {\n        return last;\n    }\n\n    public double getLow() {\n        return low;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/StockQuoteService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.stockquote.example;\n\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\nimport io.swagger.annotations.ApiParam;\nimport io.swagger.annotations.ApiResponse;\nimport io.swagger.annotations.ApiResponses;\nimport io.swagger.annotations.Contact;\nimport io.swagger.annotations.Info;\nimport io.swagger.annotations.License;\nimport io.swagger.annotations.SwaggerDefinition;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.stockquote.example.exception.DuplicateSymbolException;\nimport org.wso2.msf4j.stockquote.example.exception.SymbolNotFoundException;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.CookieParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HEAD;\nimport javax.ws.rs.OPTIONS;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.NewCookie;\nimport javax.ws.rs.core.Response;\n\n/**\n * StockQuote sample. This service will be available at.\n * http://localhost:8080/stockquote\n */\n@Api(value = \"stockquote\")\n@SwaggerDefinition(\n        info = @Info(\n                title = \"Stockquote Swagger Definition\", version = \"1.0\",\n                description = \"Stock quote service\",\n                license = @License(name = \"Apache 2.0\", url = \"http://www.apache.org/licenses/LICENSE-2.0\"),\n                contact = @Contact(\n                        name = \"Afkham Azeez\",\n                        email = \"azeez@wso2.com\",\n                        url = \"http://wso2.com\"\n                ))\n)\n@Path(\"/stockquote\")\npublic class StockQuoteService implements Microservice {\n\n    // Map that stores stocks (symbol -> stock).\n    private Map<String, Stock> stockQuotes = new HashMap<>();\n\n    /**\n     * Add initial stocks IBM, GOOG, AMZN.\n     */\n    public StockQuoteService() {\n        stockQuotes.put(\"IBM\", new Stock(\"IBM\", \"International Business Machines\", 149.62, 150.78, 149.18));\n        stockQuotes.put(\"GOOG\", new Stock(\"GOOG\", \"Alphabet Inc.\", 652.30, 657.81, 643.15));\n        stockQuotes.put(\"AMZN\", new Stock(\"AMZN\", \"Amazon.com\", 548.90, 553.20, 543.10));\n    }\n\n    /**\n     * Retrieve a stock for a given symbol.\n     * http://localhost:8080/stockquote/IBM\n     *\n     * @param symbol Stock symbol will be taken from the path parameter.\n     * @return Response\n     */\n    @GET\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Return stock quote corresponding to the symbol\",\n            notes = \"Returns HTTP 404 if the symbol is not found\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Valid stock item found\"),\n            @ApiResponse(code = 404, message = \"Stock item not found\")})\n    public Response getQuote(@ApiParam(value = \"Symbol\", required = true)\n                             @PathParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException(\"Symbol \" + symbol + \" not found\");\n        }\n        return Response.ok().entity(stock).cookie(new NewCookie(\"symbol\", symbol)).build();\n    }\n\n    /**\n     * Retrieve metainformation about the entity implied by the request.\n     * curl -i -X HEAD http://localhost:8080/stockquote/IBM\n     *\n     * @return Response\n     */\n    @HEAD\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Returns headers of corresponding GET request \",\n            notes = \"Returns metainformation contained in the HTTP header identical to the corresponding GET Request\")\n    public Response getMetaInformationForQuote(@ApiParam(value = \"Symbol\", required = true)\n                                               @PathParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException();\n        }\n        return Response.ok().build();\n    }\n\n    /**\n     * Retrieve a stock for a given symbol using a cookie.\n     * This method demonstrates the CookieParam JAXRS annotation in action.\n     *\n     * curl -v --header \"Cookie: symbol=IBM\" http://localhost:8080/stockquote\n     *\n     * @param symbol Stock symbol will be taken from the symbol cookie.\n     * @return Response\n     */\n    @GET\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Return stock quote corresponding to the symbol\",\n            notes = \"Returns HTTP 404 if the symbol is not found\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Valid stock item found\"),\n            @ApiResponse(code = 404, message = \"Stock item not found\")})\n    public Response getQuoteUsingCookieParam(@ApiParam(value = \"Symbol\", required = true)\n                                             @CookieParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException(\"Symbol \" + symbol + \" not found\");\n        }\n        return Response.ok().entity(stock).build();\n    }\n\n    /**\n     * Add a new stock.\n     * curl -v -X POST -H \"Content-Type:application/json\" \\\n     * -d '{\"symbol\":\"BAR\",\"name\": \"Bar Inc.\", \\\n     * \"last\":149.62,\"low\":150.78,\"high\":149.18,\n     * \"createdByHost\":\"10.100.1.192\"}' \\\n     * http://localhost:8080/stockquote\n     *\n     * @param stock Stock object will be created from the request Json body.\n     */\n    @POST\n    @Consumes(\"application/json\")\n    @ApiOperation(\n            value = \"Add a stock item\",\n            notes = \"Add a valid stock item\")\n    public void addStock(@ApiParam(value = \"Stock object\", required = true) Stock stock)\n            throws DuplicateSymbolException {\n        String symbol = stock.getSymbol();\n        if (stockQuotes.containsKey(symbol)) {\n            throw new DuplicateSymbolException(\"Symbol \" + symbol + \" already exists\");\n        }\n        stockQuotes.put(symbol, stock);\n    }\n\n    /**\n     * Retrieve all stocks.\n     * http://localhost:8080/stockquote/all\n     *\n     * @return All stocks will be sent to the client as Json/xml\n     * according to the Accept header of the request.\n     */\n    @GET\n    @Path(\"/all\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Get all stocks\",\n            notes = \"Returns all stock items\",\n            response = Stocks.class,\n            responseContainer = \"List\")\n    public Stocks getAllStocks(@Context Request request) {\n        return new Stocks(stockQuotes.values());\n    }\n\n    /**\n     * Retrieve information on what methods are allowed on the Request-URI.\n     * curl -i -X OPTIONS http://localhost:8080/stockquote/all\n     *\n     * @return Response\n     */\n    @OPTIONS\n    @Path(\"/all\")\n    @ApiOperation(\n            value = \"Get supported reuest methods\",\n            notes = \"Return a response with headers that show the supported HTTP Requests on the Request-URI\")\n    public Response getCommunicationInformationForRequestURI() {\n        return Response.ok().header(\"Access-Control-Allow-Methods\", \"GET,OPTIONS\").build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/Stocks.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.stockquote.example;\n\nimport java.util.Collection;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a list of Stock objects. This wrapper is\n * required for proper xml list marshaling.\n */\n@XmlRootElement\npublic class Stocks {\n\n    @XmlElement(name = \"stock\")\n    private Collection<Stock> stocks;\n\n    /**\n     * No arg constructor is required for xml marshalling.\n     */\n    public Stocks() {\n    }\n\n    public Stocks(Collection<Stock> stocks) {\n        this.stocks = stocks;\n    }\n\n    public Collection<Stock> getStocks() {\n        return stocks;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/DuplicateSymbolException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\n/**\n * DuplicateSymbolException.\n */\npublic class DuplicateSymbolException extends Exception {\n    public DuplicateSymbolException(String msg) {\n        super(msg);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/DuplicateSymbolMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * DuplicateSymbolMapper.\n */\npublic class DuplicateSymbolMapper implements ExceptionMapper<DuplicateSymbolException> {\n\n    @Override\n    public Response toResponse(DuplicateSymbolException e) {\n        return Response.status(Response.Status.CONFLICT).\n                entity(e.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/EntityNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\n/**\n * EntityNotFoundException.\n */\npublic class EntityNotFoundException extends Exception {\n    public EntityNotFoundException() {\n        super();\n    }\n\n    public EntityNotFoundException(String message) {\n        super(message);\n    }\n\n    public EntityNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public EntityNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected EntityNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/EntityNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * EntityNotFoundMapper.\n */\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/SymbolNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\n/**\n * Thrown when a Symbol is not found.\n */\npublic class SymbolNotFoundException extends EntityNotFoundException {\n    public SymbolNotFoundException() {\n        super();\n    }\n\n    public SymbolNotFoundException(String message) {\n        super(message);\n    }\n\n    public SymbolNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public SymbolNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected SymbolNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/deployable-jar/src/main/java/org/wso2/msf4j/stockquote/example/exception/SymbolNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.stockquote.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handled SymbolNotFoundException.\n */\npublic class SymbolNotFoundMapper implements ExceptionMapper<SymbolNotFoundException> {\n\n    public Response toResponse(SymbolNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from SymbolNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/README.md",
    "content": "# SimpleStockQuote Fat jar Sample\n\nA fat jar is a jar file which includes all the dependencies in one fat (uber) jar. This mode of creating a fat jar\nand running it in a Java process is also referred to as server-less execution.\n\nThis sample shows the use of @Produces and @Consumes annotations for bean conversions. In addition to that this \ndemonstrates how to develop a microservice with WSO2 MSF4J, create a fat jar & run it. The sample also demonstrates \ngenerating Swagger definitions for your services using\n[Swagger annotations](https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X).\n\nSee also; [msf4j bundle](../bundle)\n\n## Writing the pom.xml \n\nYour POM can inherit from [msf4j-service](../../../poms/msf4j-service). \nSee details [here](../../../poms/msf4j-service).\n\n### How @Produces work\n\nWhen you need to return a bean from a resource method you can specify @Produces annotation with mime types you need to \nsupport. In this case, at runtime WSO2 MSF4J framework matches the request's Accept header with the @Produce annotation \nand dispatches the correct resource method. Then, when the response is sent, the returned bean will be automatically \nserialized to the matched mime type. See the following example.\n\n```java\n    @GET\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    public Response getQuote(@PathParam(\"symbol\") String symbol) {\n        Stock stock = stockQuotes.get(symbol);\n        return (stock == null) ?\n                Response.status(Response.Status.NOT_FOUND).build() :\n                Response.status(Response.Status.OK).entity(stock).build();\n    }\n```\n\nIn the above example, if the requests Accept header is application/json, then the Stock bean object will be serialized \nas JSON and will be sent as the response. In the same way if the requests Accept header is text/xml, then the bean \nwill be serialized as XML and will be sent as the respond.\n\n\n### How @Consumes work\n\nIf a request body is JSON or XML, then you can receive a bean for it as shown in the following example.\n\n```java\n    @POST\n    @Consumes(\"application/json\")\n    public void addStock(Stock stock) {\n        stockQuotes.put(stock.getSymbol(), stock);\n    }\n```\n\nIn the above example, since @Consumes is set to application/json, if a JSON object that matches to the type of stock \nparameter is arrived in the request body, a Stock object will be automatically populated from it and passed to the \nresource method.\n\n\n## How to build the sample\n\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\n\nUse following command to run the application\n```\njava -jar target/stockquote-fatjar-*.jar\n```\n\n## How to test the sample\n\n\nUse following cURL commands.\n```\ncurl http://localhost:9090/stockquote/IBM\n```\n\nYou should get a successful response if everything worked fine.\n\n## Invoking the service via HTTPS\nUse following command to run the application\n```\njava -jar -Dtransports.netty.conf=netty-transports.yml target/stockquote-fatjar-*.jar\n```\n\nThe above command will expose the service via HTTP on port 8080 & HTTPS on 8443. Invoke the service as follows:\n\n```\ncurl --insecure https://localhost:8443/stockquote/IBM\n```\n\nYou should get a successful response if everything worked fine.\n\n## Swagger Annotations\n[Swagger](http://swagger.io/getting-started/) is a standard, language-agnostic interface to REST APIs which allows both \nhumans and computers to discover and understand the capabilities of the service without access to source code, documentation, \nor through network traffic inspection.\n\nThis sample also demonstrates the usage of [Swagger annotations](https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X).\nIn order to retrieve the [Swagger](http://swagger.io/getting-started/) definition for the StockQuote microservice, go to \n[http://localhost:8080/swagger?path=/stockquote](http://localhost:8080/swagger?path=/stockquote).\n\n## ExceptionMapper\nThis sample also demonstrates the use of [JAXRS ExceptionMapper](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ExceptionMapper.html).\nWhen a request is sent to a non-existent symbol is sent, [http://localhost:8080/stockquote/ZZZ](http://localhost:8080/stockquote/ZZZ)\nfor example, a [SymbolNotFoundException](src/main/java/org/wso2/msf4j/example/SymbolNotFoundException.java)\nis thrown. We have registered [SymbolNotFoundMapper](src/main/java/org/wso2/msf4j/example/SymbolNotFoundMapper.java) as \nthe ExceptionMapper for SymbolNotFoundException and this mapper will take care of sending back an HTTP 404 with the \nexception message.\n\nThe following code segment shows how ExceptionMappers are registered with the MSF4J runtime.\n\n```java\nnew MicroservicesRunner().addExceptionMapper(new SymbolNotFoundMapper(), new DuplicateSymbolMapper());\n```\n"
  },
  {
    "path": "samples/stockquote/fatjar/conf/netty-transports.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransportProperties:\n -\n  name: \"latency.metrics.enabled\"\n  value: true\n -\n  name: \"request.size.validation\"\n  value: false\n -\n  name: \"request.size.validation.maximum.value\" #in bytes\n  value: 2048\n -\n  name: \"request.size.validation.reject.status.code\"\n  value: 401\n -\n  name: \"request.size.validation.reject.message\"\n  value: \"Message is too big, hence cannot proceed\"\n -\n  name: \"request.size.validation.reject.message.content.type\"\n  value: \"plain/text\"\n -\n  name: \"header.size.validation\"\n  value: false\n -\n  name: \"header.validation.maximum.request.line\" #in bytes\n  value: 2048\n -\n  name: \"header.validation.maximum.size\" #in bytes\n  value: 2048\n -\n  name: \"header.validation.maximum.chunk.size\" #in bytes, refere http://netty.io/4.0/api/io/netty/handler/codec/http/HttpRequestDecoder.html\n  value: 2048\n -\n  name: \"header.validation.reject.status.code\"\n  value: 401\n -\n  name: \"header.validation.reject.message\"\n  value: \"Message's header size is too big, hence cannot proceed\"\n -\n  name: \"header.validation.reject.message.content.type\"\n  value: \"plain/text\"\n -\n  name: \"server.bootstrap.boss.group.size\"\n  value: 4\n -\n  name: \"server.bootstrap.worker.group.size\"\n  value: 8\n -\n  name: \"server.bootstrap.nodelay\"\n  value: true\n -\n  name: \"server.bootstrap.keepalive\"\n  value: true\n -\n  name: \"server.bootstrap.sendbuffersize\"\n  value: 1048576\n -\n  name: \"server.bootstrap.recievebuffersize\"\n  value: 1048576\n -\n  name: \"server.bootstrap.connect.timeout\"\n  value: 15000\n -\n  name: \"server.bootstrap.socket.reuse\"\n  value: false\n -\n  name: \"server.bootstrap.socket.timeout\"\n  value: 15\n -\n  name: \"server.bootstrap.socket.backlog\"\n  value: 100\n -\n  name: \"client.connection.pool.count\"\n  value: 0\n -\n  name: \"client.bootstrap.nodelay\"\n  value: true\n -\n  name: \"client.bootstrap.keepalive\"\n  value: true\n -\n  name: \"client.bootstrap.sendbuffersize\"\n  value: 1048576\n -\n  name: \"client.bootstrap.recievebuffersize\"\n  value: 1048576\n -\n  name: \"client.bootstrap.connect.timeout\"\n  value: 15000\n -\n  name: \"client.bootstrap.socket.reuse\"\n  value: false\n -\n  name: \"client.bootstrap.socket.timeout\"\n  value: 15\n\nlistenerConfigurations:\n -\n  id: \"default\"\n  host: \"0.0.0.0\"\n  port: 9090\n -\n  id: \"https\"\n  host: \"0.0.0.0\"\n  port: 9092\n  scheme: https\n  sslConfig:\n   keyStore: \"src/test/resources/cert.jks\"\n   keyStorePass: secret\n\nsenderConfigurations:\n -\n  id: \"http-sender\"\n"
  },
  {
    "path": "samples/stockquote/fatjar/container/docker/Dockerfile",
    "content": "# ------------------------------------------------------------------------\n#\n# Copyright WSO2, Inc. (http://wso2.com)\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\nFROM java:8-jre\nMAINTAINER architecture@wso2.org\n\nWORKDIR /opt\n\n# --------------------------------\n# Copy scripts, packages & plugins\n# --------------------------------\nCOPY packages/stockquote-fatjar.jar /opt/\n\n# ----------------------\n# Expose container ports\n# ----------------------\nEXPOSE 8080\n\nENTRYPOINT java -jar /opt/stockquote-fatjar.jar\n"
  },
  {
    "path": "samples/stockquote/fatjar/container/kubernetes/stockquote-controller.yaml",
    "content": "apiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: stockquote\n  labels:\n    name: stockquote\nspec:\n  replicas: 2\n  selector:\n    name: stockquote\n  template:\n    metadata:\n      labels:\n        name: stockquote\n    spec:\n      containers:\n      - name: stockquote\n        image: wso2msf4j/v1\n        env:\n        - name: GET_HOSTS_FROM\n          value: dns\n          # If your cluster config does not include a dns service, then to\n          # instead access environment variables to find service host\n          # info, comment out the 'value: dns' line above, and uncomment the\n          # line below.\n          # value: env\n        ports:\n        - containerPort: 80"
  },
  {
    "path": "samples/stockquote/fatjar/container/kubernetes/stockquote-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: stockquote\n  labels:\n    name: stockquote\nspec:\n  # if your cluster supports it, uncomment the following to automatically create\n  # an external load-balanced IP for the frontend service.\n  # type: LoadBalancer\n  ports:\n    # the port that this service should serve on\n    - port: 8080\n\n  type: NodePort\n  selector:\n    name: stockquote"
  },
  {
    "path": "samples/stockquote/fatjar/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <groupId>org.wso2.msf4j.example</groupId>\n    <artifactId>stockquote-fatjar</artifactId>\n    <packaging>jar</packaging>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-swagger</artifactId>\n        </dependency>\n    </dependencies>\n\n    <name>Sample: StockQuote MSF4J (Fat jar mode)</name>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.skife.maven</groupId>\n                <artifactId>really-executable-jar-maven-plugin</artifactId>\n                <configuration>\n                    <programFile>stockquote</programFile>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>really-executable-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n\n        </plugins>\n    </build>\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.example.exception.DuplicateSymbolMapper;\nimport org.wso2.msf4j.example.exception.EntityNotFoundMapper;\nimport org.wso2.msf4j.example.exception.SymbolNotFoundMapper;\n\n/**\n * Application entry point.\n */\npublic class Application {\n\n    public static void main(String[] args) {\n        new MicroservicesRunner().\n                addExceptionMapper(new EntityNotFoundMapper(), new SymbolNotFoundMapper(), new DuplicateSymbolMapper()).\n                deploy(new StockQuoteService()).\n                start();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/Stock.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a stock item. @XmlRootElement is used to support xml conversion.\n */\n@SuppressWarnings(\"unused\")\n@XmlRootElement\npublic class Stock {\n\n    private String symbol;\n    private String name;\n    private double last;\n    private double low;\n    private double high;\n\n    /**\n     * No arg constructor is required for xml marshalling\n     */\n    public Stock() {\n    }\n\n    public Stock(String symbol, String name) {\n        this.symbol = symbol;\n        this.name = name;\n    }\n\n    public Stock(String symbol, String name, double last, double low, double high) {\n        this(symbol, name);\n        this.last = last;\n        this.low = low;\n        this.high = high;\n    }\n\n    public String getSymbol() {\n        return symbol;\n    }\n\n    public void setSymbol(String symbol) {\n        this.symbol = symbol;\n    }\n\n    public void setHigh(double high) {\n        this.high = high;\n    }\n\n    public void setLast(double last) {\n        this.last = last;\n    }\n\n    public void setLow(double low) {\n        this.low = low;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public double getHigh() {\n        return high;\n    }\n\n    public double getLast() {\n        return last;\n    }\n\n    public double getLow() {\n        return low;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/StockQuoteService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\nimport io.swagger.annotations.ApiParam;\nimport io.swagger.annotations.ApiResponse;\nimport io.swagger.annotations.ApiResponses;\nimport io.swagger.annotations.Contact;\nimport io.swagger.annotations.Info;\nimport io.swagger.annotations.License;\nimport io.swagger.annotations.SwaggerDefinition;\nimport org.wso2.msf4j.Request;\nimport org.wso2.msf4j.example.exception.DuplicateSymbolException;\nimport org.wso2.msf4j.example.exception.SymbolNotFoundException;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.CookieParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.HEAD;\nimport javax.ws.rs.OPTIONS;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.Context;\nimport javax.ws.rs.core.NewCookie;\nimport javax.ws.rs.core.Response;\n\n/**\n * StockQuote sample. This service will be available at.\n * http://localhost:8080/stockquote\n */\n@Api(value = \"stockquote\")\n@SwaggerDefinition(\n        info = @Info(\n                title = \"Stockquote Swagger Definition\", version = \"1.0\",\n                description = \"Stock quote service\",\n                license = @License(name = \"Apache 2.0\", url = \"http://www.apache.org/licenses/LICENSE-2.0\"),\n                contact = @Contact(\n                        name = \"Afkham Azeez\",\n                        email = \"azeez@wso2.com\",\n                        url = \"http://wso2.com\"\n                ))\n)\n@Path(\"/stockquote\")\npublic class StockQuoteService {\n\n    // Map that stores stocks (symbol -> stock).\n    private Map<String, Stock> stockQuotes = new HashMap<>();\n\n    /**\n     * Add initial stocks IBM, GOOG, AMZN.\n     */\n    public StockQuoteService() {\n        stockQuotes.put(\"IBM\", new Stock(\"IBM\", \"International Business Machines\", 149.62, 150.78, 149.18));\n        stockQuotes.put(\"GOOG\", new Stock(\"GOOG\", \"Alphabet Inc.\", 652.30, 657.81, 643.15));\n        stockQuotes.put(\"AMZN\", new Stock(\"AMZN\", \"Amazon.com\", 548.90, 553.20, 543.10));\n    }\n\n    /**\n     * Retrieve a stock for a given symbol.\n     * http://localhost:8080/stockquote/IBM\n     *\n     * @param symbol Stock symbol will be taken from the path parameter.\n     * @return Response\n     */\n    @GET\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Return stock quote corresponding to the symbol\",\n            notes = \"Returns HTTP 404 if the symbol is not found\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Valid stock item found\"),\n            @ApiResponse(code = 404, message = \"Stock item not found\")})\n    public Response getQuote(@ApiParam(value = \"Symbol\", required = true)\n                             @PathParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        System.out.println(\"Getting symbol using PathParam...\");\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException(\"Symbol \" + symbol + \" not found\");\n        }\n        return Response.ok().entity(stock).cookie(new NewCookie(\"symbol\", symbol)).build();\n    }\n\n    /**\n     * Retrieve metainformation about the entity implied by the request.\n     * curl -i -X HEAD http://localhost:8080/stockquote/IBM\n     *\n     * @return Response\n     */\n    @HEAD\n    @Path(\"/{symbol}\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Returns headers of corresponding GET request \",\n            notes = \"Returns metainformation contained in the HTTP header identical to the corresponding GET Request\")\n    public Response getMetaInformationForQuote(@ApiParam(value = \"Symbol\", required = true)\n                                               @PathParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException();\n        }\n        return Response.ok().build();\n    }\n\n    /**\n     * Retrieve a stock for a given symbol using a cookie.\n     * This method demonstrates the CookieParam JAXRS annotation in action.\n     *\n     * curl -v --header \"Cookie: symbol=IBM\" http://localhost:8080/stockquote\n     *\n     * @param symbol Stock symbol will be taken from the symbol cookie.\n     * @return Response\n     */\n    @GET\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Return stock quote corresponding to the symbol\",\n            notes = \"Returns HTTP 404 if the symbol is not found\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Valid stock item found\"),\n            @ApiResponse(code = 404, message = \"Stock item not found\")})\n    public Response getQuoteUsingCookieParam(@ApiParam(value = \"Symbol\", required = true)\n                                             @CookieParam(\"symbol\") String symbol) throws SymbolNotFoundException {\n        System.out.println(\"Getting symbol using CookieParam...\");\n        Stock stock = stockQuotes.get(symbol);\n        if (stock == null) {\n            throw new SymbolNotFoundException(\"Symbol \" + symbol + \" not found\");\n        }\n        return Response.ok().entity(stock).build();\n    }\n\n    /**\n     * Add a new stock.\n     * curl -v -X POST -H \"Content-Type:application/json\" \\\n     * -d '{\"symbol\":\"BAR\",\"name\": \"Bar Inc.\", \\\n     * \"last\":149.62,\"low\":150.78,\"high\":149.18,\n     * \"createdByHost\":\"10.100.1.192\"}' \\\n     * http://localhost:8080/stockquote\n     *\n     * @param stock Stock object will be created from the request Json body.\n     */\n    @POST\n    @Consumes(\"application/json\")\n    @ApiOperation(\n            value = \"Add a stock item\",\n            notes = \"Add a valid stock item\")\n    public void addStock(@ApiParam(value = \"Stock object\", required = true) Stock stock)\n            throws DuplicateSymbolException {\n        String symbol = stock.getSymbol();\n        if (stockQuotes.containsKey(symbol)) {\n            throw new DuplicateSymbolException(\"Symbol \" + symbol + \" already exists\");\n        }\n        stockQuotes.put(symbol, stock);\n    }\n\n    /**\n     * Retrieve all stocks.\n     * http://localhost:8080/stockquote/all\n     *\n     * @return All stocks will be sent to the client as Json/xml\n     * according to the Accept header of the request.\n     */\n    @GET\n    @Path(\"/all\")\n    @Produces({\"application/json\", \"text/xml\"})\n    @ApiOperation(\n            value = \"Get all stocks\",\n            notes = \"Returns all stock items\",\n            response = Stocks.class,\n            responseContainer = \"List\")\n    public Stocks getAllStocks(@Context Request request) {\n        request.getHeaders().getRequestHeaders().entrySet().forEach(entry -> System.out.println(entry.getKey() + \"=\" + entry\n                .getValue()));\n        return new Stocks(stockQuotes.values());\n    }\n\n    /**\n     * Retrieve information on what methods are allowed on the Request-URI.\n     * curl -i -X OPTIONS http://localhost:8080/stockquote/all\n     *\n     * @return Response\n     */\n    @OPTIONS\n    @Path(\"/all\")\n    @ApiOperation(\n            value = \"Get supported reuest methods\",\n            notes = \"Return a response with headers that show the supported HTTP Requests on the Request-URI\")\n    public Response getCommunicationInformationForRequestURI(){\n        return Response.ok().header(\"Access-Control-Allow-Methods\",\"GET,OPTIONS\").build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/Stocks.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport java.util.Collection;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlRootElement;\n\n/**\n * Represents a list of Stock objects. This wrapper is\n * required for proper xml list marshaling.\n */\n@XmlRootElement\npublic class Stocks {\n\n    @XmlElement(name = \"stock\")\n    private Collection<Stock> stocks;\n\n    /**\n     * No arg constructor is required for xml marshalling\n     */\n    public Stocks() {\n    }\n\n    public Stocks(Collection<Stock> stocks) {\n        this.stocks = stocks;\n    }\n\n    public Collection<Stock> getStocks() {\n        return stocks;\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/DuplicateSymbolException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * DuplicateSymbolException.\n */\npublic class DuplicateSymbolException extends Throwable {\n    public DuplicateSymbolException(String msg) {\n        super(msg);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/DuplicateSymbolMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * DuplicateSymbolMapper.\n */\npublic class DuplicateSymbolMapper implements ExceptionMapper<DuplicateSymbolException> {\n\n    @Override\n    public Response toResponse(DuplicateSymbolException e) {\n        return Response.status(Response.Status.CONFLICT).\n                entity(e.getMessage()).\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/EntityNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * EntityNotFoundException.\n */\npublic class EntityNotFoundException extends Exception {\n    public EntityNotFoundException() {\n        super();\n    }\n\n    public EntityNotFoundException(String message) {\n        super(message);\n    }\n\n    public EntityNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public EntityNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected EntityNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/EntityNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * EntityNotFoundMapper.\n */\npublic class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {\n    @Override\n    public Response toResponse(EntityNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from EntityNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/SymbolNotFoundException.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\n/**\n * Thrown when a Symbol is not found.\n */\npublic class SymbolNotFoundException extends EntityNotFoundException {\n    public SymbolNotFoundException() {\n        super();\n    }\n\n    public SymbolNotFoundException(String message) {\n        super(message);\n    }\n\n    public SymbolNotFoundException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public SymbolNotFoundException(Throwable cause) {\n        super(cause);\n    }\n\n    protected SymbolNotFoundException(String message, Throwable cause,\n                                      boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "samples/stockquote/fatjar/src/main/java/org/wso2/msf4j/example/exception/SymbolNotFoundMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.example.exception;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * ExceptionMapper which handled SymbolNotFoundException.\n */\npublic class SymbolNotFoundMapper implements ExceptionMapper<SymbolNotFoundException> {\n\n    public Response toResponse(SymbolNotFoundException ex) {\n        return Response.status(404).\n                entity(ex.getMessage() + \" [from SymbolNotFoundMapper]\").\n                type(\"text/plain\").\n                build();\n    }\n}\n"
  },
  {
    "path": "samples/subresource/README.md",
    "content": "# JAX-RS Sub-Resource Sample\n\nThis is the MSF4J Sub resource sample that demonstrate how to use sub-resource with msf4j.\n\n## How to build the sample\n\nFrom this directory, run\n\n```\nmvn clean install\n```\n\n## How to run the sample\n\nFrom the target directory, run\n```\njava -jar target/subresource-sample-*.jar\n```\n\n## How to test the sample\n\nWe will use the cURL command line tool for testing. You can use your preferred HTTP or REST client too.\nTry out the following curl commands\n\n```\ncurl http://localhost:9090/country/SL/team\ncurl http://localhost:9090/country/SL/team/123/details/name\ncurl http://localhost:9090/country/SL/team/123/bowlerType\n```\n\nIf you change the Team.getPlayerObj method to return a Player Object you can try out following \n```\ncurl -X POST -H \"Content-Type: application/x-www-form-urlencoded\" -d 'type=All rounder&countryName=Sri Lanka' \"http://localhost:9090/country/2123/team/123\"\ncurl -X POST -H \"Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW\" -F \"type=All rounder\" -F \"countryName=Sri Lanka\" \"http://localhost:9090/country/2123/team/123\"\n```\n\n"
  },
  {
    "path": "samples/subresource/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>subresource-sample</artifactId>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/subresource/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner().deploy(new Country()).start();\n    }\n}\n"
  },
  {
    "path": "samples/subresource/src/main/java/org/wso2/msf4j/example/Bowler.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@Path(\"/\")\npublic class Bowler extends Player {\n\n    private String bowlerType;\n\n    public Bowler(String countryId, int playerId) {\n        setCountryId(countryId);\n        setPlayerId(playerId);\n        bowlerType = \"Fast bowler\";\n    }\n\n    @GET\n    @Path(\"/details/{filed}\")\n    public Bowler getBowlerProfileFiled(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId,\n                                        @PathParam(\"filed\") String field) {\n        String msg =\n                Bowler.class.getName() + \"Inside getPlayerProfileFiled - playerId : \" + playerId + \" for countryId : \" +\n                countryId +\n                \" with filed \" + field;\n        System.out.println(msg);\n        return new Bowler(countryId, playerId);\n    }\n\n    @GET\n    @Path(\"/bowlerType\")\n    public String getBowlerType(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId) {\n        String msg = Bowler.class.getName() + \" Inside getBowlerType - playerId : \" + playerId + \" for countryId : \" +\n                     countryId;\n        System.out.println(msg);\n        return \"Fast Bowler\";\n    }\n\n}\n"
  },
  {
    "path": "samples/subresource/src/main/java/org/wso2/msf4j/example/Country.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport java.util.HashMap;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.MediaType;\n\n@Path(\"/country\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class Country {\n\n    private String name;\n    private String id;\n    private static HashMap<String, Country> countries = new HashMap<>();\n\n    static {\n        countries.put(\"SL\", new Country(\"Sri Lanka\", \"SL\"));\n        countries.put(\"US\", new Country(\"United States\", \"US\"));\n        countries.put(\"UK\", new Country(\"United Kingdom\", \"UK\"));\n        countries.put(\"AUS\", new Country(\"Australia\", \"AUS\"));\n    }\n\n    public Country() {\n        name = \"Sri Lanka\";\n        id = \"SL\";\n    }\n\n    public Country(String name, String id) {\n        this.name = name;\n        this.id = id;\n    }\n\n    @Path(\"/{countryId}/team\")\n    public Team getCountryTeam(@PathParam(\"countryId\") String countryId) {\n        return new Team(countryId);\n    }\n\n    @GET\n    @Path(\"\")\n    public Country getDefaultCountry() {\n        return new Country();\n    }\n\n    @GET\n    @Path(\"/{countryId}\")\n    public Country getCountryId(@PathParam(\"countryId\") String countryId) {\n        return countries.get(countryId);\n    }\n}"
  },
  {
    "path": "samples/subresource/src/main/java/org/wso2/msf4j/example/Player.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@Path(\"/\")\npublic class Player {\n\n    private String name;\n    private int playerId;\n    private String countryId;\n    private String countryName;\n    private byte age;\n    private String type;\n\n    public Player(String countryId, int playerId) {\n        this.countryId = countryId;\n        this.playerId = playerId;\n        age = 30;\n        name = \"player_1\";\n    }\n\n    public Player() {\n        name = \"Sanath Jayasuriya\";\n        age = 27;\n    }\n\n    @GET\n    @Path(\"/details/{filed}\")\n    public String getPlayerProfileFiled(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId,\n                                        @PathParam(\"filed\") String field) {\n        return countryId + \"_\" + playerId + \"_\" + field + \"_\" + type + \"_\" + countryName;\n    }\n\n    @POST\n    @Path(\"\")\n    public Player getPlayerProfile(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId,\n                                        @FormParam(\"type\") String type, @FormParam(\"countryName\") String countryName) {\n        Player player = new Player(countryId, playerId);\n        player.setType(type);\n        player.setCountryName(countryName);\n        return player;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public void setAge(byte age) {\n        this.age = age;\n    }\n\n    public void setCountryId(String countryId) {\n        this.countryId = countryId;\n    }\n\n    public void setPlayerId(int playerId) {\n        this.playerId = playerId;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public void setCountryName(String countryName) {\n        this.countryName = countryName;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getPlayerId() {\n        return playerId;\n    }\n\n    public String getCountryId() {\n        return countryId;\n    }\n\n    public String getCountryName() {\n        return countryName;\n    }\n\n    public byte getAge() {\n        return age;\n    }\n\n    public String getType() {\n        return type;\n    }\n}\n"
  },
  {
    "path": "samples/subresource/src/main/java/org/wso2/msf4j/example/Team.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.example;\n\nimport javax.ws.rs.FormParam;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.POST;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@Path(\"/\")\npublic class Team {\n\n    private String teamType;\n    private String countryName;\n\n    public String getCountryId() {\n        return countryId;\n    }\n\n    public String getCountryName() {\n        return countryName;\n    }\n\n    public void setCountryName(String countryName) {\n        this.countryName = countryName;\n    }\n\n    public String getTeamType() {\n        return teamType;\n    }\n\n    public void setTeamType(String teamType) {\n        this.teamType = teamType;\n    }\n\n    private String countryId;\n\n    public void setCountryId(String countryId) {\n        this.countryId = countryId;\n    }\n\n    public Team(String countryId) {\n        this.countryId = countryId;\n        teamType = \"Cricket\";\n    }\n\n    public Team(String countryId, String countryName) {\n        this.countryName = countryName;\n        this.countryId = countryId;\n        teamType = \"Cricket\";\n    }\n\n    @Path(\"/{playerId}\")\n    public Player getPlayerObj(@PathParam(\"countryId\") String countryId, @PathParam(\"playerId\") int playerId) {\n        return new Bowler(countryId, playerId);\n    }\n\n    @GET\n    @Path(\"\")\n    public Team getCountryTeam(@PathParam(\"countryId\") String countryId) {\n        return new Team(countryId);\n    }\n\n    @POST\n    @Path(\"\")\n    public Team getCountryTeamFromPost(@PathParam(\"countryId\") String countryId,\n                                       @FormParam(\"countryName\") String countryName) {\n        return new Team(countryId, countryName);\n    }\n}\n"
  },
  {
    "path": "samples/template/README.md",
    "content": "# Template Sample\n\nThis sample shows how to render a model from a template with WSO2 MSF4J.\n\nFirst you have to add the following dependency to the pom.\n\n```xml\n     <dependency>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-mustache-template</artifactId>\n        <version>2.0.0</version>\n     </dependency>\n```\n\nFollowing resource method renders the [resources/templates/hello.mustache] template\n\n```java\n    @GET\n    @Path(\"/{name}\")\n    public Response helloMustache(@PathParam(\"name\") String name) {\n        Map map = Collections.singletonMap(\"name\", name);\n        String html = MustacheTemplateEngine.instance().render(\"hello.mustache\", map);\n        return Response.ok()\n                .type(MediaType.TEXT_HTML)\n                .entity(html)\n                .build();\n    }\n```\n\n## How to build the sample\n\nFrom this directory, run the following maven command\n\n```\nmvn clean package\n```\n\n## How to run the sample\n\nUse following command to run the application\n\n```\njava -jar target/template-*.jar\n```\n\n## How to tests the sample\n\nAfter the service is started navigate to [http://localhost:9090/MSF4J](http://localhost:9090/MSF4J) using the browser.\n"
  },
  {
    "path": "samples/template/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>org.wso2.msf4j.sample</groupId>\n    <artifactId>template</artifactId>\n\n    <name>Sample: Template Microservice</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.example.Application</microservice.mainClass>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-mustache-template</artifactId>\n            <version>${msf4j.version}</version>\n        </dependency>\n    </dependencies>\n\n</project>\n"
  },
  {
    "path": "samples/template/src/main/java/org/wso2/msf4j/example/Application.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * Application entry point.\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner()\n                .deploy(new TemplateService())\n                .start();\n    }\n}\n"
  },
  {
    "path": "samples/template/src/main/java/org/wso2/msf4j/example/TemplateService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.example;\n\nimport org.wso2.msf4j.template.MustacheTemplateEngine;\n\nimport java.util.Collections;\nimport java.util.Map;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\n\n/**\n * Template service resource class. This service has\n * endpoints that renders content from several\n * template engines.\n */\n@Path(\"/\")\npublic class TemplateService {\n\n    @GET\n    @Path(\"/{name}\")\n    public Response helloMustache(@PathParam(\"name\") String name) {\n        Map map = Collections.singletonMap(\"name\", name);\n        String html = MustacheTemplateEngine.instance().render(\"hello.mustache\", map);\n        return Response.ok()\n                .type(MediaType.TEXT_HTML)\n                .entity(html)\n                .build();\n    }\n\n}\n"
  },
  {
    "path": "samples/template/src/main/resources/templates/hello.mustache",
    "content": "<style>\n    body{\n        padding:0;\n        margin:0;\n        overflow:hidden;\n    }\n    div {\n        padding: 80px;\n        text-align: center;\n    }\n    h1{\n        display: inline-block;\n        color: #CA2A2A;\n    \tfont-size: 40px;\n    \tpadding: 20px;\n        border-radius: 5px;\n\tbox-shadow: 1px 1px 5px #999;\n\tanimation-name: spin;\n    \tanimation-duration: 1000ms;\n    \tanimation-iteration-count: initial;\n    \tanimation-timing-function: ease-out;\n    }\n    h1 span{\n        color: #484877;\n    }\n    @keyframes spin {\n        from {\n            font-size: 10px;\n            padding: 5px;\n            transform:rotate(0deg);\n        }\n        to {\n            font-size: 40px;\n            padding: 20px;\n            transform:rotate(360deg);\n        }\n    }\n</style>\n<div>\n    <h1>Hello <span>{{name}}!</span></h1>\n</div>"
  },
  {
    "path": "samples/websocket/README.md",
    "content": "# MSF4J WebSocket Tutorial\n\nIn MSF4J there are two ways to write endpoints such as HTTP and WebSocket.\nHere is the documentation for WebSocket in MSF4J.\n\nWSO2 MSF4J is driven by annotations. Since all are written according to standard javax WebSocket\nspec this is easy to learn and use. This tutorial goes through the very basic elements of \nWebSocket endpoint.\n\n## Annotations of WebSocket\nAll these annotations are coming from javax.websocket API. Since you can easily migrate\nyour code written with javax WebSocket spec for another framework to MSF4J micro-framework.\n\n### @ServerEndpoint\nThis annotation is a must for the framework to understand which this is a WebSocket server\nendpoint. Without this annotation framework cannot understand whether this is a HTTP endpoint \nor a WebSocket endpoint.\n\n```java\n@ServerEndpoint(\"/chat/\")\npublic class ChatAppEndpoint {\n\n}\n```\n\n### @PathParam\nThis annotation is used to take the path parameters of URI. Let's take this server endpoint \nexample\n```java\n@ServerEndpoint(\"/chat/{name}\")\npublic class ChatEndpoint {\n    \n}\n```\nHere in the URI the part defined within curly brackets are known as path parameters.\nIn here \"{name}\"\n\nSo let's say the client is connected to the endpoint using \n\"/chat/john\". Then this means \"name\"=\"john\".\n\nThese kind of path parameters can be taken as method parameters in WebSocket methods \nusing @PathParam annotation.\n\n```java\n@OnOpen\npublic void myMethod(@PathParam(\"name\") String name) {\n    System.out.println(\"Hi my name is \" + name);\n}\n```\n\n\n### @OnOpen\nThis is a method level annotation and is used to trigger when a new connection is opened.\nIf user need to execute some logic when a new client is connected we can use this annotation \nfor that purpose.\n\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|Session|Session of the new client connected|optional|\n|0 to N no of String parameters annotated with @PathParam|Can have any no. of path parameters|optional|\n\nex:\n```java\n@OnOpen\npublic void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n    System.out.println(\"New client connected\");\n}\n```\n\nNote that @PathParams parameters should declare first before giving other parameters.\n\n### @OnMessage\nAll the messages coming from the connected clients are coming to methods which are annotated with @OnMessage \n\nThere are 3 kinds of Messages which can be received from from a WebSocket channel.\n\n* Text Messages\n* Binary Messages\n* Pong Messages\n\nSince there are 3 kinds of messages which can be received via same annotation the way it defines is by specifying \nthe method parameters for each message type.\nFor each and every message type there are mandatory and optional parameters that we can define based on what the user \nwants to receive.\n\n#### Text Messages\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|text|Text which receives from the client|mandatory|\n|webSocketConnection|Connection of the client|optional|\n|0 to n String parameters annotated with a @PathParam annotation|To retrieve path parameter|optional|\n\nex: \n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp {\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection) {\n        // Your code goes here\n    }\n}\n```\n\n#### Binary Messages\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|bytes|This should be declared as a byte[] or ByteBuffer to receive the message from the client|mandatory|\n|isFinal|This is a boolean which says that if the received buffer is a final fragment of a whole message. If user knows that only full messages are received every time this should not be declared|optional|\n|webSocketConnection|Connection of the client|optional|\n|0 to n String parameters annotated with a @PathParam annotation|To retrieve path parameter|optional|\n\nex: with ByteBuffer\n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp { \n    @OnMessage\n    public void onBinaryMessage(byte[] bytes, WebSocketConnection webSocketConnection) {\n        // Your code goes here\n    }\n}\n```\n\nex: with byte array\n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp { \n    @OnMessage\n    public void onBinaryMessage(ByteBuffer byteBuffer, boolean isFinalFragment, WebSocketConnection webSocketConnection) {\n        // Your code goes here\n    }\n}\n```\n\n#### Pong Messages\nThis is received when server sends a ping message to check the connection.\n\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|pongMessage|PongMessage which receives from the client|mandatory|\n|webSocketConnection|Connection of the client|optional|\n|0 to n String parameters annotated with a @PathParam annotation|To retrieve path parameter|optional|\n\nex:\n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp { \n    @OnMessage\n    public void onPongMessage(PongMessage pongMessage, WebSocketConnection webSocketConnection) {\n       // Your code goes here\n    }\n}\n```\n_**Note: If you define other than these parameters the server might give an error since it cannot understand the type of message\nthis specific @OnMessage annotated method is dispatching**_\n\n\n### @OnClose\nOnClose is called when a connection between the client and the server is closed. By this user can identify the specific code\nand the reason if exists for user to leave the server.\n\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|pongMessage|PongMessage which receives from the client|mandatory|\n|webSocketConnection|Connection of the client|optional|\n|0 to n String parameters annotated with a @PathParam annotation|To retrieve path parameter|optional|\n\nex: \n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp { \n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason, WebSocketConnection webSocketConnection) {\n        // Your code goes here\n    }\n}\n```\n\n### @OnError\nThis method is called when an error occurred in the server when reading or writing data to the client. \n\n|parameter|description|mandatory/optional|\n|---------|-----------|------------------|\n|throwable|Throwable which is thrown during the reading or writing data|mandatory|\n|webSocketConnection|Connection of the client|optional|\n|0 to n String parameters annotated with a @PathParam annotation|To retrieve path parameter|optional|\n\nex: \n```java\n@ServerEndpoint(value = \"/chat/{name}\")\nclass exampleApp { \n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        // Your code goes here\n    }\n}\n```\n\n## Server Push\nServer push is one of the unique feature of WebSocket protocol. Unlike HTTP the server can write data to the client \nwithout a client request using server push. This allows user to exchange real time data from server to the client without \nmethods like polling.\n\nThere are 2 ways which you can do server push is MSf4J.\n* Using Session.getBasicRemote\n    ```java\n    webSocketConnection.pushText(message);\n    webSocketConnection.pushBinary(message);\n    ```\n    This can be used in anywhere in the program to messages to the client.\n    \n* Using return types of methods\n    ```java\n    @OnMessage\n    public String onTextMessage(String text, WebSocketConnection webSocketConnection) throws IOException {\n        String msg =  \"You said : \" + text;\n        return msg;\n    }\n    ```\n    This return statements will return the message to the same client who sent the message."
  },
  {
    "path": "samples/websocket/chatApp/bundle/README.md",
    "content": "#Simple Chat Application MSF4J OSGi bundle sample\n\nThis sample demonstrate how to use MSF4J WebSocket support \nto write a simple chat application for OSGi. \n\nIn this sample we exposed chat application as an OSGi service \nwhich implements org.wso2.msf4j.websocket.WebSocketEndpoint interface\n as shown in the following code.\n \n```java\n@Component(\n        name = \"org.wso2.msf4j.chatApp\",\n        service = WebSocketEndpoint.class,\n        immediate = true\n)\n@ServerEndpoint(\"/chat/{name}\")\npublic class ChatAppEndpoint implements WebSocketEndpoint {\n\n}\n```\n\nIn this example we have used dynamic URI to take the name\nusing **/{name}** in the @ServerEndpoint\n\nEx : ws://localhost:9090/chat/**john**\n\nThis indicates that the person who is joining the chat\nis john. \n\nTo access a variable in the URI we can use @PathParam\nannotation  as a method parameter \nprovided by javax.websocket.\n\nex : \n```java\n@OnOpen\npublic void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection session) {\n    String msg = name + \" connected to chat\";\n}\n```\nNote that @PathParams method parameters should declare first\nbefore giving other parameters.\n\n##Server Push\nThere are 2 ways which you can do server pushes.\n* Using WebSocketConnection webSocketConnection.getBasicRemote\n    ```java\n    webSocketConnection.pushText(message);\n    webSocketConnection.pushBinary(message);\n    ```\n* Using return types of methods\n    ```java\n    @OnMessage\n    public String onTextMessage(String text, WebSocketConnection webSocketConnection) throws IOException {\n        String msg =  \"You said : \" + text;\n        return msg;\n    }\n    ```\n    This return sends the value to Remote Endpoint"
  },
  {
    "path": "samples/websocket/chatApp/bundle/pom.xml",
    "content": "<!--\n  ~  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~  WSO2 Inc. licenses this file to you under the Apache License,\n  ~  Version 2.0 (the \"License\"); you may not use this file except\n  ~  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,\n  ~  software distributed under the License is distributed on an\n  ~  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~  KIND, either express or implied.  See the License for the\n  ~  specific language governing permissions and limitations\n  ~  under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>websocket-chatApp-bundle</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>Sample: WebSocket Chat Application (OSGi Bundle)</name>\n    <url>http://maven.apache.org</url>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.eclipse.osgi</groupId>\n            <artifactId>org.eclipse.osgi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.websocket</groupId>\n            <artifactId>javax.websocket-api</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <private.package>org.wso2.msf4j.sample.websocket.chatapp.*</private.package>\n        <import.package>\n            org.osgi.framework.*;version=\"${osgi.framework.import.version.range}\",\n            org.wso2.msf4j.*,\n            javax.ws.rs.*,\n            javax.websocket.*,\n            javax.xml.bind*,\n            org.slf4j.*,\n        </import.package>\n        <carbon.component>\n            osgi.service;objectClass=\"org.wso2.msf4j.websocket.WebSocketEndpoint\"\n        </carbon.component>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/websocket/chatApp/bundle/src/main/java/org/wso2/msf4j/sample/websocket/chatapp/ChatAppEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.sample.websocket.chatapp;\n\nimport org.osgi.service.component.annotations.Component;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.msf4j.websocket.WebSocketEndpoint;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n@Component(\n        name = \"org.wso2.msf4j.chatApp\",\n        service = WebSocketEndpoint.class,\n        immediate = true\n)\n@ServerEndpoint(\"/chat/{name}\")\npublic class ChatAppEndpoint implements WebSocketEndpoint {\n    private static final Logger LOGGER = LoggerFactory.getLogger(ChatAppEndpoint.class);\n    /* Stores all the active sessions in a list */\n    private List<WebSocketConnection> webSocketConnections = new ArrayList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \" : \" + text;\n        LOGGER.info(\"Received Text : \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code : \" + closeReason.getCloseCode().getCode()\n                            + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable) {\n        LOGGER.error(\"Error found in method : \" + throwable.toString());\n    }\n\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> {\n                    webSocketConnection.pushText(message);\n                }\n        );\n    }\n}\n"
  },
  {
    "path": "samples/websocket/chatApp/deployable-jar/pom.xml",
    "content": "<!--\n  ~  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~  WSO2 Inc. licenses this file to you under the Apache License,\n  ~  Version 2.0 (the \"License\"); you may not use this file except\n  ~  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,\n  ~  software distributed under the License is distributed on an\n  ~  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~  KIND, either express or implied.  See the License for the\n  ~  specific language governing permissions and limitations\n  ~  under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>chatapp-deployable-jar</artifactId>\n    <packaging>jar</packaging>\n\n    <name>Sample: WebSocket Chat App (Deployable Jar)</name>\n    <url>http://maven.apache.org</url>\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.websocket</groupId>\n            <artifactId>javax.websocket-api</artifactId>\n        </dependency>\n    </dependencies>\n\n    <properties>\n        <microservice.resourceClasses>org.wso2.msf4j.sample.websocket.chatapp.ChatAppEndpoint</microservice.resourceClasses>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/websocket/chatApp/deployable-jar/src/main/java/org/wso2/msf4j/sample/websocket/chatapp/ChatAppEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.sample.websocket.chatapp;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class ChatAppEndpoint {\n    private static final Logger LOGGER = LoggerFactory.getLogger(ChatAppEndpoint.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection)\n            throws IOException {\n        String msg = name + \" : \" + text;\n        LOGGER.info(\"Received Text : \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onBinaryMessage(byte[] bytes, WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Reading binary Message\");\n        LOGGER.info(Arrays.toString(bytes));\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason,\n                        WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code : \" + closeReason.getCloseCode().getCode()\n                            + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method : \" + throwable.toString());\n    }\n\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "samples/websocket/chatApp/fatjar/pom.xml",
    "content": "<!--\n  ~  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~  WSO2 Inc. licenses this file to you under the Apache License,\n  ~  Version 2.0 (the \"License\"); you may not use this file except\n  ~  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,\n  ~  software distributed under the License is distributed on an\n  ~  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~  KIND, either express or implied.  See the License for the\n  ~  specific language governing permissions and limitations\n  ~  under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-service</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../../../poms/msf4j-service/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>websocket-chatApp-sample</artifactId>\n\n    <name>Sample: WebSocket Chat Application (Fatjar Mode)</name>\n\n    <properties>\n        <microservice.mainClass>org.wso2.msf4j.sample.websocket.chatapp.Application</microservice.mainClass>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "samples/websocket/chatApp/fatjar/src/main/java/org/wso2/msf4j/sample/websocket/chatapp/Application.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.sample.websocket.chatapp;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n/**\n * This is the runner of the Fatjar. This should be configured as the main class in the pom.xml\n */\npublic class Application {\n    public static void main(String[] args) {\n        new MicroservicesRunner().deployWebSocketEndpoint(new ChatAppEndpoint()).start();\n    }\n}\n"
  },
  {
    "path": "samples/websocket/chatApp/fatjar/src/main/java/org/wso2/msf4j/sample/websocket/chatapp/ChatAppEndpoint.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\n\npackage org.wso2.msf4j.sample.websocket.chatapp;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.wso2.transport.http.netty.contract.websocket.WebSocketConnection;\n\nimport java.io.IOException;\nimport java.util.LinkedList;\nimport java.util.List;\nimport javax.websocket.CloseReason;\nimport javax.websocket.OnClose;\nimport javax.websocket.OnError;\nimport javax.websocket.OnMessage;\nimport javax.websocket.OnOpen;\nimport javax.websocket.server.PathParam;\nimport javax.websocket.server.ServerEndpoint;\n\n/**\n * This is a Sample class for WebSocket.\n * This provides a chat with multiple users.\n */\n\n@ServerEndpoint(value = \"/chat/{name}\")\npublic class ChatAppEndpoint {\n    private static final Logger LOGGER = LoggerFactory.getLogger(ChatAppEndpoint.class);\n    private List<WebSocketConnection> webSocketConnections = new LinkedList<>();\n\n    @OnOpen\n    public void onOpen(@PathParam(\"name\") String name, WebSocketConnection webSocketConnection) {\n        webSocketConnections.add(webSocketConnection);\n        String msg = name + \" connected to chat\";\n        LOGGER.info(msg);\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onTextMessage(@PathParam(\"name\") String name, String text, WebSocketConnection webSocketConnection) throws IOException {\n        String msg = name + \" : \" + text;\n        LOGGER.info(\"Received Text : \" + text + \" from  \" + name + webSocketConnection.getChannelId());\n        sendMessageToAll(msg);\n    }\n\n    @OnMessage\n    public void onBinaryMessage(byte[] bytes, WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Reading binary Message\");\n        LOGGER.info(bytes.toString());\n    }\n\n    @OnClose\n    public void onClose(@PathParam(\"name\") String name, CloseReason closeReason, WebSocketConnection webSocketConnection) {\n        LOGGER.info(\"Connection is closed with status code : \" + closeReason.getCloseCode().getCode()\n                            + \" On reason \" + closeReason.getReasonPhrase());\n        webSocketConnections.remove(webSocketConnection);\n        String msg = name + \" left the chat\";\n        sendMessageToAll(msg);\n    }\n\n    @OnError\n    public void onError(Throwable throwable, WebSocketConnection webSocketConnection) {\n        LOGGER.error(\"Error found in method : \" + throwable.toString());\n    }\n\n\n    private void sendMessageToAll(String message) {\n        webSocketConnections.forEach(\n                webSocketConnection -> webSocketConnection.pushText(message)\n        );\n    }\n}\n"
  },
  {
    "path": "samples/websocket/chatApp/js-client/index.html",
    "content": "<!DOCTYPE html>\n<!--\n  ~  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~  WSO2 Inc. licenses this file to you under the Apache License,\n  ~  Version 2.0 (the \"License\"); you may not use this file except\n  ~  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,\n  ~  software distributed under the License is distributed on an\n  ~  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~  KIND, either express or implied.  See the License for the\n  ~  specific language governing permissions and limitations\n  ~  under the License.\n  -->\n\n<html lang=\"en\">\n<!--\nThis is a simple browser client sample for the given chat app example.\nYou can change the URL from the browser interface with the port you are using.\nIf you are using a secured connection change ws -> wss.\n-->\n<head>\n    <meta charset=\"UTF-8\">\n    <title>WebSocket Chat App</title>\n    <link href=\"bootstrap-3/css/bootstrap.min.css\" rel=\"stylesheet\">\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n    <script src=\"bootstrap-3/js/bootstrap.min.js\"></script>\n</head>\n<body class=\"container\">\n    <h1>WebSocket Chat App</h1>\n    <div class=\"row\">\n        <div class=\"col-md-6\">\n            <form id=\"connectForm\">\n                <div class=\"form-group\">\n                    <label for=\"connectUrlTxt\"></label>\n                    <input type=\"text\" class=\"form-control\" id=\"connectUrlTxt\" value=\"ws://localhost:8080/chat/john\">\n                </div>\n                <button class=\"btn btn-primary\" type=\"button\" id=\"connectBtn\" name=\"connect\" value=\"connect\">Connect</button>\n                <button class=\"btn btn-danger\" type=\"button\" id=\"connectionCloseBtn\" name=\"connect\" value=\"connect\">Close</button>\n            </form>\n\n            <h4><span id=\"connectionStatus\"></span></h4>\n        </div>\n    </div>\n    <hr>\n    <h3>Send</h3>\n    <div class=\"row\">\n        <div class=\"col-md-6\">\n            <form id=\"chatForm\">\n                <div class=\"form-group\">\n                    <label for=\"sendText\"></label>\n                    <input type=\"text\" class=\"form-control\" id=\"sendText\" placeholder=\"Type Something and Send\">\n                </div>\n                <button class=\"btn btn-primary\" type=\"button\" id=\"sendBtn\" name=\"send\" >chat</button>\n                <button class=\"btn btn-warning\" type=\"button\" id=\"sendTextClrBtn\" name=\"receivedClear\">Clear</button>\n            </form>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-6\" id=\"responseBox\">\n        </div>\n    </div>\n\n    <script>\n        var ws = null; // WebSocketConnector\n        var name = \"\";\n        \n        $('#connectBtn').click(function(){\n            connectUrl = $('#connectUrlTxt').val();\n            ws = new WebSocket(connectUrl);\n            ws.onmessage = onMessage;\n            ws.onerror = onError;\n            ws.onclose = onClose;\n            $('#connectionStatus').text(\"Successfully connected to server\").css(\"color\", \"green\");\n            name = $('#name').val();\n        });\n\n        $('#sendText').keydown(function (e) {\n            if (e.keyCode == 13) { // enter\n                sendMessage();\n            }\n        });\n\n        $(\"#chatForm\").submit(function() {\n            return false;\n        });\n\n        $(\"#connectForm\").submit(function() {\n            return false;\n        });\n\n        $('#sendBtn').click(function () {\n            sendMessage();\n        });\n\n        $('#connectionCloseBtn').click(function () {\n            ws.close();\n            $('#connectionStatus').text(\"connection closed.\").css(\"color\", \"red\");\n        });\n\n        $('#sendTextClrBtn').click(function(){\n            $('#responseBox').empty();\n        });\n\n        function sendMessage() {\n            var text = $('#sendText').val();\n            ws.send(text);\n            $('#sendText').val(\"\");\n        }\n\n        function onMessage(msg) {\n            $('#responseBox').append('<h4>' + msg.data + '</h4>');\n        }\n\n        function onError(error) {\n            $('#connectionStatus').text(\"Error connecting to the server\").css(\"color\", \"red\");\n            console.log(error);\n        }\n\n        function onClose() {\n            $('#responseBox').append('<h4 style=\"color: red\">Server closed the connection</h4>');\n            $('#connectionStatus').text(\"connection closed.\").css(\"color\", \"red\");\n        }\n\n        function sendText(text) {\n            ws.send(text)\n        }\n\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "spring/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "spring/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-spring</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J Spring</name>\n    <description>WSO2 MSF4J core</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.kernel.feature</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.runtime.feature</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.carbon</groupId>\n                    <artifactId>org.wso2.carbon.launcher</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.wso2.eclipse.osgi</groupId>\n                    <artifactId>org.eclipse.osgi.services</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.google.code.findbugs</groupId>\n                    <artifactId>jsr305</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n            <version>${project.version}</version>\n            <type>test-jar</type>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context</artifactId>\n            <version>${org.springframework.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context-support</artifactId>\n            <version>${org.springframework.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-web</artifactId>\n            <version>${org.springframework.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpmime</artifactId>\n            <version>4.5.1</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n\n    <properties>\n        <export.package>\n            org.wso2.msf4j.spring.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            javax.annotation.*,\n            javax.ws.rs.*,\n            javax.xml.bind;resolution:=optional,\n            org.springframework.*;resolution:=optional,\n            org.slf4j.*,\n        </import.package>\n    </properties>\n\n</project>\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/MSF4JBeanDefinitionRegistryPostProcessor.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.config.BeanDefinition;\nimport org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistry;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;\nimport org.springframework.beans.factory.support.RootBeanDefinition;\nimport org.wso2.msf4j.spring.transport.HTTPSTransportConfig;\nimport org.wso2.msf4j.spring.transport.HTTPTransportConfig;\n\n/**\n * MSF4JBeanDefinitionRegistryPostProcessor is used by Spring to add default HTTP and/or HTTPS transports.\n *\n * @since 2.0.0\n *\n */\npublic class MSF4JBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {\n\n    @Override\n    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {\n\n        if (!registry.containsBeanDefinition(SpringConstants.HTTP_TRANSPORT)) {\n            registerBeanDefinition(registry, SpringConstants.HTTP_TRANSPORT, HTTPTransportConfig.class);\n        }\n\n        if (!registry.containsBeanDefinition(SpringConstants.HTTPS_TRANSPORT)) {\n            registerBeanDefinition(registry, SpringConstants.HTTPS_TRANSPORT, HTTPSTransportConfig.class);\n        }\n    }\n\n    @Override\n    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {\n\n    }\n\n    private void registerBeanDefinition(BeanDefinitionRegistry registry, String beanName, Class beanClass) {\n        RootBeanDefinition beanDefinition =\n                new RootBeanDefinition(beanClass);\n        beanDefinition.setTargetType(beanClass);\n        beanDefinition.setRole(BeanDefinition.ROLE_APPLICATION);\n        registry.registerBeanDefinition(beanName, beanDefinition);\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/MSF4JSpringApplication.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.beans.BeanUtils;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistry;\nimport org.springframework.context.ApplicationContextInitializer;\nimport org.springframework.context.ConfigurableApplicationContext;\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\nimport org.springframework.context.annotation.ClassPathBeanDefinitionScanner;\nimport org.springframework.core.GenericTypeResolver;\nimport org.springframework.core.annotation.AnnotationAwareOrderComparator;\nimport org.springframework.core.env.SimpleCommandLinePropertySource;\nimport org.springframework.core.io.ResourceLoader;\nimport org.springframework.core.io.support.SpringFactoriesLoader;\nimport org.springframework.util.Assert;\nimport org.springframework.util.ClassUtils;\nimport org.wso2.msf4j.spring.property.YamlFileApplicationContextInitializer;\n\nimport java.lang.reflect.Constructor;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\n/**\n * This class is responsible to construct Microservice application.\n *\n * @since 2.0.0\n */\npublic class MSF4JSpringApplication {\n\n    private static final String DEFAULT_CONTEXT_CLASS = \"org.springframework.context.\"\n                                                        + \"annotation.AnnotationConfigApplicationContext\";\n\n    private Class source;\n    private Class<?> configurationClass;\n    private Class<? extends ConfigurableApplicationContext> applicationContextClass;\n    private ResourceLoader resourceLoader;\n    private List<ApplicationContextInitializer<?>> initializers = new ArrayList<>();\n\n    public MSF4JSpringApplication(Class sources) {\n        initialize(sources);\n    }\n\n    private void initialize(Class source) {\n        if (source != null) {\n            this.source = source;\n        }\n        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));\n        addInitializers(new YamlFileApplicationContextInitializer());\n    }\n\n\n    public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) {\n        this.initializers = new ArrayList<>();\n        this.initializers.addAll(initializers);\n    }\n\n    private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {\n        return getSpringFactoriesInstances(type, new Class<?>[]{});\n    }\n\n    private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,\n                                                                    Class<?>[] parameterTypes, Object... args) {\n        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n        Set<String> names = new LinkedHashSet<>(\n                SpringFactoriesLoader.loadFactoryNames(type, classLoader));\n        List<T> instances = createSpringFactoriesInstances(type, parameterTypes,\n                classLoader, args, names);\n        AnnotationAwareOrderComparator.sort(instances);\n        return instances;\n    }\n\n    private <T> List<T> createSpringFactoriesInstances(Class<T> type,\n                                                       Class<?>[] parameterTypes, ClassLoader classLoader,\n                                                       Object[] args, Set<String> names) {\n        List<T> instances = new ArrayList<T>(names.size());\n        for (String name : names) {\n            try {\n                Class<?> instanceClass = ClassUtils.forName(name, classLoader);\n                Assert.isAssignable(type, instanceClass);\n                Constructor<?> constructor = instanceClass\n                        .getDeclaredConstructor(parameterTypes);\n                T instance = (T) BeanUtils.instantiateClass(constructor, args);\n                instances.add(instance);\n            } catch (Throwable ex) {\n                throw new IllegalArgumentException(\n                        \"Cannot instantiate \" + type + \" : \" + name, ex);\n            }\n        }\n        return instances;\n    }\n\n    public void addInitializers(ApplicationContextInitializer<?>... initializers) {\n        this.initializers.addAll(Arrays.asList(initializers));\n    }\n\n    public static ConfigurableApplicationContext run(Class sources, String... args) {\n        MSF4JSpringApplication application = new MSF4JSpringApplication(sources);\n        ConfigurableApplicationContext context = application.run(false, args);\n        application.applyInitializers(context);\n        context.refresh();\n        return context;\n    }\n\n    private void applyInitializers(ConfigurableApplicationContext context) {\n        for (ApplicationContextInitializer initializer : getInitializers()) {\n            Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(\n                    initializer.getClass(), ApplicationContextInitializer.class);\n            Assert.isInstanceOf(requiredType, context, \"Unable to call initializer.\");\n            initializer.initialize(context);\n        }\n    }\n\n    protected ConfigurableApplicationContext run(boolean doRefresh, String... args) {\n        ConfigurableApplicationContext context = createApplicationContext();\n        if (configurationClass != null) {\n            registerIfAnnotationConfigApplicationContext(context);\n        } else {\n            scanIfAnnotationConfigApplicationContext(context);\n        }\n\n        context.getEnvironment().getPropertySources().addFirst(new SimpleCommandLinePropertySource(args));\n\n        if (doRefresh) {\n            context.refresh();\n        }\n        return context;\n    }\n\n    private void registerIfAnnotationConfigApplicationContext(ConfigurableApplicationContext context) {\n        if (context instanceof AnnotationConfigApplicationContext) {\n//            String packagesForScan = getPackagesForScan();\n            ((AnnotationConfigApplicationContext) context).register(MSF4JSpringConfiguration.class,\n                                                                    configurationClass);\n        }\n    }\n\n    private void scanIfAnnotationConfigApplicationContext(ConfigurableApplicationContext context) {\n        if (context instanceof AnnotationConfigApplicationContext) {\n            String packagesForScan = getPackagesForScan();\n            ((AnnotationConfigApplicationContext) context).register(MSF4JSpringConfiguration.class);\n            ((AnnotationConfigApplicationContext) context).scan(packagesForScan);\n        }\n    }\n\n    private String getPackagesForScan() {\n        return source.getPackage().getName();\n    }\n\n\n    protected ConfigurableApplicationContext createApplicationContext() {\n        Class<?> contextClass = this.applicationContextClass;\n        if (contextClass == null) {\n            try {\n                contextClass = Class\n                        .forName(DEFAULT_CONTEXT_CLASS);\n            } catch (ClassNotFoundException ex) {\n                throw new IllegalStateException(\n                        \"Unable to create a default ApplicationContext, \"\n                        + \"please specify an ApplicationContextClass\", ex);\n            }\n        }\n        return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);\n    }\n\n    public Class<?> getConfigurationClass() {\n        return configurationClass;\n    }\n\n    public void setConfigurationClass(Class<?> configurationClass) {\n        this.configurationClass = configurationClass;\n    }\n\n    public Class<? extends ConfigurableApplicationContext> getApplicationContextClass() {\n        return applicationContextClass;\n    }\n\n    public void setApplicationContextClass(\n            Class<? extends ConfigurableApplicationContext> applicationContextClass) {\n        this.applicationContextClass = applicationContextClass;\n    }\n\n    public ResourceLoader getResourceLoader() {\n        return resourceLoader;\n    }\n\n    public void setResourceLoader(ResourceLoader resourceLoader) {\n        this.resourceLoader = resourceLoader;\n    }\n\n    public List<ApplicationContextInitializer<?>> getInitializers() {\n        return initializers;\n    }\n\n    public void setInitializers(List<ApplicationContextInitializer<?>> initializers) {\n        this.initializers = initializers;\n    }\n\n    /**\n     * This will add a given service class to the running instance with given base path.\n     *\n     * @param configurableApplicationContext ConfigurableApplicationContext of running app\n     * @param serviceClass                   Service class\n     * @param basePath                       Base path to which the service get registered\n     */\n    public SpringMicroservicesRunner addService(ConfigurableApplicationContext configurableApplicationContext,\n                                                Class<?> serviceClass, String basePath) {\n        ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner =\n                new ClassPathBeanDefinitionScanner((BeanDefinitionRegistry) configurableApplicationContext);\n        classPathBeanDefinitionScanner.scan(serviceClass.getPackage().getName());\n        SpringMicroservicesRunner springMicroservicesRunner =\n                configurableApplicationContext.getBean(SpringMicroservicesRunner.class);\n        springMicroservicesRunner.deploy(basePath, configurableApplicationContext.getBean(serviceClass));\n        return springMicroservicesRunner;\n    }\n}\n\n\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/MSF4JSpringConfiguration.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.PropertySource;\nimport org.springframework.context.annotation.PropertySources;\nimport org.springframework.context.support.PropertySourcesPlaceholderConfigurer;\n\n/**\n * Default Spring configuration class for Microservices, it's possible to provide alternative Spring configuration\n * classes by application developers.\n *\n * @since 2.0.0\n */\n@Configuration\n@ComponentScan\n@PropertySources({\n        @PropertySource(value = \"file:application.properties\", ignoreResourceNotFound = true,\n                name = \"applicationProperties\"),\n        @PropertySource(value = \"classpath:application.properties\", ignoreResourceNotFound = true,\n                name = \"applicationProperties\"),\n        @PropertySource(value = \"file:application-${spring.profiles.active}.properties\", ignoreResourceNotFound = true,\n                name = \"applicationProperties\"),\n        @PropertySource(value = \"classpath:application-${spring.profiles.active}.properties\",\n                ignoreResourceNotFound = true, name = \"applicationProperties\")\n})\npublic class MSF4JSpringConfiguration {\n\n    @Bean\n    public MSF4JBeanDefinitionRegistryPostProcessor msf4JBeanDefinitionRegistryPostProcessor() {\n        return new MSF4JBeanDefinitionRegistryPostProcessor();\n    }\n\n    @Bean\n    public SpringMicroservicesRunner springMicroservicesRunner() {\n        return new SpringMicroservicesRunner();\n    }\n\n    @Bean\n    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {\n        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();\n        pspc.setIgnoreUnresolvablePlaceholders(true);\n        return pspc;\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/SpringConstants.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring;\n\n/**\n * Class to hold constants used in Spring module.\n *\n * @since 2.0.0\n *\n */\npublic class SpringConstants {\n\n    public static final String HTTP_TRANSPORT = \"http\";\n    public static final String HTTPS_TRANSPORT = \"https\";\n\n    public static final String TRANSPORTS_NETTY_CONF_FILE = \"transports.netty.conf\";\n\n    public static final String APPLICATION_PROPERTIES = \"applicationProperties\";\n    public static final String PARAMETER_STR = \".parameter.\";\n    public static final String DEFAULT_HOST = \"0.0.0.0\";\n\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/SpringMicroservicesRunner.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.spring;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.internal.DataHolder;\nimport org.wso2.msf4j.spring.transport.HTTPSTransportConfig;\nimport org.wso2.msf4j.spring.transport.TransportConfig;\nimport org.wso2.transport.http.netty.contract.HttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.contract.ServerConnector;\nimport org.wso2.transport.http.netty.contract.config.ListenerConfiguration;\nimport org.wso2.transport.http.netty.contract.config.Parameter;\nimport org.wso2.transport.http.netty.contract.config.ServerBootstrapConfiguration;\nimport org.wso2.transport.http.netty.contractimpl.DefaultHttpWsConnectorFactory;\nimport org.wso2.transport.http.netty.contractimpl.common.Util;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.ext.ExceptionMapper;\n\n/**\n * This runner initializes the microservices runtime based on provided Spring configuration, deploys microservices,\n * service interceptors and starts the relevant transports.\n *\n * @since 2.0.0\n */\n\n@Component\npublic class SpringMicroservicesRunner extends MicroservicesRunner implements ApplicationContextAware,\n        InitializingBean {\n    private final Log log = LogFactory.getLog(getClass());\n\n    @Autowired\n    private ApplicationContext applicationContext;\n\n    public SpringMicroservicesRunner() {\n    }\n\n    public SpringMicroservicesRunner(int... ports) {\n        super(ports);\n    }\n\n    public void init() {\n\n        for (Map.Entry<String, Object> entry : applicationContext.getBeansWithAnnotation(Path.class).entrySet()) {\n            log.info(\"Deploying \" + entry.getKey() + \" bean as a resource\");\n            deploy(entry.getValue());\n        }\n\n        for (Map.Entry<String, ExceptionMapper> exceptionMapper :\n                applicationContext.getBeansOfType(ExceptionMapper.class).entrySet()) {\n            log.info(\"Adding \" + exceptionMapper.getKey() + \"  ExceptionMapper\");\n            addExceptionMapper(exceptionMapper.getValue());\n        }\n\n        configureTransport(applicationContext.getBeansOfType(ListenerConfiguration.class).values(),\n                applicationContext.getBeansOfType(TransportConfig.class).values());\n\n        start();\n    }\n\n\n    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n        this.applicationContext = applicationContext;\n    }\n\n\n    public void afterPropertiesSet() throws Exception {\n        init();\n    }\n\n    @Override\n    protected void configureTransport() {\n        //Do nothing, just avoid super class's transport configuring options as we use Spring to configure transports.\n    }\n\n    protected void configureTransport(Collection<ListenerConfiguration> listeners,\n                                      Collection<TransportConfig> transportConfigs) {\n        /*\n        If -Dtransports.netty.conf=netty-transports.yml present as a command line argument or system property use\n        that setting instead of Spring specific options.\n         */\n        if (System.getProperty(SpringConstants.TRANSPORTS_NETTY_CONF_FILE) != null) {\n            super.configureTransport();\n            return;\n\n        }\n        HttpWsConnectorFactory connectorFactory = new DefaultHttpWsConnectorFactory();\n        ServerBootstrapConfiguration bootstrapConfiguration = new ServerBootstrapConfiguration(new HashMap<>());\n\n        //Add ListenerConfigurations if available on Spring Configuration\n        listeners.forEach(listenerConfiguration -> {\n            DataHolder.getInstance().getMicroservicesRegistries().put(Util.createServerConnectorID\n                    (listenerConfiguration.getHost(), listenerConfiguration.getPort()), getMsRegistry());\n            ServerConnector serverConnector =\n                    connectorFactory.createServerConnector(bootstrapConfiguration, listenerConfiguration);\n            serverConnectors.add(serverConnector);\n        });\n\n        //Add NettyTransportConfig if available on Spring Configuration\n        for (TransportConfig transportConfig : transportConfigs) {\n            if (transportConfig.isEnabled()) {\n                ListenerConfiguration listenerConfiguration = createListenerConfiguration(transportConfig);\n                DataHolder.getInstance().getMicroservicesRegistries().put(Util.createServerConnectorID\n                        (listenerConfiguration.getHost(), listenerConfiguration.getPort()), getMsRegistry());\n                ServerConnector serverConnector =\n                        connectorFactory.createServerConnector(bootstrapConfiguration, listenerConfiguration);\n                serverConnectors.add(serverConnector);\n            }\n        }\n    }\n\n    private ListenerConfiguration createListenerConfiguration(TransportConfig transportConfig) {\n\n        ListenerConfiguration listenerConfig =\n                new ListenerConfiguration(transportConfig.getId(), transportConfig.getHost(),\n                        transportConfig.getPort());\n        listenerConfig.setScheme(transportConfig.getScheme());\n        List<Parameter> parameters = new ArrayList<>();\n        for (Map.Entry<String, String> entry : transportConfig.getParameters().entrySet()) {\n            parameters.add(createParameter(entry.getKey(), entry.getValue()));\n        }\n\n        listenerConfig.setParameters(parameters);\n        if (SpringConstants.HTTPS_TRANSPORT.equals(transportConfig.getScheme())) {\n            HTTPSTransportConfig httpsTransportConfig = (HTTPSTransportConfig) transportConfig;\n            listenerConfig.setKeyStoreFile(httpsTransportConfig.getKeyStoreFile());\n            listenerConfig.setKeyStorePass(httpsTransportConfig.getKeyStorePass());\n        }\n\n        return listenerConfig;\n    }\n\n    private Parameter createParameter(String key, String value) {\n        Parameter parameter = new Parameter();\n        parameter.setName(key);\n        parameter.setValue(value);\n        return parameter;\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/property/YamlFileApplicationContextInitializer.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.spring.property;\n\nimport org.springframework.context.ApplicationContextInitializer;\nimport org.springframework.context.ConfigurableApplicationContext;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\nimport org.springframework.core.io.Resource;\nimport org.springframework.util.StringUtils;\nimport org.yaml.snakeyaml.LoaderOptions;\nimport org.yaml.snakeyaml.Yaml;\nimport org.yaml.snakeyaml.constructor.SafeConstructor;\n\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\n\n/**\n * ApplicationContextInitializer class used to load environment properties from YAML files.\n */\npublic class YamlFileApplicationContextInitializer\n        implements ApplicationContextInitializer<ConfigurableApplicationContext> {\n\n    private static final String YAML_CONFIG_FILE_NAME = \"application.yml\";\n\n    @Override\n    public void initialize(ConfigurableApplicationContext applicationContext) {\n        Resource resource = applicationContext.getResource(\"classpath:\" + YAML_CONFIG_FILE_NAME);\n        if (!resource.exists()) {\n            resource = applicationContext.getResource(\"file:\" + YAML_CONFIG_FILE_NAME);\n        }\n\n        if (resource.exists()) {\n            List<Properties> applicationYmlProperties = new ArrayList<>();\n            String[] activeProfileNames = null;\n            try (InputStream input = resource.getInputStream()) {\n                Yaml yml = new Yaml(new SafeConstructor(new LoaderOptions()));\n                Iterable<Object> objects = yml.loadAll(input);\n                for (Object obj : objects) {\n                    Map<String, Object> flattenedMap = getFlattenedMap(asMap(obj));\n                    Properties properties = new Properties();\n                    properties.putAll(flattenedMap);\n                    Object activeProfile = properties.get(\"spring.profiles.active\");\n                    if (activeProfile != null) {\n                        activeProfileNames = activeProfile.toString().split(\",\");\n                    }\n                    applicationYmlProperties.add(properties);\n                }\n            } catch (FileNotFoundException e) {\n                throw new RuntimeException(\"Couldn't find \" + YAML_CONFIG_FILE_NAME, e);\n            } catch (IOException e) {\n                throw new RuntimeException(\"Error while reading \" + YAML_CONFIG_FILE_NAME, e);\n            }\n\n            if (activeProfileNames == null) {\n                activeProfileNames = applicationContext.getEnvironment().getActiveProfiles();\n            }\n\n            for (Properties properties : applicationYmlProperties) {\n                String profile = properties.getProperty(\"spring.profiles\");\n                PropertySource<?> propertySource;\n                if (profile == null) {\n                    propertySource = new MapPropertySource(YAML_CONFIG_FILE_NAME, new HashMap(properties));\n                    applicationContext.getEnvironment().getPropertySources().addLast(propertySource);\n                } else if (activeProfileNames != null && (\"default\".equals(profile) ||\n                                                          (activeProfileNames.length == 1 &&\n                                                           activeProfileNames[0].equals(profile)))) {\n                    propertySource =\n                            new MapPropertySource(YAML_CONFIG_FILE_NAME + \"[\" + profile + \"]\", new HashMap(properties));\n                    applicationContext.getEnvironment().getPropertySources()\n                                      .addAfter(\"systemEnvironment\", propertySource);\n                }\n                activeProfileNames = applicationContext.getEnvironment().getActiveProfiles();\n            }\n        }\n        applicationContext.getEnvironment().getActiveProfiles();\n    }\n\n    private Map<String, Object> asMap(Object object) {\n        // YAML can have numbers as keys\n        Map<String, Object> result = new LinkedHashMap<String, Object>();\n        if (!(object instanceof Map)) {\n            // A document can be a text literal\n            result.put(\"document\", object);\n            return result;\n        }\n\n        Map<Object, Object> map = (Map<Object, Object>) object;\n        for (Map.Entry<Object, Object> entry : map.entrySet()) {\n            Object value = entry.getValue();\n            if (value instanceof Map) {\n                value = asMap(value);\n            }\n            Object key = entry.getKey();\n            if (key instanceof CharSequence) {\n                result.put(key.toString(), value);\n            } else {\n                // It has to be a map key in this case\n                result.put(\"[\" + key.toString() + \"]\", value);\n            }\n        }\n        return result;\n    }\n\n    private final Map<String, Object> getFlattenedMap(Map<String, Object> source) {\n        Map<String, Object> result = new LinkedHashMap<String, Object>();\n        buildFlattenedMap(result, source, null);\n        return result;\n    }\n\n    private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {\n        for (Map.Entry<String, Object> entry : source.entrySet()) {\n            String key = entry.getKey();\n            if (StringUtils.hasText(path)) {\n                if (key.startsWith(\"[\")) {\n                    key = path + key;\n                } else {\n                    key = path + \".\" + key;\n                }\n            }\n            Object value = entry.getValue();\n            if (value instanceof String) {\n                result.put(key, value);\n            } else if (value instanceof Map) {\n                // Need a compound key\n                @SuppressWarnings(\"unchecked\") Map<String, Object> map = (Map<String, Object>) value;\n                buildFlattenedMap(result, map, key);\n            } else if (value instanceof Collection) {\n                // Need a compound key\n                @SuppressWarnings(\"unchecked\") Collection<Object> collection = (Collection<Object>) value;\n                int count = 0;\n                for (Object object : collection) {\n                    buildFlattenedMap(result, Collections.singletonMap(\"[\" + (count++) + \"]\", object), key);\n                }\n            } else {\n                result.put(key, value == null ? \"\" : value);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/transport/HTTPSTransportConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring.transport;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.wso2.msf4j.spring.SpringConstants;\n\n/**\n * TransportConfig bean for HTTPS transport\n *\n * @since 2.0.0\n */\npublic class HTTPSTransportConfig extends TransportConfig {\n\n    public HTTPSTransportConfig() {\n        super.setScheme(SpringConstants.HTTPS_TRANSPORT);\n    }\n\n    @Value(\"${https.id:}\")\n    public void setId(String id) {\n        super.setId(id);\n    }\n\n    @Value(\"${https.enabled:}\")\n    public void setEnabledProperty(String enabled) {\n        super.setEnabledProperty(enabled);\n    }\n\n    @Value(\"${https.port:}\")\n    public void setPortProperty(String port) {\n        super.setPortProperty(port);\n    }\n\n    @Value(\"${https.host:}\")\n    public void setHostProperty(String host) {\n        super.setHostProperty(host);\n    }\n\n    @Value(\"${https.keyStoreFile:}\")\n    public void setKeyStoreFileProperty(String keyStoreFile) {\n        super.setKeyStoreFileProperty(keyStoreFile);\n    }\n\n    @Value(\"${https.keyStorePass:}\")\n    public void setKeyStorePassProperty(String keyStorePass) {\n        super.setKeyStorePassProperty(keyStorePass);\n    }\n\n    @Value(\"${https.certPass:}\")\n    public void setCertPassProperty(String certPass) {\n        super.setCertPassProperty(certPass);\n    }\n\n    public HTTPSTransportConfig port(int port) {\n        setPort(port);\n        return this;\n    }\n\n    public HTTPSTransportConfig host(String host) {\n        setHost(host);\n        return this;\n    }\n\n    public HTTPSTransportConfig keyStore(String keyStore) {\n        setKeyStoreFile(keyStore);\n        return this;\n    }\n\n    public HTTPSTransportConfig keyStorePass(String keyStorePass) {\n        setKeyStorePass(keyStorePass);\n        return this;\n    }\n\n    public HTTPSTransportConfig certPass(String certPass) {\n        setCertPass(certPass);\n        return this;\n    }\n\n    public HTTPSTransportConfig enabled(boolean enabled) {\n        setEnabled(enabled);\n        return this;\n    }\n\n    public HTTPSTransportConfig enabled() {\n        setEnabled(true);\n        return this;\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/transport/HTTPTransportConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring.transport;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.wso2.msf4j.spring.SpringConstants;\n\n/**\n * TransportConfig bean for HTTP transport\n *\n * @since 2.0.0\n */\npublic class HTTPTransportConfig extends TransportConfig {\n\n    public HTTPTransportConfig() {\n        super.setScheme(SpringConstants.HTTP_TRANSPORT);\n    }\n\n    public HTTPTransportConfig(int port) {\n        this();\n        setPort(port);\n    }\n\n    @Value(\"${http.id:}\")\n    public void setId(String id) {\n        super.setId(id);\n    }\n\n    @Value(\"${http.enabled:}\")\n    public void setEnabledProperty(String enabled) {\n        super.setEnabledProperty(enabled);\n    }\n\n    @Value(\"${http.port:}\")\n    public void setPortProperty(String port) {\n        super.setPortProperty(port);\n    }\n\n    @Value(\"${http.host:}\")\n    public void setHostProperty(String host) {\n        super.setHostProperty(host);\n    }\n\n    public HTTPTransportConfig port(int port) {\n        setPort(port);\n        return this;\n    }\n\n    public HTTPTransportConfig host(String host) {\n        setHost(host);\n        return this;\n    }\n\n    public HTTPTransportConfig enabled(boolean enabled) {\n        setEnabled(enabled);\n        return this;\n    }\n\n    public HTTPTransportConfig enabled() {\n        setEnabled(true);\n        return this;\n    }\n}\n"
  },
  {
    "path": "spring/src/main/java/org/wso2/msf4j/spring/transport/TransportConfig.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring.transport;\n\nimport org.springframework.beans.factory.BeanNameAware;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.AbstractEnvironment;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.wso2.msf4j.spring.SpringConstants;\n\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport javax.annotation.PostConstruct;\n\n/**\n * abstract TransportConfig bean\n *\n * @since 2.0.0\n */\npublic abstract class TransportConfig implements BeanNameAware {\n\n    private String id;\n    private String enabledProperty;\n    private String portProperty;\n    private String hostProperty;\n    private String schemeProperty;\n    private String keyStoreFileProperty;\n    private String keyStorePassProperty;\n    private String certPassProperty;\n    private String bossThreadPoolSizeProperty;\n    private String workerThreadPoolSizeProperty;\n    private String execHandlerThreadPoolSizeProperty;\n    private Boolean enabled;\n    private Integer port;\n    private String host;\n    private String scheme;\n    private String keyStoreFile;\n    private String keyStorePass;\n    private String certPass;\n    private Integer bossThreadPoolSize;\n    private Integer workerThreadPoolSize;\n    private Integer execHandlerThreadPoolSize;\n    private String beanName;\n    private Map<String, String> parameters = new HashMap<>();\n\n    @Autowired\n    Environment env;\n\n    @PostConstruct\n    public void init() {\n        id = resolveId();\n        enabled = resolveEnabled();\n        port = resolvePort();\n        host = resolveHost();\n        if (isHTTPS()) {\n            keyStoreFile = resolveKeyStoreFile();\n            keyStorePass = resolveKeyStorePass();\n            certPass = resolveKeyCertPass();\n\n        }\n\n        for (Iterator it = ((AbstractEnvironment) env).getPropertySources().iterator(); it.hasNext(); ) {\n            Object propertySource = it.next();\n            if (propertySource instanceof MapPropertySource\n                && SpringConstants.APPLICATION_PROPERTIES.equals(((MapPropertySource) propertySource).getName())) {\n                MapPropertySource mapPropertySource = (MapPropertySource) propertySource;\n                for (Map.Entry<String, Object> entry : mapPropertySource.getSource().entrySet()) {\n                    String key = entry.getKey();\n                    if (key.startsWith(getScheme()) && key.contains(SpringConstants.PARAMETER_STR)) {\n                        parameters.put(key.substring(key.indexOf(SpringConstants.PARAMETER_STR) + 11), (String) entry\n                                .getValue());\n                    }\n                }\n            }\n        }\n    }\n\n    @Override\n    public void setBeanName(String name) {\n        this.beanName = name;\n    }\n\n    private String resolveKeyCertPass() {\n        if (!keyStorePassProperty.isEmpty()) {\n            return keyStorePassProperty;\n        }\n        return keyStorePass;\n    }\n\n    private String resolveKeyStorePass() {\n        if (!keyStorePassProperty.isEmpty()) {\n            return keyStorePassProperty;\n        }\n        return keyStorePass;\n    }\n\n    private String resolveKeyStoreFile() {\n        if (!keyStoreFileProperty.isEmpty()) {\n            return keyStoreFileProperty;\n        }\n        return keyStoreFile;\n    }\n\n    private String resolveId() {\n        return id.isEmpty() ? beanName : id;\n    }\n\n    private String resolveHost() {\n        if (!hostProperty.isEmpty()) {\n            return hostProperty;\n        } else if (host == null) {\n            return SpringConstants.DEFAULT_HOST;\n        }\n        return host;\n    }\n\n    private int resolvePort() {\n        if (!portProperty.isEmpty()) {\n            return Integer.parseInt(portProperty);\n        } else if (port == null) {\n            return isHTTPS() == true ? 8443 : 8080;\n        }\n        return port;\n    }\n\n    private boolean resolveEnabled() {\n        if (!enabledProperty.isEmpty()) {\n            return Boolean.valueOf(enabledProperty);\n        } else if (enabled == null) {\n            return isHTTPS() ? false : true;\n        }\n        return enabled;\n    }\n\n    public void setId(String id) {\n        this.id = id;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getEnabledProperty() {\n        return enabledProperty;\n    }\n\n    public void setEnabledProperty(String enabledProperty) {\n        this.enabledProperty = enabledProperty;\n    }\n\n    public String getPortProperty() {\n        return portProperty;\n    }\n\n    public void setPortProperty(String portProperty) {\n        this.portProperty = portProperty;\n    }\n\n    public String getHostProperty() {\n        return hostProperty;\n    }\n\n    public void setHostProperty(String hostProperty) {\n        this.hostProperty = hostProperty;\n    }\n\n    public String getSchemeProperty() {\n        return schemeProperty;\n    }\n\n    public void setSchemeProperty(String schemeProperty) {\n        this.schemeProperty = schemeProperty;\n    }\n\n    public String getKeyStoreFileProperty() {\n        return keyStoreFileProperty;\n    }\n\n    public void setKeyStoreFileProperty(String keyStoreFileProperty) {\n        this.keyStoreFileProperty = keyStoreFileProperty;\n    }\n\n    public String getKeyStorePassProperty() {\n        return keyStorePassProperty;\n    }\n\n    public void setKeyStorePassProperty(String keyStorePassProperty) {\n        this.keyStorePassProperty = keyStorePassProperty;\n    }\n\n    public String getCertPassProperty() {\n        return certPassProperty;\n    }\n\n    public void setCertPassProperty(String certPassProperty) {\n        this.certPassProperty = certPassProperty;\n    }\n\n    public String getBossThreadPoolSizeProperty() {\n        return bossThreadPoolSizeProperty;\n    }\n\n    public void setBossThreadPoolSizeProperty(String bossThreadPoolSizeProperty) {\n        this.bossThreadPoolSizeProperty = bossThreadPoolSizeProperty;\n    }\n\n    public String getWorkerThreadPoolSizeProperty() {\n        return workerThreadPoolSizeProperty;\n    }\n\n    public void setWorkerThreadPoolSizeProperty(String workerThreadPoolSizeProperty) {\n        this.workerThreadPoolSizeProperty = workerThreadPoolSizeProperty;\n    }\n\n    public String getExecHandlerThreadPoolSizeProperty() {\n        return execHandlerThreadPoolSizeProperty;\n    }\n\n    public void setExecHandlerThreadPoolSizeProperty(String execHandlerThreadPoolSizeProperty) {\n        this.execHandlerThreadPoolSizeProperty = execHandlerThreadPoolSizeProperty;\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public int getPort() {\n        return port;\n    }\n\n    public void setPort(int port) {\n        this.port = port;\n    }\n\n    public String getHost() {\n        return host;\n    }\n\n    public void setHost(String host) {\n        this.host = host;\n    }\n\n    public String getScheme() {\n        return scheme;\n    }\n\n    public void setScheme(String scheme) {\n        this.scheme = scheme;\n    }\n\n    public String getKeyStoreFile() {\n        return keyStoreFile;\n    }\n\n    public void setKeyStoreFile(String keyStoreFile) {\n        this.keyStoreFile = keyStoreFile;\n    }\n\n    public String getKeyStorePass() {\n        return keyStorePass;\n    }\n\n    public void setKeyStorePass(String keyStorePass) {\n        this.keyStorePass = keyStorePass;\n    }\n\n    public String getCertPass() {\n        return certPass;\n    }\n\n    public void setCertPass(String certPass) {\n        this.certPass = certPass;\n    }\n\n    public int getBossThreadPoolSize() {\n        return bossThreadPoolSize;\n    }\n\n    public void setBossThreadPoolSize(int bossThreadPoolSize) {\n        this.bossThreadPoolSize = bossThreadPoolSize;\n    }\n\n    public int getWorkerThreadPoolSize() {\n        return workerThreadPoolSize;\n    }\n\n    public void setWorkerThreadPoolSize(int workerThreadPoolSize) {\n        this.workerThreadPoolSize = workerThreadPoolSize;\n    }\n\n    public int getExecHandlerThreadPoolSize() {\n        return execHandlerThreadPoolSize;\n    }\n\n    public void setExecHandlerThreadPoolSize(int execHandlerThreadPoolSize) {\n        this.execHandlerThreadPoolSize = execHandlerThreadPoolSize;\n    }\n\n    public void setParameters(Map<String, String> parameters) {\n        this.parameters = parameters;\n    }\n\n    public boolean getDefaultEnabled() {\n        return isHTTPS() ? false : true;\n    }\n\n    public Map<String, String> getParameters() {\n        return parameters;\n    }\n\n    public boolean isHTTPS() {\n        return SpringConstants.HTTPS_TRANSPORT.equals(getScheme());\n    }\n}\n"
  },
  {
    "path": "spring/src/main/resources/log4j.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!--\n~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">\n<log4j:configuration debug=\"true\"\n                     xmlns:log4j='http://jakarta.apache.org/log4j/'>\n\n    <appender name=\"console\" class=\"org.apache.log4j.ConsoleAppender\">\n        <layout class=\"org.apache.log4j.PatternLayout\">\n            <param name=\"ConversionPattern\"\n                   value=\"%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n\" />\n        </layout>\n    </appender>\n\n    <root>\n        <level value=\"INFO\" />\n        <appender-ref ref=\"console\" />\n    </root>\n\n</log4j:configuration>"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/ServerConfig.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n/**\n * Server configuration for Spring.\n */\n@Configuration\npublic class ServerConfig {\n\n    /*\n     This will override \"SpringMicroservicesRunner\" bean configured in default MSF4JSpringConfiguration class, this\n     enables to start Netty transport on 9291 port.\n     NOTE - Due to Spring framework limitations this feature only work with Spring versions starting from 4.2.0\n     */\n    @Bean\n    public SpringMicroservicesRunner springMicroservicesRunner() {\n        return new SpringMicroservicesRunner(9291);\n    }\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/SpringHttpServerTest.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.context.ConfigurableApplicationContext;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.wso2.msf4j.HttpServerTest;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.spring.service.second.TestMicroServiceWithDynamicPath;\n\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Spring tests.\n */\npublic class SpringHttpServerTest extends HttpServerTest {\n\n    private static final int port = Constants.PORT;\n    private List<ConfigurableApplicationContext> configurableApplicationContexts = new ArrayList<>();\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"http://%s:%d\", Constants.HOSTNAME, port));\n        MSF4JSpringApplication msf4JSpringApplication = new MSF4JSpringApplication(SpringHttpServerTest.class);\n        configurableApplicationContexts.add(msf4JSpringApplication.run(true, \"--http.port=8090\"));\n        configurableApplicationContexts.add(MSF4JSpringApplication.run(SecondService.class, \"--http.port=8091\"));\n        msf4JSpringApplication.addService(configurableApplicationContexts.get(0), TestMicroServiceWithDynamicPath.class,\n                                          \"/DynamicPath\");\n        msf4JSpringApplication.addService(configurableApplicationContexts.get(0), TestMicroServiceWithDynamicPath.class,\n                                          \"/DynamicPath2\");\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        configurableApplicationContexts.stream().forEach(\n                configurableApplicationContext -> configurableApplicationContext.close());\n    }\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/SpringInterceptorTest.java",
    "content": "/*\n * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * 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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.wso2.msf4j.spring;\n\nimport org.springframework.context.ConfigurableApplicationContext;\nimport org.testng.AssertJUnit;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.BeforeMethod;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.InterceptorTestBase;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.interceptor.HighPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityGlobalRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityGlobalResponseInterceptor;\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.TestInterceptorDeprecated;\nimport org.wso2.msf4j.interceptor.TestRequestInterceptor;\nimport org.wso2.msf4j.interceptor.TestResponseInterceptor;\nimport org.wso2.msf4j.spring.service.second.TestMicroServiceWithDynamicPath;\n\nimport java.net.URI;\nimport java.util.Collections;\nimport java.util.Locale;\n\nimport static org.testng.Assert.assertEquals;\n\n/**\n * Class for testing interceptors with spring.\n *\n * @since 2.4.2\n */\npublic class SpringInterceptorTest extends InterceptorTestBase {\n\n    private static final int port = Constants.PORT;\n    private ConfigurableApplicationContext configurableApplicationContext;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(Locale.ENGLISH, \"http://%s:%d\", Constants.HOSTNAME, port));\n        configurableApplicationContext = MSF4JSpringApplication\n                .run(SpringInterceptorTest.class, \"--http.port=8090\");\n        MSF4JSpringApplication msf4JSpringApplication = new MSF4JSpringApplication(SpringInterceptorTest.class);\n        msf4JSpringApplication.addService(configurableApplicationContext, TestMicroServiceWithDynamicPath.class,\n                \"/DynamicPath\")\n                .addGlobalRequestInterceptor(new HighPriorityGlobalRequestInterceptor(),\n                        new MediumPriorityGlobalRequestInterceptor(), new LowPriorityGlobalRequestInterceptor())\n                .addInterceptor(new TestInterceptorDeprecated())\n                .addGlobalResponseInterceptor(new HighPriorityGlobalResponseInterceptor(),\n                        new MediumPriorityGlobalResponseInterceptor(), new LowPriorityGlobalResponseInterceptor());\n    }\n\n    @AfterClass\n    public void tearDown() throws Exception {\n        configurableApplicationContext.close();\n    }\n\n    /**\n     * Test the order and the execution of the interceptors.\n     * Order of the execution should be\n     * <p>\n     * 1) Global request interceptors according to the priority order (way developer writes them)\n     * HighPriorityGlobalRequestInterceptor -> MediumPriorityGlobalRequestInterceptor ->\n     * LowPriorityGlobalRequestInterceptor -> TestInterceptorDeprecated - [PRE CALL]\n     * <p>\n     * 2) Resource level request interceptors according to the priority order (way developer writes them)\n     * HighPriorityRRequestInterceptor -> MediumPriorityRRequestInterceptor -> LowPriorityRRequestInterceptor\n     * <p>\n     * 3) Sub-resource level request interceptors according to the priority order (way developer writes them)\n     * HighPrioritySRRequestInterceptor -> MediumPrioritySRRequestInterceptor -> LowPrioritySRRequestInterceptor\n     * <p>\n     * 4) HTTP method\n     * <p>\n     * 5) Sub-resource level response interceptors according to the priority order (way developer writes them)\n     * HighPrioritySRResponseInterceptor -> MediumPrioritySRResponseInterceptor -> LowPrioritySRResponseInterceptor\n     * <p>\n     * 6) Resource level response interceptors according to the priority order (way developer writes them)\n     * HighPriorityRResponseInterceptor -> MediumPriorityRResponseInterceptor -> LowPriorityRResponseInterceptor\n     * <p>\n     * 7) Global response interceptors according to the priority order (way developer writes them)\n     * TestInterceptorDeprecated - [POST CALL] -> HighPriorityGlobalResponseInterceptor ->\n     * MediumPriorityGlobalResponseInterceptor -> LowPriorityGlobalResponseInterceptor\n     *\n     * @throws Exception on any exception\n     */\n    @Test\n    public void springInterceptorTest() throws Exception {\n        String path = \"/DynamicPath/hello/MyMicro-Service\";\n        String response = doGetAndGetResponseString(path, false,\n                Collections.unmodifiableMap(Collections.emptyMap()));\n        assertEquals(response, \"Hello MyMicro-Service\");\n        String executionOrderString = \"HighPriorityGlobalRequestInterceptor\" +\n                                      \"MediumPriorityGlobalRequestInterceptor\" +\n                                      \"LowPriorityGlobalRequestInterceptor\" +\n                                      \"TestInterceptorDeprecated - [PRE CALL]\" +\n                                      \"HighPriorityClassRequestInterceptor\" +\n                                      \"MediumPriorityClassRequestInterceptor\" +\n                                      \"LowPriorityClassRequestInterceptor\" +\n                                      \"HighPriorityMethodRequestInterceptor\" +\n                                      \"MediumPriorityMethodRequestInterceptor\" +\n                                      \"LowPriorityMethodRequestInterceptor\" +\n                                      \"[SPRING HTTP METHOD]\" +\n                                      \"HighPriorityMethodResponseInterceptor\" +\n                                      \"MediumPriorityMethodResponseInterceptor\" +\n                                      \"LowPriorityMethodResponseInterceptor\" +\n                                      \"HighPriorityClassResponseInterceptor\" +\n                                      \"MediumPriorityClassResponseInterceptor\" +\n                                      \"LowPriorityClassResponseInterceptor\" +\n                                      \"TestInterceptorDeprecated - [POST CALL]\" +\n                                      \"HighPriorityGlobalResponseInterceptor\" +\n                                      \"MediumPriorityGlobalResponseInterceptor\" +\n                                      \"LowPriorityGlobalResponseInterceptor\";\n        AssertJUnit.assertEquals(executionOrderString, PriorityDataHolder.getPriorityOrder());\n    }\n\n    @BeforeMethod\n    public void reset() {\n        // Reset request interceptors\n        TestRequestInterceptor.reset();\n\n        // Reset response interceptors\n        TestResponseInterceptor.reset();\n\n        // Reset global request interceptors\n        HighPriorityGlobalRequestInterceptor.reset();\n        MediumPriorityGlobalRequestInterceptor.reset();\n        LowPriorityGlobalRequestInterceptor.reset();\n\n        // Reset global response interceptors\n        HighPriorityGlobalResponseInterceptor.reset();\n        MediumPriorityGlobalResponseInterceptor.reset();\n        LowPriorityGlobalResponseInterceptor.reset();\n\n        // Reset deprecated interceptor\n        TestInterceptorDeprecated.reset();\n    }\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/exception/SpringTestExceptionMapper.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.spring.exception;\n\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.exception.TestExceptionMapper;\n\n/**\n * Test exception mapper used for testing ExceptionMapper feature.\n */\n@Component\npublic class SpringTestExceptionMapper extends TestExceptionMapper {\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/exception/SpringTestExceptionMapper2.java",
    "content": "/*\n *  Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.spring.exception;\n\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.exception.TestExceptionMapper2;\n\n/**\n * Test exception mapper used for testing ExceptionMapper feature.\n */\n@Component\npublic class SpringTestExceptionMapper2 extends TestExceptionMapper2 {\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/service/SpringTestMicroservice.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring.service;\n\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport javax.ws.rs.Path;\n\n/**\n * Test service.\n */\n@SuppressWarnings(\"UnusedParameters\")\n@Component\n@Path(\"/test/v1\")\npublic class SpringTestMicroservice extends TestMicroservice {\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/service/second/CustomService.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.spring.service.second;\n\nimport org.springframework.stereotype.Component;\n\n/**\n * HelloService class to be injected to Hello resource through Spring\n */\n@Component\npublic class CustomService {\n\n    public String sayHello(String name) {\n        return \"Hello \" + name;\n    }\n\n    public int add(int no1, int no2) {\n        return no1 + no2;\n    }\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/service/second/SecondService.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.spring.service.second;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@SuppressWarnings(\"UnusedParameters\")\n@Component\n@Path(\"/SecondService\")\npublic class SecondService {\n\n    @Autowired\n    private CustomService customService;\n\n    @GET\n    @Path(\"/addNumbers/{no1}/{no2}\")\n    public int add(@PathParam(\"no1\") int no1, @PathParam(\"no2\") int no2) {\n        return customService.add(no1, no2);\n    }\n}\n"
  },
  {
    "path": "spring/src/test/java/org/wso2/msf4j/spring/service/second/TestMicroServiceWithDynamicPath.java",
    "content": "/*\n* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.spring.service.second;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\nimport org.wso2.msf4j.interceptor.HighPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.HighPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.LowPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityClassRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityClassResponseInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityMethodRequestInterceptor;\nimport org.wso2.msf4j.interceptor.MediumPriorityMethodResponseInterceptor;\nimport org.wso2.msf4j.interceptor.PriorityDataHolder;\nimport org.wso2.msf4j.interceptor.annotation.RequestInterceptor;\nimport org.wso2.msf4j.interceptor.annotation.ResponseInterceptor;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\n\n@SuppressWarnings(\"UnusedParameters\")\n@Component\n@RequestInterceptor({HighPriorityClassRequestInterceptor.class, MediumPriorityClassRequestInterceptor.class,\n                     LowPriorityClassRequestInterceptor.class})\n@ResponseInterceptor({HighPriorityClassResponseInterceptor.class, MediumPriorityClassResponseInterceptor.class,\n                      LowPriorityClassResponseInterceptor.class})\npublic class TestMicroServiceWithDynamicPath {\n\n    @Autowired\n    private CustomService customService;\n\n    @GET\n    @Path(\"/hello/{name}\")\n    @RequestInterceptor({HighPriorityMethodRequestInterceptor.class, MediumPriorityMethodRequestInterceptor.class,\n                         LowPriorityMethodRequestInterceptor.class})\n    @ResponseInterceptor({HighPriorityMethodResponseInterceptor.class, MediumPriorityMethodResponseInterceptor.class,\n                          LowPriorityMethodResponseInterceptor.class})\n    public String sayHello(@PathParam(\"name\") String name) {\n        PriorityDataHolder.setPriorityOrder(PriorityDataHolder.getPriorityOrder() + \"[SPRING HTTP METHOD]\");\n        return customService.sayHello(name);\n    }\n}\n"
  },
  {
    "path": "spring/src/test/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "spring/src/test/resources/netty-transports-1.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransportProperties:\n -\n  name: \"latency.metrics.enabled\"\n  value: true\n -\n  name: \"server.bootstrap.boss.group.size\"\n  value: 4\n -\n  name: \"server.bootstrap.worker.group.size\"\n  value: 8\nlistenerConfigurations:\n -\n  id: \"jaxrs-http\"\n  host: \"0.0.0.0\"\n  port: 8094\n  scheme: https\n  sslConfig:\n   keyStore: \"src/test/resources/cert.jks\"\n   keyStorePass: secret\n\nsenderConfigurations:\n -\n  id: \"netty-gw\"\n"
  },
  {
    "path": "spring/src/test/resources/netty-transports-2.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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################################################################################\ntransportProperties:\n -\n  name: \"latency.metrics.enabled\"\n  value: true\n -\n  name: \"server.bootstrap.boss.group.size\"\n  value: 4\n -\n  name: \"server.bootstrap.worker.group.size\"\n  value: 8\nlistenerConfigurations:\n -\n  id: \"jaxrs-http\"\n  host: \"0.0.0.0\"\n  port: 8095\n  scheme: https\n  sslConfig:\n   keyStore: \"src/test/resources/cert.jks\"\n   keyStorePass: secret\n\nsenderConfigurations:\n -\n  id: \"netty-gw\""
  },
  {
    "path": "spring/src/test/resources/testTxtFile.txt",
    "content": "9X54cMfpjnTiMTkIwlO/l8wxEn8GhoGbPxmwpEAfCaRDqqc/x8IhihSpapPLVeXZXjCTHmtzPh2e\nXkQqxZ9+WbOYJ8fJBMqdsOY6/yL/2a3k1gZxxItKfsztQnVd+kVnjL2Vb5oxZiueogAAO12Op4yt\n9yykdeJruOE5JnVUWWnG+DA4z/km883uLrO3y0Pgp9X3FuPJvFENE0uUIZresMBeHR6FbhpSNAbj\nOH1p6PCgRfEBrHWEp6oVAjvUpESvquxSouebvUok8FnjabrBgTazxCSMnsZqOYOs76h47hEJdjGq\ndtnLs3FTJ1ibdGqK5Af9U4wJV6uA/O62flu9/Fe6QJnok3gmF86SFRYuL2LpatmfbT1tQt8Q9A2C\n7cmZPSv8lEs9UrweHlaWfrTZbfBfpGiPBgv963tY9ov6nxAgdJQIEL2pGhJhysg/cDKYR2CGaeVd\n+nZ1+ByhHLQgmy/jitLYCXXNKYuoJ9ITd851EjDad1gY/oB7qzlZCEt+CZBf6T5SjWVwAW1JOTNS\nrLEkmb4UWYPucm9Mjhdv7KaoJGBRH1Y4pgyojab0B9duC3rQziyH58iC1tW9Utw8EhzwVg7PgtEc\ngEsLUFT4kN9T9H/n1LM2zpoItXoSAKwFOJcuuROF7ufohVEIrjRpRMjDGPwg40Y3a8BUsVtaGnoo\nffkNOwCVekm9tFjbA+2hqPvZTgZvBuQx2vnUUkZKxX97aIaBclKiAvGCs4Qo2RZVf5WIVRTcTi3m\n8Drfp0Dq7BCOlnk+vyKhMZ/K2C61DaNUpvV/u3rG3Aq9Q1oqPAdqzFmmTspAByLmqXitLwLPDyjd\nBf03cKKSusE21i7+HGhe2p7MLMbRL/a6z/frNHLP0lpxTri9dVhxdeSSIi9odMnVsS1JdTY+nseN\ndKopMsQu9Z+mSx7SjORj8BzFOF+bwAqyECmuJ0v+91kRM9/kVkPMQDdmxVA4l9vDxh8CES+LIKlx"
  },
  {
    "path": "spring/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Spring_MSF4J_Test-Suite\">\n\n    <test name=\"http-server-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.spring.SpringHttpServerTest\" />\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "swagger/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "swagger/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>msf4j-swagger</artifactId>\n    <packaging>bundle</packaging>\n\n    <name>WSO2 MSF4J Swagger</name>\n    <description>WSO2 MSF4J Swagger</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.ws.rs</groupId>\n            <artifactId>javax.ws.rs-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.io.swagger.core</groupId>\n            <artifactId>swagger-core</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.slf4j</groupId>\n                    <artifactId>slf4j-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.yaml</groupId>\n                    <artifactId>snakeyaml</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.datatype</groupId>\n                    <artifactId>jackson-datatype-joda</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.dataformat</groupId>\n                    <artifactId>jackson-dataformat-yaml</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-annotations</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.dataformat</groupId>\n            <artifactId>jackson-dataformat-yaml</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.orbit.io.swagger.jaxrs</groupId>\n            <artifactId>swagger-jaxrs</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>javax.ws.rs</groupId>\n                    <artifactId>jsr311-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.google.code.findbugs</groupId>\n                    <artifactId>annotations</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>com.fasterxml.jackson.dataformat</groupId>\n                    <artifactId>jackson-dataformat-xml</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.yaml</groupId>\n                    <artifactId>snakeyaml</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>io.swagger</groupId>\n            <artifactId>swagger-annotations</artifactId>\n        </dependency>\n\n        <!--Test Dependencies-->\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n            <version>${project.version}</version>\n            <type>test-jar</type>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpmime</artifactId>\n            <version>4.5.1</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <argLine>-Dmsf4jTestRunning</argLine>\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <!-- Profile for generating coverage report -->\n        <profile>\n            <id>coverage</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-surefire-plugin</artifactId>\n                            <configuration>\n                                <argLine>${argLine} -Xmx512m</argLine>\n                            </configuration>\n                        </plugin>\n                        <plugin>\n                            <groupId>org.jacoco</groupId>\n                            <artifactId>jacoco-maven-plugin</artifactId>\n                            <executions>\n                                <execution>\n                                    <id>prepare-agent</id>\n                                    <goals>\n                                        <goal>prepare-agent</goal>\n                                    </goals>\n                                </execution>\n                                <execution>\n                                    <id>report</id>\n                                    <phase>prepare-package</phase>\n                                    <goals>\n                                        <goal>report</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n\n        <!-- Profile for creating all deployment artifacts -->\n        <profile>\n            <id>release</id>\n            <build>\n                <pluginManagement>\n                    <plugins>\n                        <!-- Source jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-source-plugin</artifactId>\n                            <configuration>\n                                <excludeResources>true</excludeResources>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-sources</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar-no-fork</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- Javadoc jar -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-javadoc-plugin</artifactId>\n                            <configuration>\n                                <detectJavaApiLink>true</detectJavaApiLink>\n                                <links>\n                                    <link>http://docs.oracle.com/javaee/6/api/</link>\n                                </links>\n                                <excludePackageNames>*.internal.*</excludePackageNames>\n                                <bottom>\n                                    <![CDATA[Copyright {currentYear} WSO2, Inc. <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Licensed under the Apache License, Version 2.0</a>]]>\n                                </bottom>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <id>attach-javadoc</id>\n                                    <phase>package</phase>\n                                    <goals>\n                                        <goal>jar</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n\n                        <!-- GPG signature -->\n                        <plugin>\n                            <groupId>org.apache.maven.plugins</groupId>\n                            <artifactId>maven-gpg-plugin</artifactId>\n                            <configuration>\n                                <passphrase>${gpg.passphrase}</passphrase>\n                                <useAgent>${gpg.useagent}</useAgent>\n                            </configuration>\n                            <executions>\n                                <execution>\n                                    <goals>\n                                        <goal>sign</goal>\n                                    </goals>\n                                </execution>\n                            </executions>\n                        </plugin>\n                    </plugins>\n                </pluginManagement>\n\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-source-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-javadoc-plugin</artifactId>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <properties>\n        <private.package>org.wso2.msf4j.swagger.internal.*</private.package>\n        <export.package>\n            !org.wso2.msf4j.swagger.internal.*,\n            org.wso2.msf4j.swagger.*;version=\"${msf4j.version}\"\n        </export.package>\n        <import.package>\n            javax.annotation.*,\n            javax.ws.rs.*,\n            org.wso2.msf4j.*;version=\"${msf4j.version.range}\",\n            com.google.common.*;version=\"${guava.version.range}\",\n            org.slf4j.*;version=\"${slf4j.version.range}\",\n            io.swagger.jaxrs.config.*;version=\"${io.swagger.version.range}\",\n            io.swagger.util.*;version=\"${io.swagger.version.range}\",\n            io.swagger.jaxrs;version=\"${io.swagger.version.range}\",\n            com.fasterxml.jackson.*;version=\"${com.fasterxml.jackson.version.range}\",\n            javax.xml.bind;resolution:=optional,\n        </import.package>\n        <carbon.component>\n            osgi.service;objectClass=\"org.wso2.msf4j.SwaggerService\"\n        </carbon.component>\n    </properties>\n</project>\n"
  },
  {
    "path": "swagger/src/main/java/org/wso2/msf4j/swagger/ExtendedSwaggerReader.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.swagger;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiImplicitParam;\nimport io.swagger.annotations.ApiImplicitParams;\nimport io.swagger.annotations.ApiOperation;\nimport io.swagger.annotations.ApiResponse;\nimport io.swagger.annotations.ApiResponses;\nimport io.swagger.annotations.Authorization;\nimport io.swagger.annotations.AuthorizationScope;\nimport io.swagger.annotations.Info;\nimport io.swagger.annotations.ResponseHeader;\nimport io.swagger.annotations.SwaggerDefinition;\nimport io.swagger.converter.ModelConverters;\nimport io.swagger.jaxrs.PATCH;\nimport io.swagger.jaxrs.config.DefaultReaderConfig;\nimport io.swagger.jaxrs.config.ReaderConfig;\nimport io.swagger.jaxrs.config.ReaderListener;\nimport io.swagger.jaxrs.ext.SwaggerExtension;\nimport io.swagger.jaxrs.ext.SwaggerExtensions;\nimport io.swagger.jaxrs.utils.ReaderUtils;\nimport io.swagger.models.Contact;\nimport io.swagger.models.ExternalDocs;\nimport io.swagger.models.License;\nimport io.swagger.models.Model;\nimport io.swagger.models.Operation;\nimport io.swagger.models.Path;\nimport io.swagger.models.Response;\nimport io.swagger.models.Scheme;\nimport io.swagger.models.SecurityRequirement;\nimport io.swagger.models.Swagger;\nimport io.swagger.models.Tag;\nimport io.swagger.models.parameters.FormParameter;\nimport io.swagger.models.parameters.HeaderParameter;\nimport io.swagger.models.parameters.Parameter;\nimport io.swagger.models.parameters.PathParameter;\nimport io.swagger.models.parameters.QueryParameter;\nimport io.swagger.models.properties.ArrayProperty;\nimport io.swagger.models.properties.MapProperty;\nimport io.swagger.models.properties.Property;\nimport io.swagger.models.properties.RefProperty;\nimport io.swagger.util.BaseReaderUtils;\nimport io.swagger.util.ParameterProcessor;\nimport io.swagger.util.PathUtils;\nimport io.swagger.util.ReflectionUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.EnumSet;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport javax.ws.rs.Consumes;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.Produces;\n\n/**\n * This is borrowed from the swagger-jaxrs. We did some modifications to this since MSF4J support\n * registering same class with different paths.\n */\nclass ExtendedSwaggerReader extends io.swagger.jaxrs.Reader {\n    private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedSwaggerReader.class);\n    private static final String SUCCESSFUL_OPERATION = \"successful operation\";\n    private static final String PATH_DELIMITER = \"/\";\n\n    private final ReaderConfig config;\n    private Swagger swagger;\n    private String basePath;\n\n    ExtendedSwaggerReader(String basePath, Swagger swagger) {\n        super(swagger);\n        this.swagger = swagger;\n        this.config = new DefaultReaderConfig(null);\n        this.basePath = basePath;\n    }\n\n    /**\n     * Scans a set of classes for both ReaderListeners and Swagger annotations. All found listeners will\n     * be instantiated before any of the classes are scanned for Swagger annotations - so they can be invoked\n     * accordingly.\n     *\n     * @param classes a set of classes to scan\n     * @return the generated Swagger definition\n     */\n\n    public Swagger read(Set<Class<?>> classes) {\n\n        Map<Class<?>, ReaderListener> listeners = new HashMap<>();\n\n        for (Class<?> cls : classes) {\n            if (ReaderListener.class.isAssignableFrom(cls) && !listeners.containsKey(cls)) {\n                try {\n                    listeners.put(cls, (ReaderListener) cls.newInstance());\n                } catch (Exception e) {\n                    LOGGER.error(\"Failed to create ReaderListener\", e);\n                }\n            }\n        }\n\n        for (ReaderListener listener : listeners.values()) {\n            try {\n                listener.beforeScan(this, swagger);\n            } catch (Exception e) {\n                LOGGER.error(\"Unexpected error invoking beforeScan listener [\" + listener.getClass().getName() + \"]\",\n                             e);\n            }\n        }\n\n        // process SwaggerDefinitions first - so we get tags in desired order\n        for (Class<?> cls : classes) {\n            SwaggerDefinition swaggerDefinition = cls.getAnnotation(SwaggerDefinition.class);\n            if (swaggerDefinition != null) {\n                readSwaggerConfig(cls, swaggerDefinition);\n            }\n        }\n\n        for (Class<?> cls : classes) {\n            read(cls, \"\", null, false, new String[0], new String[0], new HashMap<>(), new ArrayList<>(),\n                 new HashSet<>());\n        }\n\n        for (ReaderListener listener : listeners.values()) {\n            try {\n                listener.afterScan(this, swagger);\n            } catch (Exception e) {\n                LOGGER.error(\"Unexpected error invoking afterScan listener [\" + listener.getClass().getName() + \"]\", e);\n            }\n        }\n\n        return swagger;\n    }\n\n    public Swagger getSwagger() {\n        return this.swagger;\n    }\n\n    /**\n     * Scans a single class for Swagger annotations - does not invoke ReaderListeners\n     */\n\n    public Swagger read(Class<?> cls) {\n\n        SwaggerDefinition swaggerDefinition = cls.getAnnotation(SwaggerDefinition.class);\n        if (swaggerDefinition != null) {\n            readSwaggerConfig(cls, swaggerDefinition);\n        }\n\n        return read(cls, \"\", null, false, new String[0], new String[0], new HashMap<>(), new ArrayList<Parameter>(),\n                    new HashSet<Class<?>>());\n    }\n\n    protected Swagger read(Class<?> cls, String parentPath, String parentMethod, boolean isSubresource,\n                           String[] parentConsumes, String[] parentProduces, Map<String, Tag> parentTags,\n                           List<Parameter> parentParameters) {\n        return read(cls, parentPath, parentMethod, isSubresource, parentConsumes, parentProduces, parentTags,\n                    parentParameters, new HashSet<>());\n    }\n\n    private Swagger read(Class<?> cls, String parentPath, String parentMethod, boolean isSubresource,\n                         String[] parentConsumes, String[] parentProduces, Map<String, Tag> parentTags,\n                         List<Parameter> parentParameters, Set<Class<?>> scannedResources) {\n        Map<String, Tag> tags = new HashMap<>();\n        List<SecurityRequirement> securities = new ArrayList<>();\n\n        String[] consumes = new String[0];\n        String[] produces = new String[0];\n        final Set<Scheme> globalSchemes = EnumSet.noneOf(Scheme.class);\n\n        Api api = cls.getAnnotation(Api.class);\n\n        boolean hasPathAnnotation = (ReflectionUtils.getAnnotation(cls, javax.ws.rs.Path.class) != null);\n        boolean hasApiAnnotation = (api != null);\n        boolean isApiHidden = hasApiAnnotation && api.hidden();\n\n        // class readable only if annotated with @Path or isSubresource, or and @Api not hidden\n        boolean classReadable = (hasPathAnnotation || isSubresource) && !isApiHidden;\n\n        // readable if classReadable or (scanAllResources true in config and @Api not hidden)\n        boolean readable = classReadable || (!isApiHidden && config.isScanAllResources());\n\n        if (!readable) {\n            return swagger;\n        }\n\n        // api readable only if @Api present; cannot be hidden because checked in classReadable.\n        boolean apiReadable = hasApiAnnotation;\n\n        if (apiReadable) {\n            // the value will be used as a tag for 2.0 UNLESS a Tags annotation is present\n            Set<String> tagStrings = extractTags(api);\n            for (String tagString : tagStrings) {\n                Tag tag = new Tag().name(tagString);\n                tags.put(tagString, tag);\n            }\n            tags.keySet().forEach(tagName -> swagger.tag(tags.get(tagName)));\n\n            if (!api.produces().isEmpty()) {\n                produces = ReaderUtils.splitContentValues(new String[] { api.produces() });\n            }\n            if (!api.consumes().isEmpty()) {\n                consumes = ReaderUtils.splitContentValues(new String[] { api.consumes() });\n            }\n            globalSchemes.addAll(parseSchemes(api.protocols()));\n            Authorization[] authorizations = api.authorizations();\n\n            for (Authorization auth : authorizations) {\n                if (auth.value() != null && !\"\".equals(auth.value())) {\n                    SecurityRequirement security = new SecurityRequirement();\n                    security.setName(auth.value());\n                    AuthorizationScope[] scopes = auth.scopes();\n                    for (AuthorizationScope scope : scopes) {\n                        if (scope.scope() != null && !\"\".equals(scope.scope())) {\n                            security.addScope(scope.scope());\n                        }\n                    }\n                    securities.add(security);\n                }\n            }\n        }\n\n        if (isSubresource) {\n            if (parentTags != null) {\n                tags.putAll(parentTags);\n            }\n        }\n        // merge consumes, produces\n        if (consumes.length == 0 && cls.getAnnotation(Consumes.class) != null) {\n            consumes = ReaderUtils.splitContentValues(cls.getAnnotation(Consumes.class).value());\n        }\n        if (produces.length == 0 && cls.getAnnotation(Produces.class) != null) {\n            produces = ReaderUtils.splitContentValues(cls.getAnnotation(Produces.class).value());\n        }\n        // look for method-level annotated properties\n\n        // handle sub-resources by looking at return type\n\n        final List<Parameter> globalParameters = new ArrayList<>();\n\n        // look for constructor-level annotated properties\n        globalParameters.addAll(ReaderUtils.collectConstructorParameters(cls, swagger));\n\n        // look for field-level annotated properties\n        globalParameters.addAll(ReaderUtils.collectFieldParameters(cls, swagger));\n\n        // build class/interface level @ApiResponse list\n        ApiResponses classResponseAnnotation = ReflectionUtils.getAnnotation(cls, ApiResponses.class);\n        List<ApiResponse> classApiResponses = new ArrayList<>();\n        if (classResponseAnnotation != null) {\n            classApiResponses.addAll(Arrays.asList(classResponseAnnotation.value()));\n        }\n\n        // parse the method\n        final javax.ws.rs.Path apiPath;\n        if (basePath != null && !basePath.isEmpty()) {\n            apiPath = new javax.ws.rs.Path() {\n\n                @Override\n                public Class<? extends Annotation> annotationType() {\n                    return javax.ws.rs.Path.class;\n                }\n\n                @Override\n                public String value() {\n                    return basePath;\n                }\n            };\n        } else {\n            apiPath = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Path.class);\n        }\n        Method methods[] = cls.getMethods();\n        for (Method method : methods) {\n            if (ReflectionUtils.isOverriddenMethod(method, cls)) {\n                continue;\n            }\n            javax.ws.rs.Path methodPath = ReflectionUtils.getAnnotation(method, javax.ws.rs.Path.class);\n\n            String operationPath = getPath(apiPath, methodPath, parentPath);\n            Map<String, String> regexMap = new HashMap<>();\n            operationPath = PathUtils.parsePath(operationPath, regexMap);\n            if (operationPath != null) {\n                if (isIgnored(operationPath)) {\n                    continue;\n                }\n\n                final ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);\n                String httpMethod = extractOperationMethod(apiOperation, method, SwaggerExtensions.chain());\n\n                Operation operation = null;\n                if (apiOperation != null || config.isScanAllResources() || httpMethod != null || methodPath != null) {\n                    operation = parseMethod(cls, method, globalParameters, classApiResponses);\n                }\n                if (operation == null) {\n                    continue;\n                }\n                if (parentParameters != null) {\n                    for (Parameter param : parentParameters) {\n                        operation.parameter(param);\n                    }\n                }\n                operation.getParameters().stream().filter(param -> regexMap.get(param.getName()) != null)\n                         .forEach(param -> {\n                             String pattern = regexMap.get(param.getName());\n                             param.setPattern(pattern);\n                         });\n\n                if (apiOperation != null) {\n                    for (Scheme scheme : parseSchemes(apiOperation.protocols())) {\n                        operation.scheme(scheme);\n                    }\n                }\n\n                if (operation.getSchemes() == null || operation.getSchemes().isEmpty()) {\n                    for (Scheme scheme : globalSchemes) {\n                        operation.scheme(scheme);\n                    }\n                }\n\n                String[] apiConsumes = consumes;\n                if (parentConsumes != null) {\n                    Set<String> both = new HashSet<>(Arrays.asList(apiConsumes));\n                    both.addAll(new HashSet<>(Arrays.asList(parentConsumes)));\n                    if (operation.getConsumes() != null) {\n                        both.addAll(new HashSet<>(operation.getConsumes()));\n                    }\n                    apiConsumes = both.toArray(new String[both.size()]);\n                }\n\n                String[] apiProduces = produces;\n                if (parentProduces != null) {\n                    Set<String> both = new HashSet<>(Arrays.asList(apiProduces));\n                    both.addAll(new HashSet<>(Arrays.asList(parentProduces)));\n                    if (operation.getProduces() != null) {\n                        both.addAll(new HashSet<>(operation.getProduces()));\n                    }\n                    apiProduces = both.toArray(new String[both.size()]);\n                }\n                final Class<?> subResource = getSubResourceWithJaxRsSubresourceLocatorSpecs(method);\n                if (subResource != null && !scannedResources.contains(subResource)) {\n                    scannedResources.add(subResource);\n                    read(subResource, operationPath, httpMethod, true, apiConsumes, apiProduces, tags,\n                         operation.getParameters(), scannedResources);\n                    // remove the sub resource so that it can visit it later in another path\n                    // but we have a room for optimization in the future to reuse the scanned result\n                    // by caching the scanned resources in the reader instance to avoid actual scanning\n                    // the the resources again\n                    scannedResources.remove(subResource);\n                }\n\n                // can't continue without a valid http method\n                httpMethod = httpMethod == null ? parentMethod : httpMethod;\n                if (httpMethod != null) {\n                    if (apiOperation != null) {\n                        for (String tag : apiOperation.tags()) {\n                            if (!\"\".equals(tag)) {\n                                operation.tag(tag);\n                                swagger.tag(new Tag().name(tag));\n                            }\n                        }\n\n                        operation.getVendorExtensions()\n                                 .putAll(BaseReaderUtils.parseExtensions(apiOperation.extensions()));\n                    }\n\n                    if (operation.getConsumes() == null) {\n                        for (String mediaType : apiConsumes) {\n                            operation.consumes(mediaType);\n                        }\n                    }\n                    if (operation.getProduces() == null) {\n                        for (String mediaType : apiProduces) {\n                            operation.produces(mediaType);\n                        }\n                    }\n\n                    if (operation.getTags() == null) {\n                        for (String tagString : tags.keySet()) {\n                            operation.tag(tagString);\n                        }\n                    }\n                    // Only add global @Api securities if operation doesn't already have more specific securities\n                    if (operation.getSecurity() == null) {\n                        for (SecurityRequirement security : securities) {\n                            operation.security(security);\n                        }\n                    }\n\n                    Path path = swagger.getPath(operationPath);\n                    if (path == null) {\n                        path = new Path();\n                        swagger.path(operationPath, path);\n                    }\n                    path.set(httpMethod, operation);\n\n                    readImplicitParameters(method, operation);\n                }\n            }\n        }\n\n        return swagger;\n    }\n\n    private void readImplicitParameters(Method method, Operation operation) {\n        ApiImplicitParams implicitParams = method.getAnnotation(ApiImplicitParams.class);\n        if (implicitParams != null && implicitParams.value().length > 0) {\n            for (ApiImplicitParam param : implicitParams.value()) {\n                Parameter p = readImplicitParam(param);\n                if (p != null) {\n                    operation.addParameter(p);\n                }\n            }\n        }\n    }\n\n    protected Parameter readImplicitParam(ApiImplicitParam param) {\n        final Parameter p;\n        if (param.paramType().equalsIgnoreCase(\"path\")) {\n            p = new PathParameter();\n        } else if (param.paramType().equalsIgnoreCase(\"query\")) {\n            p = new QueryParameter();\n        } else if (param.paramType().equalsIgnoreCase(\"form\") || param.paramType().equalsIgnoreCase(\"formData\")) {\n            p = new FormParameter();\n        } else if (param.paramType().equalsIgnoreCase(\"body\")) {\n            p = null;\n        } else if (param.paramType().equalsIgnoreCase(\"header\")) {\n            p = new HeaderParameter();\n        } else {\n            LOGGER.warn(\"Unkown implicit parameter type: [\" + param.paramType() + \"]\");\n            return null;\n        }\n        final Type type = ReflectionUtils.typeFromString(param.dataType());\n        return ParameterProcessor\n                .applyAnnotations(swagger, p, type == null ? String.class : type, Collections.singletonList(param));\n    }\n\n    protected void readSwaggerConfig(Class<?> cls, SwaggerDefinition config) {\n\n        if (!config.basePath().isEmpty()) {\n            swagger.setBasePath(config.basePath());\n        }\n\n        if (!config.host().isEmpty()) {\n            swagger.setHost(config.host());\n        }\n\n        readInfoConfig(config);\n\n        for (String consume : config.consumes()) {\n            if (StringUtils.isNotEmpty(consume)) {\n                swagger.addConsumes(consume);\n            }\n        }\n\n        for (String produce : config.produces()) {\n            if (StringUtils.isNotEmpty(produce)) {\n                swagger.addProduces(produce);\n            }\n        }\n\n        if (!config.externalDocs().value().isEmpty()) {\n            ExternalDocs externalDocs = swagger.getExternalDocs();\n            if (externalDocs == null) {\n                externalDocs = new ExternalDocs();\n                swagger.setExternalDocs(externalDocs);\n            }\n\n            externalDocs.setDescription(config.externalDocs().value());\n\n            if (!config.externalDocs().url().isEmpty()) {\n                externalDocs.setUrl(config.externalDocs().url());\n            }\n        }\n\n        for (io.swagger.annotations.Tag tagConfig : config.tags()) {\n            if (!tagConfig.name().isEmpty()) {\n                Tag tag = new Tag();\n                tag.setName(tagConfig.name());\n                tag.setDescription(tagConfig.description());\n\n                if (!tagConfig.externalDocs().value().isEmpty()) {\n                    tag.setExternalDocs(\n                            new ExternalDocs(tagConfig.externalDocs().value(), tagConfig.externalDocs().url()));\n                }\n\n                tag.getVendorExtensions().putAll(BaseReaderUtils.parseExtensions(tagConfig.extensions()));\n\n                swagger.addTag(tag);\n            }\n        }\n\n        for (SwaggerDefinition.Scheme scheme : config.schemes()) {\n            if (scheme != SwaggerDefinition.Scheme.DEFAULT) {\n                swagger.addScheme(Scheme.forValue(scheme.name()));\n            }\n        }\n    }\n\n    protected void readInfoConfig(SwaggerDefinition config) {\n        Info infoConfig = config.info();\n        io.swagger.models.Info info = swagger.getInfo();\n        if (info == null) {\n            info = new io.swagger.models.Info();\n            swagger.setInfo(info);\n        }\n\n        if (!infoConfig.description().isEmpty()) {\n            info.setDescription(infoConfig.description());\n        }\n\n        if (!infoConfig.termsOfService().isEmpty()) {\n            info.setTermsOfService(infoConfig.termsOfService());\n        }\n\n        if (!infoConfig.title().isEmpty()) {\n            info.setTitle(infoConfig.title());\n        }\n\n        if (!infoConfig.version().isEmpty()) {\n            info.setVersion(infoConfig.version());\n        }\n\n        if (!infoConfig.contact().name().isEmpty()) {\n            Contact contact = info.getContact();\n            if (contact == null) {\n                contact = new Contact();\n                info.setContact(contact);\n            }\n\n            contact.setName(infoConfig.contact().name());\n            if (!infoConfig.contact().email().isEmpty()) {\n                contact.setEmail(infoConfig.contact().email());\n            }\n\n            if (!infoConfig.contact().url().isEmpty()) {\n                contact.setUrl(infoConfig.contact().url());\n            }\n        }\n\n        if (!infoConfig.license().name().isEmpty()) {\n            License license = info.getLicense();\n            if (license == null) {\n                license = new License();\n                info.setLicense(license);\n            }\n\n            license.setName(infoConfig.license().name());\n            if (!infoConfig.license().url().isEmpty()) {\n                license.setUrl(infoConfig.license().url());\n            }\n        }\n\n        info.getVendorExtensions().putAll(BaseReaderUtils.parseExtensions(infoConfig.extensions()));\n    }\n\n    protected Class<?> getSubResource(Method method) {\n        final Class<?> rawType = method.getReturnType();\n        final Class<?> type;\n        if (Class.class.equals(rawType)) {\n            type = getClassArgument(method.getGenericReturnType());\n            if (type == null) {\n                return null;\n            }\n        } else {\n            type = rawType;\n        }\n\n        if (type.getAnnotation(Api.class) != null) {\n            return type;\n        }\n\n        // For sub-resources that are not annotated with  @Api, look for any HttpMethods.\n        for (Method m : type.getMethods()) {\n            if (extractOperationMethod(null, m, null) != null) {\n                return type;\n            }\n        }\n\n        return null;\n    }\n\n    protected Class<?> getSubResourceWithJaxRsSubresourceLocatorSpecs(Method method) {\n        final Class<?> rawType = method.getReturnType();\n        final Class<?> type;\n        if (Class.class.equals(rawType)) {\n            type = getClassArgument(method.getGenericReturnType());\n            if (type == null) {\n                return null;\n            }\n        } else {\n            type = rawType;\n        }\n\n        if (method.getAnnotation(javax.ws.rs.Path.class) != null) {\n            if (extractOperationMethod(null, method, null) == null) {\n                return type;\n            }\n        }\n        return null;\n    }\n\n    private static Class<?> getClassArgument(Type cls) {\n        if (cls instanceof ParameterizedType) {\n            final ParameterizedType parameterized = (ParameterizedType) cls;\n            final Type[] args = parameterized.getActualTypeArguments();\n            if (args.length != 1) {\n                LOGGER.error(String.format(\"Unexpected class definition: %s\", cls));\n                return null;\n            }\n            final Type first = args[0];\n            if (first instanceof Class) {\n                return (Class<?>) first;\n            } else {\n                return null;\n            }\n        } else {\n            LOGGER.error(String.format(\"Unknown class definition: %s\", cls));\n            return null;\n        }\n    }\n\n    protected Set<String> extractTags(Api api) {\n        Set<String> output = new LinkedHashSet<>();\n\n        boolean hasExplicitTags = false;\n        for (String tag : api.tags()) {\n            if (!\"\".equals(tag)) {\n                hasExplicitTags = true;\n                output.add(tag);\n            }\n        }\n        if (!hasExplicitTags) {\n            // derive tag from api path + description\n            String tagString = api.value().replace(\"/\", \"\");\n            if (!\"\".equals(tagString)) {\n                output.add(tagString);\n            }\n        }\n        return output;\n    }\n\n    private String getPath(javax.ws.rs.Path classLevelPath, javax.ws.rs.Path methodLevelPath, String parentPath) {\n        if (classLevelPath == null && methodLevelPath == null && StringUtils.isEmpty(parentPath)) {\n            return null;\n        }\n        StringBuilder b = new StringBuilder();\n        if (parentPath != null && !\"\".equals(parentPath) && !\"/\".equals(parentPath)) {\n            if (!parentPath.startsWith(\"/\")) {\n                parentPath = \"/\" + parentPath;\n            }\n            if (parentPath.endsWith(\"/\")) {\n                parentPath = parentPath.substring(0, parentPath.length() - 1);\n            }\n\n            b.append(parentPath);\n        }\n        if (classLevelPath != null) {\n            b.append(classLevelPath);\n        }\n        if (methodLevelPath != null && !\"/\".equals(methodLevelPath.value())) {\n            String methodPath = methodLevelPath.value();\n            if (!methodPath.startsWith(\"/\") && !b.toString().endsWith(\"/\")) {\n                b.append(\"/\");\n            }\n            if (methodPath.endsWith(\"/\")) {\n                methodPath = methodPath.substring(0, methodPath.length() - 1);\n            }\n            b.append(methodPath);\n        }\n        String output = b.toString();\n        if (!output.startsWith(\"/\")) {\n            output = \"/\" + output;\n        }\n        if (output.endsWith(\"/\") && output.length() > 1) {\n            return output.substring(0, output.length() - 1);\n        } else {\n            return output;\n        }\n    }\n\n    private Map<String, Property> parseResponseHeaders(ResponseHeader[] headers) {\n        Map<String, Property> responseHeaders = null;\n        if (headers != null && headers.length > 0) {\n            for (ResponseHeader header : headers) {\n                String name = header.name();\n                if (!\"\".equals(name)) {\n                    if (responseHeaders == null) {\n                        responseHeaders = new HashMap<>();\n                    }\n                    String description = header.description();\n                    Class<?> cls = header.response();\n\n                    if (!isVoid(cls)) {\n                        final Property property = ModelConverters.getInstance().readAsProperty(cls);\n                        if (property != null) {\n                            Property responseProperty = ContainerWrapper\n                                    .wrapContainer(header.responseContainer(), property, ContainerWrapper.ARRAY,\n                                                   ContainerWrapper.LIST, ContainerWrapper.SET);\n                            responseProperty.setDescription(description);\n                            responseHeaders.put(name, responseProperty);\n                            appendModels(cls);\n                        }\n                    }\n                }\n            }\n        }\n        return responseHeaders;\n    }\n\n    public Operation parseMethod(Method method) {\n        return parseMethod(method.getDeclaringClass(), method, Collections.emptyList(), Collections.emptyList());\n    }\n\n    private Operation parseMethod(Class<?> cls, Method method, List<Parameter> globalParameters,\n                                  List<ApiResponse> classApiResponses) {\n        Operation operation = new Operation();\n\n        ApiOperation apiOperation = ReflectionUtils.getAnnotation(method, ApiOperation.class);\n        ApiResponses responseAnnotation = ReflectionUtils.getAnnotation(method, ApiResponses.class);\n\n        String operationId = method.getName();\n        String responseContainer = null;\n\n        Type responseType = null;\n        Map<String, Property> defaultResponseHeaders = new HashMap<>();\n\n        if (apiOperation != null) {\n            if (apiOperation.hidden()) {\n                return null;\n            }\n            if (!\"\".equals(apiOperation.nickname())) {\n                operationId = apiOperation.nickname();\n            }\n\n            defaultResponseHeaders = parseResponseHeaders(apiOperation.responseHeaders());\n\n            operation.summary(apiOperation.value()).description(apiOperation.notes());\n\n            if (apiOperation.response() != null && !isVoid(apiOperation.response())) {\n                responseType = apiOperation.response();\n            }\n            if (!\"\".equals(apiOperation.responseContainer())) {\n                responseContainer = apiOperation.responseContainer();\n            }\n            if (apiOperation.authorizations() != null) {\n                List<SecurityRequirement> securities = new ArrayList<>();\n                for (Authorization auth : apiOperation.authorizations()) {\n                    if (auth.value() != null && !\"\".equals(auth.value())) {\n                        SecurityRequirement security = new SecurityRequirement();\n                        security.setName(auth.value());\n                        AuthorizationScope[] scopes = auth.scopes();\n                        for (AuthorizationScope scope : scopes) {\n                            if (scope.scope() != null && !\"\".equals(scope.scope())) {\n                                security.addScope(scope.scope());\n                            }\n                        }\n                        securities.add(security);\n                    }\n                }\n                if (securities.size() > 0) {\n                    securities.forEach(operation::security);\n                }\n            }\n            if (apiOperation.consumes() != null && !apiOperation.consumes().isEmpty()) {\n                String[] consumesAr = ReaderUtils.splitContentValues(new String[] { apiOperation.consumes() });\n                for (String consume : consumesAr) {\n                    operation.consumes(consume);\n                }\n            }\n            if (apiOperation.produces() != null && !apiOperation.produces().isEmpty()) {\n                String[] producesAr = ReaderUtils.splitContentValues(new String[] { apiOperation.produces() });\n                for (String produce : producesAr) {\n                    operation.produces(produce);\n                }\n            }\n        }\n\n        if (apiOperation != null && StringUtils.isNotEmpty(apiOperation.responseReference())) {\n            Response response = new Response().description(SUCCESSFUL_OPERATION);\n            response.schema(new RefProperty(apiOperation.responseReference()));\n            operation.addResponse(String.valueOf(apiOperation.code()), response);\n        } else if (responseType == null) {\n            // pick out response from method declaration\n            LOGGER.debug(\"picking up response class from method \" + method);\n            responseType = method.getGenericReturnType();\n        }\n        if (isValidResponse(responseType)) {\n            final Property property = ModelConverters.getInstance().readAsProperty(responseType);\n            if (property != null) {\n                final Property responseProperty = ContainerWrapper.wrapContainer(responseContainer, property);\n                final int responseCode = apiOperation == null ? 200 : apiOperation.code();\n                operation.response(responseCode,\n                                   new Response().description(SUCCESSFUL_OPERATION).schema(responseProperty)\n                                                 .headers(defaultResponseHeaders));\n                appendModels(responseType);\n            }\n        }\n\n        operation.operationId(operationId);\n\n        if (operation.getConsumes() == null || operation.getConsumes().isEmpty()) {\n            final Consumes consumes = ReflectionUtils.getAnnotation(method, Consumes.class);\n            if (consumes != null) {\n                for (String mediaType : ReaderUtils.splitContentValues(consumes.value())) {\n                    operation.consumes(mediaType);\n                }\n            }\n        }\n\n        if (operation.getProduces() == null || operation.getProduces().isEmpty()) {\n            final Produces produces = ReflectionUtils.getAnnotation(method, Produces.class);\n            if (produces != null) {\n                for (String mediaType : ReaderUtils.splitContentValues(produces.value())) {\n                    operation.produces(mediaType);\n                }\n            }\n        }\n\n        List<ApiResponse> apiResponses = new ArrayList<>();\n        if (responseAnnotation != null) {\n            apiResponses.addAll(Arrays.asList(responseAnnotation.value()));\n        }\n\n        Class<?>[] exceptionTypes = method.getExceptionTypes();\n        for (Class<?> exceptionType : exceptionTypes) {\n            ApiResponses exceptionResponses = ReflectionUtils.getAnnotation(exceptionType, ApiResponses.class);\n            if (exceptionResponses != null) {\n                apiResponses.addAll(Arrays.asList(exceptionResponses.value()));\n            }\n        }\n\n        for (ApiResponse apiResponse : apiResponses) {\n            addResponse(operation, apiResponse);\n        }\n        // merge class level @ApiResponse\n        for (ApiResponse apiResponse : classApiResponses) {\n            String key = apiResponse.code() == 0 ? \"default\" : String.valueOf(apiResponse.code());\n            if (operation.getResponses().containsKey(key)) {\n                continue;\n            }\n            addResponse(operation, apiResponse);\n        }\n\n        if (ReflectionUtils.getAnnotation(method, Deprecated.class) != null) {\n            operation.setDeprecated(true);\n        }\n\n        // process parameters\n        globalParameters.forEach(operation::parameter);\n\n        Type[] genericParameterTypes = method.getGenericParameterTypes();\n        Annotation[][] paramAnnotations = method.getParameterAnnotations();\n        for (int i = 0; i < genericParameterTypes.length; i++) {\n            final Type type = TypeFactory.defaultInstance().constructType(genericParameterTypes[i], cls);\n            List<Parameter> parameters = getParameters(type, Arrays.asList(paramAnnotations[i]));\n\n            parameters.forEach(operation::parameter);\n        }\n\n        if (operation.getResponses() == null) {\n            Response response = new Response().description(SUCCESSFUL_OPERATION);\n            operation.defaultResponse(response);\n        }\n        return operation;\n    }\n\n    private void addResponse(Operation operation, ApiResponse apiResponse) {\n        Map<String, Property> responseHeaders = parseResponseHeaders(apiResponse.responseHeaders());\n\n        Response response = new Response().description(apiResponse.message()).headers(responseHeaders);\n\n        if (apiResponse.code() == 0) {\n            operation.defaultResponse(response);\n        } else {\n            operation.response(apiResponse.code(), response);\n        }\n\n        if (StringUtils.isNotEmpty(apiResponse.reference())) {\n            response.schema(new RefProperty(apiResponse.reference()));\n        } else if (!isVoid(apiResponse.response())) {\n            Type responseType = apiResponse.response();\n            final Property property = ModelConverters.getInstance().readAsProperty(responseType);\n            if (property != null) {\n                response.schema(ContainerWrapper.wrapContainer(apiResponse.responseContainer(), property));\n                appendModels(responseType);\n            }\n        }\n    }\n\n    private List<Parameter> getParameters(Type type, List<Annotation> annotations) {\n        final Iterator<SwaggerExtension> chain = SwaggerExtensions.chain();\n        if (!chain.hasNext()) {\n            return Collections.emptyList();\n        }\n        LOGGER.debug(\"getParameters for \" + type);\n        Set<Type> typesToSkip = new HashSet<>();\n        final SwaggerExtension extension = chain.next();\n        LOGGER.debug(\"trying extension \" + extension);\n\n        final List<Parameter> parameters = extension.extractParameters(annotations, type, typesToSkip, chain);\n        if (parameters.size() > 0) {\n            final List<Parameter> processed = new ArrayList<>(parameters.size());\n            processed.addAll(parameters.stream().filter(parameter -> ParameterProcessor\n                                                                             .applyAnnotations(swagger, parameter, type,\n                                                                                               annotations) != null)\n                                       .collect(Collectors.toList()));\n            return processed;\n        } else {\n            LOGGER.debug(\"no parameter found, looking at body params\");\n            final List<Parameter> body = new ArrayList<>();\n            if (!typesToSkip.contains(type)) {\n                Parameter param = ParameterProcessor.applyAnnotations(swagger, null, type, annotations);\n                if (param != null) {\n                    body.add(param);\n                }\n            }\n            return body;\n        }\n    }\n\n    public String extractOperationMethod(ApiOperation apiOperation, Method method, Iterator<SwaggerExtension> chain) {\n        if (apiOperation != null && apiOperation.httpMethod() != null && !\"\".equals(apiOperation.httpMethod())) {\n            return apiOperation.httpMethod().toLowerCase(Locale.US);\n        } else if (method.getAnnotation(javax.ws.rs.GET.class) != null) {\n            return \"get\";\n        } else if (method.getAnnotation(javax.ws.rs.PUT.class) != null) {\n            return \"put\";\n        } else if (method.getAnnotation(javax.ws.rs.POST.class) != null) {\n            return \"post\";\n        } else if (method.getAnnotation(javax.ws.rs.DELETE.class) != null) {\n            return \"delete\";\n        } else if (method.getAnnotation(javax.ws.rs.OPTIONS.class) != null) {\n            return \"options\";\n        } else if (method.getAnnotation(javax.ws.rs.HEAD.class) != null) {\n            return \"head\";\n        } else if (method.getAnnotation(PATCH.class) != null) {\n            return \"patch\";\n        } else if (method.getAnnotation(HttpMethod.class) != null) {\n            HttpMethod httpMethod = method.getAnnotation(HttpMethod.class);\n            return httpMethod.value().toLowerCase(Locale.US);\n        } else if (!StringUtils.isEmpty(getHttpMethodFromCustomAnnotations(method))) {\n            return getHttpMethodFromCustomAnnotations(method);\n        } else if ((ReflectionUtils.getOverriddenMethod(method)) != null) {\n            return extractOperationMethod(apiOperation, ReflectionUtils.getOverriddenMethod(method), chain);\n        } else if (chain != null && chain.hasNext()) {\n            return chain.next().extractOperationMethod(apiOperation, method, chain);\n        } else {\n            return null;\n        }\n    }\n\n    private String getHttpMethodFromCustomAnnotations(Method method) {\n        for (Annotation methodAnnotation : method.getAnnotations()) {\n            HttpMethod httpMethod = methodAnnotation.annotationType().getAnnotation(HttpMethod.class);\n            if (httpMethod != null) {\n                return httpMethod.value().toLowerCase(Locale.US);\n            }\n        }\n        return null;\n    }\n\n    private static Set<Scheme> parseSchemes(String schemes) {\n        final Set<Scheme> result = EnumSet.noneOf(Scheme.class);\n        for (String item : StringUtils.trimToEmpty(schemes).split(\",\")) {\n            final Scheme scheme = Scheme.forValue(StringUtils.trimToNull(item));\n            if (scheme != null) {\n                result.add(scheme);\n            }\n        }\n        return result;\n    }\n\n    private void appendModels(Type type) {\n        final Map<String, Model> models = ModelConverters.getInstance().readAll(type);\n        for (Map.Entry<String, Model> entry : models.entrySet()) {\n            swagger.model(entry.getKey(), entry.getValue());\n        }\n    }\n\n    private static boolean isVoid(Type type) {\n        final Class<?> cls = TypeFactory.defaultInstance().constructType(type).getRawClass();\n        return Void.class.isAssignableFrom(cls) || Void.TYPE.isAssignableFrom(cls);\n    }\n\n    private boolean isIgnored(String path) {\n        for (String item : config.getIgnoredRoutes()) {\n            final int length = item.length();\n            if (path.startsWith(item) && (path.length() == length || path.startsWith(PATH_DELIMITER, length))) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private static boolean isValidResponse(Type type) {\n        if (type == null) {\n            return false;\n        }\n        final JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n        if (isVoid(javaType)) {\n            return false;\n        }\n        final Class<?> cls = javaType.getRawClass();\n        return !javax.ws.rs.core.Response.class.isAssignableFrom(cls) && !isResourceClass(cls);\n    }\n\n    private static boolean isResourceClass(Class<?> cls) {\n        return cls.getAnnotation(Api.class) != null;\n    }\n\n    public ReaderConfig getConfig() {\n        return config;\n    }\n\n    enum ContainerWrapper {\n        LIST(\"list\") {\n            @Override\n            protected Property doWrap(Property property) {\n                return new ArrayProperty(property);\n            }\n        }, ARRAY(\"array\") {\n            @Override\n            protected Property doWrap(Property property) {\n                return new ArrayProperty(property);\n            }\n        }, MAP(\"map\") {\n            @Override\n            protected Property doWrap(Property property) {\n                return new MapProperty(property);\n            }\n        }, SET(\"set\") {\n            @Override\n            protected Property doWrap(Property property) {\n                ArrayProperty arrayProperty = new ArrayProperty(property);\n                arrayProperty.setUniqueItems(true);\n                return arrayProperty;\n            }\n        };\n\n        private final String container;\n\n        ContainerWrapper(String container) {\n            this.container = container;\n        }\n\n        public static Property wrapContainer(String container, Property property, ContainerWrapper... allowed) {\n            final Set<ContainerWrapper> tmp =\n                    allowed.length > 0 ? EnumSet.copyOf(Arrays.asList(allowed)) : EnumSet.allOf(ContainerWrapper.class);\n            for (ContainerWrapper wrapper : tmp) {\n                final Property prop = wrapper.wrap(container, property);\n                if (prop != null) {\n                    return prop;\n                }\n            }\n            return property;\n        }\n\n        public Property wrap(String container, Property property) {\n            if (this.container.equalsIgnoreCase(container)) {\n                return doWrap(property);\n            }\n            return null;\n        }\n\n        protected abstract Property doWrap(Property property);\n    }\n}\n"
  },
  {
    "path": "swagger/src/main/java/org/wso2/msf4j/swagger/MSF4JBeanConfig.java",
    "content": "/*\n *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.swagger;\n\nimport io.swagger.jaxrs.Reader;\nimport io.swagger.jaxrs.config.BeanConfig;\nimport io.swagger.models.Contact;\nimport io.swagger.models.Info;\nimport io.swagger.models.License;\nimport io.swagger.models.Scheme;\nimport io.swagger.models.Swagger;\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Swagger BeanConfig for MS4J. We don't need to do a package scan because we know the services in advance, hence\n * we have overridden the classes method.\n */\npublic class MSF4JBeanConfig extends BeanConfig {\n    private Set<Class<?>> classes = new HashSet<>();\n    private Reader reader;\n\n    public MSF4JBeanConfig(Reader reader) {\n        this.reader = reader;\n    }\n\n    @Override\n    public Set<Class<?>> classes() {\n        return Collections.unmodifiableSet(classes);\n    }\n\n    public void addServiceClass(Class<?> clazz) {\n        classes.add(clazz);\n    }\n\n    @Override\n    public void scanAndRead() {\n        Swagger swagger = reader.read(classes());\n        if (StringUtils.isNotBlank(getHost())) {\n            swagger.setHost(getHost());\n        }\n\n        if (StringUtils.isNotBlank(getBasePath())) {\n            swagger.setBasePath(getBasePath());\n        }\n\n        updateInfoFromConfig();\n    }\n\n    private void updateInfoFromConfig() {\n        if (getSwagger().getInfo() == null) {\n            setInfo(new Info());\n        }\n\n        if (StringUtils.isNotBlank(getDescription())) {\n            getSwagger().getInfo().setDescription(getDescription());\n        }\n\n        if (StringUtils.isNotBlank(getTitle())) {\n            getSwagger().getInfo().setTitle(getTitle());\n        }\n\n        if (StringUtils.isNotBlank(getVersion())) {\n            getSwagger().getInfo().setVersion(getVersion());\n        }\n\n        if (StringUtils.isNotBlank(getTermsOfServiceUrl())) {\n            getSwagger().getInfo().setTermsOfService(getTermsOfServiceUrl());\n        }\n\n        if (getContact() != null) {\n            getSwagger().getInfo().setContact((new Contact()).name(getContact()));\n        }\n\n        if (getLicense() != null && getLicenseUrl() != null) {\n            getSwagger().getInfo().setLicense((new License()).name(getLicense()).url(getLicenseUrl()));\n        }\n\n        if (getSchemes() != null) {\n            for (String scheme : getSchemes()) {\n                reader.getSwagger().scheme(Scheme.forValue(scheme));\n            }\n        }\n\n        reader.getSwagger().setInfo(getInfo());\n    }\n\n    @Override\n    public Swagger getSwagger() {\n        return reader.getSwagger();\n    }\n}\n"
  },
  {
    "path": "swagger/src/main/java/org/wso2/msf4j/swagger/SwaggerDefinitionService.java",
    "content": "/*\n *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.swagger;\n\nimport io.swagger.models.Swagger;\nimport io.swagger.util.Json;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.SwaggerService;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.QueryParam;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\n\n/**\n * This service returns the Swagger definition of all the APIs of the microservices deployed in this runtime.\n */\n@Path(\"/swagger\")\npublic class SwaggerDefinitionService implements SwaggerService {\n    private static final String GLOBAL = \"global\";\n\n    private Map<String, MSF4JBeanConfig> swaggerBeans = new HashMap<>();\n    private MicroservicesRegistry serviceRegistry;\n\n    public SwaggerDefinitionService() {\n    }\n\n    public SwaggerDefinitionService(MicroservicesRegistry serviceRegistry) {\n        this.serviceRegistry = serviceRegistry;\n    }\n\n    public void init(MicroservicesRegistry serviceRegistry) {\n        this.serviceRegistry = serviceRegistry;\n    }\n\n    @GET\n    @Produces({ MediaType.APPLICATION_JSON })\n    public Response getSwaggerDefinition(@QueryParam(\"path\") String path) throws Exception {\n        MSF4JBeanConfig msf4JBeanConfig;\n        if (path == null) {\n            msf4JBeanConfig = swaggerBeans.get(GLOBAL);\n            if (msf4JBeanConfig == null) {\n                MSF4JBeanConfig beanConfig = new MSF4JBeanConfig(new ExtendedSwaggerReader(\"\", new Swagger()));\n                serviceRegistry.getHttpServices().stream().\n                        filter(service -> !service.getClass().equals(SwaggerDefinitionService.class)).\n                                       forEach(service -> beanConfig.addServiceClass(service.getClass()));\n                beanConfig.setScan(true);\n                msf4JBeanConfig = beanConfig;\n                swaggerBeans.put(GLOBAL, msf4JBeanConfig);\n            }\n        } else {\n            msf4JBeanConfig = swaggerBeans.get(path);\n            if (msf4JBeanConfig == null) {\n                Optional<Map.Entry<String, Object>> service = serviceRegistry.getServiceWithBasePath(path);\n                if (service.isPresent()) {\n                    MSF4JBeanConfig beanConfig = new MSF4JBeanConfig(new ExtendedSwaggerReader(path, new Swagger()));\n                    beanConfig.addServiceClass(service.get().getValue().getClass());\n                    beanConfig.setBasePath(service.get().getKey());\n                    beanConfig.setScan(true);\n                    msf4JBeanConfig = beanConfig;\n                    swaggerBeans.put(path, msf4JBeanConfig);\n                }\n            }\n        }\n        return (msf4JBeanConfig == null) ? Response.status(Response.Status.NOT_FOUND).\n                entity(\"{\\\"error\\\": \\\"Swagger definition not found for path \" + path + \"\\\"}\").build() :\n               Response.status(Response.Status.OK).\n                       entity(Json.mapper().\n                               writerWithDefaultPrettyPrinter().writeValueAsString(msf4JBeanConfig.getSwagger())).\n                               build();\n    }\n}\n"
  },
  {
    "path": "swagger/src/main/java/org/wso2/msf4j/swagger/internal/DataHolder.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.msf4j.swagger.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.wso2.msf4j.MicroservicesRegistry;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * DataHolder for Swagger component.\n */\npublic class DataHolder {\n\n    private static final DataHolder instance = new DataHolder();\n\n    private Map<String, MicroservicesRegistry> microserviceRegistries = new HashMap<>();\n\n    private BundleContext bundleContext;\n\n    private DataHolder() {\n    }\n\n    public static DataHolder getInstance() {\n        return instance;\n    }\n\n    public MicroservicesRegistry getMicroserviceRegistry(String registryId) {\n        return microserviceRegistries.get(registryId);\n    }\n\n    public void addMicroserviceRegistry(String registryId, MicroservicesRegistry microservicesRegistry) {\n        microserviceRegistries.put(registryId, microservicesRegistry);\n    }\n\n    public Map<String, MicroservicesRegistry> getMicroserviceRegistries() {\n        return microserviceRegistries;\n    }\n\n    public void setBundleContext(BundleContext bundleContext) {\n        this.bundleContext = bundleContext;\n    }\n\n    public BundleContext getBundleContext() {\n        return bundleContext;\n    }\n}\n"
  },
  {
    "path": "swagger/src/main/java/org/wso2/msf4j/swagger/internal/SwaggerDefinitionSC.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.msf4j.swagger.internal;\n\nimport org.osgi.framework.BundleContext;\nimport org.osgi.service.component.annotations.Activate;\nimport org.osgi.service.component.annotations.Component;\nimport org.osgi.service.component.annotations.Reference;\nimport org.osgi.service.component.annotations.ReferenceCardinality;\nimport org.osgi.service.component.annotations.ReferencePolicy;\nimport org.wso2.msf4j.MicroservicesRegistry;\nimport org.wso2.msf4j.SwaggerService;\nimport org.wso2.msf4j.swagger.SwaggerDefinitionService;\n\nimport java.util.Dictionary;\nimport java.util.Hashtable;\nimport java.util.Map;\n\n/**\n * OSGi service component for SwaggerDefinitionService.\n */\n@Component(name = \"SwaggerDefinitionSC\",\n        service = SwaggerDefinitionSC.class,\n        immediate = true)\npublic class SwaggerDefinitionSC {\n    private static final String CHANNEL_ID = \"listener.interface.id\";\n    \n    @Reference(\n            name = \"microserviceregsitry\",\n            service = MicroservicesRegistry.class,\n            cardinality = ReferenceCardinality.AT_LEAST_ONE,\n            policy = ReferencePolicy.DYNAMIC,\n            unbind = \"removeRegistry\")\n    protected void addRegistry(MicroservicesRegistry registry, Map properties) {\n        DataHolder.getInstance().addMicroserviceRegistry(properties.get(CHANNEL_ID).toString(), registry);\n        Dictionary<String, String> serviceProperties = new Hashtable<>();\n        serviceProperties.put(CHANNEL_ID, properties.get(CHANNEL_ID).toString());\n\n        BundleContext bundleContext = DataHolder.getInstance().getBundleContext();\n        if (bundleContext != null) {\n            bundleContext.registerService(SwaggerService.class,\n                    new SwaggerDefinitionService(registry), serviceProperties);\n        }\n    }\n\n    protected void removeRegistry(MicroservicesRegistry registry) {\n    }\n\n    @Activate\n    protected void start(final BundleContext bundleContext) {\n        DataHolder.getInstance().setBundleContext(bundleContext);\n        DataHolder.getInstance().getMicroserviceRegistries().forEach((registryId, registry) -> {\n            Dictionary<String, String> properties = new Hashtable<>();\n            properties.put(CHANNEL_ID, registryId);\n            bundleContext.registerService(SwaggerService.class, new SwaggerDefinitionService(registry), properties);\n        });\n    }\n}\n"
  },
  {
    "path": "swagger/src/main/resources/META-INF/services/org.wso2.msf4j.SwaggerService",
    "content": "org.wso2.msf4j.swagger.SwaggerDefinitionService\n"
  },
  {
    "path": "swagger/src/test/java/org/wso2/msf4j/swagger/SwaggerTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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 */\npackage org.wso2.msf4j.swagger;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\nimport org.wso2.msf4j.MicroservicesRunner;\nimport org.wso2.msf4j.conf.Constants;\nimport org.wso2.msf4j.service.SecondService;\nimport org.wso2.msf4j.service.TestMicroservice;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport javax.ws.rs.HttpMethod;\nimport javax.ws.rs.core.HttpHeaders;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\npublic class SwaggerTest {\n\n    public static final String HEADER_VAL_CLOSE = \"CLOSE\";\n    private final TestMicroservice testMicroservice = new TestMicroservice();\n    private static final int port = Constants.PORT + 39;\n    private MicroservicesRunner microservicesRunner;\n    private MicroservicesRunner secondMicroservicesRunner;\n    private final SecondService secondService = new SecondService();\n    protected static URI baseURI;\n\n    @BeforeClass\n    public void setup() throws Exception {\n        baseURI = URI.create(String.format(\"http://%s:%d\", Constants.HOSTNAME, port));\n        microservicesRunner = new MicroservicesRunner(port);\n        microservicesRunner.deploy(testMicroservice).start();\n        secondMicroservicesRunner = new MicroservicesRunner(port + 1);\n        secondMicroservicesRunner.deploy(secondService).start();\n    }\n\n    @AfterClass\n    public void teardown() throws Exception {\n        microservicesRunner.stop();\n        secondMicroservicesRunner.stop();\n    }\n\n    @Test\n    public void testGlobalSwagger() throws Exception {\n        HttpURLConnection urlConn = request(\"/swagger\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(MediaType.APPLICATION_JSON, urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testServiceSwagger() throws Exception {\n        HttpURLConnection urlConn = request(\"/swagger?path=/test/v1\", HttpMethod.GET);\n        assertEquals(Response.Status.OK.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(MediaType.APPLICATION_JSON, urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE));\n        urlConn.disconnect();\n    }\n\n    @Test\n    public void testNonExistentServiceSwagger() throws Exception {\n        HttpURLConnection urlConn = request(\"/swagger?path=/zzaabdf\", HttpMethod.GET);\n        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), urlConn.getResponseCode());\n        assertEquals(MediaType.APPLICATION_JSON, urlConn.getHeaderField(HttpHeaders.CONTENT_TYPE));\n        urlConn.disconnect();\n    }\n\n    private HttpURLConnection request(String path, String method) throws IOException {\n        return request(path, method, false);\n    }\n\n    private HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n}\n"
  },
  {
    "path": "swagger/src/test/resources/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # MSF4J configuration\nwso2.msf4j.configuration:\n    # No of worker pool threads to handle MSF4J requests\n  threadCount: 100\n  threadPoolName: msf4j.executor.workerpool\n\n"
  },
  {
    "path": "swagger/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Swagger_MSF4J_Test-Suite\">\n\n    <test name=\"http-server-unit-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.swagger.SwaggerTest\" />\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "templating/msf4j-mustache-template/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <artifactId>msf4j-mustache-template</artifactId>\n    <packaging>jar</packaging>\n\n    <name>WSO2 MSF4J Mustache template engine integration</name>\n\n    <!-- Test dependencies -->\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.github.spullara.mustache.java</groupId>\n            <artifactId>compiler</artifactId>\n            <version>0.9.0</version>\n        </dependency>\n\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n</project>\n"
  },
  {
    "path": "templating/msf4j-mustache-template/src/main/java/org/wso2/msf4j/template/MustacheTemplateEngine.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.template;\n\nimport com.github.mustachejava.DefaultMustacheFactory;\nimport com.github.mustachejava.Mustache;\nimport com.github.mustachejava.MustacheFactory;\n\nimport java.io.IOException;\nimport java.io.StringWriter;\n\n/**\n * Wrapper for mustache template engine that implements\n * org.wso2.msf4j.template.TemplateEngine.\n */\npublic class MustacheTemplateEngine implements TemplateEngine {\n\n    private MustacheFactory mustacheFactory;\n    private static MustacheTemplateEngine mustacheTemplateEngine = new MustacheTemplateEngine();\n\n    /**\n     * Constructs a mustache template engine\n     */\n    private MustacheTemplateEngine() {\n        mustacheFactory = new DefaultMustacheFactory(\"templates\");\n    }\n\n    /**\n     * Render a given model from a given template.\n     *\n     * @param view  name of the template file in resources/templates directory\n     * @param model model to be rendered from the template\n     * @return rendered template\n     */\n    @Override\n    public String render(String view, Object model) {\n        Mustache mustache = mustacheFactory.compile(view);\n        StringWriter stringWriter = new StringWriter();\n        try {\n            mustache.execute(stringWriter, model).close();\n        } catch (IOException e) {\n            throw new RuntimeTemplateException(e);\n        }\n        return stringWriter.toString();\n    }\n\n    /**\n     * @return MustacheTemplateEngine singleton\n     */\n    public static MustacheTemplateEngine instance() {\n        return mustacheTemplateEngine;\n    }\n}\n"
  },
  {
    "path": "templating/msf4j-mustache-template/src/test/java/org/wso2/msf4j/template/MustacheTemplateEngineTest.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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\npackage org.wso2.msf4j.template;\n\n\nimport org.testng.Assert;\nimport org.testng.annotations.Test;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Tests for MustacheTemplateEngine\n */\npublic class MustacheTemplateEngineTest {\n\n    @Test\n    public void testTemplateWithNoModel() {\n        String rendered = MustacheTemplateEngine.instance().render(\"nomodel.mustache\", null);\n        Assert.assertEquals(\"Hello, world!\", rendered);\n    }\n\n    @Test\n    public void testTemplateWithAModel() {\n        String content = \"MODEL_CONTENT\";\n        Map<String, String> map = new HashMap<>();\n        map.put(\"name\", content);\n        String rendered = MustacheTemplateEngine.instance().render(\"withmodel.mustache\", map);\n        Assert.assertEquals(\"Hello, \" + content + \"!\", rendered);\n    }\n\n}\n"
  },
  {
    "path": "templating/msf4j-mustache-template/src/test/resources/templates/nomodel.mustache",
    "content": "Hello, world!"
  },
  {
    "path": "templating/msf4j-mustache-template/src/test/resources/templates/withmodel.mustache",
    "content": "Hello, {{name}}!"
  },
  {
    "path": "tests/osgi-tests/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-tests</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <artifactId>wso2-msf4j-osgi-test</artifactId>\n    <name>WSO2 MSF4J OSGi tests</name>\n    <description>WSO2 MSF4J core</description>\n    <url>https://github.com/wso2/msf4j</url>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>msf4j-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.utils</groupId>\n            <artifactId>org.wso2.carbon.utils</artifactId>\n        </dependency>\n\n        <!-- Pax Exam Dependencies-->\n        <dependency>\n            <groupId>org.testng</groupId>\n            <artifactId>testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-inject</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-extender-service</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.osgi</groupId>\n            <artifactId>org.osgi.compendium</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.base</groupId>\n            <artifactId>ops4j-base</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.geronimo.specs</groupId>\n            <artifactId>geronimo-atinject_1.0_spec</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-container-native</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-testng</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.exam</groupId>\n            <artifactId>pax-exam-link-mvn</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ops4j.pax.url</groupId>\n            <artifactId>pax-url-aether</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.ow2.spec.ee</groupId>\n            <artifactId>ow2-jta-1.1-spec</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.jacoco</groupId>\n            <artifactId>org.jacoco.ant</artifactId>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>wso2-msf4j-tests</artifactId>\n            <version>${msf4j.version}</version>\n            <type>zip</type>\n        </dependency>\n\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.container</artifactId>\n            <version>${carbon.kernel.version}</version>\n        </dependency>\n\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.rat</groupId>\n                <artifactId>apache-rat-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <configuration>\n                    <!--<argLine>-Dmsf4jTestRunning</argLine>-->\n                    <suiteXmlFiles>\n                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                    </suiteXmlFiles>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.felix</groupId>\n                <artifactId>maven-bundle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <profiles>\n        <profile>\n            <id>with-tests</id>\n            <activation>\n                <property>\n                    <name>!maven.test.skip</name>\n                </property>\n            </activation>\n            <build>\n                <plugins>\n                    <plugin>\n                        <artifactId>maven-resources-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <!--copying distribution/carbon-home directory to the target folder-->\n                                <id>copy-resources</id>\n                                <phase>generate-resources</phase>\n                                <goals>\n                                    <goal>copy-resources</goal>\n                                </goals>\n                                <configuration>\n                                    <outputDirectory>${project.build.directory}/carbon-home</outputDirectory>\n                                    <overwrite>true</overwrite>\n                                    <resources>\n                                        <resource>\n                                            <directory>src/test/resources/carbon-home</directory>\n                                        </resource>\n                                    </resources>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-dependency-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <id>copy-jacoco-dependencies</id>\n                                <phase>compile</phase>\n                                <goals>\n                                    <goal>copy-dependencies</goal>\n                                </goals>\n                                <configuration>\n                                    <outputDirectory>${project.build.directory}</outputDirectory>\n                                    <includeTypes>jar</includeTypes>\n                                    <includeArtifactIds>org.jacoco.ant</includeArtifactIds>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-surefire-plugin</artifactId>\n                        <configuration>\n                            <systemPropertyVariables>\n                                <org.ops4j.pax.url.mvn.localRepository>${settings.localRepository}\n                                </org.ops4j.pax.url.mvn.localRepository>\n                                <jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>\n                                <org.wso2.carbon.test.default.distribution>\n                                    org.wso2.msf4j:wso2-msf4j-tests\n                                </org.wso2.carbon.test.default.distribution>\n                                <org.ops4j.pax.logging.DefaultServiceLog.level>ERROR</org.ops4j.pax.logging.DefaultServiceLog.level>\n                            </systemPropertyVariables>\n                            <suiteXmlFiles>\n                                <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>\n                            </suiteXmlFiles>\n                            <environmentVariables>\n                                <JAVA_OPTS>${jcoverage.command}</JAVA_OPTS>\n                            </environmentVariables>\n                        </configuration>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.jacoco</groupId>\n                        <artifactId>jacoco-maven-plugin</artifactId>\n                        <version>${jacoco.version}</version>\n                        <executions>\n                            <execution>\n                                <id>default-prepare-agent</id>\n                                <goals>\n                                    <goal>prepare-agent</goal>\n                                </goals>\n                                <configuration>\n                                    <propertyName>jcoverage.command</propertyName>\n                                    <includes>\n                                        <include>org.wso2.carbon*</include>\n                                    </includes>\n                                    <append>true</append>\n                                </configuration>\n                            </execution>\n                            <execution>\n                                <id>default-check</id>\n                                <goals>\n                                    <goal>check</goal>\n                                </goals>\n                                <configuration>\n                                    <rules>\n                                        <rule>\n                                        </rule>\n                                    </rules>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-antrun-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <phase>prepare-package</phase>\n                                <configuration>\n                                    <target xmlns:jacoco=\"antlib:org.jacoco.ant\">\n                                        //this task is to provide class/src files locations for jacoco report generation\n                                        <taskdef uri=\"antlib:org.jacoco.ant\" resource=\"org/jacoco/ant/antlib.xml\">\n                                            <classpath path=\"${project.build.directory}\" />\n                                        </taskdef>\n                                        <jacoco:report>\n                                            <executiondata>\n                                                <file file=\"${project.build.directory}/jacoco.exec\" />\n                                            </executiondata>\n                                            <structure name=\"MSF4J OSGi Tests\">\n                                                <classfiles>\n                                                    <fileset dir=\"../../core/target/classes\" />\n                                                </classfiles>\n                                                <sourcefiles encoding=\"UTF-8\">\n                                                    <fileset dir=\"../../core/src\" />\n                                                </sourcefiles>\n                                            </structure>\n                                            <html destdir=\"${project.build.directory}/site/jacoco\" />\n                                        </jacoco:report>\n                                    </target>\n                                </configuration>\n                                <goals>\n                                    <goal>run</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                        <dependencies>\n                            <dependency>\n                                <groupId>org.jacoco</groupId>\n                                <artifactId>org.jacoco.ant</artifactId>\n                                <version>${org.jacoco.ant.version}</version>\n                            </dependency>\n                        </dependencies>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.ops4j.pax.exam</groupId>\n                        <artifactId>maven-paxexam-plugin</artifactId>\n                        <version>${maven.paxexam.plugin.version}</version>\n                        <executions>\n                            <execution>\n                                <id>generate-config</id>\n                                <goals>\n                                    <goal>generate-depends-file</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n</project>\n"
  },
  {
    "path": "tests/osgi-tests/src/test/java/org/wso2/msf4j/osgi/test/MSF4JOSGiTest.java",
    "content": "/*\n *  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  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,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n *\n */\npackage org.wso2.msf4j.osgi.test;\n\nimport io.netty.handler.codec.http.HttpHeaderNames;\nimport org.apache.commons.io.Charsets;\nimport org.apache.commons.io.IOUtils;\nimport org.ops4j.pax.exam.ExamFactory;\nimport org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;\nimport org.ops4j.pax.exam.spi.reactors.PerClass;\nimport org.ops4j.pax.exam.testng.listener.PaxExam;\nimport org.osgi.framework.BundleContext;\nimport org.testng.Assert;\nimport org.testng.annotations.Listeners;\nimport org.testng.annotations.Test;\nimport org.wso2.carbon.container.CarbonContainerFactory;\nimport org.wso2.carbon.kernel.CarbonServerInfo;\nimport org.wso2.msf4j.Microservice;\nimport org.wso2.msf4j.osgi.test.service.SecondService;\nimport org.wso2.msf4j.osgi.test.service.TestService;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URL;\nimport java.util.Dictionary;\nimport java.util.Hashtable;\nimport javax.inject.Inject;\nimport javax.ws.rs.HttpMethod;\n\nimport static org.testng.AssertJUnit.assertEquals;\n\n/**\n * OSGi tests class to test MSF4J startup.\n *\n * @since 5.0.0\n */\n@Listeners(PaxExam.class)\n@ExamReactorStrategy(PerClass.class)\n@ExamFactory(CarbonContainerFactory.class)\npublic class MSF4JOSGiTest {\n\n    private static final String HEADER_VAL_CLOSE = \"CLOSE\";\n\n    private static final String HOSTNAME = \"localhost\";\n    private static final int PORT = 8079;\n\n    @Inject\n    private CarbonServerInfo carbonServerInfo;\n\n    @Inject\n    BundleContext bundleContext;\n\n    @Test\n    public void testServerStarup() {\n        Assert.assertNotNull(carbonServerInfo, \"CarbonServerInfo Service is null\");\n    }\n\n    @Test\n    public void testDynamicServiceRegistration() throws IOException {\n        Dictionary<String, String> properties = new Hashtable<>();\n        properties.put(\"contextPath\", \"/BasePathV1\");\n        bundleContext.registerService(Microservice.class, new TestService(), properties);\n\n        // Register same service with different base path\n        properties.put(\"contextPath\", \"/BasePathV2\");\n        bundleContext.registerService(Microservice.class, new TestService(), properties);\n\n        //Register some other service\n        bundleContext.registerService(Microservice.class, new SecondService(), null);\n\n        HttpURLConnection urlConn = request(\"/BasePathV1/hello\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        String content = getContent(urlConn);\n        assertEquals(\"Hello MSF4J from TestService\", content);\n        urlConn.disconnect();\n\n        urlConn = request(\"/BasePathV2/hello\", HttpMethod.GET);\n        assertEquals(200, urlConn.getResponseCode());\n        content = getContent(urlConn);\n        assertEquals(\"Hello MSF4J from TestService\", content);\n        urlConn.disconnect();\n    }\n\n    private HttpURLConnection request(String path, String method) throws IOException {\n        return request(path, method, false);\n    }\n\n    private HttpURLConnection request(String path, String method, boolean keepAlive) throws IOException {\n        URI baseURI = URI.create(String.format(\"http://%s:%d\", HOSTNAME, PORT));\n        URL url = baseURI.resolve(path).toURL();\n        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();\n        if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {\n            urlConn.setDoOutput(true);\n        }\n        urlConn.setRequestMethod(method);\n        if (!keepAlive) {\n            urlConn.setRequestProperty(HttpHeaderNames.CONNECTION.toString(), HEADER_VAL_CLOSE);\n        }\n\n        return urlConn;\n    }\n\n    private String getContent(HttpURLConnection urlConn) throws IOException {\n        return new String(IOUtils.toByteArray(urlConn.getInputStream()), Charsets.UTF_8);\n    }\n}\n"
  },
  {
    "path": "tests/osgi-tests/src/test/java/org/wso2/msf4j/osgi/test/service/SecondService.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.osgi.test.service;\n\nimport org.wso2.msf4j.Microservice;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Response;\n\n@Path(\"/CustomService\")\npublic class SecondService implements Microservice {\n\n    @GET\n    @Path(\"hello\")\n    public Response sayHello() {\n        return Response.ok().entity(\"Hello MSF4J from CustomService\").build();\n    }\n}\n"
  },
  {
    "path": "tests/osgi-tests/src/test/java/org/wso2/msf4j/osgi/test/service/TestService.java",
    "content": "/*\n* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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*/\npackage org.wso2.msf4j.osgi.test.service;\n\nimport org.wso2.msf4j.Microservice;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.core.Response;\n\n@Path(\"/BasePathV1\")\npublic class TestService implements Microservice {\n\n    @GET\n    @Path(\"hello\")\n    public Response sayHello() {\n        return Response.ok().entity(\"Hello MSF4J from TestService\").build();\n    }\n}\n"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/carbon-home/conf/carbon.yml",
    "content": "################################################################################\n#   Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\nid: carbon-kernel\nname: WSO2 Carbon Kernel\nversion: 5.0.0\ntenant: default\n\n# Ports used by this server\nports:\n# Ports offset. This entry will set the value of the ports defined below to\n# the define value + Offset.\n# e.g. Offset=2 and HTTPS port=9443 will set the effective HTTPS port to 9445\n offset: 0\n# Deployment Engine related configurations\ndeployment:\n# Currently there can be two modes\n#  1. Scheduled Mode - (enable below property to \"scheduled\") - where the task runs periodically and trigger deployment\n#  2. Triggered Mode - (enable below property to \"triggered\") - the deployment has to be triggered externally,\n#   eg : in a worker node we don't need the task to run, but rather when we receive a\n#        cluster msg,  the deployment has to be triggered manually\n mode: scheduled\n\n# Location of the artifact repository\n repositoryLocation: ${carbon.home}/deployment/\n\n# Deployment update interval in seconds. This is the interval between repository listener\n# executions.\n updateInterval: 15\n\n\n# StartupOrderResolver related configurations\nstartupResolver:\n# Configuration for the timer task which checks for satisfiable RequiredCapabilityListeners periodically\n capabilityListenerTimer:\n  delay: 200\n  period: 200\n\n# Configuration for the timer task which checks for pending Capabilities\n pendingCapabilityTimer:\n  delay: 60000\n  period: 30000\n\n# JMX Configuration\njmx:\n enabled: false\n hostName: \"127.0.0.1\"\n rmiServerPort: 11111\n rmiRegistryPort: 9999\n"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/carbon-home/conf/etc/pax-logging.properties",
    "content": "org.ops4j.pax.logging.log4j2.config.file=${carbon.home}/conf/log4j2.xml\n"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/carbon-home/conf/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright 2015 WSO2, Inc. (http://wso2.com)\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<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"debug\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n\n"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/carbon-home/conf/osgi/launch.properties",
    "content": "# Uncomment the following line to enable OSGi console. Specify a port as value of the following property to allow\n# telnet access to OSGi console\n# TODO Implement SSH access to the OSGi console.\nosgi.console=\n\norg.osgi.framework.bundle.parent=framework\n\n\n# When osgi.clean is set to \"true\", any cached data used by the OSGi framework\n# will be wiped clean. This will clean the caches used to store bundle\n# dependency resolution and eclipse extension registry data. Using this\n# option will force OSGi framework to reinitialize these caches.\n# The following setting is put in place to get rid of the problems\n# faced when re-starting the system. Please note that, when this setting is\n# true, if you manually start a bundle, it would not be available when\n# you re-start the system. To avid this, copy the bundle jar to the plugins\n# folder, before you re-start the system.\nosgi.clean=true\n\n# Uncomment the following line to turn on Eclipse Equinox debugging.\n# You may also edit the osgi-debug.options file and fine tune the debugging\n# options to suite your needs.\n#osgi.debug=./conf/osgi/osgi-debug.options\n\ncarbon.server.listeners=org.wso2.carbon.launcher.extensions.DropinsBundleDeployer\norg.osgi.framework.system.packages.extra=sun.misc\n\n"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/carbon-home/deployment/README.txt",
    "content": "Empty file"
  },
  {
    "path": "tests/osgi-tests/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Carbon-Kernel-Core_OSGI-Test-Suite\">\n    <test name=\"carbon-core-osgi-tests\" preserve-order=\"true\" parallel=\"false\">\n        <classes>\n            <class name=\"org.wso2.msf4j.osgi.test.MSF4JOSGiTest\"/>\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "tests/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-parent</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../poms/parent/pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>msf4j-tests</artifactId>\n    <packaging>pom</packaging>\n    <name>WSO2 msf4j - Tests</name>\n    <url>http://wso2.com</url>\n\n    <modules>\n        <module>test-distribution</module>\n        <module>osgi-tests</module>\n    </modules>\n\n</project>\n"
  },
  {
    "path": "tests/test-distribution/carbon-home/conf/deployment.yaml",
    "content": "#   Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved\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  # Carbon Configuration Parameters\nwso2.carbon:\n    # value to uniquely identify a server\n  id: carbon-kernel\n    # server name\n  name: WSO2 Carbon Kernel\n    # ports used by this server\n  ports:\n      # port offset\n    offset: -1\n\nwso2.securevault:\n  secretRepository:\n    type: org.wso2.carbon.secvault.repository.DefaultSecretRepository\n    parameters:\n      privateKeyAlias: wso2carbon\n      keystoreLocation: ${sys:carbon.home}/resources/security/securevault.jks\n      secretPropertiesFile: ${sys:carbon.home}/conf/${sys:wso2.runtime}/secrets.properties\n  masterKeyReader:\n    type: org.wso2.carbon.secvault.reader.DefaultMasterKeyReader\n    parameters:\n      masterKeyReaderFile: ${sys:carbon.home}/conf/${sys:wso2.runtime}/master-keys.yaml\n\nwso2.transport.http:\n  transportProperties:\n   - name: \"latency.metrics.enabled\"\n     value: true\n   - name: \"server.bootstrap.socket.timeout\"\n     value: 60\n   - name: \"client.bootstrap.socket.timeout\"\n     value: 60\n\n  listenerConfigurations:\n   - id: \"default\"\n     host: \"0.0.0.0\"\n     port: 8080\n\n  senderConfigurations:\n   - id: \"http-sender\"\n"
  },
  {
    "path": "tests/test-distribution/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright 2017 WSO2, Inc. (http://wso2.com)\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <parent>\n        <groupId>org.wso2.msf4j</groupId>\n        <artifactId>msf4j-tests</artifactId>\n        <version>2.8.14-SNAPSHOT</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n    <packaging>pom</packaging>\n\n    <artifactId>wso2-msf4j-tests</artifactId>\n    <name>WSO2 MSF4j - Test - Distribution</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>org.wso2.msf4j.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.msf4j</groupId>\n            <artifactId>org.wso2.msf4j.deployer.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.server.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.osgi.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.runtime.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon</groupId>\n            <artifactId>org.wso2.carbon.pax.exam.feature</artifactId>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.transport</groupId>\n            <artifactId>org.wso2.carbon.connector.framework.feature</artifactId>\n            <version>${org.wso2.carbon.transport.http.netty.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.core.feature</artifactId>\n            <version>${carbon.metrics.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.jdbc.core.feature</artifactId>\n            <version>${carbon.metrics.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.metrics</groupId>\n            <artifactId>org.wso2.carbon.metrics.das.core.feature</artifactId>\n            <version>${carbon.metrics.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.deployment</groupId>\n            <artifactId>org.wso2.carbon.deployment.engine.feature</artifactId>\n            <version>${carbon.deployment.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.jndi</groupId>\n            <artifactId>org.wso2.carbon.jndi.feature</artifactId>\n            <version>${carbon.jndi.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.datasources</groupId>\n            <artifactId>org.wso2.carbon.datasource.core.feature</artifactId>\n            <version>${carbon.datasources.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.config</groupId>\n            <artifactId>org.wso2.carbon.config.feature</artifactId>\n            <version>${carbon.config.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.secvault</groupId>\n            <artifactId>org.wso2.carbon.secvault.feature</artifactId>\n            <version>${carbon.secvault.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.utils</groupId>\n            <artifactId>org.wso2.carbon.utils.feature</artifactId>\n            <version>${carbon.utils.version}</version>\n            <type>zip</type>\n        </dependency>\n        <dependency>\n            <groupId>org.wso2.carbon.touchpoint</groupId>\n            <artifactId>org.wso2.carbon.touchpoint.feature</artifactId>\n            <version>${carbon.touchpoint.version}</version>\n            <type>zip</type>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-dependency-plugin</artifactId>\n                <inherited>false</inherited>\n                <executions>\n                    <execution>\n                        <id>unpack-equinox-executable</id>\n                        <phase>test</phase>\n                        <goals>\n                            <goal>unpack</goal>\n                        </goals>\n                        <configuration>\n                            <artifactItems>\n                                <artifactItem>\n                                    <groupId>org.eclipse.equinox</groupId>\n                                    <artifactId>org.eclipse.equinox.executable</artifactId>\n                                    <version>3.5.0.v20110530-7P7NFUFFLWUl76mart</version>\n                                    <type>zip</type>\n                                    <overWrite>true</overWrite>\n                                    <outputDirectory>target</outputDirectory>\n                                </artifactItem>\n                            </artifactItems>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.wso2.carbon.maven</groupId>\n                <artifactId>carbon-feature-plugin</artifactId>\n                <version>3.1.3</version>\n                <executions>\n                    <execution>\n                        <id>p2-repo-generation</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>generate-repo</goal>\n                        </goals>\n                        <configuration>\n                            <targetRepository>file:${basedir}/target/p2-repo</targetRepository>\n                            <features>\n                                <feature>\n                                    <id>org.wso2.carbon.server.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.osgi.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.runtime.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.config.feature</id>\n                                    <version>${carbon.config.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.secvault.feature</id>\n                                    <version>${carbon.secvault.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.utils.feature</id>\n                                    <version>${carbon.utils.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.touchpoint.feature</id>\n                                    <version>${carbon.touchpoint.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.msf4j.feature</id>\n                                    <version>${msf4j.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.msf4j.deployer.feature</id>\n                                    <version>${msf4j.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.pax.exam.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.deployment.engine.feature</id>\n                                    <version>${carbon.deployment.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.connector.framework.feature</id>\n                                    <version>${org.wso2.carbon.transport.http.netty.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.metrics.core.feature</id>\n                                    <version>${carbon.metrics.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.metrics.jdbc.core.feature</id>\n                                    <version>${carbon.metrics.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.metrics.das.core.feature</id>\n                                    <version>${carbon.metrics.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.jndi.feature</id>\n                                    <version>${carbon.jndi.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.datasource.core.feature</id>\n                                    <version>${carbon.datasources.version}</version>\n                                </feature>\n                            </features>\n                        </configuration>\n                    </execution>\n                    <execution>\n                        <id>publishing products</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>publish-product</goal>\n                        </goals>\n                        <configuration>\n                            <executable>\n                                ${basedir}/target/org.eclipse.equinox.executable_3.5.0.v20110530-7P7NFUFFLWUl76mart\n                            </executable>\n                            <repositoryURL>file:${basedir}/target/p2-repo</repositoryURL>\n                        </configuration>\n                    </execution>\n                    <execution>\n                        <id>materialize-product</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>generate-runtime</goal>\n                        </goals>\n                        <configuration>\n                            <repositoryURL>file:${basedir}/target/p2-repo</repositoryURL>\n                            <targetPath>file:${basedir}/target/wso2-msf4j-${msf4j.version}/wso2\n                            </targetPath>\n                            <runtime>default</runtime>\n                        </configuration>\n                    </execution>\n                    <execution>\n                        <id>feature-installation</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>install</goal>\n                        </goals>\n                        <configuration>\n                            <runtime>default</runtime>\n                            <repositoryURL>file:${basedir}/target/p2-repo</repositoryURL>\n                            <destination>\n                                ${basedir}/target/wso2-msf4j-${msf4j.version}/wso2\n                            </destination>\n                            <deleteOldRuntimeFiles>true</deleteOldRuntimeFiles>\n                            <features>\n                                <feature>\n                                    <id>org.wso2.carbon.config.feature</id>\n                                    <version>${carbon.config.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.secvault.feature</id>\n                                    <version>${carbon.secvault.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.utils.feature</id>\n                                    <version>${carbon.utils.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.server.feature.group</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.osgi.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.deployment.engine.feature</id>\n                                    <version>${carbon.deployment.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.msf4j.feature</id>\n                                    <version>${msf4j.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.msf4j.deployer.feature</id>\n                                    <version>${msf4j.version}</version>\n                                </feature>\n                                <feature>\n                                    <id>org.wso2.carbon.pax.exam.feature</id>\n                                    <version>${carbon.kernel.version}</version>\n                                </feature>\n                            </features>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-antrun-plugin</artifactId>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <configuration>\n                            <tasks>\n                                <replace dir=\"target/wso2-msf4j-${msf4j.version}/wso2\" token=\"false\" value=\"true\">\n                                    <include name=\"**/bundles.info\" />\n                                </replace>\n                            </tasks>\n                        </configuration>\n                        <goals>\n                            <goal>run</goal>\n                        </goals>\n                    </execution>\n                    <execution>\n                        <id>clean_target</id>\n                        <phase>install</phase>\n                        <configuration>\n                            <target>\n                                <delete dir=\"target/archive-tmp\" />\n                                <delete dir=\"target/dependency-maven-plugin-markers\" />\n                                <delete dir=\"target/org.eclipse.equinox.executable-3.5.0.v20110530-7P7NFUFFLWUl76mart\" />\n                                <delete dir=\"target/p2-repo\" />\n                                <delete file=\"target/tmp\" />\n                                <delete dir=\"target/wso2-msf4j-${msf4j.version}\" />\n                                <delete dir=\"target/antrun\" />\n                            </target>\n                        </configuration>\n                        <goals>\n                            <goal>run</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <configuration>\n                    <descriptors>\n                        <descriptor>${basedir}/src/assembly/bin.xml</descriptor>\n                    </descriptors>\n                    <finalName>wso2-msf4j-${msf4j.version}</finalName>\n                    <appendAssemblyId>false</appendAssemblyId>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>make-assembly</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>single</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "tests/test-distribution/src/assembly/bin.xml",
    "content": "<!--\r\n Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\r\n\r\n Licensed under the Apache License, Version 2.0 (the \"License\");\r\n you may not use this file except in compliance with the License.\r\n You may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n Unless required by applicable law or agreed to in writing, software\r\n distributed under the License is distributed on an \"AS IS\" BASIS,\r\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n See the License for the specific language governing permissions and\r\n limitations under the License.\r\n-->\r\n<assembly>\r\n    <includeBaseDirectory>true</includeBaseDirectory>\r\n    <baseDirectory>wso2-msf4j-${msf4j.version}</baseDirectory>\r\n    <id>wso2-msf4j</id>\r\n    <formats>\r\n        <format>zip</format>\r\n    </formats>\r\n    <fileSets>\r\n        <fileSet>\r\n            <directory>target/wso2-msf4j-${msf4j.version}</directory>\r\n            <outputDirectory>.</outputDirectory>\r\n            <excludes>\r\n                <exclude>README.txt</exclude>\r\n                <exclude>LICENSE.txt</exclude>\r\n                <exclude>INSTALL.txt</exclude>\r\n                <exclude>release-notes.html</exclude>\r\n                <exclude>**/*.ipr</exclude>\r\n                <exclude>**/*.iwr</exclude>\r\n                <exclude>**/*.eclipse</exclude>\r\n            </excludes>\r\n        </fileSet>\r\n    </fileSets>\r\n    <files>\r\n        <file>\r\n            <source>carbon-home/conf/deployment.yaml</source>\r\n            <outputDirectory>conf/default/</outputDirectory>\r\n            <fileMode>644</fileMode>\r\n            <filtered>true</filtered>\r\n        </file>\r\n    </files>\r\n</assembly>\r\n"
  },
  {
    "path": "tooling/LICENSE",
    "content": "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\n"
  },
  {
    "path": "tooling/README.md",
    "content": "#WSO2 Developer Studio Kernel Plugin for WSO2 Microservices Framework for Java (MSF4J)\n\nThis directory provides an Eclipse plugin installable with Eclipse Luna\n\n##How to Install?\n1. Run Eclipse Mars 2, then select Help > Install New Software.\n2. Click Add\n3. In the Add dialog, enter \"MSF4J Tool\" for the Name and http://builder1.us1.wso2.org/~developerstudio/msf4j-tools/updates/ \nfor the Location:\n4. Click OK.\n5. In the Available Software dialog, select all the checkboxes and click Next.\n6. Read and accept the license agreements, then click Finish.\n7. If you get a security warning saying that the authenticity or validity of the software can't be established, click OK.\n8. You will have to restart the Eclipse to complete the installation.\n"
  },
  {
    "path": "tooling/features/org.wso2.developerstudio.msf4j.feature/build.properties",
    "content": "bin.includes = feature.xml,\\\n\t       icon.png\n"
  },
  {
    "path": "tooling/features/org.wso2.developerstudio.msf4j.feature/feature.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<feature\n        id=\"org.wso2.developerstudio.msf4j.feature\"\n        label=\"MSF4J Tooling Feature\"\n        version=\"2.0.0.qualifier\"\n        provider-name=\"WSO2 Inc.\">\n\n    <description url=\"http://wso2.com\">\n        This feature will install plugins related to WSO2 Microservices Server Support.\n    </description>\n\n    <copyright url=\"http://wso2.com\">\n        Copyright 2015 WSO2, Inc. (http://wso2.com)\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    </copyright>\n\n    <license url=\"http://www.apache.org/licenses/LICENSE-2.0\">\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    </license>\n\n    <plugin\n            id=\"org.wso2.developerstudio.msf4j.artifact\"\n            download-size=\"0\"\n            install-size=\"0\"\n            version=\"0.0.0\"\n            unpack=\"false\"/>\n\n</feature>\n"
  },
  {
    "path": "tooling/features/org.wso2.developerstudio.msf4j.feature/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>wso2-developerstudio-msf4j-features</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>org.wso2.developerstudio.msf4j.feature</artifactId>\n    <packaging>eclipse-feature</packaging>\n\n    <name>MSF4J tooling Feature</name>\n</project>\n"
  },
  {
    "path": "tooling/features/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>msf4j-tool-parent</artifactId>\n    \t<version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <artifactId>wso2-developerstudio-msf4j-features</artifactId>\n    <packaging>pom</packaging>\n    <name>WSO2 MSF4J Tooling Features</name>\n\n    <modules>\n        <module>org.wso2.developerstudio.msf4j.feature</module>\n    </modules>\n\n</project>\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/.gitignore",
    "content": "/bin/\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/META-INF/MANIFEST.MF",
    "content": "Manifest-Version: 1.0\nBundle-ManifestVersion: 2\nBundle-Name: MSF4JTool\nBundle-SymbolicName: org.wso2.developerstudio.msf4j.artifact;singleton:=true\nBundle-Version: 2.0.0.qualifier\nBundle-Activator: org.wso2.developerstudio.msf4j.artifact.Activator\nRequire-Bundle: org.wso2.developerstudio.eclipse.kernel.libraries;bundle-version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.libraries;bundle-version=\"[4.1.0,5.0.0)\"\nBundle-RequiredExecutionEnvironment: JavaSE-1.7\nBundle-ActivationPolicy: lazy\nImport-Package: com.google.common.base,\n com.google.common.collect,\n org.apache.commons.lang3;version=\"3.1.0\",\n org.apache.commons.lang3.builder;version=\"3.1.0\",\n org.apache.commons.lang3.concurrent;version=\"3.1.0\",\n org.apache.commons.lang3.event;version=\"3.1.0\",\n org.apache.commons.lang3.exception;version=\"3.1.0\",\n org.apache.commons.lang3.math;version=\"3.1.0\",\n org.apache.commons.lang3.mutable;version=\"3.1.0\",\n org.apache.commons.lang3.reflect;version=\"3.1.0\",\n org.apache.commons.lang3.text;version=\"3.1.0\",\n org.apache.commons.lang3.text.translate;version=\"3.1.0\",\n org.apache.commons.lang3.time;version=\"3.1.0\",\n org.apache.commons.lang3.tuple;version=\"3.1.0\",\n org.eclipse.jdt.core,\n org.eclipse.m2e.core,\n org.eclipse.m2e.core.embedder,\n org.eclipse.m2e.core.project,\n org.eclipse.wst.command.internal.env.core.common,\n org.wso2.developerstudio.eclipse.libraries.utils;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.logging.core;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.maven.util;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.exception;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.manifest;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.model;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.nature;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.project.export;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.core.project.model;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.ui.validator;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.ui.wizard;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.platform.ui.wizard.pages;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.samples.contributor;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.archive;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.data;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.file;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.ide;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.jdt;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.project;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.template;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.ui;version=\"[4.1.0,5.0.0)\",\n org.wso2.developerstudio.eclipse.utils.wst;version=\"[4.1.0,5.0.0)\"\nBundle-ClassPath: lib/swagger-annotations-1.5.0.jar,\n lib/swagger-codegen-2.1.5.jar,\n lib/swagger-core-1.5.4.jar,\n .,\n lib/slf4j-api-1.7.7.jar,\n lib/swagger-models-1.5.4.jar,\n lib/commons-lang3-3.0.jar,\n lib/jackson-annotations-2.6.3.jar,\n lib/jackson-core-2.6.2.jar,\n lib/jackson-databind-2.6.3.jar,\n lib/jackson-dataformat-yaml-2.6.3.jar,\n lib/jersey-bundle-1.19.jar,\n lib/jersey-multipart-1.19.jar,\n lib/jmustache-1.11.jar,\n lib/joda-time-2.8.2.jar,\n lib/swagger-parser-1.0.10.jar,\n lib/swagger-codegen-2.1.4.jar\nExport-Package: io.swagger.annotations,\n io.swagger.codegen,\n io.swagger.codegen.auth,\n io.swagger.codegen.config,\n io.swagger.codegen.examples,\n io.swagger.codegen.languages,\n io.swagger.config,\n io.swagger.converter,\n io.swagger.core.filter,\n io.swagger.jackson,\n io.swagger.model,\n io.swagger.models,\n io.swagger.models.auth,\n io.swagger.models.parameters,\n io.swagger.models.properties,\n io.swagger.models.refs,\n io.swagger.parser,\n io.swagger.parser.processors,\n io.swagger.parser.util,\n io.swagger.util,\n org.apache.commons.lang3,\n org.apache.commons.lang3.builder,\n org.apache.commons.lang3.concurrent,\n org.apache.commons.lang3.event,\n org.apache.commons.lang3.exception,\n org.apache.commons.lang3.math,\n org.apache.commons.lang3.mutable,\n org.apache.commons.lang3.reflect,\n org.apache.commons.lang3.text,\n org.apache.commons.lang3.text.translate,\n org.apache.commons.lang3.time,\n org.apache.commons.lang3.tuple,\n org.slf4j,\n org.slf4j.helpers,\n org.slf4j.spi\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/build.properties",
    "content": "source.. = src/\noutput.. = bin/\nbin.includes = .,\\\n               META-INF/,\\\n               icons/,\\\n               plugin.xml,\\\n               project_wizard.xml,\\\n               src/,\\\n               lib/\nsrc.includes = META-INF/,\\\n               icons/,\\\n               lib/,\\\n               plugin.xml,\\\n               project_wizard.xml,\\\n               src/\n\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?eclipse version=\"3.4\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<plugin>\n    <extension point=\"org.eclipse.ui.newWizards\">\n        <category name=\"Service Hosting\" id=\"org.wso2.developerstudio.eclipse.service.hosting.msf4j\"\n                  parentCategory=\"org.wso2.developerstudio.eclipse.capp.project\">\n        </category>\n        <wizard name=\"MSF4J Project\"\n                category=\"org.wso2.developerstudio.eclipse.capp.project/org.wso2.developerstudio.eclipse.service.hosting.msf4j\"\n                class=\"org.wso2.developerstudio.msf4j.artifact.ui.wizard.MSF4JProjectCreationWizard\"\n                wizardManifest=\"project_wizard.xml\"\n                id=\"org.wso2.developerstudio.msf4j.artifact.newmsf4jartifact\"\n                descriptionImage=\"icons/msf4j-wizard.png\"\n                project=\"true\" icon=\"icons/msf4j.png\">\n            <description>MSF4J Project</description>\n        </wizard>\n    </extension>\n    <extension point=\"org.eclipse.ui.perspectives\">\n   <perspective\n         name=\"MSF4J Perspective\"\n         class=\"org.wso2.developerstudio.msf4j.artifact.ui.wizard.MSF4JPerspective\"\n         id=\"org.eclipse.ui.articles.perspective.msf4jperspective\">\n   </perspective>\n</extension>\n     <extension\n     point=\"org.eclipse.ui.perspectiveExtensions\">\n  <perspectiveExtension targetID=\"org.eclipse.ui.articles.perspective.msf4jperspective\">\n     <newWizardShortcut\n           id=\"org.wso2.developerstudio.msf4j.artifact.newmsf4jartifact\">\n     </newWizardShortcut>\n  </perspectiveExtension>\n</extension>\n    <extension point=\"org.eclipse.core.resources.natures\"\n               id=\"org.wso2.developerstudio.eclipse.msf4j.project.nature\" name=\"MSF4J Project Nature\">\n        <runtime>\n            <run class=\"org.wso2.developerstudio.msf4j.artifact.project.nature.MSF4JArtifactProjectNature\"/>\n        </runtime>\n    </extension>\n    <extension point=\"org.eclipse.ui.ide.projectNatureImages\">\n        <image id=\"org.wso2.developerstudio.eclipse.msf4j.project.natureImage\"\n               natureId=\"org.wso2.developerstudio.eclipse.msf4j.project.nature\" icon=\"icons/msf4j-nature.png\">\n        </image>\n    </extension>\n\n</plugin>\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>wso2-developerstudio-msf4j-plugins</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>org.wso2.developerstudio.msf4j.artifact</artifactId>\n    <packaging>eclipse-plugin</packaging>\n\n    <name>MSF4J Project</name>\n</project>\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/project_wizard.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<wizard>\n    <projectOptions title=\"MSF4J Project Creation Options\"\n                    description=\"Select how would you like to create your new project\"\n                    error=\"Please select a method to create the project\">\n        <option id=\"new.MSF4J\" default=\"true\">Create New MSF4J Project Using Swagger</option>\n    </projectOptions>\n\n    <projectOptionSettings>\n        <settings optionId=\"new.MSF4J\" title=\"MSF4J Project\"\n                  description=\"Create New MSF4J Project Using Swagger\" error=\"Please give a name to the project\">\n            <data modelProperty=\"project.name\" type=\"string\"\n                  fieldController=\"org.wso2.developerstudio.msf4j.artifact.validators.MSF4JArtifactFieldController\">Project Name</data>\n            <data group=\"paramGroup\" modelProperty=\"swagger.file\" type=\"file\"\n                  filter=\"*.json\"\n                  fieldController=\"org.wso2.developerstudio.msf4j.artifact.validators.MSF4JArtifactFieldController\">Swagger File</data>\n            <data modelProperty=\"service.class.package.name\" type=\"string\"\n                  fieldController=\"org.wso2.developerstudio.msf4j.artifact.validators.MSF4JArtifactFieldController\"\n                  group=\"paramGroup\">Package Name</data>\n            <data modelProperty=\"service.class.msf4j.version\" type=\"string\"\n                  fieldController=\"org.wso2.developerstudio.msf4j.artifact.validators.MSF4JArtifactFieldController\"\n                  group=\"paramGroup\">MSF4J Version</data>\n            <group id=\"paramGroup\"/>\n            <projectNatures>\n                <nature>org.eclipse.jdt.core.javanature</nature>\n            </projectNatures>\n        </settings>\n    </projectOptionSettings>\n</wizard>"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/Activator.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact;\n\nimport org.eclipse.ui.plugin.AbstractUIPlugin;\nimport org.osgi.framework.BundleContext;\nimport org.wso2.developerstudio.eclipse.logging.core.IDeveloperStudioLog;\nimport org.wso2.developerstudio.eclipse.logging.core.Logger;\n\n/**\n * The activator class controls the plug-in life cycle\n */\npublic class Activator extends AbstractUIPlugin {\n\n\t// The plug-in ID\n\tpublic static final String PLUGIN_ID = \"org.wso2.developerstudio.msf4j.artifact\"; //$NON-NLS-1$\n\n\t// The shared instance\n\tprivate static Activator plugin;\n\n\t/**\n\t * The constructor\n\t */\n\tpublic Activator() {\n\t}\n\n\t/*\n\t * (non-Javadoc)\n\t * \n\t * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext )\n\t */\n\tpublic void start(BundleContext context) throws Exception {\n\t\tsuper.start(context);\n\t\tplugin = this;\n\t}\n\n\t/*\n\t * (non-Javadoc)\n\t * \n\t * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext )\n\t */\n\tpublic void stop(BundleContext context) throws Exception {\n\t\tplugin = null;\n\t\tsuper.stop(context);\n\t}\n\n\t/**\n\t * Returns the shared instance\n\t *\n\t * @return the shared instance\n\t */\n\tpublic static Activator getDefault() {\n\t\treturn plugin;\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/generator/SwaggerToJavaGenerator.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.generator;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport io.swagger.codegen.ClientOptInput;\nimport io.swagger.codegen.DefaultGenerator;\nimport io.swagger.codegen.config.CodegenConfigurator;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.wso2.developerstudio.msf4j.artifact.util.GeneratorUtils;\n\n/**\n * Class for generating JAX-RS services Java code from a Swagger API definition using IO Swagger Codegen libraries\n */\npublic class SwaggerToJavaGenerator {\n\tprivate Boolean verbose;\n\tprivate String generatedCodeLanguage;\n\tprivate String outputLocation;\n\tprivate String swaggerSpec;\n\tprivate String templateDir;\n\tprivate String auth;\n\tprivate String systemProperties;\n\tprivate String configFile;\n\tprivate Boolean skipOverwrite;\n\tprivate String apiPackage;\n\tprivate String modelPackage;\n\tprivate String instantiationTypes;\n\tprivate String typeMappings;\n\tprivate String additionalProperties;\n\tprivate String languageSpecificPrimitives;\n\tprivate String importMappings;\n\tprivate String invokerPackage;\n\tprivate String groupId;\n\tprivate String artifactId;\n\tprivate String artifactVersion;\n\tprivate String library;\n\n\tpublic SwaggerToJavaGenerator(String swaggerSpec, String outputLocation, String packageName) {\n\t\tthis.swaggerSpec = swaggerSpec;\n\t\tthis.outputLocation = outputLocation;\n\t\tthis.apiPackage = packageName + \".api\";\n\t\tthis.modelPackage = packageName + \".model\";\n\t\tthis.generatedCodeLanguage = \"jaxrs\";\n\t}\n\n\tpublic void generateService() {\n\n\t\t// attempt to read from config file\n\t\tCodegenConfigurator configurator = CodegenConfigurator.fromFile(configFile);\n\n\t\t// if a config file wasn't specified or we were unable to read it\n\t\tif (configurator == null) {\n\t\t\t// createa a fresh configurator\n\t\t\tconfigurator = new CodegenConfigurator();\n\t\t}\n\n\t\t// now override with any specified parameters\n\t\tif (verbose != null) {\n\t\t\tconfigurator.setVerbose(verbose);\n\t\t}\n\n\t\tif (skipOverwrite != null) {\n\t\t\tconfigurator.setSkipOverwrite(skipOverwrite);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(swaggerSpec)) {\n\t\t\tconfigurator.setInputSpec(swaggerSpec);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(generatedCodeLanguage)) {\n\t\t\tconfigurator.setLang(generatedCodeLanguage);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(outputLocation)) {\n\t\t\tconfigurator.setOutputDir(outputLocation);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(auth)) {\n\t\t\tconfigurator.setAuth(auth);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(templateDir)) {\n\t\t\tconfigurator.setTemplateDir(templateDir);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(apiPackage)) {\n\t\t\tconfigurator.setApiPackage(apiPackage);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(modelPackage)) {\n\t\t\tconfigurator.setModelPackage(modelPackage);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(invokerPackage)) {\n\t\t\tconfigurator.setInvokerPackage(invokerPackage);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(groupId)) {\n\t\t\tconfigurator.setGroupId(groupId);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(artifactId)) {\n\t\t\tconfigurator.setArtifactId(artifactId);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(artifactVersion)) {\n\t\t\tconfigurator.setArtifactVersion(artifactVersion);\n\t\t}\n\n\t\tif (StringUtils.isNotEmpty(library)) {\n\t\t\tconfigurator.setLibrary(library);\n\t\t}\n\n\t\tsetSystemProperties(configurator);\n\t\tsetInstantiationTypes(configurator);\n\t\tsetImportMappings(configurator);\n\t\tsetTypeMappings(configurator);\n\t\tsetAdditionalProperties(configurator);\n\t\tsetLanguageSpecificPrimitives(configurator);\n\n\t\tfinal ClientOptInput clientOptInput = configurator.toClientOptInput();\n\t\tnew DefaultGenerator().opts(clientOptInput).generate();\n\t}\n\n\tprivate void setSystemProperties(CodegenConfigurator configurator) {\n\t\tfinal Map<String, String> map = createMapFromKeyValuePairs(systemProperties);\n\t\tfor (Map.Entry<String, String> entry : map.entrySet()) {\n\t\t\tconfigurator.addSystemProperty(entry.getKey(), entry.getValue());\n\t\t}\n\t}\n\n\tprivate void setInstantiationTypes(CodegenConfigurator configurator) {\n\t\tfinal Map<String, String> map = createMapFromKeyValuePairs(instantiationTypes);\n\t\tfor (Map.Entry<String, String> entry : map.entrySet()) {\n\t\t\tconfigurator.addInstantiationType(entry.getKey(), entry.getValue());\n\t\t}\n\t}\n\n\tprivate void setImportMappings(CodegenConfigurator configurator) {\n\t\tfinal Map<String, String> map = createMapFromKeyValuePairs(importMappings);\n\t\tfor (Map.Entry<String, String> entry : map.entrySet()) {\n\t\t\tconfigurator.addImportMapping(entry.getKey(), entry.getValue());\n\t\t}\n\t}\n\n\tprivate void setTypeMappings(CodegenConfigurator configurator) {\n\t\tfinal Map<String, String> map = createMapFromKeyValuePairs(typeMappings);\n\t\tfor (Map.Entry<String, String> entry : map.entrySet()) {\n\t\t\tconfigurator.addTypeMapping(entry.getKey(), entry.getValue());\n\t\t}\n\t}\n\n\tprivate void setAdditionalProperties(CodegenConfigurator configurator) {\n\t\tfinal Map<String, String> map = createMapFromKeyValuePairs(additionalProperties);\n\t\tfor (Map.Entry<String, String> entry : map.entrySet()) {\n\t\t\tconfigurator.addAdditionalProperty(entry.getKey(), entry.getValue());\n\t\t}\n\t}\n\n\tprivate void setLanguageSpecificPrimitives(CodegenConfigurator configurator) {\n\t\tfinal Set<String> set = createSetFromCsvList(languageSpecificPrimitives);\n\t\tfor (String item : set) {\n\t\t\tconfigurator.addLanguageSpecificPrimitive(item);\n\t\t}\n\t}\n\n\tprivate Set<String> createSetFromCsvList(String csvProperty) {\n\t\tfinal List<String> values = GeneratorUtils.splitCommaSeparatedList(csvProperty);\n\t\treturn new HashSet<String>(values);\n\t}\n\n\tprivate Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) {\n\t\tfinal List<Pair<String, String>> pairs = GeneratorUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);\n\t\tMap<String, String> result = new HashMap<String, String>();\n\t\tfor (Pair<String, String> pair : pairs) {\n\t\t\tresult.put(pair.getLeft(), pair.getRight());\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic String getGroupId() {\n\t\treturn groupId;\n\t}\n\n\tpublic void setGroupId(String groupId) {\n\t\tthis.groupId = groupId;\n\t}\n\n\tpublic String getArtifactId() {\n\t\treturn artifactId;\n\t}\n\n\tpublic void setArtifactId(String artifactId) {\n\t\tthis.artifactId = artifactId;\n\t}\n\n\tpublic String getArtifactVersion() {\n\t\treturn artifactVersion;\n\t}\n\n\tpublic void setArtifactVersion(String artifactVersion) {\n\t\tthis.artifactVersion = artifactVersion;\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/model/MSF4JProjectModel.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.model;\n\nimport java.io.File;\n\nimport org.eclipse.core.resources.IProject;\nimport org.wso2.developerstudio.eclipse.platform.core.exception.ObserverFailedException;\nimport org.wso2.developerstudio.eclipse.platform.core.project.model.ProjectDataModel;\n\npublic class MSF4JProjectModel extends ProjectDataModel {\n\tprivate File swaggerFile;\n\tprivate IProject project;\n\tprivate String sourceFolder;\n\tprivate String generatedCodeLocation;\n\tprivate String packageName;\n\tprivate String msf4jVersion;\n\tprivate File folderLocation;\n\tprivate File projectFolder;\n\tprivate String createdProjectN;\n\tprivate String createdProjectFile;\n\n\tpublic String getCreatedProjectN() {\n\t\treturn createdProjectN;\n\t}\n\n\tpublic void setCreatedProjectN(String createdProjectN) {\n\t\tthis.createdProjectN = createdProjectN;\n\t}\n\n\tpublic File getProjectFolder() {\n\t\treturn projectFolder;\n\t}\n\n\tpublic void setProjectFolder(File projectFolder) {\n\t\tthis.projectFolder = projectFolder;\n\t}\n\n\tpublic String getCreatedProjectFile() {\n\t\treturn createdProjectFile;\n\t}\n\n\tpublic void setCreatedProjectFile(String createdProjectFile) {\n\t\tthis.createdProjectFile = createdProjectFile;\n\t}\n\n\tpublic File getFolderLocation() {\n\t\treturn folderLocation;\n\t}\n\n\tpublic void setFolderLocation(File folderLocation) {\n\t\tthis.folderLocation = folderLocation;\n\t}\n\n\tpublic Object getModelPropertyValue(String key) {\n\t\tObject modelPropertyValue = super.getModelPropertyValue(key);\n\t\tif (modelPropertyValue == null) {\n\t\t\tif (key.equalsIgnoreCase(\"swagger.file\")) {\n\t\t\t\tmodelPropertyValue = getSwaggerFile();\n\t\t\t} else if (key.equalsIgnoreCase(\"service.class.package.name\")) {\n\t\t\t\tmodelPropertyValue = getPackageName();\n\t\t\t}\n\t\t}\n\t\treturn modelPropertyValue;\n\t}\n\n\tpublic boolean setModelPropertyValue(String key, Object data) throws ObserverFailedException {\n\t\tboolean returnValue = super.setModelPropertyValue(key, data);\n\t\tif (key.equals(\"swagger.file\")) {\n\t\t\tif (data != null && data instanceof File) {\n\t\t\t\tsetSwaggerFile((File) data);\n\t\t\t}\n\t\t} else if (key.equals(\"service.class.package.name\")) {\n\t\t\tsetPackageName(data.toString());\n\t\t} else if (key.equals(\"service.class.msf4j.version\")) {\n\t\t\tsetMsf4jVersion(data.toString());\n\t\t}\n\t\treturn returnValue;\n\t}\n\n\tpublic File getSwaggerFile() {\n\t\treturn swaggerFile;\n\t}\n\n\tpublic void setSwaggerFile(File swaggerFile) {\n\t\tthis.swaggerFile = swaggerFile;\n\t}\n\n\tpublic IProject getProject() {\n\t\treturn project;\n\t}\n\n\tpublic void setProject(IProject project) {\n\t\tthis.project = project;\n\t}\n\n\tpublic String getSourceFolder() {\n\t\treturn sourceFolder;\n\t}\n\n\tpublic void setSourceFolder(String sourceFolder) {\n\t\tthis.sourceFolder = sourceFolder;\n\t}\n\n\tpublic String getGeneratedCodeLocation() {\n\t\treturn generatedCodeLocation;\n\t}\n\n\tpublic void setGeneratedCodeLocation(String generatedCodeLocation) {\n\t\tthis.generatedCodeLocation = generatedCodeLocation;\n\t}\n\n\tpublic String getPackageName() {\n\t\treturn packageName;\n\t}\n\n\tpublic void setPackageName(String packageName) {\n\t\tthis.packageName = packageName;\n\t}\n\n\tpublic String getMsf4jVersion() {\n\t\treturn msf4jVersion;\n\t}\n\n\tpublic void setMsf4jVersion(String msf4jVersion) {\n\t\tthis.msf4jVersion = msf4jVersion;\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/project/nature/MSF4JArtifactProjectNature.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.project.nature;\n\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_SERVICE_PARENT_ARTIFACT_ID;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_SERVICE_PARENT_GROUP_ID;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.POM_FILE;\n\nimport java.io.File;\nimport java.io.IOException;\n//import java.util.ArrayList;\nimport java.util.Properties;\n\nimport org.apache.maven.model.Parent;\nimport org.apache.maven.project.MavenProject;\nimport org.codehaus.plexus.util.xml.pull.XmlPullParserException;\nimport org.eclipse.core.resources.IProject;\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IStatus;\nimport org.eclipse.core.runtime.Status;\nimport org.wso2.developerstudio.eclipse.logging.core.IDeveloperStudioLog;\nimport org.wso2.developerstudio.eclipse.logging.core.Logger;\nimport org.wso2.developerstudio.eclipse.maven.util.MavenUtils;\nimport org.wso2.developerstudio.eclipse.platform.core.nature.AbstractWSO2ProjectNature;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\nimport org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants;\n\n/**\n * Class for represent the nature of a Microservices project inside Eclipse\n * workspace\n */\n@Deprecated\npublic class MSF4JArtifactProjectNature extends AbstractWSO2ProjectNature {\n\n\tprivate static IDeveloperStudioLog log = Logger.getLog(Activator.PLUGIN_ID);\n\tprivate static final String PERSPECTIVE_ID = \"org.eclipse.ui.articles.perspective.msf4jperspective\";\n\t@Override\n\tpublic void configure() throws CoreException {\n\t\ttry {\n\t\t\tupdatePom(getProject());\n\t\t} catch (IOException | XmlPullParserException e) {\n\t\t\tlog.error(\"Error while updating pom.xml file of created MSF4J project\", e);\n\t\t\tIStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,\n\t\t\t\t\t\"Error while updating pom.xml file of created MSF4J project\");\n\t\t\tthrow new CoreException(status);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void deconfigure() throws CoreException {\n\n\t}\n\n\t/**\n\t * Update created pom.xml file with necessary dependencies and plug-ins so\n\t * that it works with WSO2 MSF4J server\n\t * \n\t * @throws IOException\n\t * @throws XmlPullParserException\n\t *\n\t */\n\tprivate void updatePom(IProject project) throws IOException, XmlPullParserException {\n\t\tFile mavenProjectPomLocation = project.getFile(POM_FILE).getLocation().toFile();\n\t\tMavenProject mavenProject = MavenUtils.getMavenProject(mavenProjectPomLocation);\n\t\tParent msf4jParent = new Parent();\n\t\tmsf4jParent.setGroupId(MSF4J_SERVICE_PARENT_GROUP_ID);\n\t\tmsf4jParent.setArtifactId(MSF4J_SERVICE_PARENT_ARTIFACT_ID);\n\t\tmsf4jParent.setVersion(MSF4JArtifactConstants.getMSF4JServiceParentVersion());\n\t\tmavenProject.getModel().setParent(msf4jParent);\n\n\t\tProperties generatedProperties = mavenProject.getModel().getProperties();\n\t\tgeneratedProperties.clear();\n\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/ui/wizard/MSF4JPerspective.java",
    "content": "package org.wso2.developerstudio.msf4j.artifact.ui.wizard;\n\nimport org.eclipse.ui.IFolderLayout;\nimport org.eclipse.ui.IPageLayout;\nimport org.eclipse.ui.IPerspectiveFactory;\n\npublic class MSF4JPerspective implements IPerspectiveFactory{\n\n\t@Override\n\tpublic void createInitialLayout(IPageLayout layout) {\n\t\tString editorArea = layout.getEditorArea();\n\n\t\t// Top left: Project Explorer\n\t\tIFolderLayout topLeft = layout.createFolder(\"topLeft\",\n\t\t\t\tIPageLayout.LEFT, 0.15f, editorArea);\n\t\ttopLeft.addView(IPageLayout.ID_PROJECT_EXPLORER);\n\n\n\t\t\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/ui/wizard/MSF4JProjectCreationWizard.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.ui.wizard;\n\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.CODE_GENERATION_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.GEN_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.IMAGE_FILE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.JAVA_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MAIN_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MAVEN2_PROJECT_NATURE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_PROJECT_CREATION_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_PROJECT_NATURE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.NEW_MSF4J_PROJECT_CREATION_OPTION;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.OK_BUTTON;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.PROCESSING_CONFIGURATION_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.PROJECT_WIZARD_WINDOW_TITLE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.RESOURCES_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.WEBAPP_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.SRC_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.NOT_FOUND_EXCEPTION_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_EXCEPTION_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_ORIGIN_FILTER_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_RESPONSE_MESSAGE_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\n\nimport org.apache.commons.io.FileUtils;\nimport org.eclipse.core.internal.resources.Folder;\nimport org.eclipse.core.resources.IFolder;\nimport org.eclipse.core.resources.IProject;\nimport org.eclipse.core.resources.IResource;\nimport org.eclipse.core.resources.IWorkspaceRoot;\nimport org.eclipse.core.resources.ResourcesPlugin;\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.core.runtime.NullProgressMonitor;\nimport org.eclipse.jdt.core.JavaModelException;\nimport org.eclipse.jface.dialogs.MessageDialog;\nimport org.eclipse.jface.dialogs.ProgressMonitorDialog;\nimport org.eclipse.jface.operation.IRunnableWithProgress;\nimport org.eclipse.jface.viewers.IStructuredSelection;\nimport org.eclipse.ui.IWorkbench;\nimport org.wso2.developerstudio.eclipse.logging.core.IDeveloperStudioLog;\nimport org.wso2.developerstudio.eclipse.logging.core.Logger;\nimport org.wso2.developerstudio.eclipse.platform.ui.wizard.AbstractWSO2ProjectCreationWizard;\nimport org.wso2.developerstudio.eclipse.utils.jdt.JavaUtils;\nimport org.wso2.developerstudio.eclipse.utils.project.ProjectUtils;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\nimport org.wso2.developerstudio.msf4j.artifact.generator.SwaggerToJavaGenerator;\nimport org.wso2.developerstudio.msf4j.artifact.model.MSF4JProjectModel;\nimport org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants;\nimport org.wso2.developerstudio.msf4j.artifact.util.MSF4JDependencyResolverJob;\nimport org.wso2.developerstudio.msf4j.artifact.util.MSF4JImageUtils;\nimport org.wso2.developerstudio.msf4j.artifact.util.MSF4JProjectImporter;\n\n/**\n * Class for creating MSF4J Server project\n */\npublic class MSF4JProjectCreationWizard extends AbstractWSO2ProjectCreationWizard {\n\n\tprivate static IDeveloperStudioLog log = Logger.getLog(Activator.PLUGIN_ID);\n\n\tprivate MSF4JProjectModel msf4jArtifactModel;\n\tprivate File newJavaFolder;\n\n\tpublic MSF4JProjectCreationWizard() {\n\t\tsetMsf4JModel(new MSF4JProjectModel());\n\t\tsetModel(getMsf4jModel());\n\t\tsetWindowTitle(PROJECT_WIZARD_WINDOW_TITLE);\n\t\tsetDefaultPageImageDescriptor(MSF4JImageUtils.getInstance().getImageDescriptor(IMAGE_FILE));\n\t}\n\n\tpublic void init(IWorkbench workbench, IStructuredSelection selection) {\n\t\tsuper.init(workbench, selection);\n\t}\n\n\t@Override\n\tpublic boolean performFinish() {\n\n\t\ttry {\n\t\t\tif (getModel().getSelectedOption().equals(NEW_MSF4J_PROJECT_CREATION_OPTION)) {\n\n\t\t\t\t// Creating new Eclipse project\n\t\t\t\tIProject project = createNewProject();\n\t\t\t\tmsf4jArtifactModel.setCreatedProjectFile(project.getLocation().toOSString());\n\t\t\t\tmsf4jArtifactModel.setCreatedProjectN(project.getName());\n\t\t\t\tnewJavaFolder = new File(project.getLocation().toOSString());\n\t\t\t\tproject.delete(true, new NullProgressMonitor());\n\t\t\t\tnewJavaFolder.mkdir();\n\t\t\t\tmsf4jArtifactModel.setProjectFolder(newJavaFolder);\n\n\t\t\t\tmsf4jArtifactModel.setGeneratedCodeLocation(newJavaFolder.getAbsolutePath());\n\t\t\t\tif (msf4jArtifactModel.getMsf4jVersion() != null) {\n\t\t\t\t\tMSF4JArtifactConstants.setMSF4JServiceParentVersion(msf4jArtifactModel.getMsf4jVersion());\n\t\t\t\t}\n\t\t\t\tProgressMonitorDialog progressMonitorDialog = new ProgressMonitorDialog(getShell());\n\t\t\t\tprogressMonitorDialog.create();\n\t\t\t\tprogressMonitorDialog.open();\n\t\t\t\tprogressMonitorDialog.run(false, false, new CodegenJob());\n\n\t\t\t} else {\n\t\t\t\tlog.error(\"Unsupported MSF4J project creation option\" + getModel().getSelectedOption());\n\t\t\t\tMessageDialog errorDialog = new MessageDialog(getShell(), \"Error\", null,\n\t\t\t\t\t\t\"Unsupported Microserices project creation option\", MessageDialog.ERROR,\n\t\t\t\t\t\tnew String[] { OK_BUTTON }, 0);\n\t\t\t\terrorDialog.open();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch (CoreException | InvocationTargetException | InterruptedException e) {\n\t\t\tlog.error(\"Error while creating MSF4J project for given Swagger API\", e);\n\t\t\tMessageDialog errorDialog = new MessageDialog(getShell(), \"Error\", null,\n\t\t\t\t\t\"Error while creating MSF4J project for given Swagger API\", MessageDialog.ERROR,\n\t\t\t\t\tnew String[] { OK_BUTTON }, 0);\n\t\t\terrorDialog.open();\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic IResource getCreatedResource() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Class responsible for running Codegen job for creation of JAX-RS services\n\t */\n\tprivate class CodegenJob implements IRunnableWithProgress {\n\n\t\tpublic void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\n\t\t\tString operationText = MSF4J_PROJECT_CREATION_TASK;\n\t\t\tmonitor.beginTask(operationText, 100);\n\t\t\tmonitor.subTask(PROCESSING_CONFIGURATION_TASK);\n\t\t\tmonitor.worked(10);\n\t\t\tmonitor.subTask(CODE_GENERATION_TASK);\n\t\t\tmonitor.worked(75);\n\n\t\t\t// Generating MSF4J JAX-RS source code from given\n\t\t\t// Swagger API definition\n\t\t\tString swaggerFilePath = msf4jArtifactModel.getSwaggerFile().getAbsolutePath();\n\t\t\tSwaggerToJavaGenerator sourceGenerator = new SwaggerToJavaGenerator(swaggerFilePath,\n\t\t\t\t\tmsf4jArtifactModel.getGeneratedCodeLocation(), msf4jArtifactModel.getPackageName());\n\t\t\tsourceGenerator.setGroupId(msf4jArtifactModel.getMavenInfo().getGroupId());\n\t\t\tsourceGenerator.setArtifactId(msf4jArtifactModel.getMavenInfo().getArtifactId());\n\t\t\tsourceGenerator.setArtifactVersion(msf4jArtifactModel.getMavenInfo().getVersion());\n\t\t\tsourceGenerator.generateService();\n\n\t\t\tMSF4JDependencyResolverJob msf4jDependencyResolverJob = new MSF4JDependencyResolverJob(\n\t\t\t\t\t\"msf4jDependencyResolverJob\", msf4jArtifactModel);\n\t\t\tmsf4jDependencyResolverJob.schedule();\n\n\t\t}\n\n\t}\n\n\tpublic MSF4JProjectModel getMsf4jModel() {\n\t\treturn msf4jArtifactModel;\n\t}\n\n\tpublic void setMsf4JModel(MSF4JProjectModel msf4jModel) {\n\t\tthis.msf4jArtifactModel = msf4jModel;\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/GeneratorUtils.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.commons.lang3.tuple.Pair;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class GeneratorUtils {\n\n\tpublic static List<Pair<String, String>> parseCommaSeparatedTuples(String input) {\n\t\tList<Pair<String, String>> results = new ArrayList<Pair<String, String>>();\n\t\tfinal List<String> tuples = splitCommaSeparatedList(input);\n\t\tfor (String tuple : tuples) {\n\t\t\tint ix = tuple.indexOf('=');\n\t\t\tif (ix > 0 && ix < tuple.length() - 1) {\n\t\t\t\tfinal Pair<String, String> pair = Pair.of(tuple.substring(0, ix), tuple.substring(ix + 1));\n\t\t\t\tresults.add(pair);\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tpublic static List<String> splitCommaSeparatedList(String input) {\n\t\tList<String> results = new ArrayList<String>();\n\t\tif (input != null && !input.isEmpty()) {\n\t\t\tfor (String value : input.split(\",\")) {\n\t\t\t\tif (StringUtils.isNotEmpty(value))\n\t\t\t\t\tresults.add(value);\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/LibraryUtils.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.URL;\n\nimport org.eclipse.core.runtime.IPath;\nimport org.eclipse.core.runtime.Path;\nimport org.eclipse.core.runtime.Platform;\nimport org.wso2.developerstudio.eclipse.utils.ide.EclipseUtils;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\n\npublic class LibraryUtils {\n\n\tpublic static File getDependencyPath(String dependencyName, boolean isRelativePath) {\n\t\tString dependencyPath = getLibLocation() + dependencyName;\n\t\tURL resource = getResourceURL(dependencyPath);\n\t\treturn getDependencyPath(resource, isRelativePath);\n\t}\n\n\tpublic static File getDependencyPath(String dependencyName) {\n\t\treturn getDependencyPath(dependencyName, true);\n\t}\n\n\tpublic static URL getResourceURL(String dependencyPath) {\n\t\treturn Platform.getBundle(Activator.PLUGIN_ID).getResource(dependencyPath);\n\t}\n\n\tpublic static File getDependencyPath(URL resource) {\n\t\treturn getDependencyPath(resource, true);\n\t}\n\n\tpublic static File getDependencyPath(URL resource, boolean isRelativePath) {\n\t\tif (resource != null) {\n\t\t\tIPath path = Activator.getDefault().getStateLocation();\n\t\t\tIPath libFolder = path.append(\"lib\");\n\t\t\tString[] paths = resource.getFile().split(\"/\");\n\t\t\tIPath library = libFolder.append(paths[paths.length - 1]);\n\t\t\tFile libraryFile = library.toFile();\n\t\t\tif (!libraryFile.exists()) {\n\t\t\t\ttry {\n\t\t\t\t\twriteToFile(libraryFile, resource.openStream());\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (isRelativePath) {\n\t\t\t\tIPath relativePath = EclipseUtils.getWorkspaceRelativePath(library);\n\t\t\t\trelativePath = new Path(\"ECLIPSE_WORKSPACE\").append(relativePath);\n\t\t\t\treturn relativePath.toFile();\n\t\t\t} else {\n\t\t\t\treturn library.toFile();\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate static String getLibLocation() {\n\t\treturn \"lib/\";\n\t}\n\n\tprivate static void writeToFile(File file, InputStream stream) throws IOException {\n\t\tfile.getParentFile().mkdirs();\n\t\tOutputStream out = new FileOutputStream(file);\n\t\tbyte buf[] = new byte[1024];\n\t\tint len;\n\t\twhile ((len = stream.read(buf)) > 0)\n\t\t\tout.write(buf, 0, len);\n\t\tout.close();\n\t\tstream.close();\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/MSF4JArtifactConstants.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\npublic class MSF4JArtifactConstants {\n\n    public static final String MAVEN2_PROJECT_NATURE = \"org.eclipse.m2e.core.maven2Nature\";\n    public static final String MSF4J_PROJECT_NATURE = \"org.wso2.developerstudio.eclipse.msf4j.project.nature\";\n    public static final String IMAGE_FILE = \"msf4j-wizard.png\";\n    public static final Object NEW_MSF4J_PROJECT_CREATION_OPTION = \"new.MSF4J\";\n    public static final String POM_FILE = \"pom.xml\";\n\n    public static final String MSF4J_SERVICE_PARENT_GROUP_ID = \"org.wso2.msf4j\";\n    public static final String MSF4J_SERVICE_PARENT_ARTIFACT_ID = \"msf4j-service\";\n    public static String MSF4JServiceParentVersion = \"2.0.0\";\n   \n\tpublic static final String SWAGGER_ANNOTATIONS_DEPENDENCY_GROUP_ID = \"io.swagger\";\n    public static final String SWAGGER_ANNOTATIONS_DEPENDENCY_ARTIFACT_ID = \"swagger-annotations\";\n    public static final String SWAGGER_ANNOTATIONS_DEPENDENCY_VERSION = \"1.5.0\";\n\n    public static final String OK_BUTTON = \"OK\";\n    public static final String ERROR_TAG = \"ERROR\";\n    public static final String DEPENDENCY_RESOLVING_TASK = \"Resloving Dependencies of generated project...\";\n    public static final String READING_POM_TASK = \"Reading pom.xml file\";\n    public static final String POM_FILE_PREFIX = \"pom\";\n    public static final String XML_EXTENTION = \".xml\";\n    public static final Object MAVEN_ECLIPSE_ECLIPSE_GOAL = \"eclipse:eclipse\";\n    public static final String SETTING_MAVEN_INVOKER_TASK = \"Setting Maven invoker\";\n    public static final String EXECUTING_MAVEN_REQUEST_TASK = \"Executing Maven Request\";\n    public static final String PROJECT_REFRESH_TASK = \"Refreshing project\";\n    public static final String MAVEN_DEPENDENCY_RESOLVER_TAG = \"Maven Dependency Resolver\";\n    public static final String MSF4J_MAIN_CLASS_PROPERTY = \"msf4j.mainClass\";\n    public static final String DEFAULT_MAIN_CLASS_PROPERTY_VALUE = \"TODO : Update this place with fully qualified service class name\";\n    public static final String PROJECT_WIZARD_WINDOW_TITLE = \"New MSF4J Project\";\n\n    public static final String GEN_DIRECTORY = \"gen\";\n    public static final String RESOURCES_DIRECTORY = \"resources\";\n    public static final String JAVA_DIRECTORY = \"java\";\n    public static final String MAIN_DIRECTORY = \"main\";\n    public static final String SRC_DIRECTORY = \"src\";\n    public static final String TRGET_DIRECTORY = \"target\";\n    public static final String WEBAPP_DIRECTORY = \"webapp\";\n    public static final String MSF4J_PROJECT_CREATION_TASK = \"Creating MSF4J Project...\";\n    public static final String PROCESSING_CONFIGURATION_TASK = \"Processing configuration...\";\n    public static final String CODE_GENERATION_TASK = \"Generating code...\";\n    \n    public static final String API_EXCEPTION_JAVA = \"ApiException.java\";\n    public static final String API_RESPONSE_MESSAGE_JAVA = \"ApiResponseMessage.java\";\n    public static final String API_ORIGIN_FILTER_JAVA = \"ApiOriginFilter.java\";\n    public static final String NOT_FOUND_EXCEPTION_JAVA = \"NotFoundException.java\";\n    public static final String API = \"api\";\n\n    \n    public static String getMSF4JServiceParentVersion() {\n\t\treturn MSF4JServiceParentVersion;\n\t}\n\tpublic static void setMSF4JServiceParentVersion(String mSF4J_SERVICE_PARENT_VERSION) {\n\t\tMSF4JServiceParentVersion = mSF4J_SERVICE_PARENT_VERSION;\n\t}\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/MSF4JDependencyResolverJob.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_EXCEPTION_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_ORIGIN_FILTER_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.API_RESPONSE_MESSAGE_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.GEN_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.JAVA_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MAIN_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MAVEN2_PROJECT_NATURE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_PROJECT_NATURE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.NOT_FOUND_EXCEPTION_JAVA;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.OK_BUTTON;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.RESOURCES_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.SRC_DIRECTORY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.WEBAPP_DIRECTORY;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport org.apache.commons.io.FileUtils;\nimport org.eclipse.core.resources.IFolder;\nimport org.eclipse.core.resources.IProject;\nimport org.eclipse.core.resources.IResource;\nimport org.eclipse.core.resources.IWorkspaceRoot;\nimport org.eclipse.core.resources.ResourcesPlugin;\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.core.runtime.IStatus;\nimport org.eclipse.core.runtime.NullProgressMonitor;\nimport org.eclipse.core.runtime.Status;\nimport org.eclipse.core.runtime.jobs.Job;\nimport org.eclipse.jdt.core.JavaModelException;\nimport org.eclipse.jface.dialogs.MessageDialog;\nimport org.eclipse.swt.widgets.Display;\nimport org.eclipse.swt.widgets.Shell;\nimport org.eclipse.ui.IPerspectiveDescriptor;\nimport org.eclipse.ui.IWorkbench;\nimport org.eclipse.ui.IWorkbenchWindow;\nimport org.eclipse.ui.PlatformUI;\nimport org.eclipse.ui.WorkbenchException;\nimport org.eclipse.ui.progress.UIJob;\nimport org.wso2.developerstudio.eclipse.logging.core.IDeveloperStudioLog;\nimport org.wso2.developerstudio.eclipse.logging.core.Logger;\nimport org.wso2.developerstudio.eclipse.maven.util.MavenUtils;\nimport org.wso2.developerstudio.eclipse.utils.jdt.JavaUtils;\nimport org.wso2.developerstudio.eclipse.utils.project.ProjectUtils;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\nimport org.wso2.developerstudio.msf4j.artifact.model.MSF4JProjectModel;\n\npublic class MSF4JDependencyResolverJob extends Job {\n\n\tMSF4JProjectModel msf4jArtifactModel;\n\tprivate static IDeveloperStudioLog log = Logger.getLog(Activator.PLUGIN_ID);\n\tprivate static final String PERSPECTIVE_ID = \"org.eclipse.ui.articles.perspective.msf4jperspective\";\n\n\tpublic MSF4JDependencyResolverJob(String name, MSF4JProjectModel projectModel) {\n\t\tsuper(name);\n\t\tthis.msf4jArtifactModel = projectModel;\n\t}\n\n\t@Override\n\tprotected IStatus run(IProgressMonitor monitor) {\n\t\ttry {\n\t\t\tprojectDependencyResolver(monitor);\n\t\t\tfinal IWorkbench workbench = PlatformUI.getWorkbench();\n\t\t\tnew UIJob(\"Switching perspectives\") {\n\t\t\t\t@Override\n\t\t\t\tpublic IStatus runInUIThread(IProgressMonitor monitor) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tworkbench.showPerspective(PERSPECTIVE_ID, workbench.getActiveWorkbenchWindow());\n\t\t\t\t\t} catch (WorkbenchException e) {\n\t\t\t\t\t\treturn new Status(IStatus.ERROR, Activator.PLUGIN_ID, \"Error while switching perspectives\", e);\n\t\t\t\t\t}\n\t\t\t\t\treturn Status.OK_STATUS;\n\t\t\t\t}\n\t\t\t}.run(new NullProgressMonitor());\n\n\t\t} catch (CoreException | IOException e) {\n\t\t\tlog.error(\"error in resolving project dependencies\", e);\n\t\t\tShell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();\n\t\t\tMessageDialog errorDialog = new MessageDialog(shell, \"Error\", null,\n\t\t\t\t\t\"Error while creating MSF4J project for given Swagger API\", MessageDialog.ERROR,\n\t\t\t\t\tnew String[] { OK_BUTTON }, 0);\n\t\t\terrorDialog.open();\n\t\t\treturn Status.CANCEL_STATUS;\n\t\t}\n\t\treturn Status.OK_STATUS;\n\t}\n\n\tprivate void projectDependencyResolver(IProgressMonitor monitor)\n\t\t\tthrows CoreException, IOException, JavaModelException {\n\t\tMSF4JProjectImporter msf4jProjectImporter = new MSF4JProjectImporter();\n\t\tFile pomFile = new File(msf4jArtifactModel.getProjectFolder().getPath() + File.separator + \"pom.xml\");\n\t\tmsf4jProjectImporter.importMSF4JProject(msf4jArtifactModel, msf4jArtifactModel.getCreatedProjectFile(), pomFile,\n\t\t\t\tmonitor);\n\n\t\tIWorkspaceRoot myWorkspaceRoot = resourceAlteration();\n\n\t\t// refresh the workspace after deleting files from the file\n\t\t// system\n\t\tmyWorkspaceRoot.refreshLocal(0, new NullProgressMonitor());\n\t}\n\n\tprivate IWorkspaceRoot resourceAlteration() throws IOException, CoreException, JavaModelException {\n\t\t// Renaming generated folder structure to match with WSO2\n\t\t// conventional directory structure\n\t\tIWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();\n\t\tIProject project = workspace.getProject(msf4jArtifactModel.getProjectName());\n\t\tmsf4jArtifactModel.setProject(project);\n\t\tIFolder resourceFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY,\n\t\t\t\tMAIN_DIRECTORY);\n\t\tFile resourcePhysicalFolder = resourceFolder.getRawLocation().makeAbsolute().toFile();\n\t\tFile newResourcePhysicalFolder = new File(\n\t\t\t\tresourcePhysicalFolder.getParent() + File.separator + RESOURCES_DIRECTORY);\n\t\tresourcePhysicalFolder.renameTo(newResourcePhysicalFolder);\n\n\t\tIFolder sourceFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY,\n\t\t\t\tGEN_DIRECTORY);\n\t\tFile sourcePhysicalFolder = sourceFolder.getRawLocation().makeAbsolute().toFile();\n\t\tFile newSourcePhysicalFolder = new File(sourcePhysicalFolder.getParent() + File.separator + MAIN_DIRECTORY);\n\t\tsourcePhysicalFolder.renameTo(newSourcePhysicalFolder);\n\n\t\t// Moving src/resources to src/main\n\t\tresourceFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY,\n\t\t\t\tRESOURCES_DIRECTORY);\n\t\tresourcePhysicalFolder = resourceFolder.getRawLocation().makeAbsolute().toFile();\n\t\tsourceFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY, MAIN_DIRECTORY);\n\t\tsourcePhysicalFolder = sourceFolder.getRawLocation().makeAbsolute().toFile();\n\t\tFileUtils.moveDirectoryToDirectory(resourcePhysicalFolder, sourcePhysicalFolder, true);\n\n\t\t// Adding Java support to the source folder src/main/java\n\t\t// delete the project target folder\n\t\tIFolder targetFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(),\n\t\t\t\tMSF4JArtifactConstants.TRGET_DIRECTORY);\n\t\ttargetFolder.delete(true, new NullProgressMonitor());\n\t\tIFolder mainFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY,\n\t\t\t\tMAIN_DIRECTORY, JAVA_DIRECTORY);\n\t\tJavaUtils.addJavaSupportAndSourceFolder(msf4jArtifactModel.getProject(), mainFolder);\n\n\t\t// removing the webapps folder generated by the tool\n\t\tIFolder webAppFolder = ProjectUtils.getWorkspaceFolder(msf4jArtifactModel.getProject(), SRC_DIRECTORY,\n\t\t\t\tMAIN_DIRECTORY, RESOURCES_DIRECTORY, WEBAPP_DIRECTORY);\n\t\tFile webAppPhysicalFolder = webAppFolder.getRawLocation().makeAbsolute().toFile();\n\t\tif (webAppPhysicalFolder.exists()) {\n\t\t\tFileUtils.forceDelete(webAppPhysicalFolder);\n\t\t}\n\n\t\t// removing unnecessary classes generated by the tool\n\t\tIProject newMSF4JProject = workspace.getProject(msf4jArtifactModel.getProject().getName());\n\t\tString[] filesToBeDeleted = { NOT_FOUND_EXCEPTION_JAVA, API_ORIGIN_FILTER_JAVA, API_RESPONSE_MESSAGE_JAVA,\n\t\t\t\tAPI_EXCEPTION_JAVA };\n\n\t\tfor (String fileToBeDeleted : filesToBeDeleted) {\n\t\t\tIResource originFilterFile = newMSF4JProject\n\t\t\t\t\t.getFile(SRC_DIRECTORY + File.separator + MAIN_DIRECTORY + File.separator + JAVA_DIRECTORY\n\t\t\t\t\t\t\t+ File.separator + msf4jArtifactModel.getPackageName().replace(\".\", File.separator)\n\t\t\t\t\t\t\t+ File.separator + API + File.separator + fileToBeDeleted);\n\t\t\tFile fileToDelete = originFilterFile.getRawLocation().makeAbsolute().toFile();\n\t\t\tif (fileToDelete.exists()) {\n\t\t\t\tFileUtils.forceDelete(fileToDelete);\n\t\t\t}\n\t\t}\n\t\tProjectUtils.addNatureToProject(project, false, MAVEN2_PROJECT_NATURE);\n\t\tProjectUtils.addNatureToProject(project, false, MSF4J_PROJECT_NATURE);\n\t\tproject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());\n\t\treturn workspace;\n\t}\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/MSF4JImageUtils.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport org.eclipse.core.runtime.Platform;\nimport org.osgi.framework.Bundle;\nimport org.wso2.developerstudio.eclipse.utils.ui.ImageUtils;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\n\npublic class MSF4JImageUtils extends ImageUtils {\n\n\tprivate static ImageUtils instance;\n\n\tpublic static ImageUtils getInstance() {\n\t\tif (instance == null) {\n\t\t\tinstance = new MSF4JImageUtils();\n\t\t}\n\t\treturn instance;\n\t}\n\n\tpublic Bundle getBundle() {\n\t\treturn Platform.getBundle(Activator.PLUGIN_ID);\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/MSF4JMavenDependencyResolverJob.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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 */\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.DEPENDENCY_RESOLVING_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.ERROR_TAG;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.EXECUTING_MAVEN_REQUEST_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MAVEN_ECLIPSE_ECLIPSE_GOAL;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.OK_BUTTON;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.POM_FILE_PREFIX;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.PROJECT_REFRESH_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.READING_POM_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.SETTING_MAVEN_INVOKER_TASK;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.XML_EXTENTION;\n\nimport java.io.File;\nimport java.util.Collections;\n\nimport org.apache.maven.shared.invoker.DefaultInvocationRequest;\nimport org.apache.maven.shared.invoker.DefaultInvoker;\nimport org.apache.maven.shared.invoker.InvocationRequest;\nimport org.apache.maven.shared.invoker.InvocationResult;\nimport org.apache.maven.shared.invoker.Invoker;\nimport org.apache.maven.shared.invoker.MavenInvocationException;\nimport org.eclipse.core.resources.IProject;\nimport org.eclipse.core.resources.IResource;\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.core.runtime.IStatus;\nimport org.eclipse.core.runtime.NullProgressMonitor;\nimport org.eclipse.core.runtime.Status;\nimport org.eclipse.core.runtime.jobs.Job;\nimport org.eclipse.jface.dialogs.MessageDialog;\nimport org.eclipse.swt.widgets.Shell;\nimport org.eclipse.ui.PlatformUI;\nimport org.wso2.developerstudio.eclipse.logging.core.IDeveloperStudioLog;\nimport org.wso2.developerstudio.eclipse.logging.core.Logger;\nimport org.wso2.developerstudio.eclipse.utils.file.FileUtils;\nimport org.wso2.developerstudio.msf4j.artifact.Activator;\n\n/**\n * This class extended from {@link Job} class and handles the maven dependency\n * resolving operation of given maven project\n * \n * Deprecated : we need to integrate the method to run these commands from m2e\n * plugin if needed, currently this is not required.\n *\n */\n@Deprecated\npublic class MSF4JMavenDependencyResolverJob extends Job {\n\n\tprivate static IDeveloperStudioLog log = Logger.getLog(Activator.PLUGIN_ID);\n\n\tprivate IProject project;\n\n\tpublic MSF4JMavenDependencyResolverJob(String name, IProject project) {\n\t\tsuper(name);\n\t\tthis.project = project;\n\t\tsetUser(true);\n\t}\n\n\t@Override\n\tprotected IStatus run(IProgressMonitor monitor) {\n\t\tString operationText = DEPENDENCY_RESOLVING_TASK;\n\t\tIStatus status = Status.OK_STATUS;\n\t\ttry {\n\t\t\tString mavenHome = \"EMBEDDED\";\n\t\t\tmonitor.beginTask(operationText, 100);\n\t\t\tmonitor.subTask(READING_POM_TASK);\n\t\t\tmonitor.worked(10);\n\t\t\tInvocationRequest request = new DefaultInvocationRequest();\n\t\t\tFile pomFile = FileUtils.getMatchingFiles(project.getLocation().toOSString(), POM_FILE_PREFIX,\n\t\t\t\t\tXML_EXTENTION)[0];\n\t\t\trequest.setPomFile(pomFile);\n\t\t\trequest.setGoals(Collections.singletonList(MAVEN_ECLIPSE_ECLIPSE_GOAL));\n\t\t\tmonitor.subTask(SETTING_MAVEN_INVOKER_TASK);\n\t\t\tmonitor.worked(25);\n\t\t\tInvoker invoker = new DefaultInvoker();\n\t\t\tinvoker.setMavenHome(new File(mavenHome));\n\t\t\tmonitor.subTask(EXECUTING_MAVEN_REQUEST_TASK);\n\t\t\tmonitor.worked(70);\n\t\t\tInvocationResult result = invoker.execute(request);\n\t\t\tif (result.getExitCode() != 0) {\n\t\t\t\tthrow new MavenInvocationException(\"Maven Invoker was unable to execute the request\");\n\t\t\t}\n\t\t\tmonitor.subTask(PROJECT_REFRESH_TASK);\n\t\t\tmonitor.worked(90);\n\t\t} catch (MavenInvocationException e) {\n\t\t\tlog.error(\"Error while resolving dependencies from the project pom file\", e);\n\t\t\tstatus = new Status(0, Activator.PLUGIN_ID,\n\t\t\t\t\t\"Error occured while resolving dependencies of the file in eclipse.\\n\"\n\t\t\t\t\t\t\t+ \" Please execute \\\"mvn eclipse:eclipse\\\" command in the generated project \"\n\t\t\t\t\t\t\t+ \"folder to resolve dependencies.\",\n\t\t\t\t\te);\n\t\t} /*\n\t\t\t * catch (NoSuchFieldException e) { log.error(\n\t\t\t * \"Maven Home system variable is not set as a environment variable\"\n\t\t\t * ); status = new Status(0, Activator.PLUGIN_ID,\n\t\t\t * \"Maven Home system variable is not set.\" +\n\t\t\t * \" Please execute \\\"mvn eclipse:eclipse\\\" command in the generated project \"\n\t\t\t * + \"folder to resolve dependencies.\"); }\n\t\t\t */\n\n\t\ttry {\n\t\t\tproject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());\n\t\t} catch (CoreException e) {\n\t\t\tlog.error(\"Error while refreshing the project\", e);\n\t\t} finally {\n\t\t\tmonitor.done();\n\t\t}\n\t\tif (status != Status.OK_STATUS) {\n\t\t\tfinal String message = status.getMessage();\n\t\t\tPlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\n\n\t\t\t\t@Override\n\t\t\t\tpublic void run() {\n\t\t\t\t\tShell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();\n\t\t\t\t\tMessageDialog errorDialog = new MessageDialog(shell, ERROR_TAG, null, message, MessageDialog.ERROR,\n\t\t\t\t\t\t\tnew String[] { OK_BUTTON }, 0);\n\t\t\t\t\terrorDialog.open();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn status;\n\t}\n\n\t/*\n\t * public static String getMavenHome() throws NoSuchFieldException { if\n\t * (System.getenv(\"M2_HOME\") != null) { return System.getenv(\"M2_HOME\"); }\n\t * else if (System.getenv(\"MAVEN_HOME\") != null) { return\n\t * System.getenv(\"MAVEN_HOME\"); } else if (System.getenv(\"M3_HOME\") != null)\n\t * { return System.getenv(\"M3_HOME\"); } else if\n\t * (System.getProperty(\"maven.home\") != null) { return\n\t * System.getProperty(\"maven.home\"); } else { log.error(\n\t * \"Maven Home variable value is not found in system properties or in environment variable list\"\n\t * ); throw new NoSuchFieldException(\n\t * \"Maven Home variable is not set as a environment variable\"); } }\n\t */\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/util/MSF4JProjectImporter.java",
    "content": "/*\n * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.util;\n\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.DEFAULT_MAIN_CLASS_PROPERTY_VALUE;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.ERROR_TAG;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_MAIN_CLASS_PROPERTY;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_SERVICE_PARENT_ARTIFACT_ID;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.MSF4J_SERVICE_PARENT_GROUP_ID;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.OK_BUTTON;\nimport static org.wso2.developerstudio.msf4j.artifact.util.MSF4JArtifactConstants.POM_FILE;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.Set;\n\nimport org.apache.maven.model.Parent;\nimport org.apache.maven.project.MavenProject;\nimport org.codehaus.plexus.util.xml.pull.XmlPullParserException;\nimport org.eclipse.core.resources.IProject;\nimport org.eclipse.core.resources.IWorkspaceRoot;\nimport org.eclipse.core.resources.ResourcesPlugin;\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.core.runtime.SubProgressMonitor;\nimport org.eclipse.jface.dialogs.MessageDialog;\nimport org.eclipse.m2e.core.MavenPlugin;\nimport org.eclipse.m2e.core.embedder.MavenModelManager;\nimport org.eclipse.m2e.core.project.IMavenProjectImportResult;\nimport org.eclipse.m2e.core.project.IProjectConfigurationManager;\nimport org.eclipse.m2e.core.project.LocalProjectScanner;\nimport org.eclipse.m2e.core.project.MavenProjectInfo;\nimport org.eclipse.m2e.core.project.ProjectImportConfiguration;\nimport org.eclipse.swt.widgets.Shell;\nimport org.eclipse.ui.PlatformUI;\nimport org.wso2.developerstudio.eclipse.maven.util.MavenUtils;\nimport org.wso2.developerstudio.msf4j.artifact.model.MSF4JProjectModel;\n\npublic class MSF4JProjectImporter {\n\n\tpublic void importMSF4JProject(MSF4JProjectModel msf4jProjectModel, String projectName, File pomFile,\n\t\t\tIProgressMonitor monitor) throws CoreException {\n\t\tString operationText;\n\t\tSet<MavenProjectInfo> projectSet = null;\n\t\tif (pomFile.exists()) {\n\n\t\t\tIProjectConfigurationManager configurationManager = MavenPlugin.getProjectConfigurationManager();\n\t\t\tMavenModelManager mavenModelManager = MavenPlugin.getMavenModelManager();\n\t\t\tLocalProjectScanner scanner = new LocalProjectScanner(\n\t\t\t\t\tResourcesPlugin.getWorkspace().getRoot().getLocation().toFile(), //\n\t\t\t\t\tprojectName, false, mavenModelManager);\n\t\t\toperationText = \"Scanning maven project.\";\n\t\t\tmonitor.subTask(operationText);\n\t\t\ttry {\n\t\t\t\tscanner.run(new SubProgressMonitor(monitor, 15));\n\t\t\t\tprojectSet = configurationManager.collectProjects(scanner.getProjects());\n\t\t\t\tfor (MavenProjectInfo projectInfo : projectSet) {\n\t\t\t\t\tif (projectInfo != null) {\n\t\t\t\t\t\tsaveMavenParentInfo(projectInfo);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tProjectImportConfiguration configuration = new ProjectImportConfiguration();\n\t\t\t\toperationText = \"importing maven project.\";\n\t\t\t\tmonitor.subTask(operationText);\n\t\t\t\tif (projectSet != null && !projectSet.isEmpty()) {\n\t\t\t\t\tList<IMavenProjectImportResult> importResults = configurationManager.importProjects(projectSet,\n\t\t\t\t\t\t\tconfiguration, new SubProgressMonitor(monitor, 60));\n\t\t\t\t}\n\t\t\t} catch (InterruptedException | IOException | XmlPullParserException e) {\n\t\t\t\tShell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();\n\t\t\t\tMessageDialog errorDialog = new MessageDialog(shell, ERROR_TAG, null,\n\t\t\t\t\t\t\"Unable to import the project, Error occurred while importing the generated project.\",\n\t\t\t\t\t\tMessageDialog.ERROR, new String[] { OK_BUTTON }, 0);\n\t\t\t\terrorDialog.open();\n\t\t\t}\n\n\t\t} else {\n\t\t}\n\t}\n\n\tprivate void saveMavenParentInfo(MavenProjectInfo projectInfo) throws IOException, XmlPullParserException {\n\t\tFile mavenProjectPomLocation = projectInfo.getPomFile();// project.getFile(POM_FILE).getLocation().toFile();\n\t\tMavenProject mavenProject = null;\n\t\tmavenProject = MavenUtils.getMavenProject(mavenProjectPomLocation);\n\t\tParent msf4jParent = new Parent();\n\t\tmsf4jParent.setGroupId(MSF4J_SERVICE_PARENT_GROUP_ID);\n\t\tmsf4jParent.setArtifactId(MSF4J_SERVICE_PARENT_ARTIFACT_ID);\n\t\tmsf4jParent.setVersion(MSF4JArtifactConstants.getMSF4JServiceParentVersion());\n\t\tmavenProject.getModel().setParent(msf4jParent);\n\n\t\tProperties generatedProperties = mavenProject.getModel().getProperties();\n\t\tgeneratedProperties.clear();\n\n\t\tmavenProject.getModel().addProperty(MSF4J_MAIN_CLASS_PROPERTY, DEFAULT_MAIN_CLASS_PROPERTY_VALUE);\n\t\tMavenUtils.saveMavenProject(mavenProject, mavenProjectPomLocation);\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/org.wso2.developerstudio.msf4j.artifact/src/org/wso2/developerstudio/msf4j/artifact/validators/MSF4JArtifactFieldController.java",
    "content": "/*\n * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\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\npackage org.wso2.developerstudio.msf4j.artifact.validators;\n\nimport java.io.File;\n\nimport org.wso2.developerstudio.eclipse.platform.core.exception.FieldValidationException;\nimport org.wso2.developerstudio.eclipse.platform.core.model.AbstractFieldController;\nimport org.wso2.developerstudio.eclipse.platform.core.project.model.ProjectDataModel;\nimport org.wso2.developerstudio.eclipse.platform.ui.validator.CommonFieldValidator;\n\npublic class MSF4JArtifactFieldController extends AbstractFieldController {\n\n\t@Override\n\tpublic void validate(String modelProperty, Object value, ProjectDataModel model) throws FieldValidationException {\n\t\tif (modelProperty.equals(\"project.name\")) {\n\t\t\tCommonFieldValidator.validateProjectField(value);\n\t\t} else if (modelProperty.equals(\"service.class.package.name\")) {\n\t\t\tCommonFieldValidator.validateJavaPackageNameField(value);\n\t\t} else if (modelProperty.equals(\"swagger.file\")) {\n\t\t\tif (value == null) {\n\t\t\t\tthrow new FieldValidationException(\"Specified Swagger file location is invalid\");\n\t\t\t}\n\t\t\tFile importFile = (File) value;\n\t\t\tif (!importFile.exists()) {\n\t\t\t\tthrow new FieldValidationException(\"Specified Swagger file doesn't exist\");\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "tooling/plugins/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>msf4j-tool-parent</artifactId>\n    \t<version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <artifactId>wso2-developerstudio-msf4j-plugins</artifactId>\n    <packaging>pom</packaging>\n    <name>WSO2 MSF4J Tooling Plugins</name>\n  \n    <modules>\n   \t<module>org.wso2.developerstudio.msf4j.artifact</module>\n    </modules>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-eclipse-plugin</artifactId>\n                <version>2.10</version>\n                <configuration>\n                    <projectnatures>\n                        <projectnature>org.eclipse.jdt.core.javanature</projectnature>\n                        <projectnature>org.eclipse.pde.PluginNature</projectnature>\n                    </projectnatures>\n                    <buildcommands>\n                        <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>\n                        <buildcommand>org.eclipse.pde.ManifestBuilder</buildcommand>\n                        <buildcommand>org.eclipse.pde.SchemaBuilder</buildcommand>\n                    </buildcommands>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>    \n\n\n</project>\n"
  },
  {
    "path": "tooling/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>org.wso2.developerstudio.msf4j</groupId>\n    <artifactId>msf4j-tool-parent</artifactId>\n    <version>2.0.0</version>\n    <packaging>pom</packaging>\n\n    <name>MSF4J Tool</name>\n\n    <modules>\n        <module>plugins</module>\n        <module>features</module>\n        <module>repository</module>\n    </modules>\n\n    <repositories>\n        <repository>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n            <id>Eclipse-p2-repo</id>\n            <url>http://download.eclipse.org/releases/mars/</url>\n            <layout>p2</layout>\n        </repository>\n        <repository>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n            <id>Eclipse-kernel-p2</id>\n            <url>http://product-dist.wso2.com/p2/developer-studio-kernel/4.1.0/kernel/releases/</url>\n            <layout>p2</layout>\n        </repository>\n        <repository>\n            <releases>\n                <enabled>true</enabled>\n                <updatePolicy>daily</updatePolicy>\n                <checksumPolicy>ignore</checksumPolicy>\n            </releases>\n            <id>DevS-Platform-p2-releases-Repository</id>\n            <url>http://builder1.us1.wso2.org/~developerstudio/developer-studio-kernel/4.1.0/platform-bundles/releases/</url>\n            <layout>p2</layout>\n        </repository>\n    </repositories>\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.eclipse.tycho</groupId>\n                <artifactId>tycho-maven-plugin</artifactId>\n                <version>0.23.0</version>\n                <extensions>true</extensions>\n            </plugin>\n            <plugin>\n                <groupId>org.eclipse.tycho</groupId>\n                <artifactId>tycho-source-plugin</artifactId>\n                <version>0.23.0</version>\n                <executions>\n                    <execution>\n                        <id>plugin-source</id>\n                        <goals>\n                            <goal>plugin-source</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.eclipse.tycho</groupId>\n                <artifactId>target-platform-configuration</artifactId>\n                <version>0.23.0</version>\n                <configuration>\n                    <resolver>p2</resolver>\n                    <environments>\n                        <environment>\n                            <os>linux</os>\n                            <ws>gtk</ws>\n                            <arch>x86</arch>\n                        </environment>\n                        <environment>\n                            <os>linux</os>\n                            <ws>gtk</ws>\n                            <arch>x86_64</arch>\n                        </environment>\n                        <environment>\n                            <os>win32</os>\n                            <ws>win32</ws>\n                            <arch>x86</arch>\n                        </environment>\n                        <environment>\n                            <os>win32</os>\n                            <ws>win32</ws>\n                            <arch>x86_64</arch>\n                        </environment>\n                        <environment>\n                            <os>macosx</os>\n                            <ws>cocoa</ws>\n                            <arch>x86</arch>\n                        </environment>\n                        <environment>\n                            <os>macosx</os>\n                            <ws>cocoa</ws>\n                            <arch>x86_64</arch>\n                        </environment>\n                    </environments>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-release-plugin</artifactId>\n                <configuration>\n                    <preparationGoals>clean install</preparationGoals>\n                    <autoVersionSubmodules>false</autoVersionSubmodules>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "tooling/repository/composite/category.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<site>\n   <category-def name=\"org.wso2.developerstudio.msf4j.feature.category\" label=\"MSF4J Tool\">\n\t   <description>\n\t\tThis is the MSF4J Tools Feature for the Developer Studio. This provides\n          tooling support for WSO2 MSF4J Artifact creation with Developer Studio.\n\t   </description>\n   </category-def>\n\n   <!-- MSS prodcut feature (itself)-->\n   <feature url=\"features/org.wso2.developerstudio.msf4j.feature_2.0.0.qualifier.jar\" id=\"org.wso2.developerstudio.msf4j.feature\" version=\"2.0.0.qualifier\">\n      <category name=\"org.wso2.developerstudio.msf4j.feature.category\"/>\n   </feature>\n   \n   <!-- Kernel Features and category-->\t\n <feature id=\"org.wso2.developerstudio.kernel.feature\" version=\"0.0.0\">\n      <category name=\"org.wso2.developerstudio.msf4j.feature.category\"/>\n </feature>\n <feature id=\"org.wso2.developerstudio.kernel.wso2plugins.default.samples.feature\" version=\"0.0.0\">\n      <category name=\"org.wso2.developerstudio.msf4j.feature.category\"/>\n   </feature>\n <feature id=\"org.wso2.developerstudio.kernel.utils.feature\" version=\"0.0.0\">\n      <category name=\"org.wso2.developerstudio.msf4j.feature.category\"/>\n   </feature>\n <feature id=\"org.wso2.developerstudio.platform.libraries.feature\" version=\"0.0.0\">\n      <category name=\"org.wso2.developerstudio.msf4j.feature.category\"/>\n   </feature>\n</site>\n"
  },
  {
    "path": "tooling/repository/composite/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>wso2-developer-studio-msf4j-tool-p2-parent</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>wso2-developer-studio-msf4j-tool-p2-composite</artifactId>\n    <packaging>eclipse-repository</packaging>\n    <name>MSF4J Composite Repository</name>\n</project>\n"
  },
  {
    "path": "tooling/repository/main/category.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<site>\n   <feature url=\"features/org.wso2.developerstudio.msf4j.feature_2.0.0.qualifier.jar\" id=\"org.wso2.developerstudio.msf4j.feature\" version=\"2.0.0.qualifier\">\n      <category name=\"org.wso2.developerstudio.msf4j\"/>\n   </feature>\n   <category-def name=\"org.wso2.developerstudio.msf4j\" label=\"MSF4J Tool\"/>\n</site>\n"
  },
  {
    "path": "tooling/repository/main/pom.xml",
    "content": "<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>wso2-developer-studio-msf4j-tool-p2-parent</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>wso2-developer-studio-msf4j-tool-p2-main</artifactId>\n    <packaging>eclipse-repository</packaging>\n\n    <name>MSF4J Main Repository</name>\n</project>\n"
  },
  {
    "path": "tooling/repository/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2016, WSO2 Inc. (http://wso2.com) All Rights Reserved.\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<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>org.wso2.developerstudio.msf4j</groupId>\n        <artifactId>msf4j-tool-parent</artifactId>\n        <version>2.0.0</version>\n        <relativePath>../pom.xml</relativePath>\n    </parent>\n    <artifactId>wso2-developer-studio-msf4j-tool-p2-parent</artifactId>\n    <packaging>pom</packaging>\n    <name>WSO2 Developer Studio - MSF4J-Tools P2 Repositories</name>\n    <url>http://wso2.org</url>\n    <modules>\n\t<module>main</module>\n\t<module>composite</module>\n    </modules>\n</project>\n\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/ApiException.mustache",
    "content": "package {{apiPackage}};\n\n{{>generatedAnnotation}}\npublic class ApiException extends Exception{\n\tprivate int code;\n\tpublic ApiException (int code, String msg) {\n\t\tsuper(msg);\n\t\tthis.code = code;\n\t}\n}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/ApiOriginFilter.mustache",
    "content": "package {{apiPackage}};\n\nimport java.io.IOException;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletResponse;\n\n{{>generatedAnnotation}}\npublic class ApiOriginFilter implements javax.servlet.Filter {\n\tpublic void doFilter(ServletRequest request, ServletResponse response,\n\t\t\tFilterChain chain) throws IOException, ServletException {\n\t\tHttpServletResponse res = (HttpServletResponse) response;\n\t\tres.addHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\tres.addHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, PUT\");\n\t\tres.addHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\t\tchain.doFilter(request, response);\n\t}\n\n\tpublic void destroy() {}\n\n\tpublic void init(FilterConfig filterConfig) throws ServletException {}\n}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/ApiResponseMessage.mustache",
    "content": "package {{apiPackage}};\n\nimport javax.xml.bind.annotation.XmlTransient;\n\n@javax.xml.bind.annotation.XmlRootElement\n{{>generatedAnnotation}}\npublic class ApiResponseMessage {\n\tpublic static final int ERROR = 1;\n\tpublic static final int WARNING = 2;\n\tpublic static final int INFO = 3;\n\tpublic static final int OK = 4;\n\tpublic static final int TOO_BUSY = 5;\n\n\tint code;\n\tString type;\n\tString message;\n\t\n\tpublic ApiResponseMessage(){}\n\t\n\tpublic ApiResponseMessage(int code, String message){\n\t\tthis.code = code;\n\t\tswitch(code){\n\t\tcase ERROR:\n\t\t\tsetType(\"error\");\n\t\t\tbreak;\n\t\tcase WARNING:\n\t\t\tsetType(\"warning\");\n\t\t\tbreak;\n\t\tcase INFO:\n\t\t\tsetType(\"info\");\n\t\t\tbreak;\n\t\tcase OK:\n\t\t\tsetType(\"ok\");\n\t\t\tbreak;\n\t\tcase TOO_BUSY:\n\t\t\tsetType(\"too busy\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsetType(\"unknown\");\n\t\t\tbreak;\n\t\t}\n\t\tthis.message = message;\n\t}\n\n\t@XmlTransient\n\tpublic int getCode() {\n\t\treturn code;\n\t}\n\n\tpublic void setCode(int code) {\n\t\tthis.code = code;\n\t}\n\n\tpublic String getType() {\n\t\treturn type;\n\t}\n\n\tpublic void setType(String type) {\n\t\tthis.type = type;\n\t}\n\n\tpublic String getMessage() {\n\t\treturn message;\n\t}\n\n\tpublic void setMessage(String message) {\n\t\tthis.message = message;\n\t}\n}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/NotFoundException.mustache",
    "content": "package {{apiPackage}};\n\n{{>generatedAnnotation}}\npublic class NotFoundException extends ApiException {\n\tprivate int code;\n\tpublic NotFoundException (int code, String msg) {\n\t\tsuper(code, msg);\n\t\tthis.code = code;\n\t}\n}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/README.mustache",
    "content": "# Swagger generated server\n\n## Overview\nThis server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the \n[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub.  This\nis an example of building a swagger-enabled JAX-RS server.\n\nThis example uses the [JAX-RS](https://jax-rs-spec.java.net/) framework.\n\nTo run the server, please execute the following:\n\n```\nmvn clean package jetty:run\n```\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/api.mustache",
    "content": "package {{package}};\n\nimport {{modelPackage}}.*;\nimport {{package}}.{{classname}}Service;\nimport {{package}}.factories.{{classname}}ServiceFactory;\n\n\n{{#imports}}import {{import}};\n{{/imports}}\n\nimport java.util.List;\n\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.*;\n\nimport org.wso2.msf4j.MicroservicesRunner;\n\n@Path(\"/{{baseName}}\")\n{{#hasConsumes}}@Consumes({ {{#consumes}}\"{{mediaType}}\"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}\n{{#hasProduces}}@Produces({ {{#produces}}\"{{mediaType}}\"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}\n\n{{>generatedAnnotation}}\n{{#operations}}\npublic class {{classname}}  {\n\n   private final {{classname}}Service delegate = {{classname}}ServiceFactory.get{{classname}}();\n\n   public static void main(String[] args) {\n       new MicroservicesRunner().deploy(new {{classname}}()).start();\n    }\n\n{{#operation}}\n    @{{httpMethod}}\n    {{#subresourceOperation}}@Path(\"{{path}}\"){{/subresourceOperation}}\n    {{#hasConsumes}}@Consumes({ {{#consumes}}\"{{mediaType}}\"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}\n    {{#hasProduces}}@Produces({ {{#produces}}\"{{mediaType}}\"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}\n   \n    public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},\n    {{/hasMore}}{{/allParams}}) {\n        return delegate.{{nickname}}({{#allParams}}{{#isFile}}fileDetail{{/isFile}}{{^isFile}}{{paramName}}{{/isFile}}{{#hasMore}},{{/hasMore}}{{/allParams}});\n    }\n{{/operation}}\n}\n{{/operations}}\n\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/apiService.mustache",
    "content": "package {{package}};\n\nimport {{package}}.*;\nimport {{modelPackage}}.*;\n\n{{#imports}}import {{import}};\n{{/imports}}\n\nimport java.util.List;\n\nimport java.io.InputStream;\n\nimport javax.ws.rs.core.Response;\n\n{{>generatedAnnotation}}\n{{#operations}}\npublic abstract class {{classname}}Service {\n  {{#operation}}\n      public abstract Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{#hasMore}},{{/hasMore}}{{/allParams}});\n  {{/operation}}\n}\n{{/operations}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/apiServiceFactory.mustache",
    "content": "package {{package}}.factories;\n\nimport {{package}}.{{classname}}Service;\nimport {{package}}.impl.{{classname}}ServiceImpl;\n\n{{>generatedAnnotation}}\npublic class {{classname}}ServiceFactory {\n\n   private final static {{classname}}Service service = new {{classname}}ServiceImpl();\n\n   public static {{classname}}Service get{{classname}}()\n   {\n      return service;\n   }\n}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/apiServiceImpl.mustache",
    "content": "package {{package}}.impl;\n\nimport {{package}}.*;\nimport {{modelPackage}}.*;\n\n{{#imports}}import {{import}};\n{{/imports}}\n\nimport java.util.List;\n\nimport java.io.InputStream;\n\nimport javax.ws.rs.core.Response;\n\n{{>generatedAnnotation}}\n{{#operations}}\npublic class {{classname}}ServiceImpl extends {{classname}}Service {\n  {{#operation}}\n      @Override\n      public Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}){\n      // do some magic!\n      return Response.ok().entity(\"magic!\").build();\n  }\n  {{/operation}}\n}\n{{/operations}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/bodyParams.mustache",
    "content": "{{#isBodyParam}}@BodyParam(\"{{baseName}}\") {{{dataType}}} {{paramName}}{{/isBodyParam}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/formParams.mustache",
    "content": "{{#isFormParam}}{{#notFile}}@FormParam(\"{{paramName}}\")  {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}  @FormDataParam(\"file\") InputStream inputStream,\n      @FormDataParam(\"file\") FormDataContentDisposition fileDetail{{/isFile}}{{/isFormParam}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/generatedAnnotation.mustache",
    "content": "@javax.annotation.Generated(value = \"{{generatorClass}}\", date = \"{{generatedDate}}\")"
  },
  {
    "path": "tooling/swagger-mustache/1.4/headerParams.mustache",
    "content": "{{#isHeaderParam}}@HeaderParam(\"{{baseName}}\") {{{dataType}}} {{paramName}}{{/isHeaderParam}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/model.mustache",
    "content": "package {{package}};\n\n{{#imports}}import {{import}};\n{{/imports}}\n\n{{#models}}\n\n{{#model}}{{#unescapedDescription}}\n/**\n * {{unescapedDescription}}\n **/{{/unescapedDescription}}\n{{>generatedAnnotation}}\npublic class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {\n  {{#vars}}{{#isEnum}}\n  public enum {{datatypeWithEnum}} {\n    {{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}\n  };\n  private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}}\n  private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}}\n\n  {{#vars}}\n  /**{{#unescapedDescription}}\n   * {{{unescapedDescription}}}{{/unescapedDescription}}{{#minimum}}\n   * minimum: {{minimum}}{{/minimum}}{{#maximum}}\n   * maximum: {{maximum}}{{/maximum}}\n   **/\n  public {{{datatypeWithEnum}}} {{getter}}() {\n    return {{name}};\n  }\n  public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {\n    this.{{name}} = {{name}};\n  }\n\n  {{/vars}}\n\n  @Override\n  public String toString()  {\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"class {{classname}} {\\n\");\n    {{#parent}}sb.append(\"  \" + super.toString()).append(\"\\n\");{{/parent}}\n    {{#vars}}sb.append(\"  {{name}}: \").append({{name}}).append(\"\\n\");\n    {{/vars}}sb.append(\"}\\n\");\n    return sb.toString();\n  }\n}\n{{/model}}\n{{/models}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/pathParams.mustache",
    "content": "{{#isPathParam}}@PathParam(\"{{baseName}}\") {{{dataType}}} {{paramName}}{{/isPathParam}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/pom.mustache",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>{{groupId}}</groupId>\n  <artifactId>{{artifactId}}</artifactId>\n  <packaging>jar</packaging>\n  <name>{{artifactId}}</name>\n  <version>{{artifactVersion}}</version>\n       <dependencies>\n\t\t<dependency>\n\t\t\t<groupId>io.swagger</groupId>\n\t\t\t<artifactId>swagger-annotations</artifactId>\n\t\t\t<version>1.5.0</version>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/queryParams.mustache",
    "content": "{{#isQueryParam}}@QueryParam(\"{{baseName}}\") {{{dataType}}} {{paramName}}{{/isQueryParam}}\n"
  },
  {
    "path": "tooling/swagger-mustache/1.4/returnTypes.mustache",
    "content": "{{#returnContainer}}{{#isMapContainer}}Map<String, {{{returnType}}}>{{/isMapContainer}}{{#isListContainer}}List<{{{returnType}}}>{{/isListContainer}}{{/returnContainer}}{{^returnContainer}}{{{returnType}}}{{/returnContainer}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/serviceBodyParams.mustache",
    "content": "{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/serviceFormParams.mustache",
    "content": "{{#isFormParam}}{{#notFile}}{{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}FormDataContentDisposition fileDetail{{/isFile}}{{/isFormParam}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/serviceHeaderParams.mustache",
    "content": "{{#isHeaderParam}}{{{dataType}}} {{paramName}}{{/isHeaderParam}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/servicePathParams.mustache",
    "content": "{{#isPathParam}}{{{dataType}}} {{paramName}}{{/isPathParam}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/serviceQueryParams.mustache",
    "content": "{{#isQueryParam}}{{{dataType}}} {{paramName}}{{/isQueryParam}}"
  },
  {
    "path": "tooling/swagger-mustache/1.4/web.mustache",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<web-app version=\"2.4\" xmlns=\"http://java.sun.com/xml/ns/j2ee\"\n  xmlns:j2ee=\"http://java.sun.com/xml/ns/j2ee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://java.sun.com/xml/ns/j2ee    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd\">\n\n  <servlet>\n    <servlet-name>jersey</servlet-name>\n    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>\n    <init-param>\n      <param-name>com.sun.jersey.config.property.packages</param-name>\n      <param-value>io.swagger.jaxrs.json;io.swagger.jaxrs.listing;{{apiPackage}}</param-value>\n    </init-param>\n    <init-param>\n      <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>\n      <param-value>com.sun.jersey.api.container.filter.PostReplaceFilter</param-value>\n    </init-param>\n    <init-param>\n      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>\n      <param-value>true</param-value>\n    </init-param>\n    <load-on-startup>1</load-on-startup>\n  </servlet>\n\n  <servlet>\n    <servlet-name>DefaultJaxrsConfig</servlet-name>\n    <servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>\n    <init-param>\n      <param-name>api.version</param-name>\n      <param-value>1.0.0</param-value>\n    </init-param>\n    <init-param>\n      <param-name>swagger.api.title</param-name>\n      <param-value>{{{title}}}</param-value>\n    </init-param>\n    <init-param>\n      <param-name>swagger.api.basepath</param-name>\n      <param-value>http://localhost:8080</param-value>\n    </init-param>\n    <load-on-startup>2</load-on-startup>\n  </servlet>\n\n  <servlet-mapping>\n    <servlet-name>jersey</servlet-name>\n    <url-pattern>/*</url-pattern>\n  </servlet-mapping>\n  <filter>\n    <filter-name>ApiOriginFilter</filter-name>\n    <filter-class>{{apiPackage}}.ApiOriginFilter</filter-class>\n  </filter>\n  <filter-mapping>\n    <filter-name>ApiOriginFilter</filter-name>\n    <url-pattern>/*</url-pattern>\n  </filter-mapping>\n</web-app>\n"
  },
  {
    "path": "tooling/swagger-mustache/README.md",
    "content": "Please replace the files for the relevant version of the swagger codegen library from the mustache files.\n\nThese files contain changes that are needed to generate the code in the expected format by MSF4J.\n"
  }
]