[
  {
    "path": ".buildscript/deploy_snapshot.sh",
    "content": "#!/bin/bash\n#\n# Deploy a jar, source jar, and javadoc jar to Sonatype's snapshot repo.\n#\n# Adapted from https://coderwall.com/p/9b_lfq and\n# http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/\n\nSLUG=\"serj-lotutovici/moshi-lazy-adapters\"\nBRANCH=\"master\"\n\nset -e\n\nif [ \"$TRAVIS_REPO_SLUG\" != \"$SLUG\" ]; then\n  echo \"Skipping snapshot deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'.\"\nelif [ \"$TRAVIS_PULL_REQUEST\" != \"false\" ]; then\n  echo \"Skipping snapshot deployment: was pull request.\"\nelif [ \"$TRAVIS_BRANCH\" != \"$BRANCH\" ]; then\n  echo \"Skipping snapshot deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'.\"\nelse\n  echo \"Deploying snapshot...\"\n  ./gradlew clean uploadArchives -PnexusUsername=\"$TRAVIS_USER_NAME\" -PnexusPassword=\"$TRAVIS_PASSWORD\"\n  echo \"Snapshot deployed!\"\nfi"
  },
  {
    "path": ".gitignore",
    "content": "# Gradle junk\n.gradle/\nbuild/\nlocal.properties\n\n# Idea junk\n.idea/\n*.iml\nout/\n\n# MacOS junk\n.DS_Store\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: java\n\njdk:\n  - oraclejdk8\n\nscript:\n  - ./gradlew clean check --stacktrace\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n  - .buildscript/deploy_snapshot.sh\n\nenv:\n  global:\n    - secure: \"PD2ZaZxyrpLDq8dsC+JdfkGg7kEPgmhBzqO+zr+ONBuVe+YDLqsTAUF6J6zXoMF6mgBvkalW/v1nRbDvKJBXhGJdrIqPoQ2yhc7nPH1shzUK6WFptsRsPk2+B45M+FmAjlsSHqCjXIcPmRKykCjgjFyR6DVsik2mPA/C8dINwM2LUsD6eKsed79VHjhrpmqBfIKsvSY1saGfqlGmNzYOFHJ8wHfgjBVUlJmzJzWM49gudW8J27zphP59GjAR1/ZHeYAhE+KQEMUfMKtpFUjZiWvE5kNd+4xgUfXh9mRpwA/RuCJhipgzMTBPxHF4WHHC4pIQDJ5/KeF++L6xzweuBheGvOewWvjSWnPpBsEk3YK6X0SI52OcAApsk1KX+8h58ABU/85DObFpxLsAYTNnePWc6f4a1boV/K2f/RTZBp9U15h9z7474BXIZ7t/IFCZgPZp+v5a15CJrjBq/8g1Yi7f0KGj6ax5vctRaQK5pvIasT1Z0bZLWoRO8WWOkatymkUhBT/aPiVm3PbZeqLgp+tljiSzCF6oF7rQDjbCHsNOAr9Y1+SS/bIu0sLXCgQ4Ji4HGDYpub3v6vRWMW5sv23LR9YsgVXXaehZR1k4hScqbscu6/FfYy5N/2h8IeABNZW3mYnR6zmk1VM4uzHcMkD9iJAc07tPsmrxd4aOaNQ=\"\n    - secure: \"fiI2ZFtZ1LRVcZizbbiHCiKrtKkcyzAPZse8quvuB3VumnfqhPTT1hyyRkV3vXP6R6oigdZG67pG2yGvMovHfyMfQfOfTyfyQw/i7xJTTgOkH2NmeTA+SPn/VnZjZPSwyvkDXgxOOjyoa3G7eSTpblzh13247tZppA4ERKyUUmHPDBVL0kktkabQjRltu6vuUT1vLh0j5Lg/A5HRWF22Bkt0NqrmkYbJaDaW40w/f62OonXS8g4LIKolmHFIfhyoMG4Pj1gUAPUl+0mJ6d/CkCYxnRmWSzTvodsYCp+y06e9MXLL95A+2wg/5oUrwOPigwMlWDp0rWgceU9X0wWK6+7I7nWCJb/+Hr+okL/UE62BxnDPWecyvXRsGbXHAx/VXv2dP3f4qi9GMn2NnpgswQZUdFLfBzZTghT9UftaLeUej6rWrnnlEJLr78ZyYPvXVtwXm0oAWH0iA39Nd6OCmV+YIqgnptUzWugHKCbR4/bgs02HvuIfw+bRGEYUshjD3gSZYNYKcuV8TYmFOnQqRXaYm4yosxwX/t6Zp1mH+s6N98OEEYHIwyaQ8hxBKrpAWmVYr0Nzu7rfITNwLkTB2LBHlv3K2zYP8vz8mz3gm5Y6VFEUqbnHLIfLDWw8jy0Q4oZSyzytgrKeQTeI0erku2uOJFzRce6bHmEjRfOLwDM=\"\n\nbranches:\n  except:\n    - gh-pages\n\nnotifications:\n  email: false\n\ncache:\n  directories:\n    - $HOME/.gradle\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "Change Log\n===\n\n2.2 *(02-05-2018)*\n---\n* Usage selectString in FallbackEnumJsonAdapter. (#64)\n* Fix FallbackOnNull naming bug with implicit user locale. (#66)\n\n2.1 *(11-10-2017)*\n---\n* Fix: Forces WrappedJsonAdapter to re-throw all exceptions. (#60)\n\n2.0 *(06-06-2017)*\n---\n* New: Move all adapter factories to their respective annotations. (#47)\n* New: Added `DefaultOnDataMismatchAdapter`. (#54)\n* New: Added `@FilterNulls` annotation and its respective adapter. (#52)\n* New: Added `@LastElement` annotation plus adapter (#50)\n* New: Added `@Transient` annotation and it's respective adapter. (#49)\n* New: Makes `JsonAdapter` for `@Wrapped` more strict. (#45)\n\n* Enhancement: Rely on moshi's resialize nulls functionality. (#46)\n* Enhancement: Use moshi's Types.nextAnnotations() where possible. (#44)\n\n* New: Upgrade to Moshi 1.5.0.\n\n   ```\n   compile 'com.squareup.moshi:moshi:1.5.0'\n   ```\n\n1.3 *(04-01-2017)*\n---\n* New: Added `SerializeOnlyNonEmpty` for all collections and arrays.\n* New: Allow `WrappedJsonAdapter` to fail on un-found value.\n* New: Upgrade to Moshi 1.3.0.\n\n   ```\n   compile 'com.squareup.moshi:moshi:1.3.0'\n   ```\n\n1.2 *(08-11-2016)*\n---\n* New: `@FallbackEnum` annotation and it's respective adapter.\n* New: `@ElementAt` (similar to `@FirstElement` but more powerful) and it's respective adapter.\n* Fix: `@SerializeNulls` adapter now maintains previous writer setting.\n\n1.1 *(17-10-2016)*\n---\n*  New: Rename `@UnwrapJson` to `@Wrapped` annotation and it's respective adapter to `WrappedJsonAdapter`.\n*  New: Allow manual creation of `@Wrapped` annotation via `Wrapped.Factory`.\n*  New: `@SerializeOnly` & `@DeserializeOnly` annotations and their respective adapters.\n*  New: Upgrade to Moshi 1.3.0.\n   \n   ```\n   compile 'com.squareup.moshi:moshi:1.3.0'\n   ```\n*  Fix: Restrict `@Target` for each declared annotation.\n\n1.0 *(14-09-2016)*\n---\n*  Initial release.\n*  Introduce few handy adapters:\n  * **SerializeNullsJsonAdapter** - Instructs moshi to serialize a value even if it's `null`;\n  * **FirstElementJsonAdapter** - Instructs moshi to retrieve only the first element of a list;\n  * **UnwrapJsonAdapter** - Unwraps a json object under the specified path;\n  * **FallbackOnNullJsonAdapter** - Instructs moshi to fallback to a default value in case the json field is `null`.\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 2016 Serj Lotutovici\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "Moshi Lazy Adapters\n===\n\n\n[![Build Status][travis.svg]][travis]\n[![codecov][codecov.svg]][codecov]\n[![Latest Build][latestbuild.svg]][latestbuild]\n[![Android Arsenal][arsenal.svd]][arsenal]\n\nA collection of simple JsonAdapters for [Moshi][moshi].\n \nThis library acts as an extension to Moshi by providing general purpose, yet useful `JsonAdapter`s \n that are not present in the main library. Most provided adapters are linked via specialized \n `JsonQualifier` annotations that alter serialization/deserialization strategies.\n\n##### How To Use It\n\nThis library is **not** forcing any of it's own adapters by default. To leverage from any of\n the provided annotations/adapters add their respective factory to your `Moshi.Builder`:\n\n```java\n// Creates a Moshi instance with an adapter that will handle the @Wrapped annotations.\nMoshi moshi = new Moshi.Builder()\n  .add(Wrapped.ADAPTER_FACTORY)\n  .build();\n```\n\n##### Overall contract\n\nEvery declared annotation/adapter in this library (unless specified in the class's documentation)\n supports adapter composition. Which means that no `JsonAdapter.Factory` will short circuit adapter\n construction on it's own annotation, and instead will delegate to the next adapter returned by\n `Moshi`. Meaning that given the following type declaration:\n \n```java\ninterface WebService {\n  @GET(\"/data\")\n  @Wrapped(path={\"result\", \"data\"}) @FirstElement MyData getData();\n}\n\n```\n\nThe resulting `JsonAdapter` will unwrap a list of `MyData` from the json response and return only \n the first element of that list.\n \nOne **important** concept to keep in mind, that the order of declared annotations in the example \n above **does not have any influence** on the way how the final adapter will be constructed. \n Instead **the order** of the `JsonAdapter.Factory`'s added to the `Moshi` instance is what plays \n a major role in overall behavior. Meaning that in order for the example above to satisfy the \n expected result, one must add the factories in the following order:\n \n```\nMoshi moshi = new Moshi.Builder()\n  .add(Wrapped.ADAPTER_FACTORY)\n  .add(FirstElement.ADAPTER_FACTORY)\n  .build()\n\n```\n\n\nSome Lazy Adapters\n---\n\n### `@Wrapped`\n\nSome apis enjoy wrapping the response object inside other json objects. This creates a lot of inconvenience\n when it comes to consuming the request. The following example contains a list of a users\n favorite pokemon which is wrapped behind two keys:\n \n```json\n{\n  \"favorite_pokemon\": {\n    \"pokemons\": [\n      \"Snorlax\",\n      \"Pikachu\",\n      \"Bulbasaur\",\n      \"Charmander\",\n      \"Squirtle\"\n    ]\n  }\n}\n```\n\nIn the end the consumer is just interested in the names of the pokemon, but the json object forces to create\n a wrapping object, which will contain the list:\n \n```java\nclass FavoritePokemonResponse {\n  FavoritePokemon favorite_pokemon;\n}\n\nclass FavoritePokemon {\n  List<String> pokemons;\n}\n```\n\nA custom adapter would be another option, and `WrappedJsonAdapter` is just the one. By annotating\n the response type with `@Wrapped` and providing the path to the desired list, the need for \n an additional object is dropped:\n\n```java\n// This assumes that Retrofit is used to obtain the response.\ninterface PokemonService {\n  @GET(\"/pokemon/favorite\")\n  @Wrapped({\"favorite_pokemon\", \"pokemons\"}) Call<List<String>> getFavorite();\n}\n```\n\nNo need for a new class, which results in less code and less methods generated by the consumer code. \n You can also annotate any field in your response entity and the same rules will apply.\n\n\n### `@FallbackOnNull`\n\nPrimitives are simple and safe. Primitives have also a smaller memory footprint. Some apis may return\n `null` for values that are normally processed as primitives. A safe alternative would be to use\n their boxed counterparts, but that would result in redundant boxing and unboxing. By annotating \n any primitive field with `@FallbackOnNull` the consumer can specify a default value for the field, \n in case it's json representation is null.\n\n```json\n[\n  {\n    \"name\": \"Pikachu\",\n    \"number_of_wins\": 1\n  },\n  {\n    \"name\": \"Magikarp\",\n    \"number_of_wins\": null\n  } \n]\n```\n\nThe json above contains a list of pokemon of a user with their names and the number of wins the \n respective pokemon has obtained during it's trainings of fights. Notice that the 'Magikarp' pokemon\n has `null` wins. Normally the representing POJO would declare the filed as `Integer`, but #perfmatters.\n With `@FallbackOnNull` the `Pokemon` object can be declared as:\n\n```java\nclass Pokemon {\n  String name;\n  @FallbackOnNull int number_of_wins;\n}\n```\n\nIf the incoming value would be `null` the `number_of_wins` field would default to `Integer.MIN_VALUE`,\n this can be altered by providing an alternative fallback:\n\n```java\n  @FallbackOnNull(fallbackInt = -1) int number_of_wins;\n```\n\nSee [FallbackOnNull's documentation](../master/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.java) \n for a full reference.\n\n\nList of provided Adapters\n---\n\n* **DefaultOnDataMismatchAdapter** - Allows the consumer to provided a default fallback value for any type.\n* **SerializeNulls (annotation)** - Serializes a value even if it's `null`;\n* **FirstElement (annotation)** - Deserializes only the first element of a list.\n* **LastElement (annotation)** - Deserializes only the last element of a list.\n* **ElementAt (annotation)** - Deserializes an element from a specified position of a list.\n* **FallbackOnNull (annotation)** - Fallbacks to a default value in case the json field is `null`.\n* **FallbackEnum (annotation)** - Fallbacks to a default enum value if the parsed value can not be matched to an existing one.\n* **Wrapped (annotation)** - Unwraps a json object under the specified path when parsing, and wraps it when serializing to json.\n* **SerializeOnly (annotation)** - Only serializes the annotated field, and ignores it during deserialization.\n* **DeserializeOnly (annotation)** - Only deserializes the annotated field, and ignores it during serialization.\n* **Transient (annotation)** - (Targets methods only) indicates that a field should be ignored for serialization/deserialization.\n* **SerializeOnlyNonEmpty (annotation)** - Will serialize a collection or array only if it contains at-least one value.\n\nDownload\n---\n\nDownload [the latest JAR][dl] or depend via Maven:\n```xml\n<dependency>\n  <groupId>com.serjltt.moshi</groupId>\n  <artifactId>moshi-lazy-adapters</artifactId>\n  <version>x.y</version>\n</dependency>\n```\nor Gradle:\n```groovy\ncompile 'com.serjltt.moshi:moshi-lazy-adapters:x.y'\n```\n\nSnapshots of the development version are available in [Sonatype's `snapshots` repository][sonatype].\n\nLicense\n===\n\n    Copyright 2017 Serj Lotutovici\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF 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 [moshi]: https://github.com/square/moshi\n [travis]: https://travis-ci.org/serj-lotutovici/moshi-lazy-adapters\n [travis.svg]: https://travis-ci.org/serj-lotutovici/moshi-lazy-adapters.svg?branch=master\n [codecov]: https://codecov.io/gh/serj-lotutovici/moshi-lazy-adapters\n [codecov.svg]: https://codecov.io/gh/serj-lotutovici/moshi-lazy-adapters/branch/master/graph/badge.svg\n [latestbuild]: http://search.maven.org/#search%7Cga%7C1%7Ccom.serjltt.moshi\n [latestbuild.svg]: https://img.shields.io/maven-central/v/com.serjltt.moshi/moshi-lazy-adapters.svg\n [arsenal.svd]: https://img.shields.io/badge/Android%20Arsenal-Moshi%20Lazy%20Adapters-orange.svg?style=flat\n [arsenal]: http://android-arsenal.com/details/1/4481\n [sonatype]: https://oss.sonatype.org/content/repositories/snapshots/com/serjltt/moshi/\n [dl]: https://search.maven.org/remote_content?g=com.serjltt.moshi&a=moshi-lazy-adapters&v=LATEST\n"
  },
  {
    "path": "build.gradle",
    "content": "buildscript {\n  repositories {\n    mavenCentral()\n    maven { url 'https://jitpack.io' }\n  }\n\n  // Needed to use auto-value-moshi in tests\n  dependencies {\n    classpath 'com.github.tbroyer:gradle-apt-plugin:v0.12'\n  }\n}\n\nrepositories {\n  mavenCentral()\n}\n\napply plugin: 'net.ltgt.apt-idea'\napply plugin: 'java'\n\napply from: rootProject.file('dependencies.gradle')\napply from: rootProject.file('checkstyle.gradle')\napply from: rootProject.file('jacoco.gradle')\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n\nsourceCompatibility = javaVersion\ntargetCompatibility = javaVersion\n\nsourceSets {\n  // Setup source sets to split unit and integration tests\n  test {\n    java.srcDirs = ['src/unitTest/java', 'src/integrationTest/java']\n    resources.srcDirs = ['src/unitTest/resources', 'src/integrationTest/resources']\n  }\n}\n\ndependencies {\n  compile moshi\n\n  testCompile junit\n  testCompile assertJ\n  testCompile privateConstructorChecker\n  testCompile retrofit\n  testCompile retrofitMoshiConverter\n  testCompile mockWebServer\n  testCompile rxJava2\n\n  // This is needed to test integration with auto-value-moshi\n  testCompileOnly autoValueMoshiAnnotations\n  testCompileOnly autoValueAnnotations\n  testApt autoValueMoshi\n}\n"
  },
  {
    "path": "checkstyle.gradle",
    "content": "apply plugin: 'checkstyle'\n\ncheckstyle {\n  toolVersion '6.0'\n}\n\ntask checkstyle(type: Checkstyle) {\n  configFile rootProject.file('config/checkstyle/checkstyle.xml')\n  source = ['src']\n  ignoreFailures false\n  showViolations true\n  include '**/*.java'\n\n  classpath = files()\n  configProperties = [\n          'proj.module.dir'      : projectDir.absolutePath,\n          'checkstyle.cache.file': './build/cache/checkstyle-cache'\n  ]\n}\n\nafterEvaluate {\n  if (project.tasks.findByName('check')) {\n    check.dependsOn('checkstyle')\n  }\n}\n"
  },
  {
    "path": "config/checkstyle/checkstyle.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\"\n    \"http://www.puppycrawl.com/dtds/configuration_1_2.dtd\">\n\n<module name=\"Checker\">\n  <!--module name=\"NewlineAtEndOfFile\"/-->\n  <module name=\"FileLength\"/>\n  <module name=\"FileTabCharacter\"/>\n\n  <!-- Trailing spaces -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"\\s+$\"/>\n    <property name=\"message\" value=\"Line has trailing spaces.\"/>\n  </module>\n\n  <!-- Space after 'for' and 'if' -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"^\\s*(for|if)[^ ]\"/>\n    <property name=\"message\" value=\"Space needed before opening parenthesis.\"/>\n  </module>\n\n  <!-- For each spacing -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"^\\s*for \\(.*?([^ ]:|:[^ ])\"/>\n    <property name=\"message\" value=\"Space needed around ':' character.\"/>\n  </module>\n\n  <module name=\"TreeWalker\">\n    <!--<property name=\"cacheFile\" value=\"${checkstyle.cache.file}\"/>-->\n\n    <!-- Checks for Javadoc comments.                     -->\n    <!-- See http://checkstyle.sf.net/config_javadoc.html -->\n    <!--module name=\"JavadocMethod\"/-->\n    <!--module name=\"JavadocType\"/-->\n    <!--module name=\"JavadocVariable\"/-->\n    <!--module name=\"JavadocStyle\"/-->\n\n\n    <!-- Checks for Naming Conventions.                  -->\n    <!-- See http://checkstyle.sf.net/config_naming.html -->\n    <module name=\"ConstantName\"/>\n    <module name=\"LocalFinalVariableName\"/>\n    <module name=\"LocalVariableName\"/>\n    <module name=\"MemberName\"/>\n    <module name=\"MethodName\">\n      <property name=\"format\" value=\"^[a-z][a-zA-Z0-9_]*$\"/>\n    </module>\n    <module name=\"PackageName\"/>\n    <module name=\"ParameterName\"/>\n    <module name=\"StaticVariableName\"/>\n    <module name=\"TypeName\">\n      <property name=\"format\" value=\"^[A-Z][a-zA-Z0-9_]*$\"/>\n    </module>\n\n\n    <!-- Checks for imports                              -->\n    <!-- See http://checkstyle.sf.net/config_import.html -->\n    <module name=\"AvoidStarImport\"/>\n    <module name=\"IllegalImport\"/>\n    <module name=\"RedundantImport\"/>\n    <module name=\"UnusedImports\">\n      <property name=\"processJavadoc\" value=\"true\"/>\n    </module>\n\n\n    <!-- Checks for Size Violations.                    -->\n    <!-- See http://checkstyle.sf.net/config_sizes.html -->\n    <module name=\"LineLength\">\n      <property name=\"max\" value=\"100\"/>\n    </module>\n    <!--<module name=\"MethodLength\"/>-->\n    <!--<module name=\"ParameterNumber\"/>-->\n\n\n    <!-- Checks for whitespace                               -->\n    <!-- See http://checkstyle.sf.net/config_whitespace.html -->\n    <module name=\"GenericWhitespace\"/>\n    <module name=\"EmptyForIteratorPad\"/>\n    <module name=\"MethodParamPad\"/>\n    <!--<module name=\"NoWhitespaceAfter\"/>-->\n    <module name=\"NoWhitespaceBefore\"/>\n    <module name=\"OperatorWrap\"/>\n    <module name=\"ParenPad\"/>\n    <module name=\"TypecastParenPad\"/>\n    <module name=\"WhitespaceAfter\"/>\n    <module name=\"WhitespaceAround\"/>\n\n\n    <!-- Modifier Checks                                    -->\n    <!-- See http://checkstyle.sf.net/config_modifiers.html -->\n    <!--module name=\"ModifierOrder\"/-->\n    <module name=\"RedundantModifier\"/>\n\n\n    <!-- Checks for blocks. You know, those {}'s         -->\n    <!-- See http://checkstyle.sf.net/config_blocks.html -->\n    <module name=\"AvoidNestedBlocks\"/>\n    <!--<module name=\"EmptyBlock\"/>-->\n    <module name=\"LeftCurly\"/>\n    <module name=\"NeedBraces\">\n      <property name=\"tokens\" value=\"LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE\"/>\n    </module>\n    <module name=\"RightCurly\"/>\n\n\n    <!-- Checks for common coding problems               -->\n    <!-- See http://checkstyle.sf.net/config_coding.html -->\n    <!--<module name=\"AvoidInlineConditionals\"/>-->\n    <module name=\"CovariantEquals\"/>\n    <!--<module name=\"DoubleCheckedLocking\"/>-->\n    <module name=\"EmptyStatement\"/>\n    <module name=\"EqualsAvoidNull\"/>\n    <module name=\"EqualsHashCode\"/>\n    <!--<module name=\"HiddenField\"/>-->\n    <module name=\"IllegalInstantiation\"/>\n    <module name=\"InnerAssignment\"/>\n    <!--<module name=\"MagicNumber\"/>-->\n    <module name=\"MissingSwitchDefault\"/>\n    <module name=\"RedundantThrows\"/>\n    <module name=\"SimplifyBooleanExpression\"/>\n    <module name=\"SimplifyBooleanReturn\"/>\n\n    <!-- Checks for class design                         -->\n    <!-- See http://checkstyle.sf.net/config_design.html -->\n    <!--module name=\"DesignForExtension\"/-->\n    <!--module name=\"FinalClass\"/-->\n    <module name=\"HideUtilityClassConstructor\"/>\n    <module name=\"InterfaceIsType\"/>\n    <!--<module name=\"VisibilityModifier\"/>-->\n\n\n    <!-- Miscellaneous other checks.                   -->\n    <!-- See http://checkstyle.sf.net/config_misc.html -->\n    <module name=\"ArrayTypeStyle\"/>\n    <!--module name=\"FinalParameters\"/-->\n    <!--<module name=\"TodoComment\"/>-->\n    <module name=\"UpperEll\"/>\n\n    <!-- Custom checks for JUnit's Assert usage.       -->\n    <!-- From https://gist.github.com/vanniktech/e8117fb245e804971a83288c1498c9d7 -->\n    <module name=\"RegexpSinglelineJava\">\n      <property name=\"format\" value=\"import static org\\.junit\\.Assert\\.assertEquals;\"/>\n      <property name=\"message\"\n          value=\"Don't use JUnits assertEquals, AssertJ is preferred: assertThat(foo).isEqualTo();\"/>\n    </module>\n\n    <module name=\"RegexpSinglelineJava\">\n      <property name=\"format\" value=\"import static org\\.junit\\.Assert\\.assertNotEquals;\"/>\n      <property name=\"message\"\n          value=\"Don't use JUnits assertNotEquals, AssertJ is preferred: assertThat(foo).isNotEqualTo();\"/>\n    </module>\n\n    <module name=\"RegexpSinglelineJava\">\n      <property name=\"format\" value=\"import static org\\.junit\\.Assert\\.assertSame;\"/>\n      <property name=\"message\"\n          value=\"Don't use JUnits assertSame, AssertJ is preferred: assertThat(foo).isSameAs();\"/>\n    </module>\n\n    <module name=\"RegexpSinglelineJava\">\n      <property name=\"format\" value=\"import static org\\.junit\\.Assert\\.assertNull;\"/>\n      <property name=\"message\"\n          value=\"Don't use JUnits assertNull, AssertJ is preferred: assertThat(foo).isNull()\"/>\n    </module>\n\n    <module name=\"RegexpSinglelineJava\">\n      <property name=\"format\" value=\"import static org\\.junit\\.Assert\\.assertNotNull;\"/>\n      <property name=\"message\"\n          value=\"Don't use JUnits assertNotNull, AssertJ is preferred: assertThat(foo).isNotNull()\"/>\n    </module>\n  </module>\n</module>\n"
  },
  {
    "path": "dependencies.gradle",
    "content": "ext {\n  javaVersion = JavaVersion.VERSION_1_7\n\n  ci = 'true'.equals(System.getenv('CI'))\n\n  /* Dependencies */\n  moshi = 'com.squareup.moshi:moshi:1.5.0'\n\n  /* Testing */\n  junit = 'junit:junit:4.12'\n  assertJ = 'org.assertj:assertj-core:2.5.0'\n  retrofit = 'com.squareup.retrofit2:retrofit:2.1.0'\n  retrofitMoshiConverter = 'com.squareup.retrofit2:converter-moshi:2.1.0'\n  mockWebServer = 'com.squareup.okhttp3:mockwebserver:3.4.1'\n  privateConstructorChecker = 'com.pushtorefresh.java-private-constructor-checker:checker:1.2.0'\n  rxJava2 = 'io.reactivex.rxjava2:rxjava:2.0.3'\n\n  autoValueMoshi = 'com.ryanharter.auto.value:auto-value-moshi:0.4.2'\n  autoValueMoshiAnnotations = 'com.ryanharter.auto.value:auto-value-moshi-annotations:0.4.2'\n  autoValueAnnotations = 'com.jakewharton.auto.value:auto-value-annotations:1.3'\n}\n"
  },
  {
    "path": "gradle/gradle-mvn-push.gradle",
    "content": "/*\n * Copyright (C) 2013 Chris Banes\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport static org.gradle.internal.jvm.Jvm.current\n\napply plugin: 'maven'\napply plugin: 'signing'\n\nversion = VERSION_NAME\ngroup = GROUP\n\ndef isSnapshot = VERSION_NAME.endsWith('-SNAPSHOT')\ndef ossrhUsername = hasProperty('nexusUsername') ? nexusUsername : \"\"\ndef ossrhPassword = hasProperty('nexusPassword') ? nexusPassword : \"\"\n\nafterEvaluate { project ->\n    uploadArchives {\n        repositories {\n            mavenDeployer {\n                beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }\n\n                pom.groupId = GROUP\n                pom.artifactId = POM_ARTIFACT_ID\n                pom.version = VERSION_NAME\n\n                repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') {\n                    authentication(userName: ossrhUsername, password: ossrhPassword)\n                }\n                snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') {\n                    authentication(userName: ossrhUsername, password: ossrhPassword)\n                }\n\n                pom.project {\n                    name POM_NAME\n                    packaging POM_PACKAGING\n                    description POM_DESCRIPTION\n                    url POM_URL\n\n                    scm {\n                        url POM_SCM_URL\n                        connection POM_SCM_CONNECTION\n                        developerConnection POM_SCM_DEV_CONNECTION\n                    }\n\n                    licenses {\n                        license {\n                            name POM_LICENCE_NAME\n                            url POM_LICENCE_URL\n                            distribution POM_LICENCE_DIST\n                        }\n                    }\n\n                    developers {\n                        developer {\n                            id POM_DEVELOPER_ID\n                            name POM_DEVELOPER_NAME\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    signing {\n        required { !isSnapshot && gradle.taskGraph.hasTask(\"uploadArchives\") }\n        sign configurations.archives\n    }\n\n    if (project.getPlugins().hasPlugin('com.android.application')\n            || project.getPlugins().hasPlugin('com.android.library')) {\n\n        uploadArchives.dependsOn(build)\n\n        task install(type: Upload, dependsOn: assemble) {\n            group 'upload'\n            repositories.mavenInstaller {\n                configuration = configurations.archives\n\n                pom.groupId = GROUP\n                pom.artifactId = POM_ARTIFACT_ID\n                pom.version = VERSION_NAME\n\n                pom.project {\n                    name POM_NAME\n                    packaging POM_PACKAGING\n                    description POM_DESCRIPTION\n                    url POM_URL\n\n                    scm {\n                        url POM_SCM_URL\n                        connection POM_SCM_CONNECTION\n                        developerConnection POM_SCM_DEV_CONNECTION\n                    }\n\n                    licenses {\n                        license {\n                            name POM_LICENCE_NAME\n                            url POM_LICENCE_URL\n                            distribution POM_LICENCE_DIST\n                        }\n                    }\n\n                    developers {\n                        developer {\n                            id POM_DEVELOPER_ID\n                            name POM_DEVELOPER_NAME\n                        }\n                    }\n                }\n            }\n        }\n\n        task androidJavadocs(type: Javadoc) {\n            source = android.sourceSets.main.java.source\n            classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n        }\n\n        task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {\n            classifier = 'javadoc'\n            from androidJavadocs.destinationDir\n        }\n\n        task androidSourcesJar(type: Jar) {\n            classifier = 'sources'\n            from android.sourceSets.main.java.source\n        }\n    } else {\n        install {\n            repositories.mavenInstaller {\n                pom.groupId = GROUP\n                pom.artifactId = POM_ARTIFACT_ID\n                pom.version = VERSION_NAME\n\n                pom.project {\n                    name POM_NAME\n                    packaging POM_PACKAGING\n                    description POM_DESCRIPTION\n                    url POM_URL\n\n                    scm {\n                        url POM_SCM_URL\n                        connection POM_SCM_CONNECTION\n                        developerConnection POM_SCM_DEV_CONNECTION\n                    }\n\n                    licenses {\n                        license {\n                            name POM_LICENCE_NAME\n                            url POM_LICENCE_URL\n                            distribution POM_LICENCE_DIST\n                        }\n                    }\n\n                    developers {\n                        developer {\n                            id POM_DEVELOPER_ID\n                            name POM_DEVELOPER_NAME\n                        }\n                    }\n                }\n            }\n        }\n\n        task sourcesJar(type: Jar, dependsOn: classes) {\n            classifier = 'sources'\n            from sourceSets.main.allSource\n        }\n\n        task javadocJar(type: Jar, dependsOn: javadoc) {\n            classifier = 'javadoc'\n            //noinspection GroovyAccessibility\n            from javadoc.destinationDir\n        }\n    }\n\n    // JDK 1.8 is more strict then 1.7. Have JDK 1.8 behave like 1.7 for javadoc generation\n    if (current().getJavaVersion() == JavaVersion.VERSION_1_8) {\n        allprojects {\n            tasks.withType(Javadoc) {\n                options.addStringOption('Xdoclint:none', '-quiet')\n            }\n        }\n    }\n\n    artifacts {\n        if (project.getPlugins().hasPlugin('com.android.application')\n                || project.getPlugins().hasPlugin('com.android.library')) {\n            archives androidSourcesJar\n            archives androidJavadocsJar\n        } else {\n            archives sourcesJar\n            archives javadocJar\n        }\n    }\n\n    /** Task that allows to install archives to local maven. */\n    task installArchives(type: Upload) {\n        group 'upload'\n        description \"Installs the artifacts to the local Maven repository.\"\n        configuration = configurations['archives']\n        repositories {\n            mavenDeployer {\n\n                pom.groupId = GROUP\n                pom.artifactId = POM_ARTIFACT_ID\n                pom.version = VERSION_NAME\n\n                repository url: \"file://${System.properties['user.home']}/.m2/repository\"\n\n                pom.project {\n                    name POM_NAME\n                    packaging POM_PACKAGING\n                    description POM_DESCRIPTION\n                    url POM_URL\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Oct 09 10:31:26 CEST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.2.1-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "GROUP=com.serjltt.moshi\nVERSION_NAME=2.3-SNAPSHOT\n\nPOM_DESCRIPTION=A collection of simple JsonAdapters for Moshi.\nPOM_ARTIFACT_ID=moshi-lazy-adapters\nPOM_NAME=Moshi Lazy Adapters\nPOM_PACKAGING=jar\n\nPOM_URL=https://github.com/serj-lotutovici/moshi-lazy-adapters/\nPOM_SCM_URL=https://github.com/serj-lotutovici/moshi-lazy-adapters\nPOM_SCM_CONNECTION=scm:git:git@github.com:serj-lotutovici/moshi-lazy-adapters.git\nPOM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com:serj-lotutovici/moshi-lazy-adapters.git\n\nPOM_LICENCE_NAME=The Apache Software License, Version 2.0\nPOM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt\nPOM_LICENCE_DIST=repo\n\nPOM_DEVELOPER_ID=serj-lotutovici\nPOM_DEVELOPER_NAME=Serj Lotutovici\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave ( ) {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "jacoco.gradle",
    "content": "apply plugin: 'jacoco'\n\njacoco {\n  toolVersion = '0.7.7.201606060606' // See http://www.eclemma.org/jacoco/.\n}\n\njacocoTestReport {\n  reports {\n    xml.enabled = true\n    html.enabled = true\n  }\n}\n\ncheck.dependsOn jacocoTestReport\n"
  },
  {
    "path": "settings.gradle",
    "content": "rootProject.name = 'moshi-lazy-adapters'\n\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/Data.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.google.auto.value.AutoValue;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\n\n/** Data class for testing auto-value-moshi integration. */\n@AutoValue\nabstract class Data {\n  public static JsonAdapter<Data> jsonAdapter(Moshi moshi) {\n    return new AutoValue_Data.MoshiJsonAdapter(moshi);\n  }\n\n  abstract String name();\n\n  /**\n   * The name of the method will be taken as the first key, then the path provided with the\n   * annotation.\n   */\n  @Wrapped(path = {\"1\"}) abstract Meta meta();\n\n  static class Meta {\n    String value1;\n    int value2;\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/DataFactories.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.ryanharter.auto.value.moshi.MoshiAdapterFactory;\nimport com.squareup.moshi.JsonAdapter;\n\n/** Provided the factory for generated adapters. */\n@MoshiAdapterFactory\nabstract class DataFactories implements JsonAdapter.Factory {\n  public static JsonAdapter.Factory create() {\n    return new AutoValueMoshi_DataFactories();\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/DeserializeOnlyAutoValueTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.google.auto.value.AutoValue;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class DeserializeOnlyAutoValueTest {\n  private final Moshi moshi = new Moshi.Builder()\n      .add(DeserializeOnly.ADAPTER_FACTORY)\n      .add(DataFactories.create())\n      .build();\n\n  @Test public void serialize() {\n    final String json = AutoValueClass.jsonAdapter(moshi)\n        .toJson(new AutoValue_DeserializeOnlyAutoValueTest_AutoValueClass(1, 2));\n    assertThat(json).isEqualTo(\"{\\\"foo\\\":1}\");\n  }\n\n  @Test public void deserialize() throws IOException {\n    final AutoValueClass autoValueClass =\n        AutoValueClass.jsonAdapter(moshi).fromJson(\"{\\\"foo\\\": 1,\\\"bar\\\": 2}\");\n\n    assertThat(autoValueClass.foo()).isEqualTo(1);\n    assertThat(autoValueClass.bar()).isEqualTo(2);\n  }\n\n  @AutoValue abstract static class AutoValueClass {\n    public static JsonAdapter<AutoValueClass> jsonAdapter(Moshi moshi) {\n      return new AutoValue_DeserializeOnlyAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi);\n    }\n\n    abstract Integer foo();\n\n    @DeserializeOnly abstract Integer bar();\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersAutoValueTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport java.util.Collections;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\n/** Test all lazy adapters to work in integration with AutoValue extensions. */\npublic class LazyAdaptersAutoValueTest {\n  private final Moshi moshi = new Moshi.Builder()\n      .add(Wrapped.ADAPTER_FACTORY)\n      .add(DataFactories.create())\n      .build();\n\n  @Test public void unwrap() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    Data fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"name\\\": \\\"data_name\\\",\\n\"\n        + \"  \\\"meta\\\": {\\n\"\n        + \"    \\\"1\\\": {\\n\"\n        + \"      \\\"value1\\\": \\\"value1\\\",\\n\"\n        + \"      \\\"value2\\\": 2\\n\"\n        + \"    }\\n\"\n        + \"  }\\n\"\n        + \"}\");\n\n    assertThat(fromJson.name()).isEqualTo(\"data_name\");\n    assertThat(fromJson.meta().value1).isEqualTo(\"value1\");\n    assertThat(fromJson.meta().value2).isEqualTo(2);\n  }\n\n  @Test\n  public void wrap() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class,\n        Collections.singleton(Wrapped.Factory.create(\"foo\")));\n\n    Data.Meta meta = new Data.Meta();\n    meta.value1 = \"value1\";\n    meta.value2 = 2;\n    Data data = new AutoValue_Data(\"data_name\", meta);\n\n    String toJson = adapter.toJson(data);\n    assertThat(toJson).isEqualTo(\n        \"{\\\"foo\\\":{\\\"name\\\":\\\"data_name\\\",\"\n            + \"\\\"meta\\\":{\\\"1\\\":{\\\"value1\\\":\\\"value1\\\",\\\"value2\\\":2}}}}\");\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRetrofitTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport okhttp3.ResponseBody;\nimport okhttp3.mockwebserver.MockResponse;\nimport okhttp3.mockwebserver.MockWebServer;\nimport okhttp3.mockwebserver.RecordedRequest;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport retrofit2.Call;\nimport retrofit2.Response;\nimport retrofit2.Retrofit;\nimport retrofit2.converter.moshi.MoshiConverterFactory;\nimport retrofit2.http.Body;\nimport retrofit2.http.GET;\nimport retrofit2.http.POST;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\n/** Test all lazy adapters to work in integration with retrofit. */\npublic final class LazyAdaptersRetrofitTest {\n  @Rule public final MockWebServer server = new MockWebServer();\n\n  private final Moshi moshi = new Moshi.Builder()\n      .add(Wrapped.ADAPTER_FACTORY)\n      .add(FirstElement.ADAPTER_FACTORY)\n      .add(ElementAt.ADAPTER_FACTORY)\n      .build();\n\n  private final Retrofit retrofit = new Retrofit.Builder()\n      .addConverterFactory(MoshiConverterFactory.create(moshi))\n      .baseUrl(server.url(\"/\"))\n      .build();\n\n  private final Service service = retrofit.create(Service.class);\n\n  @Test public void unwrapJsonAdapter() throws Exception {\n    assertResponse(service.unwrap(), \"{\\n\"\n        + \"  \\\"one\\\": {\\n\"\n        + \"    \\\"two\\\": \\\"works!\\\"\\n\"\n        + \"  }\\n\"\n        + \"}\", \"works!\");\n  }\n\n  @Test public void unwrapNestedJsonAdapter() throws Exception {\n    server.enqueue(new MockResponse().setBody(\"{\\n\"\n        + \" \\\"one\\\": {\\n\"\n        + \"  \\\"two\\\": {\\n\"\n        + \"   \\\"item\\\": {\\n\"\n        + \"    \\\"foo\\\": \\\"this\\\"\\n\"\n        + \"   },\\n\"\n        + \"   \\\"item2\\\": {\\n\"\n        + \"    \\\"bar\\\": 1234\\n\"\n        + \"   },\\n\"\n        + \"   \\\"foobar\\\": 567\\n\"\n        + \"  }\\n\"\n        + \" }\\n\"\n        + \"}\"));\n\n    Response<Nested> response = service.unwrapNested().execute();\n\n    assertThat(response.body().foobar).isEqualTo(567);\n    assertThat(response.body().foo).isEqualTo(\"this\");\n    assertThat(response.body().bar).isEqualTo(1234);\n  }\n\n  @Test public void wrapPostBody() throws Exception {\n    server.enqueue(new MockResponse());\n\n    Call<ResponseBody> call = service.wrappedPost(\"one\");\n    call.execute();\n\n    RecordedRequest recorded = server.takeRequest();\n    assertThat(recorded.getBody()\n        .readUtf8())\n        .isEqualTo(\"{\\\"1\\\":{\\\"2\\\":\\\"one\\\"}}\");\n  }\n\n  @Test public void firstElementJsonAdapter() throws Exception {\n    assertResponse(service.firstElement(), \"[\\n\"\n        + \"  \\\"expected\\\",\\n\"\n        + \"  \\\"ignored\\\"\\n\"\n        + \"]\", \"expected\");\n  }\n\n  @Test public void elementAtJsonAdapter() throws Exception {\n    assertResponse(service.elementAt(), \"[\\n\"\n        + \"  \\\"one\\\",\\n\"\n        + \"  \\\"two\\\",\\n\"\n        + \"  \\\"three\\\"\\n\"\n        + \"]\", \"three\");\n  }\n\n  @Test public void unwrapFirstElement() throws Exception {\n    assertResponse(service.unwrapFirstElement(), \"{\\n\"\n        + \"  \\\"one\\\": {\\n\"\n        + \"    \\\"two\\\": [\\n\"\n        + \"      \\\"first\\\"\\n\"\n        + \"    ]\\n\"\n        + \"  }\\n\"\n        + \"}\", \"first\");\n  }\n\n  private <T> void assertResponse(Call<T> call, String input, T expected) throws IOException {\n    server.enqueue(new MockResponse().setBody(input));\n\n    Response<T> response = call.execute();\n    assertThat(response.body()).isEqualTo(expected);\n  }\n\n  /** Test service for all lazy adapters. */\n  private interface Service {\n    /** Helps to test the unwrap adapter. */\n    @GET(\"/\")\n    @Wrapped(path = {\"one\", \"two\"}) Call<String> unwrap();\n\n    @GET(\"/\")\n    @Wrapped(path = {\"one\", \"two\"}) Call<Nested> unwrapNested();\n\n    @POST(\"/\") Call<ResponseBody> wrappedPost(@Body @Wrapped(path = {\"1\", \"2\"}) String value);\n\n    /** Helps to test the first element json adapter. */\n    @GET(\"/\")\n    @FirstElement Call<String> firstElement();\n\n    /** Helps to test the first element json adapter. */\n    @GET(\"/\")\n    @Wrapped(path = {\"one\", \"two\"})\n    @FirstElement Call<String> unwrapFirstElement();\n\n    @GET(\"/\")\n    @ElementAt(index = 2) Call<String> elementAt();\n  }\n\n  static class Nested {\n    @Json(name = \"item\") @Wrapped(path = \"foo\") String foo;\n    @Json(name = \"item2\") @Wrapped(path = \"bar\") int bar;\n    int foobar;\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRxJavaTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.Moshi;\nimport io.reactivex.Flowable;\nimport io.reactivex.Maybe;\nimport io.reactivex.Observable;\nimport io.reactivex.Single;\nimport io.reactivex.observers.BaseTestConsumer;\nimport java.lang.annotation.Annotation;\nimport java.util.Collections;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Parameterized;\n\n/** Tests if specific adapters behave properly with RxJava2. */\n@RunWith(Parameterized.class)\npublic final class LazyAdaptersRxJavaTest {\n  private static final Moshi MOSHI = new Moshi.Builder()\n      .add(Wrapped.ADAPTER_FACTORY)\n      .build();\n\n  private static Callable<String> failingCallable() {\n    Set<Annotation> annotations =\n        Collections.<Annotation>singleton(Wrapped.Factory.create(true, \"one\", \"two\", \"three\"));\n    final JsonAdapter<String> adapter = MOSHI.adapter(String.class, annotations);\n\n    return new Callable<String>() {\n      @Override public String call() throws Exception {\n        return adapter.fromJson(\"{\\n\"\n            + \"  \\\"one\\\": {\\n\"\n            + \"    \\\"two\\\": null\\n\"\n            + \"  }\\n\"\n            + \"}\");\n      }\n    };\n  }\n\n  @Parameterized.Parameters\n  public static BaseTestConsumer[] testData() {\n    return new BaseTestConsumer[] {\n        Single.fromCallable(failingCallable()).test(),\n        Observable.fromCallable(failingCallable()).test(),\n        Maybe.fromCallable(failingCallable()).test(),\n        Flowable.fromCallable(failingCallable()).test()\n    };\n  }\n\n  private final BaseTestConsumer testConsumer;\n\n  public LazyAdaptersRxJavaTest(BaseTestConsumer testConsumer) {\n    this.testConsumer = testConsumer;\n  }\n\n  @Test public void reactiveTypeYieldsAppropriateError() throws Exception {\n    //noinspection unchecked\n    testConsumer\n        .assertFailureAndMessage(JsonDataException.class,\n            \"Wrapped Json expected at path: [one, two, three]. Found null at $.one.two\");\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/Nullable.java",
    "content": "package com.serjltt.moshi.adapters;\n\n/** For testing purposes. */\npublic @interface Nullable {\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/SerializeOnlyAutoValueTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.google.auto.value.AutoValue;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class SerializeOnlyAutoValueTest {\n  private final Moshi moshi = new Moshi.Builder()\n      .add(SerializeOnly.ADAPTER_FACTORY)\n      .add(DataFactories.create())\n      .build();\n\n  @Test public void serialize() {\n    final String json = AutoValueClass.jsonAdapter(moshi)\n        .toJson(new AutoValue_SerializeOnlyAutoValueTest_AutoValueClass(1, 2));\n    assertThat(json).isEqualTo(\"{\\\"foo\\\":1,\\\"bar\\\":2}\");\n  }\n\n  @Test public void deserialize() throws IOException {\n    final AutoValueClass autoValueClass =\n        AutoValueClass.jsonAdapter(moshi).fromJson(\"{\\\"foo\\\": 1,\\\"bar\\\": 2}\");\n\n    assertThat(autoValueClass.foo()).isEqualTo(1);\n    assertThat(autoValueClass.bar()).isNull();\n  }\n\n  @AutoValue abstract static class AutoValueClass {\n    public static JsonAdapter<AutoValueClass> jsonAdapter(Moshi moshi) {\n      return new AutoValue_SerializeOnlyAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi);\n    }\n\n    abstract Integer foo();\n\n    @SerializeOnly @Nullable abstract Integer bar();\n  }\n}\n"
  },
  {
    "path": "src/integrationTest/java/com/serjltt/moshi/adapters/TransientAutoValueTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.google.auto.value.AutoValue;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.util.Collections;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class TransientAutoValueTest {\n  private final Moshi moshi = new Moshi.Builder()\n      .add(Transient.ADAPTER_FACTORY)\n      .add(DataFactories.create())\n      .build();\n\n  @Test public void serialize() {\n    final String json = AutoValueClass.jsonAdapter(moshi)\n        .toJson(new AutoValue_TransientAutoValueTest_AutoValueClass(1, 2));\n    assertThat(json).isEqualTo(\"{\\\"foo\\\":1}\");\n  }\n\n  @Test public void deserialize() throws IOException {\n    final AutoValueClass autoValueClass =\n        AutoValueClass.jsonAdapter(moshi).fromJson(\"{\\\"foo\\\": 1,\\\"bar\\\": 2}\");\n\n    assertThat(autoValueClass.foo()).isEqualTo(1);\n    assertThat(autoValueClass.bar()).isNull();\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter =\n        moshi.adapter(String.class, Collections.singleton(new SerializeOnly() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Transient.class;\n          }\n        }));\n\n    assertThat(adapter.toString()).isEqualTo(\"JsonAdapter(String).nullSafe().transient()\");\n  }\n\n  @AutoValue abstract static class AutoValueClass {\n    public static JsonAdapter<AutoValueClass> jsonAdapter(Moshi moshi) {\n      return new AutoValue_TransientAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi);\n    }\n\n    abstract Integer foo();\n\n    @Transient @Nullable abstract Integer bar();\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapter.java",
    "content": "/*\n * Copyright (C) 2017 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Adapter that fallbacks to a default value in case there's a mismatch.\n */\npublic final class DefaultOnDataMismatchAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<T> delegate;\n  private final T defaultValue;\n\n  DefaultOnDataMismatchAdapter(JsonAdapter<T> delegate, T defaultValue) {\n    this.delegate = delegate;\n    this.defaultValue = defaultValue;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    Object jsonValue = reader.readJsonValue();\n\n    try {\n      return delegate.fromJsonValue(jsonValue);\n    } catch (JsonDataException ignore) {\n      return defaultValue;\n    }\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    delegate.toJson(writer, value);\n  }\n\n  @Override public String toString() {\n    return delegate + \".defaultOnDatMisMatch(\" + defaultValue + ')';\n  }\n\n  /** Builds an adapter that fallbacks to a default value in case there's a mismatch. */\n  public static <T> JsonAdapter.Factory newFactory(final Type type, final T defaultValue) {\n    return new Factory() {\n      @Override public JsonAdapter<?> create(Type requestedType,\n          Set<? extends Annotation> annotations, Moshi moshi) {\n        if (Types.equals(type, requestedType)) {\n          JsonAdapter<T> delegate = moshi.nextAdapter(this, type, annotations);\n          return new DefaultOnDataMismatchAdapter<>(delegate, defaultValue);\n        }\n\n        return null;\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated field may only be deserialized.\n *\n * <p>To leverage from {@link DeserializeOnly} {@link DeserializeOnly#ADAPTER_FACTORY} must be\n * added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(DeserializeOnly.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface DeserializeOnly {\n  /** Builds an adapter that can process a types annotated with {@link DeserializeOnly}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, DeserializeOnly.class);\n      if (nextAnnotations == null) return null;\n\n      return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), false, true);\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/ElementAt.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\nimport static com.serjltt.moshi.adapters.Util.nextAnnotations;\n\n/**\n * Indicates that the annotated type/field is <strong>expected</strong> to be the element\n * at the given index of a json array.\n *\n * <p>For example if a json object is:\n * <pre>\n *   [\n *    {\n *      \"some_field\": \"some_value\",\n *      \"other_field\": \"other_value\"\n *    },\n *    {\n *      \"some_field\": \"some_value_2\",\n *      \"other_field\": \"other_value_2\"\n *    }\n *   ]\n * </pre>\n * And the consumer only cares about the second element, if using retrofit a service method would\n * look like:\n *\n * <pre><code>\n *   {@literal @}GET(\"path/\")\n *   {@literal @}ElementAt(index = 1) Call&lt;DataObject&gt; getData();\n * </code></pre>\n *\n * The resulting response returned by {@code response.body()} will be an instance of {@code\n * DataObject} with the respective values set.\n *\n * <p>To leverage from {@link ElementAt} {@link ElementAt#ADAPTER_FACTORY}\n * must be added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(ElementAt.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })\npublic @interface ElementAt {\n  /**\n   * Represents the index location at which the element will be expected to be.\n   * If the size of the array will be less then the provided index,\n   * the companion adapter will return {@code null}.\n   */\n  int index();\n\n  /** Builds an adapter that can process a types annotated with {@link ElementAt}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Pair<ElementAt, Set<Annotation>> nextAnnotations =\n          nextAnnotations(annotations, ElementAt.class);\n      if (nextAnnotations == null || !nextAnnotations.second.isEmpty()) return null;\n\n      return new ElementAtJsonAdapter<>(type, moshi, nextAnnotations.first.index());\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/ElementAtJsonAdapter.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * {@linkplain JsonAdapter} that extracts the element at the given index\n * of an array of (a field) type annotated with {@linkplain ElementAt}.\n */\nfinal class ElementAtJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<List<T>> delegate;\n  private final int index;\n\n  ElementAtJsonAdapter(Type type, Moshi moshi, int index) {\n    Type listType = Types.newParameterizedType(List.class, type);\n    delegate = moshi.adapter(listType);\n    this.index = index;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    List<T> fromJson = delegate.fromJson(reader);\n    if (fromJson != null && index < fromJson.size()) return fromJson.get(index);\n    return null;\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    delegate.toJson(writer, Collections.singletonList(value));\n  }\n\n  @Override public String toString() {\n    return delegate + \".elementAt(\" + index + \")\";\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FallbackEnum.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated enum has a fallback value. The fallback must be set via\n * {@link #name()}. If no enum constant with the provided name is declared in the annotated\n * enum type an {@linkplain AssertionError assertion error} will be thrown.\n *\n * <p>To leverage from {@link FallbackEnum} {@link FallbackEnum#ADAPTER_FACTORY} must be added to\n * your {@linkplain Moshi moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(FallbackEnum.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\npublic @interface FallbackEnum {\n  String name();\n\n  /** Builds an adapter that can process enums annotated with {@link FallbackEnum}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      if (!annotations.isEmpty()) return null;\n\n      Class<?> rawType = Types.getRawType(type);\n      if (rawType.isEnum()) {\n        FallbackEnum annotation = rawType.getAnnotation(FallbackEnum.class);\n        if (annotation == null) return null;\n\n        //noinspection unchecked\n        return new FallbackEnumJsonAdapter<>((Class<? extends Enum>) rawType, annotation.name())\n            .nullSafe();\n      }\n\n      return null;\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapter.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n * Copyright (C) 2014 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\n\n/**\n * {@linkplain JsonAdapter} that fallbacks to a default enum constant declared in the enum type\n * annotated with {@linkplain FallbackEnum}.\n */\nfinal class FallbackEnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {\n  private final Class<T> enumType;\n  private final String[] nameStrings;\n  private final T[] constants;\n  private final JsonReader.Options options;\n  private final T fallbackConstant;\n\n  FallbackEnumJsonAdapter(Class<T> enumType, String fallback) {\n    fallbackConstant = Enum.valueOf(enumType, fallback);\n    this.enumType = enumType;\n    try {\n      constants = enumType.getEnumConstants();\n      nameStrings = new String[constants.length];\n      for (int i = 0; i < constants.length; i++) {\n        T constant = constants[i];\n        Json annotation = enumType.getField(constant.name()).getAnnotation(Json.class);\n        String name = annotation != null ? annotation.name() : constant.name();\n        nameStrings[i] = name;\n      }\n      options = JsonReader.Options.of(nameStrings);\n    } catch (NoSuchFieldException e) {\n      throw new AssertionError(e);\n    }\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    int index = reader.selectString(options);\n    if (index != -1) return constants[index];\n    reader.nextString();\n    return fallbackConstant;\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    writer.value(nameStrings[value.ordinal()]);\n  }\n\n  @Override public String toString() {\n    return \"JsonAdapter(\" + enumType.getName() + \").fallbackEnum(\" + fallbackConstant + \")\";\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.Set;\nimport java.util.Locale;\n\nimport static com.serjltt.moshi.adapters.Util.nextAnnotations;\n\n/**\n * Indicates that the annotated field may be {@code null} in the json source and thus requires a\n * fallback value.\n *\n * <p>To leverage from {@linkplain FallbackOnNull} {@linkplain FallbackOnNull#ADAPTER_FACTORY}\n * must be added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(FallbackOnNull.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })\npublic @interface FallbackOnNull {\n  /** Fallback value for {@code boolean} primitives. Default: {@code false}. */\n  boolean fallbackBoolean() default false;\n\n  /** Fallback value for {@code byte} primitives. Default: {@code Byte.MIN_VALUE}. */\n  byte fallbackByte() default Byte.MIN_VALUE;\n\n  /** Fallback value for {@code char} primitives. Default: {@code Character.MIN_VALUE}. */\n  char fallbackChar() default Character.MIN_VALUE;\n\n  /** Fallback value for {@code double} primitives. Default: {@code Double.MIN_VALUE}. */\n  double fallbackDouble() default Double.MIN_VALUE;\n\n  /** Fallback value for {@code float} primitives. Default: {@code Float.MIN_VALUE}. */\n  float fallbackFloat() default Float.MIN_VALUE;\n\n  /** Fallback value for {@code int} primitives. Default: {@code Integer.MIN_VALUE}. */\n  int fallbackInt() default Integer.MIN_VALUE;\n\n  /** Fallback value for {@code long} primitives. Default: {@code Long.MIN_VALUE}. */\n  long fallbackLong() default Long.MIN_VALUE;\n\n  /** Fallback value for {@code short} primitives. Default: {@code Short.MIN_VALUE}. */\n  short fallbackShort() default Short.MIN_VALUE;\n\n  /** Builds an adapter that can process a types annotated with {@link FallbackOnNull}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Pair<FallbackOnNull, Set<Annotation>> nextAnnotations =\n          nextAnnotations(annotations, FallbackOnNull.class);\n      if (nextAnnotations == null) return null;\n\n      Class<?> rawType = Types.getRawType(type);\n      if (!FallbackOnNullJsonAdapter.PRIMITIVE_CLASSES.contains(rawType)) return null;\n\n      String fallbackType = fallbackType(rawType);\n      Object fallback = retrieveFallback(nextAnnotations.first, fallbackType);\n\n      return new FallbackOnNullJsonAdapter<>(moshi.adapter(type, nextAnnotations.second),\n          fallback, fallbackType);\n    }\n\n    /** Invokes the appropriate fallback method based on the {@code fallbackType}. */\n    private Object retrieveFallback(FallbackOnNull annotation, String fallbackType) {\n      try {\n        Method fallbackMethod = FallbackOnNull.class.getMethod(fallbackType);\n        return fallbackMethod.invoke(annotation);\n      } catch (Exception e) {\n        throw new AssertionError(e);\n      }\n    }\n\n    /** Constructs the appropriate fallback method name based on the {@code rawType}. */\n    private String fallbackType(Class<?> rawType) {\n      String typeName = rawType.getSimpleName();\n      String methodSuffix = typeName.substring(0, 1).toUpperCase(Locale.US) + typeName.substring(1);\n      return \"fallback\" + methodSuffix;\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\n\n/**\n * {@linkplain JsonAdapter} that fallbacks to a default value of a primitive field annotated with\n * {@linkplain FallbackOnNull}.\n */\nfinal class FallbackOnNullJsonAdapter<T> extends JsonAdapter<T> {\n  /** Set of primitives classes that are supported by <strong>this</strong> adapter. */\n  static final Set<Class<?>> PRIMITIVE_CLASSES = new LinkedHashSet<>();\n\n  static {\n    PRIMITIVE_CLASSES.add(boolean.class);\n    PRIMITIVE_CLASSES.add(byte.class);\n    PRIMITIVE_CLASSES.add(char.class);\n    PRIMITIVE_CLASSES.add(double.class);\n    PRIMITIVE_CLASSES.add(float.class);\n    PRIMITIVE_CLASSES.add(int.class);\n    PRIMITIVE_CLASSES.add(long.class);\n    PRIMITIVE_CLASSES.add(short.class);\n  }\n\n  final JsonAdapter<T> delegate;\n  final T fallback;\n  final String fallbackType;\n\n  FallbackOnNullJsonAdapter(JsonAdapter<T> delegate, T fallback, String fallbackType) {\n    this.delegate = delegate;\n    this.fallback = fallback;\n    this.fallbackType = fallbackType;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    if (reader.peek() == JsonReader.Token.NULL) {\n      reader.nextNull(); // We need to consume the value.\n      return fallback;\n    }\n    return delegate.fromJson(reader);\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    delegate.toJson(writer, value);\n  }\n\n  @Override public String toString() {\n    return delegate + \".fallbackOnNull(\" + fallbackType + '=' + fallback + ')';\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FilterNulls.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Collection;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated field may not contain any null values.\n * This annotation is applicable to all Collections.\n *\n * <p>To leverage from {@link FilterNulls} {@link FilterNulls#ADAPTER_FACTORY} must be\n * added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(FilterNulls.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface FilterNulls {\n  /** Builds an adapter that can process types annotated with {@link FilterNulls}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, FilterNulls.class);\n      if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null;\n\n      Class<?> rawType = Types.getRawType(type);\n\n      if (Collection.class.isAssignableFrom(rawType)) {\n        return new FilterNullsJsonAdapter<>(moshi.adapter(type, nextAnnotations));\n      }\n\n      return null;\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapter.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Iterator;\n\n/**\n * {@link JsonAdapter} that filters null values out.\n */\nfinal class FilterNullsJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<T> delegate;\n\n  FilterNullsJsonAdapter(JsonAdapter<T> delegate) {\n    this.delegate = delegate;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    return removeNulls(delegate.fromJson(reader));\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    delegate.toJson(writer, removeNulls(value));\n  }\n\n  @Override public String toString() {\n    return delegate + \".filterNulls()\";\n  }\n\n  private T removeNulls(final T value) {\n    if (value != null) {\n      final Iterator<?> it = ((Collection<?>) value).iterator();\n\n      while (it.hasNext()) {\n        if (it.next() == null) {\n          it.remove();\n        }\n      }\n    }\n\n    return value;\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/FirstElement.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated type/field is <strong>expected</strong> to be the first element of a\n * json array.\n *\n * <p>For example if a json object is returned as:\n * <pre>\n *   [\n *    {\n *      \"some_field\": \"some_value\",\n *      \"other_field\": \"other_value\"\n *    }\n *   ]\n * </pre>\n * And the consumer only cares about the actual element, in the case of using a retrofit service\n * method the code would look like:\n *\n * <pre><code>\n *   {@literal @}GET(\"path/\")\n *   {@literal @}FirstElement Call&lt;DataObject&gt; getData();\n * </code></pre>\n *\n * The resulting response returned by {@code response.body()} will be an instance of {@code\n * DataObject} with the respective values set.\n *\n * <p>To leverage from {@link FirstElement} {@linkplain FirstElement#ADAPTER_FACTORY}\n * must be added to a {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(FirstElement.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface FirstElement {\n  /** Builds an adapter that can process a types annotated with {@link FirstElement}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, FirstElement.class);\n      if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null;\n\n      return new ElementAtJsonAdapter<>(type, moshi, 0);\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/LastElement.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated type/field is <strong>expected</strong> to be the last element of a\n * json array.\n *\n * <p>For example if a json object is returned as:\n * <pre>\n *   [\n *    {\n *      \"some_field\": \"some_value\",\n *      \"other_field\": \"other_value\"\n *    }\n *   ]\n * </pre>\n * And the consumer only cares about the last element, in the case of using a retrofit service\n * method the code would look like:\n *\n * <pre><code>\n *   {@literal @}GET(\"path/\")\n *   {@literal @}LastElement Call&lt;DataObject&gt; getData();\n * </code></pre>\n *\n * The resulting response returned by {@code response.body()} will be an instance of {@code\n * DataObject} with the respective values set.\n *\n * <p>To leverage from {@link LastElement} {@linkplain LastElement#ADAPTER_FACTORY}\n * must be added to a {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(LastElement.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface LastElement {\n  /** Builds an adapter that can process a type/field annotated with {@link LastElement}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, LastElement.class);\n      if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null;\n\n      return new LastElementJsonAdapter<>(type, moshi);\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/LastElementJsonAdapter.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * {@linkplain JsonAdapter} that extracts the last element\n * of an array of (a field) type or a method annotated with {@linkplain LastElement}.\n */\nfinal class LastElementJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<List<T>> delegate;\n\n  LastElementJsonAdapter(Type type, Moshi moshi) {\n    Type listType = Types.newParameterizedType(List.class, type);\n    delegate = moshi.adapter(listType);\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    List<T> fromJson = delegate.fromJson(reader);\n    if (fromJson != null && !fromJson.isEmpty()) return fromJson.get(fromJson.size() - 1);\n    return null;\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    delegate.toJson(writer, Collections.singletonList(value));\n  }\n\n  @Override public String toString() {\n    return delegate + \".lastElement()\";\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/Pair.java",
    "content": "package com.serjltt.moshi.adapters;\n\n/** A simple pair data class. */\nfinal class Pair<F, S> {\n  final F first;\n  final S second;\n\n  Pair(F first, S second) {\n    this.first = first;\n    this.second = second;\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/SerializeNulls.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated type/field should be serialized as {@code null} in case of a\n * empty/null value.\n *\n * <p>To leverage from {@link SerializeNulls} {@link SerializeNulls#ADAPTER_FACTORY}\n * must be added to a {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(SerializeNulls.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface SerializeNulls {\n  /** Builds an adapter that can process a types annotated with {@link SerializeNulls}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, SerializeNulls.class);\n      if (nextAnnotations == null) return null;\n\n      return moshi.adapter(type, nextAnnotations).serializeNulls();\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/SerializeOnly.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated field may only be serialized.\n *\n * <p>To leverage from {@link SerializeOnly} {@link SerializeOnly#ADAPTER_FACTORY} must be added\n * to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(SerializeOnly.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface SerializeOnly {\n  /** Builds an adapter that can process a types annotated with {@link SerializeOnly}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, SerializeOnly.class);\n      if (nextAnnotations == null) return null;\n\n      return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), true, false);\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmpty.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated type/field should not be serialized in case of an\n * empty value.\n *\n * <p>To leverage from {@link SerializeOnlyNonEmpty} {@link SerializeOnlyNonEmpty#ADAPTER_FACTORY}\n * must be added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(SerializeOnlyNonEmpty.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.FIELD, ElementType.METHOD })\npublic @interface SerializeOnlyNonEmpty {\n  /** Builds an adapter that can process a types annotated with {@link SerializeOnlyNonEmpty}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, SerializeOnlyNonEmpty.class);\n      if (nextAnnotations == null) return null;\n\n      Class<?> rawType = Types.getRawType(type);\n\n      if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)\n          || Map.class.isAssignableFrom(rawType)) {\n        return new SerializeOnlyNonEmptyJsonAdapter<>(moshi.adapter(type, nextAnnotations));\n      }\n\n      return null;\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapter.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * {@linkplain JsonAdapter} that will not serialize {@code T} when the passed value is empty.\n */\nfinal class SerializeOnlyNonEmptyJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<T> delegate;\n\n  SerializeOnlyNonEmptyJsonAdapter(JsonAdapter<T> delegate) {\n    this.delegate = delegate;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    return delegate.fromJson(reader);\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    if (isNotEmpty(value)) {\n      delegate.toJson(writer, value);\n    } else {\n      // We'll need to consume this property otherwise we'll get an IllegalArgumentException.\n      delegate.toJson(writer, null);\n    }\n  }\n\n  private boolean isNotEmpty(final T value) {\n    if (value instanceof Collection) {\n      Collection collection = (Collection) value;\n      return collection.size() > 0;\n    } else if (value instanceof Map) {\n      Map map = (Map) value;\n      return map.size() > 0;\n    } else if (value != null) {\n      return Array.getLength(value) > 0;\n    }\n\n    return false;\n  }\n\n  @Override public String toString() {\n    return delegate + \".serializeOnlyNonEmpty()\";\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/Transient.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\n/**\n * Indicates that the annotated method is transient.\n *\n * <p>To leverage from {@link Transient} {@link Transient#ADAPTER_FACTORY} must be added\n * to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(Transient.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.METHOD })\npublic @interface Transient {\n  /** Builds an adapter that can process a type annotated with {@link Transient}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Set<? extends Annotation> nextAnnotations =\n          Types.nextAnnotations(annotations, Transient.class);\n      if (nextAnnotations == null) return null;\n\n      return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), false, false);\n    }\n  };\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\n\n/**\n * {@link JsonAdapter} with transient functionality. The consumer can decide to ether serialize or\n * deserialize, or make the adapter completely transient.\n */\nfinal class TransientJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<T> delegate;\n  private final boolean serialize;\n  private final boolean deserialize;\n\n  TransientJsonAdapter(JsonAdapter<T> delegate, boolean serialize, boolean deserialize) {\n    this.delegate = delegate;\n    this.serialize = serialize;\n    this.deserialize = deserialize;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    if (deserialize) {\n      return delegate.fromJson(reader);\n    } else {\n      reader.skipValue();\n      return null;\n    }\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    if (serialize) {\n      delegate.toJson(writer, value);\n    } else {\n      // We'll need to consume this property otherwise we'll get an IllegalArgumentException.\n      delegate.toJson(writer, null);\n    }\n  }\n\n  @Override public String toString() {\n    return delegate + ((serialize && deserialize)\n        ? \"\" : serialize\n        ? \".serializeOnly()\" : deserialize\n        ? \".deserializeOnly()\" : \".transient()\");\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/Util.java",
    "content": "/*\n * Copyright 2014 Square, Inc.\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonQualifier;\nimport java.lang.annotation.Annotation;\nimport java.util.Collections;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\n\nfinal class Util {\n  /**\n   * Checks if {@code annotations} contains {@code jsonQualifier}.\n   * Returns a pair containing the subset of {@code annotations} without {@code jsonQualifier}\n   * and the {@code jsonQualified} instance, or null if {@code annotations} does not contain\n   * {@code jsonQualifier}.\n   */\n  public static <A extends Annotation> Pair<A, Set<Annotation>> nextAnnotations(\n      Set<? extends Annotation> annotations, Class<A> jsonQualifier) {\n    if (!jsonQualifier.isAnnotationPresent(JsonQualifier.class)) {\n      throw new IllegalArgumentException(jsonQualifier + \" is not a JsonQualifier.\");\n    }\n    if (annotations.isEmpty()) {\n      return null;\n    }\n    for (Annotation annotation : annotations) {\n      if (jsonQualifier.equals(annotation.annotationType())) {\n        Set<? extends Annotation> delegateAnnotations = new LinkedHashSet<>(annotations);\n        delegateAnnotations.remove(annotation);\n        //noinspection unchecked Protected by the if statment.\n        return new Pair<>((A) annotation, Collections.unmodifiableSet(delegateAnnotations));\n      }\n      A delegate = findDelegatedAnnotation(annotation, jsonQualifier);\n      if (delegate != null) {\n        Set<? extends Annotation> delegateAnnotations = new LinkedHashSet<>(annotations);\n        delegateAnnotations.remove(annotation);\n        return new Pair<>(delegate, Collections.unmodifiableSet(delegateAnnotations));\n      }\n    }\n    return null;\n  }\n\n  private static <A extends Annotation> A findDelegatedAnnotation(\n    Annotation annotation, Class<A> jsonQualifier) {\n    for (Annotation delegatedAnnotation : annotation.annotationType().getAnnotations()) {\n      if (jsonQualifier.equals(delegatedAnnotation.annotationType())) {\n        //noinspection unchecked\n        return (A) delegatedAnnotation;\n      }\n    }\n    return null;\n  }\n\n  private Util() {\n    throw new AssertionError(\"No instances.\");\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/Wrapped.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport java.lang.annotation.Annotation;\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;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.Set;\n\nimport static com.serjltt.moshi.adapters.Util.nextAnnotations;\n\n/**\n * Indicates that the annotated type/field should be unwrapped from the provided {@code path}.\n *\n * <p>For example if a json object is:\n * <pre>\n *   {\n *     \"response\": {\n *       \"status\": \"OK\"\n *     }\n *   }\n * </pre>\n * And the consumer only cares about the value of {@code status}, if using retrofit, a service\n * method would look like:\n *\n * <pre><code>\n *   {@literal @}GET(\"path/\")\n *   {@literal @}Wrapped({\"response\", \"status\"}) Call&lt;String&gt; getStatus();\n * </code></pre>\n *\n * The resulting response returned by {@code response.body()} will be a {@code String} with the\n * value {@code \"OK\"}.\n *\n * <p>To leverage from {@link Wrapped} {@link Wrapped#ADAPTER_FACTORY} must be\n * added to your {@linkplain Moshi Moshi instance}:\n *\n * <pre><code>\n *   Moshi moshi = new Moshi.Builder()\n *      .add(Wrapped.ADAPTER_FACTORY)\n *      .build();\n * </code></pre>\n *\n * <b>DISCLAIMER: </b> The order of {@linkplain JsonAdapter added json adapters} matters, to ensure\n * {@linkplain Wrapped correct un-wrapping} behaviour the adapter factory must be the\n * <strong>first</strong> custom adapter added to the {@link Moshi.Builder}.\n */\n@Documented\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME)\n@Target({\n  ElementType.FIELD,\n  ElementType.METHOD,\n  ElementType.PARAMETER,\n  ElementType.ANNOTATION_TYPE\n})\npublic @interface Wrapped {\n  /** The path to the wrapped json path. */\n  String[] path();\n\n  /**\n   * Indicates if the adapter should fail when the json object was not found at the indicated path.\n   * Default {@code true}.\n   */\n  boolean failOnNotFound() default true;\n\n  /** Builds an adapter that can process a types annotated with {@link Wrapped}. */\n  JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() {\n    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n        Moshi moshi) {\n      Pair<Wrapped, Set<Annotation>> nextAnnotations = nextAnnotations(annotations, Wrapped.class);\n      if (nextAnnotations == null) return null;\n\n      JsonAdapter<Object> adapter = moshi.adapter(type, nextAnnotations.second);\n      Wrapped wrapped = nextAnnotations.first;\n      return new WrappedJsonAdapter<>(adapter, wrapped.path(), wrapped.failOnNotFound());\n    }\n  };\n\n  /** Allows to easily create a new instance of {@link Wrapped} annotation. */\n  final class Factory {\n    /** Create a new instance of {@link Wrapped} with the specified JSON path. */\n    public static Wrapped create(final String... path) {\n      return create(true, path);\n    }\n\n    /** Create a new instance of {@link Wrapped} with the specified JSON path. */\n    public static Wrapped create(final boolean failOnNotFound, final String... path) {\n      return new Wrapped() {\n        @Override public Class<? extends Annotation> annotationType() {\n          return Wrapped.class;\n        }\n\n        @Override public String[] path() {\n          return path;\n        }\n\n        @Override public boolean failOnNotFound() {\n          return failOnNotFound;\n        }\n\n        @Override public int hashCode() {\n          int result = Arrays.hashCode(path);\n          result = 43 * result + (failOnNotFound ? 1 : 0);\n          return result;\n        }\n\n        @Override public boolean equals(Object obj) {\n          if (this == obj) return true;\n          if (obj == null || getClass() != obj.getClass()) return false;\n\n          Wrapped wrapped = (Wrapped) obj;\n          return Arrays.equals(path, wrapped.path())\n              && failOnNotFound == wrapped.failOnNotFound();\n        }\n\n        @Override public String toString() {\n          return \"Wrapped(\"\n              + \"path=\" + Arrays.asList(path)\n              + \", failOnNotFound=\" + failOnNotFound\n              + \")\";\n        }\n      };\n    }\n\n    private Factory() {\n      throw new AssertionError(\"No instances.\");\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/serjltt/moshi/adapters/WrappedJsonAdapter.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport java.io.IOException;\nimport java.util.Arrays;\n\n/** {@linkplain JsonAdapter} that unwraps the type/field annotated with {@linkplain Wrapped}. */\nfinal class WrappedJsonAdapter<T> extends JsonAdapter<T> {\n  private final JsonAdapter<T> delegate;\n  private final String[] path;\n  private final boolean failOnNotFound;\n\n  WrappedJsonAdapter(JsonAdapter<T> delegate, String[] path, boolean failOnNotFound) {\n    this.delegate = delegate;\n    this.path = path;\n    this.failOnNotFound = failOnNotFound;\n  }\n\n  @Override public T fromJson(JsonReader reader) throws IOException {\n    return fromJson(delegate, reader, path, 0, failOnNotFound);\n  }\n\n  @Override public void toJson(JsonWriter writer, T value) throws IOException {\n    toJson(delegate, writer, value, path, 0);\n  }\n\n  @Override public String toString() {\n    return delegate + String.format(\".wrapped(%s)\", Arrays.asList(path))\n        + (failOnNotFound ? \".failOnNotFound()\" : \"\");\n  }\n\n  /**\n   * Recursively goes through the json and finds the given root. Returns the object wrapped by the\n   * provided {@code path}.\n   */\n  private static <T> T fromJson(JsonAdapter<T> adapter, JsonReader reader, String[] path,\n      int index, boolean failOnNotFound) throws IOException {\n    if (index == path.length) {\n      //noinspection unchecked This puts full responsibility on the caller.\n      return adapter.fromJson(reader);\n    } else {\n      reader.beginObject();\n      Exception caughtException = null;\n      try {\n        String root = path[index];\n        while (reader.hasNext()) {\n          if (reader.nextName().equals(root)) {\n            if (reader.peek() == JsonReader.Token.NULL) {\n              // Consumer expects a value, not a null.\n              if (failOnNotFound) {\n                throw new JsonDataException(String.format(\n                    \"Wrapped Json expected at path: %s. Found null at %s\",\n                    Arrays.asList(path), reader.getPath()\n                ));\n              }\n\n              return reader.nextNull();\n            }\n            return fromJson(adapter, reader, path, ++index, failOnNotFound);\n          } else {\n            reader.skipValue();\n          }\n        }\n      } catch (Exception e) {\n        caughtException = e;\n      } finally {\n        // If the try block throw an exception, rethrow it up the stack.\n        if (caughtException instanceof IOException) {\n          //noinspection ThrowFromFinallyBlock\n          throw (IOException) caughtException;\n        } else if (caughtException instanceof JsonDataException) {\n          //noinspection ThrowFromFinallyBlock\n          throw (JsonDataException) caughtException;\n        } else if (caughtException != null) {\n          //noinspection ThrowFromFinallyBlock\n          throw new AssertionError(caughtException);\n        }\n        // If the json has an additional key, that was not red, we ignore it.\n        while (reader.hasNext()) {\n          reader.skipValue();\n        }\n        // End object, so that other adapters (if any) can proceed.\n        reader.endObject();\n      }\n      throw new JsonDataException(String.format(\n          \"Wrapped Json expected at path: %s. Actual: %s\",\n          Arrays.asList(path), reader.getPath()));\n    }\n  }\n\n  /**\n   * Recursively writes the respective roots forming a json object that resembles the {@code path}\n   * wrapping the type of the {@code adapter}.\n   */\n  private static <T> void toJson(JsonAdapter<T> adapter, JsonWriter writer, T value,\n      String[] path, int index) throws IOException {\n    if (value != null || writer.getSerializeNulls()) {\n      if (index == path.length) {\n        adapter.toJson(writer, value);\n      } else {\n        writer.beginObject();\n        writer.name(path[index]);\n        toJson(adapter, writer, value, path, ++index);\n        writer.endObject();\n      }\n    } else {\n      // If we don't propagate the null value the writer will throw.\n      writer.nullValue();\n    }\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/Custom.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.FromJson;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.ToJson;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n/**\n * Helper annotation (to test if JsonQualifier annotations are propagated further down the stream).\n */\n@JsonQualifier\n@Retention(RetentionPolicy.RUNTIME) @interface Custom {\n  /** String adapter, that will append \"Custom\" on read, and exclude it on write. */\n  final class CustomAdapter {\n    @Custom @FromJson String fromJson(String str) {\n      return str + \"Custom\";\n    }\n\n    @ToJson String toJson(@Custom String str) {\n      return str.substring(0, str.length() - \"Custom\".length());\n    }\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapterTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.JsonReader;\nimport com.squareup.moshi.JsonWriter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Type;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport org.junit.Test;\n\nimport static com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest.Fruit.APPLE;\nimport static com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest.Fruit.BANANA;\nimport static org.assertj.core.api.Java6Assertions.assertThat;\n\npublic final class DefaultOnDataMismatchAdapterTest {\n  @Test public void deserializeMismatch() throws IOException {\n    Fruit fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).fromJson(\"\\\"mango\\\"\");\n    assertThat(fruit).isNull();\n  }\n\n  @Test public void deserializeMatch() throws IOException {\n    Fruit fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).fromJson(\"\\\"banana\\\"\");\n    assertThat(fruit).isEqualTo(BANANA);\n  }\n\n  @Test public void serialize() {\n    String fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).toJson(APPLE);\n    assertThat(fruit).isEqualTo(\"\\\"apple\\\"\");\n  }\n\n  @Test public void factorySupportsType() throws Exception {\n    Type parameterized = Types.newParameterizedType(List.class, String.class);\n    List<String> fallback = Collections.singletonList(\"test\");\n\n    // Build a moshi instance using the adapter under test and one that will throw on each read.\n    Moshi moshi = buildMoshi(DefaultOnDataMismatchAdapter.newFactory(parameterized, fallback))\n        .newBuilder()\n        .add(new JsonAdapter.Factory() {\n          @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,\n              Moshi moshi) {\n            final JsonAdapter<Object> next = moshi.nextAdapter(this, type, annotations);\n            return new JsonAdapter<Object>() {\n              @Override public Object fromJson(JsonReader reader) throws IOException {\n                throw new JsonDataException(\"Fail for all types\");\n              }\n\n              @Override public void toJson(JsonWriter writer, Object value) throws IOException {\n                next.toJson(writer, value);\n              }\n            };\n          }\n        })\n        .build();\n    JsonAdapter<List<String>> adapter = moshi.adapter(parameterized);\n\n    List<String> fromJson = adapter.fromJson(\"[]\");\n    assertThat(fromJson)\n        .isEqualTo(fallback)\n        .containsExactly(\"test\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"[\\\"test\\\"]\");\n  }\n\n  @Test public void toStringReflectsInner() {\n    assertThat(buildMoshi(newFruitFactory()).adapter(Fruit.class).toString())\n        .isEqualTo(\"JsonAdapter(com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest$Fruit)\"\n            + \".nullSafe().defaultOnDatMisMatch(null)\");\n  }\n\n  private JsonAdapter.Factory newFruitFactory() {\n    return DefaultOnDataMismatchAdapter.newFactory(Fruit.class, null);\n  }\n\n  private Moshi buildMoshi(JsonAdapter.Factory factory) {\n    return new Moshi.Builder()\n        .add(factory)\n        .build();\n  }\n\n  enum Fruit {\n    @Json(name = \"banana\")BANANA,\n    @Json(name = \"apple\")APPLE\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class DeserializeOnlyJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(DeserializeOnly.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void deserializeOnly() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\\"data\\\": \\\"test\\\"}\");\n    assertThat(fromJson.data).isEqualTo(\"test\");\n\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n  }\n\n  @Test public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\\"data\\\": \\\"test\\\"}\");\n    assertThat(fromJson.data).isEqualTo(\"testCustom\");\n\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class, DeserializeOnly.class);\n\n    assertThat(adapter.toString()).isEqualTo(\"JsonAdapter(String).nullSafe().deserializeOnly()\");\n  }\n\n  private static class Data1 {\n    @DeserializeOnly String data;\n  }\n\n  private static class Data2 {\n    @DeserializeOnly @Custom String data;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/ElementAtJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.util.Collections;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class ElementAtJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(ElementAt.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void elementAt() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    Data fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"obj\\\": [\\n\"\n        + \"    \\\"one\\\",\\n\"\n        + \"    \\\"two\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"two\");\n\n    String toJson = adapter.toJson(fromJson);\n    // The excluded data is lost during parsing\n    // Adapter under test assumes that the consumer doesn't need that data\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[\\\"two\\\"]}\");\n  }\n\n  @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": []\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonOnArrayOfSizeOneReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": [\\\"test\\\"]\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonOnNullArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": null\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonExpectsAnArray() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"obj\\\": \\\"this_will_throw\\\"\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException e) {\n      // Moshi's Collection adapter will throw\n      assertThat(e).hasMessage(\"Expected BEGIN_ARRAY but was STRING at path $.obj\");\n    }\n  }\n\n  // Currently there is no way to create an adapter\n  @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"str\\\": [\\n\"\n        + \"    \\\"test\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"testCustom\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"str\\\":[\\\"test\\\"]}\");\n  }\n\n  // This one is redundant, but keeps JaCoCo quiet\n  @Test public void factoryExpectsOnlyOneAnnotation() {\n    // A list of fake annotations.\n    Set<Annotation> annotations = new LinkedHashSet<Annotation>() {\n      {\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Test.class;\n          }\n        });\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Custom.class;\n          }\n        });\n      }\n    };\n    assertThat(ElementAt.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n\n    // Emulate existing annotation (should also return null).\n    annotations.add(new ElementAt() {\n      @Override public Class<? extends Annotation> annotationType() {\n        return ElementAt.class;\n      }\n\n      @Override public int index() {\n        return 0;\n      }\n    });\n    assertThat(ElementAt.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class,\n        Collections.singleton(new ElementAt() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return ElementAt.class;\n          }\n\n          @Override public int index() {\n            return 2;\n          }\n        }));\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().collection().nullSafe().elementAt(2)\");\n  }\n\n  @Test public void elementAtDelegated() throws Exception {\n    JsonAdapter<Data3> adapter = moshi.adapter(Data3.class);\n\n    Data3 fromJson = adapter.fromJson(\"{\\n\"\n            + \"  \\\"obj\\\": [\\n\"\n            + \"    \\\"one\\\",\\n\"\n            + \"    \\\"two\\\"\\n\"\n            + \"  ]\\n\"\n            + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"two\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[\\\"two\\\"]}\");\n  }\n\n  @JsonQualifier\n  @ElementAt(index = 1)\n  @Retention(RetentionPolicy.RUNTIME)\n  @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })\n  @interface AlwaysElementAtIndexOne { }\n\n  private void assertNullReturn(String string) throws IOException {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    Data fromJson = adapter.fromJson(string);\n    assertThat(fromJson.str).isNull();\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[null]}\");\n  }\n\n  private static class Data {\n    @ElementAt(index = 1)\n    @Json(name = \"obj\") String str;\n  }\n\n  private static class Data2 {\n    @ElementAt(index = 0)\n    @Custom String str;\n  }\n\n  private static class Data3 {\n    @AlwaysElementAtIndexOne\n    @Json(name = \"obj\") String str;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n * Copyright (C) 2014 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.Moshi;\nimport java.lang.annotation.Annotation;\nimport java.util.Collections;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class FallbackEnumJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(FallbackEnum.ADAPTER_FACTORY)\n      .build();\n\n  @Test public void asRegularEnumAdapter() throws Exception {\n    JsonAdapter<Roshambo> adapter = moshi.adapter(Roshambo.class).lenient();\n    assertThat(adapter.fromJson(\"\\\"ROCK\\\"\")).isEqualTo(Roshambo.ROCK);\n    assertThat(adapter.toJson(Roshambo.PAPER)).isEqualTo(\"\\\"PAPER\\\"\");\n    // Check annotated value\n    assertThat(adapter.fromJson(\"\\\"scr\\\"\")).isEqualTo(Roshambo.SCISSORS);\n    assertThat(adapter.toJson(Roshambo.SCISSORS)).isEqualTo(\"\\\"scr\\\"\");\n  }\n\n  @Test public void fallbackEnum() throws Exception {\n    JsonAdapter<Roshambo> adapter = moshi.adapter(Roshambo.class).lenient();\n    assertThat(adapter.fromJson(\"\\\"SPOCK\\\"\")).isEqualTo(Roshambo.UNKNOWN);\n  }\n\n  @Test public void nullEnum() throws Exception {\n    JsonAdapter<Roshambo> adapter = moshi.adapter(Roshambo.class).lenient();\n    assertThat(adapter.fromJson(\"null\")).isNull();\n    assertThat(adapter.toJson(null)).isEqualTo(\"null\");\n  }\n\n  @Test public void throwsOnInvalidFallback() throws Exception {\n    try {\n      moshi.adapter(Value.class);\n      fail();\n    } catch (IllegalArgumentException expected) {\n      assertThat(expected).hasMessage(\n          \"No enum constant com.serjltt.moshi.adapters.FallbackEnumJsonAdapterTest.Value.UNK\");\n    }\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<Roshambo> adapter = moshi.adapter(Roshambo.class);\n\n    assertThat(adapter.toString()).isEqualTo(\n        \"JsonAdapter(com.serjltt.moshi.adapters.FallbackEnumJsonAdapterTest$Roshambo)\"\n            + \".fallbackEnum(UNKNOWN).nullSafe()\");\n  }\n\n  @Test public void ignoresUnannotatedEnums() throws Exception {\n    JsonAdapter<Regular> adapter = moshi.adapter(Regular.class).lenient();\n    assertThat(adapter.fromJson(\"\\\"ONE\\\"\")).isEqualTo(Regular.ONE);\n\n    try {\n      adapter.fromJson(\"\\\"TWO\\\"\");\n      fail();\n    } catch (JsonDataException expected) {\n      assertThat(expected).hasMessage(\n          \"Expected one of [ONE] but was TWO at path $\");\n    }\n  }\n\n  @Test public void factoryIgnoresUnsupportedTypes() throws Exception {\n    JsonAdapter<?> adapter1 = FallbackEnum.ADAPTER_FACTORY\n        .create(String.class, Collections.<Annotation>emptySet(), moshi);\n    assertThat(adapter1).isNull();\n\n    JsonAdapter<?> adapter2 = FallbackEnum.ADAPTER_FACTORY\n        .create(Roshambo.class, Collections.singleton(Wrapped.Factory.create(\"\")), moshi);\n    assertThat(adapter2).isNull();\n  }\n\n  @FallbackEnum(name = \"UNKNOWN\") enum Roshambo {\n    ROCK,\n    PAPER,\n    @Json(name = \"scr\") SCISSORS,\n    UNKNOWN\n  }\n\n  @FallbackEnum(name = \"UNK\") enum Value {\n    @SuppressWarnings(\"unused\") UNKNOWN\n  }\n\n  enum Regular {\n    ONE\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.FromJson;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.ToJson;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Set;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class FallbackOnNullJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(FallbackOnNull.ADAPTER_FACTORY)\n      .add(new Multiply.MultiplyAdapter())\n      .build();\n\n  @Test public void booleanFallbacks() throws Exception {\n    assertForClass(WrapsBool.class, false, true, \"{\\\"first\\\":false,\\\"second\\\":true}\");\n  }\n\n  private static class WrapsBool implements Wrapper<Boolean> {\n    @FallbackOnNull boolean first;\n    @FallbackOnNull(fallbackBoolean = true) boolean second;\n\n    @Override public Boolean first() {\n      return first;\n    }\n\n    @Override public Boolean second() {\n      return second;\n    }\n  }\n\n  @Test public void byteFallbacks() throws Exception {\n    assertForClass(WrapsByte.class, Byte.MIN_VALUE, (byte) 42, \"{\\\"first\\\":128,\\\"second\\\":42}\");\n  }\n\n  private static class WrapsByte implements Wrapper<Byte> {\n    @FallbackOnNull byte first;\n    @FallbackOnNull(fallbackByte = 42) byte second;\n\n    @Override public Byte first() {\n      return first;\n    }\n\n    @Override public Byte second() {\n      return second;\n    }\n  }\n\n  @Test public void charFallbacks() throws Exception {\n    assertForClass(WrapsChar.class, '\\u0000', 'a', \"{\\\"first\\\":\\\"\\\\u0000\\\",\\\"second\\\":\\\"a\\\"}\");\n  }\n\n  private static class WrapsChar implements Wrapper<Character> {\n    @FallbackOnNull char first;\n    @FallbackOnNull(fallbackChar = 'a') char second;\n\n    @Override public Character first() {\n      return first;\n    }\n\n    @Override public Character second() {\n      return second;\n    }\n  }\n\n  @Test public void doubleFallbacks() throws Exception {\n    assertForClass(WrapsDouble.class, Double.MIN_VALUE, 12.0,\n        \"{\\\"first\\\":4.9E-324,\\\"second\\\":12.0}\");\n  }\n\n  private static class WrapsDouble implements Wrapper<Double> {\n    @FallbackOnNull double first;\n    @FallbackOnNull(fallbackDouble = 12.0) double second;\n\n    @Override public Double first() {\n      return first;\n    }\n\n    @Override public Double second() {\n      return second;\n    }\n  }\n\n  @Test public void floatFallbacks() throws Exception {\n    assertForClass(WrapsFloat.class, Float.MIN_VALUE, 16.0f,\n        \"{\\\"first\\\":1.4E-45,\\\"second\\\":16.0}\");\n  }\n\n  private static class WrapsFloat implements Wrapper<Float> {\n    @FallbackOnNull float first;\n    @FallbackOnNull(fallbackFloat = 16.0f) float second;\n\n    @Override public Float first() {\n      return first;\n    }\n\n    @Override public Float second() {\n      return second;\n    }\n  }\n\n  @Test public void intFallbacks() throws Exception {\n    assertForClass(WrapsInt.class, Integer.MIN_VALUE, -1, \"{\\\"first\\\":-2147483648,\\\"second\\\":-1}\");\n  }\n\n  @Test public void intFallbacksNoLocaleInfluence() throws Exception {\n    Locale defaultLocale = Locale.getDefault();\n\n    Locale.setDefault(new Locale(\"tr\", \"TR\"));\n    assertForClass(WrapsInt.class, Integer.MIN_VALUE, -1, \"{\\\"first\\\":-2147483648,\\\"second\\\":-1}\");\n\n    Locale.setDefault(defaultLocale);\n  }\n\n  private static class WrapsInt implements Wrapper<Integer> {\n    @FallbackOnNull int first;\n    @FallbackOnNull(fallbackInt = -1) int second;\n\n    @Override public Integer first() {\n      return first;\n    }\n\n    @Override public Integer second() {\n      return second;\n    }\n  }\n\n  @Test public void longFallbacks() throws Exception {\n    assertForClass(WrapsLong.class, Long.MIN_VALUE, -113L,\n        \"{\\\"first\\\":-9223372036854775808,\\\"second\\\":-113}\");\n  }\n\n  private static class WrapsLong implements Wrapper<Long> {\n    @FallbackOnNull long first;\n    @FallbackOnNull(fallbackLong = -113) long second;\n\n    @Override public Long first() {\n      return first;\n    }\n\n    @Override public Long second() {\n      return second;\n    }\n  }\n\n  @Test public void shortFallbacks() throws Exception {\n    assertForClass(WrapsShort.class, Short.MIN_VALUE, (short) 121,\n        \"{\\\"first\\\":-32768,\\\"second\\\":121}\");\n  }\n\n  private static class WrapsShort implements Wrapper<Short> {\n    @FallbackOnNull short first;\n    @FallbackOnNull(fallbackShort = 121) short second;\n\n    @Override public Short first() {\n      return first;\n    }\n\n    @Override public Short second() {\n      return second;\n    }\n  }\n\n  @Test public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<AnotherInt> adapter = moshi.adapter(AnotherInt.class);\n\n    AnotherInt fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"willFallback\\\": null,\\n\"\n        + \"  \\\"willMultiply\\\": 3\\n\"\n        + \"}\");\n    assertThat(fromJson.willFallback).isEqualTo(2);\n    assertThat(fromJson.willMultiply).isEqualTo(6);\n\n    String toJson = adapter.toJson(fromJson);\n    // Both values should be serialized by the Multiply json adapter.\n    assertThat(toJson).isEqualTo(\"{\\\"willFallback\\\":1,\\\"willMultiply\\\":3}\");\n  }\n\n  private static class AnotherInt {\n    @FallbackOnNull(fallbackInt = 2) @Multiply int willFallback;\n    @FallbackOnNull(fallbackInt = 2) @Multiply int willMultiply;\n  }\n\n  @Test public void factoryIgnoresNonPrimitiveTypes() {\n    List<Class<?>> classes = new ArrayList<Class<?>>() {\n      {\n        add(Boolean.class);\n        add(Byte.class);\n        add(Character.class);\n        add(Double.class);\n        add(Float.class);\n        add(Integer.class);\n        add(Long.class);\n        add(Short.class);\n        add(String.class);\n        add(Object.class);\n      }\n    };\n\n    for (Class<?> cls : classes) {\n      assertThat(FallbackOnNull.ADAPTER_FACTORY.create(cls, ANNOTATIONS, moshi)).isNull();\n    }\n  }\n\n  @Test public void fallbackOnNullIsDelegated() throws Exception {\n    JsonAdapter<AndAnotherInt> adapter = moshi.adapter(AndAnotherInt.class);\n\n    AndAnotherInt fromJson = adapter.fromJson(\"{\\n\"\n            + \"  \\\"willFallback\\\": null\\n\"\n            + \"}\");\n    assertThat(fromJson.willFallback).isEqualTo(2);\n  }\n\n  private static class AndAnotherInt {\n    @AlwaysFallBackToTwoOnNull int willFallback;\n  }\n\n  @JsonQualifier\n  @FallbackOnNull(fallbackInt = 2)\n  @Retention(RetentionPolicy.RUNTIME)\n  @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })\n  @interface AlwaysFallBackToTwoOnNull { }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<Integer> adapter = moshi.adapter(int.class, ANNOTATIONS);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(Integer).fallbackOnNull(fallbackInt=-1)\");\n  }\n\n  private static final Set<? extends Annotation> ANNOTATIONS = Collections.singleton(\n      new FallbackOnNull() {\n\n        @Override public Class<? extends Annotation> annotationType() {\n          return FallbackOnNull.class;\n        }\n\n        @Override public boolean fallbackBoolean() {\n          return false;\n        }\n\n        @Override public byte fallbackByte() {\n          return 0;\n        }\n\n        @Override public char fallbackChar() {\n          return 0;\n        }\n\n        @Override public double fallbackDouble() {\n          return 0;\n        }\n\n        @Override public float fallbackFloat() {\n          return 0;\n        }\n\n        @Override public int fallbackInt() {\n          return -1; // Only this method will be taken into account\n        }\n\n        @Override public long fallbackLong() {\n          return 0;\n        }\n\n        @Override public short fallbackShort() {\n          return 0;\n        }\n      });\n\n  private <T extends Wrapper<P>, P> void assertForClass(Class<T> cls, P first, P second,\n      String asJson) throws IOException {\n    JsonAdapter<T> adapter = moshi.adapter(cls);\n\n    T fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"first\\\": null,\\n\"\n        + \"  \\\"second\\\": null\\n\"\n        + \"}\");\n    assertThat(fromJson.first()).isEqualTo(first);\n    assertThat(fromJson.second()).isEqualTo(second);\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(asJson);\n  }\n\n  private interface Wrapper<P> {\n    P first();\n\n    P second();\n  }\n\n  @JsonQualifier\n  @Retention(RetentionPolicy.RUNTIME) private @interface Multiply {\n    final class MultiplyAdapter {\n      @Multiply @FromJson int fromJson(int val) {\n        return val * 2;\n      }\n\n      @ToJson int toJson(@Multiply int val) {\n        return val / 2;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapterTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.Types;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport org.junit.Test;\n\nimport static java.util.Arrays.asList;\nimport static org.assertj.core.api.Java6Assertions.assertThat;\n\npublic final class FilterNullsJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(FilterNulls.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void noNullValues() throws Exception {\n    JsonAdapter<List<String>> adapter = moshi.adapter(Types.newParameterizedType(List.class,\n        String.class), FilterNulls.class);\n\n    List<String> fromJson = adapter.fromJson(\"[\\\"apple\\\",\\\"banana\\\"]\");\n    assertThat(fromJson).containsExactly(\"apple\", \"banana\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"[\\\"apple\\\",\\\"banana\\\"]\");\n  }\n\n  @Test public void nullValues() throws Exception {\n    JsonAdapter<List<String>> adapter = moshi.adapter(Types.newParameterizedType(List.class,\n        String.class), FilterNulls.class);\n\n    List<String> fromJson = adapter.fromJson(\"[\\\"apple\\\",\\\"banana\\\",null]\");\n    assertThat(fromJson).containsExactly(\"apple\", \"banana\");\n\n    String toJson = adapter.toJson(new ArrayList<>(asList(\"apple\", \"banana\", null)));\n    assertThat(toJson).isEqualTo(\"[\\\"apple\\\",\\\"banana\\\"]\");\n  }\n\n  @Test public void nullList() throws Exception {\n    JsonAdapter<List<String>> adapter = moshi.adapter(Types.newParameterizedType(List.class,\n        String.class), FilterNulls.class);\n\n    List<String> fromJson = adapter.fromJson(\"null\");\n    assertThat(fromJson).isNull();\n\n    String toJson = adapter.toJson(null);\n    assertThat(toJson).isEqualTo(\"null\");\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(Types.newParameterizedType(Collection.class,\n        String.class), FilterNulls.class);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().collection().nullSafe().filterNulls()\");\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/FirstElementJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class FirstElementJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(FirstElement.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void first() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    Data fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"obj\\\": [\\n\"\n        + \"    \\\"one\\\",\\n\"\n        + \"    \\\"two\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"one\");\n\n    String toJson = adapter.toJson(fromJson);\n    // The excluded data is lost during parsing\n    // Adapter under test assumes that the consumer doesn't need that data\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[\\\"one\\\"]}\");\n  }\n\n  @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": []\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonOnNullArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": null\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonExpectsAnArray() throws Exception {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"obj\\\": \\\"this_will_throw\\\"\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException e) {\n      // Moshi's Collection adapter will throw\n      assertThat(e).hasMessage(\"Expected BEGIN_ARRAY but was STRING at path $.obj\");\n    }\n  }\n\n  // Currently there is no way to create an adapter\n  @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"str\\\": [\\n\"\n        + \"    \\\"test\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"testCustom\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"str\\\":[\\\"test\\\"]}\");\n  }\n\n  // This one is redundant, but keeps JaCoCo quiet\n  @Test public void factoryExpectsOnlyOneAnnotation() throws Exception {\n    // A list of fake annotations.\n    Set<Annotation> annotations = new LinkedHashSet<Annotation>() {\n      {\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Test.class;\n          }\n        });\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Custom.class;\n          }\n        });\n      }\n    };\n    assertThat(FirstElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n\n    // Emulate existing annotation (should also return null).\n    annotations.add(new Annotation() {\n      @Override public Class<? extends Annotation> annotationType() {\n        return FirstElement.class;\n      }\n    });\n    assertThat(FirstElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class, FirstElement.class);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().collection().nullSafe().elementAt(0)\");\n  }\n\n  private void assertNullReturn(String string) throws IOException {\n    JsonAdapter<Data> adapter = moshi.adapter(Data.class);\n\n    Data fromJson = adapter.fromJson(string);\n    assertThat(fromJson.str).isNull();\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[null]}\");\n  }\n\n  private static class Data {\n    @FirstElement\n    @Json(name = \"obj\") String str;\n  }\n\n  private static class Data2 {\n    @FirstElement\n    @Custom String str;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/LastElementJsonAdapterTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.Moshi;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class LastElementJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(LastElement.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void last() throws Exception {\n    JsonAdapter<LastElementJsonAdapterTest.Data>\n        adapter = moshi.adapter(LastElementJsonAdapterTest.Data.class);\n\n    LastElementJsonAdapterTest.Data fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"obj\\\": [\\n\"\n        + \"    \\\"one\\\",\\n\"\n        + \"    \\\"two\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"two\");\n\n    String toJson = adapter.toJson(fromJson);\n    // The excluded data is lost during parsing\n    // Adapter under test assumes that the consumer doesn't need that data\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[\\\"two\\\"]}\");\n  }\n\n  @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": []\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonOnNullArrayReturnsNull() throws Exception {\n    assertNullReturn(\"{\\n\"\n        + \"  \\\"obj\\\": null\\n\"\n        + \"}\");\n  }\n\n  @Test public void fromJsonExpectsAnArray() throws Exception {\n    JsonAdapter<LastElementJsonAdapterTest.Data> adapter = moshi.adapter(Data.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"obj\\\": \\\"this_will_throw\\\"\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException e) {\n      // Moshi's Collection adapter will throw\n      assertThat(e).hasMessage(\"Expected BEGIN_ARRAY but was STRING at path $.obj\");\n    }\n  }\n\n  // Currently there is no way to create an adapter\n  @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<LastElementJsonAdapterTest.Data2> adapter = moshi.adapter(Data2.class);\n\n    LastElementJsonAdapterTest.Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"str\\\": [\\n\"\n        + \"    \\\"test\\\"\\n\"\n        + \"  ]\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"testCustom\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"str\\\":[\\\"test\\\"]}\");\n  }\n\n  // This one is redundant, but keeps JaCoCo quiet\n  @Test public void factoryExpectsOnlyOneAnnotation() throws Exception {\n    // A list of fake annotations.\n    Set<Annotation> annotations = new LinkedHashSet<Annotation>() {\n      {\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Test.class;\n          }\n        });\n        add(new Annotation() {\n          @Override public Class<? extends Annotation> annotationType() {\n            return Custom.class;\n          }\n        });\n      }\n    };\n    assertThat(LastElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n\n    // Emulate existing annotation (should also return null).\n    annotations.add(new Annotation() {\n      @Override public Class<? extends Annotation> annotationType() {\n        return LastElement.class;\n      }\n    });\n    assertThat(LastElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull();\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class, LastElement.class);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().collection().nullSafe().lastElement()\");\n  }\n\n  private void assertNullReturn(String string) throws IOException {\n    JsonAdapter<LastElementJsonAdapterTest.Data> adapter = moshi.adapter(Data.class);\n\n    LastElementJsonAdapterTest.Data fromJson = adapter.fromJson(string);\n    assertThat(fromJson.str).isNull();\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"obj\\\":[null]}\");\n  }\n\n  private static class Data {\n    @LastElement\n    @Json(name = \"obj\") String str;\n  }\n\n  private static class Data2 {\n    @LastElement\n    @Custom String str;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/SerializeNullsJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonWriter;\nimport com.squareup.moshi.Moshi;\nimport okio.Buffer;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class SerializeNullsJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(SerializeNulls.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void serializesNulls() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"data\\\": null\\n\"\n        + \"}\");\n    assertThat(fromJson.data).isNull();\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":null}\");\n  }\n\n  @Test public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"data\\\": \\\"val\\\"\\n\"\n        + \"}\");\n    assertThat(fromJson.data).isEqualTo(\"valCustom\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":\\\"val\\\"}\");\n\n    Data2 data = new Data2();\n    data.data = null;\n    toJson = adapter.toJson(data);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":null}\");\n  }\n\n  @Test public void maintainsPreviousSerializationValue() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n    Data1 data1 = new Data1();\n\n    JsonWriter writer1 = JsonWriter.of(new Buffer());\n    writer1.setSerializeNulls(true);\n    adapter.toJson(writer1, data1);\n    assertThat(writer1.getSerializeNulls()).isTrue();\n\n    JsonWriter writer2 = JsonWriter.of(new Buffer());\n    writer2.setSerializeNulls(false);\n    adapter.toJson(writer2, data1);\n    assertThat(writer2.getSerializeNulls()).isFalse();\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class, SerializeNulls.class);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().serializeNulls()\");\n  }\n\n  private static class Data1 {\n    @SerializeNulls String data;\n  }\n\n  private static class Data2 {\n    @Custom\n    @SerializeNulls String data;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyJsonAdapterTest.java",
    "content": "package com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class SerializeOnlyJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(SerializeOnly.ADAPTER_FACTORY)\n      .add(SerializeNulls.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void serializeOnly() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\\"data\\\": \\\"test\\\"}\");\n    assertThat(fromJson.data).isNull();\n\n    fromJson.data = \"1234\";\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"data\\\":\\\"1234\\\"}\");\n  }\n\n  @Test public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\\"data\\\": \\\"test\\\"}\");\n    assertThat(fromJson.data).isNull();\n\n    fromJson.data = \"1234Custom\";\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":\\\"1234\\\"}\");\n\n    Data2 data = new Data2();\n    data.data = null;\n    toJson = adapter.toJson(data);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":null}\");\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class, SerializeOnly.class);\n\n    assertThat(adapter.toString()).isEqualTo(\"JsonAdapter(String).nullSafe().serializeOnly()\");\n  }\n\n  private static class Data1 {\n    @SerializeOnly String data;\n  }\n\n  private static class Data2 {\n    @Custom @SerializeOnly @SerializeNulls String data;\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 com.serjltt.moshi.adapters;\n\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.Moshi;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\npublic final class SerializeOnlyNonEmptyJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(SerializeOnlyNonEmpty.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .build();\n\n  @Test public void serializesOnlyNonEmptyCustomArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"customArray\\\": [{\"\n        + \"\\\"data\\\":\\\"blub\\\"\"\n        + \"}]\\n\"\n        + \"}\");\n    assertThat(fromJson.customArray).isNotNull().hasSize(1);\n    assertThat(fromJson.customArray[0].data).isEqualTo(\"blub\");\n\n    fromJson.customArray = new CustomType[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.customArray = new CustomType[] { new CustomType(\"blub\") };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"customArray\\\":[{\\\"data\\\":\\\"blub\\\"}]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyByteArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"byteArray\\\": [1]\\n\"\n        + \"}\");\n    assertThat(fromJson.byteArray).containsExactly((byte) 1);\n\n    fromJson.byteArray = new byte[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.byteArray = new byte[] { 5 };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"byteArray\\\":[5]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyCharArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"charArray\\\": [\\\"A\\\"]\\n\"\n        + \"}\");\n    assertThat(fromJson.charArray).containsExactly((char) 65);\n\n    fromJson.charArray = new char[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.charArray = new char[] { 65 };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"charArray\\\":[\\\"A\\\"]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyShortArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"shortArray\\\": [1]\\n\"\n        + \"}\");\n    assertThat(fromJson.shortArray).containsExactly((short) 1);\n\n    fromJson.shortArray = new short[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.shortArray = new short[] { 5 };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"shortArray\\\":[5]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyIntArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"intArray\\\": [1]\\n\"\n        + \"}\");\n    assertThat(fromJson.intArray).containsExactly(1);\n\n    fromJson.intArray = new int[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.intArray = new int[] { 5 };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"intArray\\\":[5]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyLongArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"longArray\\\": [1]\\n\"\n        + \"}\");\n    assertThat(fromJson.longArray).containsExactly(1L);\n\n    fromJson.longArray = new long[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.longArray = new long[] { 5L };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"longArray\\\":[5]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyFloatArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"floatArray\\\": [1.0]\\n\"\n        + \"}\");\n    assertThat(fromJson.floatArray).containsExactly(1.f);\n\n    fromJson.floatArray = new float[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.floatArray = new float[] { 5f };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"floatArray\\\":[5.0]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyDoubleArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"doubleArray\\\": [1.0]\\n\"\n        + \"}\");\n    assertThat(fromJson.doubleArray).containsExactly(1.f);\n\n    fromJson.doubleArray = new double[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.doubleArray = new double[] { 5f };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"doubleArray\\\":[5.0]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyBooleanArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"booleanArray\\\": [false]\\n\"\n        + \"}\");\n    assertThat(fromJson.booleanArray).containsExactly(false);\n\n    fromJson.booleanArray = new boolean[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.booleanArray = new boolean[] { false };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"booleanArray\\\":[false]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyStringArray() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"stringArray\\\": [\\\"blub\\\"]\\n\"\n        + \"}\");\n    assertThat(fromJson.stringArray).containsExactly(\"blub\");\n\n    fromJson.stringArray = new String[0];\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.stringArray = new String[] { \"blub\" };\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"stringArray\\\":[\\\"blub\\\"]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyCollection() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"collection\\\": [\\\"blub\\\"]\\n\"\n        + \"}\");\n    assertThat(fromJson.collection).containsExactly(\"blub\");\n\n    fromJson.collection = new ArrayList<>(0);\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.collection.add(\"blub\");\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"collection\\\":[\\\"blub\\\"]}\");\n  }\n\n  @Test public void serializesOnlyNonEmptyMap() throws Exception {\n    JsonAdapter<Data1> adapter = moshi.adapter(Data1.class);\n\n    Data1 fromJson = adapter.fromJson(\"{\\n\"\n        + \"\\\"map\\\": {\"\n        + \"\\\"email\\\":\\\"blub\\\"\\n\"\n        + \"}\\n\"\n        + \"}\");\n    assertThat(fromJson.map).containsEntry(\"email\", \"blub\");\n\n    fromJson.map = new HashMap<>();\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{}\");\n\n    fromJson.map.put(\"email\", \"blub\");\n    assertThat(adapter.toJson(fromJson)).isEqualTo(\"{\\\"map\\\":{\\\"email\\\":\\\"blub\\\"}}\");\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String[].class, SerializeOnlyNonEmpty.class);\n\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().array().nullSafe().serializeOnlyNonEmpty()\");\n  }\n\n  static class Data1 {\n    @SerializeOnlyNonEmpty CustomType[] customArray;\n    @SerializeOnlyNonEmpty byte[] byteArray;\n    @SerializeOnlyNonEmpty char[] charArray;\n    @SerializeOnlyNonEmpty short[] shortArray;\n    @SerializeOnlyNonEmpty int[] intArray;\n    @SerializeOnlyNonEmpty long[] longArray;\n    @SerializeOnlyNonEmpty float[] floatArray;\n    @SerializeOnlyNonEmpty double[] doubleArray;\n    @SerializeOnlyNonEmpty boolean[] booleanArray;\n    @SerializeOnlyNonEmpty String[] stringArray;\n    @SerializeOnlyNonEmpty Collection<String> collection;\n    @SerializeOnlyNonEmpty Map<String, String> map;\n  }\n\n  static class CustomType {\n    final String data;\n\n    CustomType(final String data) {\n      this.data = data;\n    }\n  }\n}\n"
  },
  {
    "path": "src/unitTest/java/com/serjltt/moshi/adapters/WrappedJsonAdapterTest.java",
    "content": "/*\n * Copyright 2016 Serj Lotutovici\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS 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 com.serjltt.moshi.adapters;\n\nimport com.pushtorefresh.private_constructor_checker.PrivateConstructorChecker;\nimport com.squareup.moshi.FromJson;\nimport com.squareup.moshi.JsonAdapter;\nimport com.squareup.moshi.JsonDataException;\nimport com.squareup.moshi.JsonEncodingException;\nimport com.squareup.moshi.JsonQualifier;\nimport com.squareup.moshi.Moshi;\nimport com.squareup.moshi.ToJson;\nimport com.squareup.moshi.Types;\nimport java.io.IOException;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.util.Collections;\nimport java.util.List;\nimport org.junit.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class WrappedJsonAdapterTest {\n  // Lazy adapters work only within the context of moshi.\n  private final Moshi moshi = new Moshi.Builder()\n      .add(Wrapped.ADAPTER_FACTORY)\n      .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost.\n      .add(new ThrowingAdapter()) // We need to check that exceptions are propagated correctly.\n      .build();\n\n  @Test public void oneObject() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"data\\\": {\\n\"\n        + \"    \\\"1\\\": {\\n\"\n        + \"      \\\"2\\\": {\\n\"\n        + \"        \\\"str\\\": \\\"test\\\",\\n\"\n        + \"        \\\"val\\\": 42\\n\"\n        + \"      }\\n\"\n        + \"    }\\n\"\n        + \"  }\\n\"\n        + \"}\");\n    assertThat(fromJson).isNotNull();\n    assertThat(fromJson.data.str).isEqualTo(\"test\");\n    assertThat(fromJson.data.val).isEqualTo(42);\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":{\\\"1\\\":{\\\"2\\\":{\\\"str\\\":\\\"test\\\",\\\"val\\\":42}}}}\");\n  }\n\n  @Test public void arrayOfObjects() throws Exception {\n    JsonAdapter<List<Data2>> adapter = moshi.adapter(\n        Types.newParameterizedType(List.class, Data2.class));\n\n    List<Data2> fromJson = adapter.fromJson(\"[\\n\"\n        + \"  {\\n\"\n        + \"    \\\"data\\\": {\\n\"\n        + \"      \\\"1\\\": {\\n\"\n        + \"        \\\"2\\\": {\\n\"\n        + \"          \\\"str\\\": \\\"funny\\\",\\n\"\n        + \"          \\\"val\\\": 42\\n\"\n        + \"        }\\n\"\n        + \"      }\\n\"\n        + \"    }\\n\"\n        + \"  },\\n\"\n        + \"  {\\n\"\n        + \"    \\\"data\\\": {\\n\"\n        + \"      \\\"1\\\": {\\n\"\n        + \"        \\\"2\\\": {\\n\"\n        + \"          \\\"str\\\": \\\"prime\\\",\\n\"\n        + \"          \\\"val\\\": 43\\n\"\n        + \"        }\\n\"\n        + \"      }\\n\"\n        + \"    }\\n\"\n        + \"  }\\n\"\n        + \"]\");\n    assertThat(fromJson.get(0).data.str).isEqualTo(\"funny\");\n    assertThat(fromJson.get(0).data.val).isEqualTo(42);\n    assertThat(fromJson.get(1).data.str).isEqualTo(\"prime\");\n    assertThat(fromJson.get(1).data.val).isEqualTo(43);\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"[\"\n        + \"{\\\"data\\\":{\\\"1\\\":{\\\"2\\\":{\\\"str\\\":\\\"funny\\\",\\\"val\\\":42}}}},\"\n        + \"{\\\"data\\\":{\\\"1\\\":{\\\"2\\\":{\\\"str\\\":\\\"prime\\\",\\\"val\\\":43}}}}\"\n        + \"]\");\n  }\n\n  @Test public void failOnNotFound() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"data\\\": {\\n\"\n          + \"    \\\"1\\\": {\\n\"\n          + \"      \\\"2\\\": null\\n\"\n          + \"    }\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException ex) {\n      assertThat(ex).hasMessage(\n          \"Wrapped Json expected at path: [1, 2]. Found null at $.data.1.2\");\n    }\n  }\n\n  @Test public void failOnNotFound2() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"data\\\": {\\n\"\n          + \"    \\\"1\\\": null\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException ex) {\n      assertThat(ex).hasMessage(\n          \"Wrapped Json expected at path: [1, 2]. Found null at $.data.1\");\n    }\n  }\n\n  @Test public void failOnNotFoundFalse() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class,\n        Collections.singleton(Wrapped.Factory.create(false, \"one\")));\n\n    String fromJson = adapter.fromJson(\"{\\\"one\\\":null}\");\n    assertThat(fromJson).isEqualTo(null);\n  }\n\n  @Test public void notNullSafe() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"data\\\": null\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException expected) {\n    }\n\n    Data2 data2 = new Data2();\n    String toJson = adapter.toJson(data2);\n    assertThat(toJson).isEqualTo(\"{}\");\n\n    toJson = adapter.serializeNulls().toJson(data2);\n    assertThat(toJson).isEqualTo(\"{\\\"data\\\":{\\\"1\\\":{\\\"2\\\":null}}}\");\n  }\n\n  @Test public void fromJsonSkipsNonPathValues() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"data\\\": {\\n\"\n        + \"    \\\"should_be_skipped\\\": null,\\n\"\n        + \"    \\\"1\\\": {\\n\"\n        + \"      \\\"2\\\": {\\n\"\n        + \"        \\\"str\\\": \\\"works\\\",\\n\"\n        + \"        \\\"val\\\": 11\\n\"\n        + \"      }\\n\"\n        + \"    }\\n\"\n        + \"\\n\"\n        + \"  }\\n\"\n        + \"}\");\n\n    assertThat(fromJson.data.str).isEqualTo(\"works\");\n    assertThat(fromJson.data.val).isEqualTo(11);\n  }\n\n  @Test public void fromJsonRemainingPathValues() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    Data2 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"data\\\": {\\n\"\n        + \"    \\\"1\\\": {\\n\"\n        + \"      \\\"2\\\": {\\n\"\n        + \"        \\\"str\\\": \\\"works\\\",\\n\"\n        + \"        \\\"val\\\": 11\\n\"\n        + \"      }\\n\"\n        + \"    },\\n\"\n        + \"    \\\"should_be_skipped1\\\": null,\\n\"\n        + \"    \\\"should_be_skipped2\\\": null\\n\"\n        + \"  }\\n\"\n        + \"}\");\n\n    assertThat(fromJson.data.str).isEqualTo(\"works\");\n    assertThat(fromJson.data.val).isEqualTo(11);\n  }\n\n  @Test public void fromJsonOnIncorrectPath() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"data\\\": {\\n\"\n          + \"    \\\"2\\\": {\\n\"\n          + \"      \\\"1\\\": null\\n\"\n          + \"    }\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException e) {\n      assertThat(e).hasMessage(\"Wrapped Json expected at path: [1, 2]. Actual: $.data\");\n    }\n  }\n\n  @Test public void fromJsonDoesNotSwallowIOExceptions() throws Exception {\n    JsonAdapter<Data4> adapter = moshi.adapter(Data4.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"th\\\": {\\n\"\n          + \"    \\\"1\\\": \\\"this_will_throw\\\"\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (IOException e) {\n      assertThat(e).hasMessage(\"ThrowingAdapter.fromJson\");\n    }\n  }\n\n  @Test public void fromJsonDoesNotSwallowJsonEncodingExceptions() throws Exception {\n    JsonAdapter<Data2> adapter = moshi.adapter(Data2.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"data\\\": {\\n\"\n          + \"    \\\"1\\\": {\\n\"\n          + \"      \\\"2\\\": {\\n\"\n          + \"        \\\"str\\\": \\\"valid\\\",\\n\"\n          + \"        \\\"val\\\": NaN\\n\"\n          + \"      }\\n\"\n          + \"    }\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonEncodingException e) {\n      assertThat(e).hasMessage(\n          \"Use JsonReader.setLenient(true) to accept malformed JSON at path $.data.1.2.val\");\n    }\n  }\n\n  @Test public void fromJsonDoesNotSwallowJsonDataExceptions() throws Exception {\n    JsonAdapter<Data3> adapter = moshi.adapter(Data3.class);\n\n    try {\n      adapter.fromJson(\"{\\n\"\n          + \"  \\\"str\\\": {\\n\"\n          + \"    \\\"1\\\": false\\n\"\n          + \"  }\\n\"\n          + \"}\");\n      fail();\n    } catch (JsonDataException e) {\n      assertThat(e).hasMessage(\"Expected a string but was BOOLEAN at path $.str.1\");\n    }\n  }\n\n  @Test public void toJsonDoesNotSwallowExceptions() throws Exception {\n    JsonAdapter<Data4> adapter = moshi.adapter(Data4.class);\n\n    Data4 data4 = new Data4();\n    data4.th = new Throws();\n    try {\n      adapter.toJson(data4);\n      fail();\n    } catch (Throwable e) {\n      // Moshi wraps write exceptions in an AssertionError\n      assertThat(e.getCause()).hasMessage(\"ThrowingAdapter.toJson\");\n    }\n  }\n\n  @Test public void factoryMaintainsOtherAnnotations() throws Exception {\n    JsonAdapter<Data3> adapter = moshi.adapter(Data3.class);\n\n    Data3 fromJson = adapter.fromJson(\"{\\n\"\n        + \"  \\\"str\\\": {\\n\"\n        + \"    \\\"1\\\": \\\"test\\\"\\n\"\n        + \"  }\\n\"\n        + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"testCustom\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"str\\\":{\\\"1\\\":\\\"test\\\"}}\");\n  }\n\n  @Test public void toStringReflectsInnerAdapter() throws Exception {\n    JsonAdapter<String> adapter = moshi.adapter(String.class,\n        Collections.singleton(Wrapped.Factory.create(\"1\", \"2\")));\n    assertThat(adapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().wrapped([1, 2]).failOnNotFound()\");\n\n    JsonAdapter<String> failingAdapter = moshi.adapter(String.class,\n        Collections.singleton(Wrapped.Factory.create(false, \"1\", \"2\")));\n    assertThat(failingAdapter.toString())\n        .isEqualTo(\"JsonAdapter(String).nullSafe().wrapped([1, 2])\");\n  }\n\n  @Test\n  public void wrappedFactoryRespectsEquals() throws Exception {\n    Wrapped wrapped1 = Wrapped.Factory.create(\"one\", \"two\", \"three\");\n    Wrapped wrapped2 = Wrapped.Factory.create(\"one\", \"two\", \"three\");\n    Wrapped wrapped3 = Wrapped.Factory.create(\"one\", \"two\", \"four\");\n\n    assertThat(wrapped1).isEqualTo(wrapped2);\n    assertThat(wrapped1.hashCode()).isEqualTo(wrapped2.hashCode());\n    assertThat(wrapped1.toString()).isEqualTo(wrapped2.toString());\n\n    assertThat(wrapped1).isNotEqualTo(wrapped3);\n    assertThat(wrapped1.hashCode()).isNotEqualTo(wrapped3.hashCode());\n    assertThat(wrapped1.toString()).isNotEqualTo(wrapped3.toString());\n  }\n\n  @Test public void checkWrappedFactoryConstructorThrows() throws Exception {\n    PrivateConstructorChecker\n        .forClass(Wrapped.Factory.class)\n        .expectedTypeOfException(AssertionError.class)\n        .expectedExceptionMessage(\"No instances.\")\n        .check();\n  }\n\n  @Test public void factoryFetchesWrappedFromDelegate() throws Exception {\n    JsonAdapter<Data5> adapter = moshi.adapter(Data5.class);\n\n    Data5 fromJson = adapter.fromJson(\"{\\n\"\n            + \"  \\\"str\\\": {\\n\"\n            + \"    \\\"1\\\": \\\"test\\\"\\n\"\n            + \"  }\\n\"\n            + \"}\");\n    assertThat(fromJson.str).isEqualTo(\"test\");\n\n    String toJson = adapter.toJson(fromJson);\n    assertThat(toJson).isEqualTo(\"{\\\"str\\\":{\\\"1\\\":\\\"test\\\"}}\");\n  }\n\n  private static class Data1 {\n    String str;\n    int val;\n  }\n\n  private static class Data2 {\n    @Wrapped(path = { \"1\", \"2\" }) Data1 data;\n  }\n\n  private static class Data3 {\n    @Custom\n    @Wrapped(path = \"1\") String str;\n  }\n\n  private static class Data4 {\n    @Wrapped(path = \"1\") Throws th;\n  }\n\n  private static class Data5 {\n    @WrappedDelegate String str;\n  }\n  private static class Throws {\n  }\n\n  @JsonQualifier\n  @Wrapped(path = \"1\")\n  @Retention(RetentionPolicy.RUNTIME)\n  @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })\n  @interface WrappedDelegate { }\n\n  /** String adapter, that will throw on read and write. */\n  private static final class ThrowingAdapter {\n    @FromJson Throws fromJson(String str) throws IOException {\n      throw new IOException(\"ThrowingAdapter.fromJson\");\n    }\n\n    @ToJson String toJson(Throws th) throws IOException {\n      throw new IOException(\"ThrowingAdapter.toJson\");\n    }\n  }\n}\n"
  }
]