[
  {
    "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=\"JakeWharton/butterknife\"\nJDK=\"oraclejdk8\"\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_JDK_VERSION\" != \"$JDK\" ]; then\n  echo \"Skipping snapshot deployment: wrong JDK. Expected '$JDK' but was '$TRAVIS_JDK_VERSION'.\"\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 uploadArchives\n  echo \"Snapshot deployed!\"\nfi\n"
  },
  {
    "path": ".github/workflows/gradle-wrapper-validation.yml",
    "content": "name: \"Validate Gradle Wrapper\"\non: [push, pull_request]\n\njobs:\n  validation:\n    name: \"Validation\"\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: gradle/wrapper-validation-action@v1\n"
  },
  {
    "path": ".gitignore",
    "content": "bin\ngen\nout\nlib\n\n.idea\n*.iml\nclasses\n\nobj\n\n.DS_Store\n\n# Gradle\n.gradle\njniLibs\nbuild\nlocal.properties\nreports\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: android\n\njdk:\n  - oraclejdk8\n\nbefore_install:\n  # Install SDK license so Android Gradle plugin can install deps.\n  - mkdir \"$ANDROID_HOME/licenses\" || true\n  - echo \"d56f5187479451eabf01fb78af6dfcb131a6481e\" > \"$ANDROID_HOME/licenses/android-sdk-license\"\n  - echo \"24333f8a63b6825ea9c5514f83c2829b004d1fee\" >> \"$ANDROID_HOME/licenses/android-sdk-license\"\n  # Install the rest of tools (e.g., avdmanager)\n  - sdkmanager tools\n  # Install the system image\n  - sdkmanager \"system-images;android-18;default;armeabi-v7a\"\n  # Create and start emulator for the script. Meant to race the install task.\n  - echo no | avdmanager create avd --force -n test -k \"system-images;android-18;default;armeabi-v7a\"\n  - $ANDROID_HOME/emulator/emulator -avd test -no-audio -no-window &\n\ninstall: ./gradlew clean assemble assembleAndroidTest --stacktrace\n\nbefore_script:\n  - android-wait-for-emulator\n  - adb shell input keyevent 82\n\nscript: ./gradlew check connectedCheck --stacktrace\n\nafter_success:\n  - .buildscript/deploy_snapshot.sh\n\nenv:\n  global:\n    - secure: \"ESbreW4FNMPQhV1zbFb9iBvhFWFbVHecaig3Si3+4nrJCMn9x4nqB18ZcU+Aviw67WQNcuSH4I0Hl08uknl+kzE/xKEfPLmu28bptXRCSued49aL11i2aQmRj5nqP2yxkinhtRGOQxzIo56NmFt7sIcEXODM3D5a6q7s9tlvPfw=\"\n    - secure: \"JWEeqx0CWBqAkjcREHUg3Ei8wxqp59HZag8EidSLwmekgPJQwipwuEeXMZyPCGJCP+4ijUirtS/hRApi37BW0LYdt+XR7dI1TSZ0HFLTLqSPfWfsUcjmGpmoqVUv8FLVhC+KA42YeEhqkEaCUW92gJeAyK8swxDqGHAPT/sfKRA=\"\n\nbranches:\n  except:\n    - gh-pages\n\nnotifications:\n  email: false\n\nsudo: false\n\nbefore_cache:\n  - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock\n  - rm -fr $HOME/.gradle/caches/*/plugin-resolution/\n\ncache:\n  directories:\n    - $HOME/.gradle/caches/\n    - $HOME/.gradle/wrapper/\n    - $HOME/.android/build-cache\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "Change Log\n==========\n\nVersion 10.2.3 *(2020-08-12)*\n-----------------------------\n\nHeads up: Development on this tool is winding down as [view binding](https://developer.android.com/topic/libraries/view-binding) is stable in AS/AGP 3.6+.\n\n * Fix: Support receiving `MotionEvent` in an `@OnTouch` callback when using 'butterknife-reflect'.\n\n\nVersion 10.2.2 *(2020-08-03)*\n-----------------------------\n\nHeads up: Development on this tool is winding down as [view binding](https://developer.android.com/topic/libraries/view-binding) is stable in AS/AGP 3.6+.\n\n * Fix: Views detached while processing click callbacks will no longer disable future clicks on other views.\n\n\nVersion 10.2.1 *(2019-12-19)*\n-----------------------------\n\nHeads up: Development on this tool is winding down as [view binding](https://developer.android.com/topic/libraries/view-binding) will be stable in AS/AGP 3.6.\n\n * New: Make R2-generating Gradle task cacheable by default.\n * Fix: R2 classes now generate their own unique values for entries. This ensures that the annotation processor\n   can always do a reverse mapping from ID back to name and type. In AGP 3.6.0, the `R.txt` symbol table that was\n   previously used as a source for values now uses 0 for every entry which required this change.\n * Fix: Lint check for R2 values now properly handles static imports for entries.\n\n\nVersion 10.2.0 *(2019-09-12)*\n-----------------------------\n\n * New: Support incremental annotation processing.\n * Fix: Detect generated superclass bindings across compilation units.\n * Fix: Avoid deprecated APIs from the Android Gradle plugin. As a result, the new minimum supported version\n   of the Android Gradle plugin is 3.3.\n\n\nVersion 10.1.0 *(2019-02-13)*\n-----------------------------\n\n * New: Listeners which require return values (e.g., long click) can now be bound to methods returning `void`.\n   The default value of `true` will be returned in this case.\n * New: Add support for `@OnTextChanged` and `@OnPageChange` to reflection backend.\n * Remove enforcement of required views in the reflection backend. Most `@Nullable` annotations do not have\n   runtime retention so they can't be checked at runtime with reflection. Instead of forcing everyone to find\n   a new annotation, this enforcement is now dropped. While this might lead to nulls in otherwise required\n   view bindings, they'll either be unused or quickly cause a `NullPointerException`.\n\n\nVersion 10.0.0 *(2019-01-03)*\n-----------------------------\n\n * Equivalent to 9.0.0 but only supports AndroidX-enabled builds.\n * Removed APIs deprecated in 9.0.0.\n\n\nVersion 9.0.0 *(2019-01-03)*\n----------------------------\n\n * New: Support for AndroidX. Requires `android.useAndroidX=true` in `gradle.properties` to generate\n   AndroidX code.\n\n * New: A `butterknife-runtime` artifact has been extracted from `butterknife` which contains the APIs\n   required for the generated code but does not contain the code to reflectively look up the generated\n   code. This allows you to reference the generated code directly such that R8/ProGuard optimization can\n   rename both the generated code and your classes. `ButterKnife.bind` and the consumer R8/ProGuard rules\n   remain in the old `butterknife` artifact.\n \n * New: Experimental `butterknife-reflect` artifact eliminates the need to run the annotation\n   processor for IDE builds. This artifact is binary compatible with `butterknife` so it can be interchanged\n   depending on how your build is being invoked. See [its README](butterknife-reflect/README.md) for more\n   information. Currently about 90% of functionality is covered. File bugs for anything that does not work.\n\n   Note: This artifact requires Java 8. There's no good reason for this except to push the ecosystem to\n   having this be a default. As of AGP 3.2 there is no reason not to do this.\n\n * New: Lint checks have been ported to UAST and now work on Kotlin code.\n \n * Helpers such as `apply` have been deprecated on `ButterKnife` and are now available on the `ViewCollections` class.\n\n * Add support for Android Gradle plugin 3.3 and newer where `R` is no longer generated as Java source. This\n   has a side-effect of removing support for Android Gradle plugin 3.0.x (and older).\n * Use Java 8 bytecode for all artifacts as announced in RC1 release notes.\n * Fix: Allow `@BindFont` to work prior to API 26 using `ResourcesCompat`.\n * Fix: Update Android Gradle plugin to 3.1 or newer to fix binary incompatibilities.\n * Fix: Correct generated resource annotation names when running Turkish locale.\n * Fix: Use the application ID instead of the resource package for generating `R2`.\n * Cache the fact that a class hierarchy has no remaining bindings to prevent traversing the hierarchy\n   multiple times.\n * Deprecated methods from 8.x have been removed.\n\n\nVersion 9.0.0-rc3 *(2018-12-20)*\n--------------------------------\n\n * Fix: Correct generated resource annotation names when running Turkish locale.\n * Cache the fact that a class hierarchy has no remaining bindings to prevent traversing the hierarchy\n   multiple times.\n\n\nVersion 9.0.0-rc2 *(2018-11-19)*\n--------------------------------\n\n * Add support for Android Gradle plugin 3.3 and newer where `R` is no longer generated as Java source. This\n   has a side-effect of removing support for Android Gradle plugin 3.0.x (and older).\n * Use Java 8 bytecode for all artifacts as announced in RC1 release notes.\n\n\nVersion 9.0.0-rc1 *(2018-10-10)*\n--------------------------------\n\n * New: Support for AndroidX. Requires `android.useAndroidX=true` in `gradle.properties` to generate\n   AndroidX code.\n\n * New: A `butterknife-runtime` artifact has been extracted from `butterknife` which contains the APIs\n   required for the generated code but does not contain the code to reflectively look up the generated\n   code. This allows you to reference the generated code directly such that R8/ProGuard optimization can\n   rename both the generated code and your classes. `ButterKnife.bind` and the consumer R8/ProGuard rules\n   remain in the old `butterknife` artifact.\n \n * New: Experimental `butterknife-reflect` artifact eliminates the need to run the annotation\n   processor for IDE builds. This artifact is binary compatible with `butterknife` so it can be interchanged\n   depending on how your build is being invoked. See [its README](butterknife-reflect/README.md) for more\n   information. Currently about 90% of functionality is covered. File bugs for anything that does not work.\n\n   Note: This artifact requires Java 8. There's no good reason for this except to push the ecosystem to\n   having this be a default. As of AGP 3.2 there is no reason not to do this.\n\n * New: Lint checks have been ported to UAST and now work on Kotlin code.\n\n * Fix: Allow `@BindFont` to work prior to API 26 using `ResourcesCompat`.\n * Fix: Update Android Gradle plugin to 3.1 or newer to fix binary incompatibilities.\n * Fix: Use the application ID instead of the resource package for generating `R2`.\n * Deprecated methods from 8.x have been removed.\n\nNote: The next release candidate will switch all artifacts to require Java 8 bytecode which will force\nyour applications to enable Java 8 bytecode. As of AGP 3.2 there is no cost to this, and there is no\nreason to have it set any lower.\n\n\nVersion 8.8.1 *(2017-08-09)*\n----------------------------\n\n * Fix: Properly emit casts for single-bound view subtypes when `butterknife.debuggable` is set to `false`.\n\n\nVersion 8.8.0 *(2017-08-04)*\n----------------------------\n\n * New: Processor option `butterknife.debuggable` controls whether debug information is generated. When\n   specified as `false`, checks for required views being non-null are elided and casts are no longer guarded\n   with user-friendly error messages. This reduces the amount of generated code for release builds at the\n   expense of less friendly exceptions when something breaks.\n * Deprecate the `findById` methods. Compile against API 26 and use the normal `findViewById` for the same\n   functionality.\n * Fix: Correct `@BindFont` code generation on pre-API 26 builds to pass a `Context` (not a `Resources`) to\n   `ResourceCompat`.\n\n\nVersion 8.7.0 *(2017-07-07)*\n----------------------------\n\n * New: `@BindFont` annotation binds `Typeface` instances with an optional style. Requires support libraries\n   26.0.0-beta1 or newer.\n * New: `@BindAnim` annotation binds `Animation` instances.\n * New: Generate `R2` constants for animation, layout, menu, plurals, styles, and styleables.\n * Fix: Properly catch and re-throw type cast exceptions when method binding arguments do not match.\n\n\nVersion 8.6.0 *(2017-05-16)*\n----------------------------\n\n * Plugin was ported to Kotlin and updated to support future Android Gradle plugin versions.\n * Fix: Properly handle multiple library modules using Butter Knife and defining the same ID.\n * Fix: Use the same classloader of the binding target to load the generated view binding class.\n\n\nVersion 8.5.1 *(2017-01-24)*\n----------------------------\n\n * Fix: Tweak bundled ProGuard rules to only retain the two-argument constructor accessed via reflection.\n\n\nVersion 8.5.0 *(2017-01-23)*\n----------------------------\n\n * Emit `@SuppressLint` when using `@OnTouch` to avoid a lint warning.\n * Migrate lint checks from Lombok AST to JetBrains PSI.\n * Annotations are no longer claimed by the processor.\n * Based on the minimum SDK version (as specified by `butterknife.minSdk` until http://b.android.com/187527 is\n   released) the generated code now changes to use newer APIs when available.\n * Generated classes now include single-argument overloads for `View`, `Activity`, and `Dialog` subclasses.\n * Generated classes are no longer generic.\n * Minimum supported SDK is now 9.\n\n\nVersion 8.4.0 *(2016-08-26)*\n----------------------------\n\n * New: `@BindFloat` annotation for dimensions whose format is of type 'float'. See the annotation for more\n   information.\n * Generated constructors are now annotated with `@UiThread` and non-final, base classes `unbind()` methods\n   are annotated with `@CallSuper`.\n\n\nVersion 8.3.0 *(2016-08-23)*\n----------------------------\n\n * New: Support for Jack compiler in application projects.\n * Fix: Generate ~20% less code and ~40% less methods.\n * Fix: Allow `@BindView` to reference types which are generated by other annotation processors.\n * Experimental: The generated view binding class can now be used directly. This allows ProGuard shrinking,\n   optimization, and obfuscation to work without any rules being needed. For a class `Test`, the binding\n   class will be named `Test_ViewBinding`. Calling its constructor will bind the instance passed in, and\n   the create object is also the implementation of `Unbinder` that can be used to unbind the views.\n   Note: The API of this generated code is subject to backwards-incompatible changes until v9.0.\n\n\nVersion 8.2.1 *(2016-07-11)*\n----------------------------\n\n * Fix: Do not emit `android.R` imports in generated code.\n * Fix: Ensure the processor does not crash when scanning for `R` classes. This can occur when used in a\n   Kotlin project.\n\n\nVersion 8.2.0 *(2016-07-10)*\n----------------------------\n\n * New: Support for library projects. Requires application of a Butter Knife Gradle plugin. See README for\n   details.\n * New: Generated code now emits `R` references instead of raw integer IDs.\n * Fix: `@OnPageChange` listener binding now uses the 'add'/'remove' methods on `ViewPager` instead of 'set'.\n\n\nVersion 8.1.0 *(2016-06-14)*\n----------------------------\n\n * New: Change the structure of generated view binders to optimize for performance and generated code. This\n   should result in faster binding (not that it's slow) and a reduction of methods.\n * Fix: Call the correct method on `TextView` to unbind `@OnTextChanged` uses.\n * Fix: Properly handle package names which contain uppercase letters.\n\n\nVersion 8.0.1 *(2016-04-27)*\n----------------------------\n\n * Fix: ProGuard rules now prevent obfuscation of only types which reference ButterKnife annotations.\n * Eliminate some of the generated machinery when referenced from `final` types.\n\n\nVersion 8.0.0 *(2016-04-25)*\n----------------------------\n\n *  `@Bind` becomes `@BindView` and `@BindViews` (one view and multiple views, respectively).\n *  Calls to `bind` now return an `Unbinder` instance which can be used to `null` references. This replaces\n    the `unbind` API and adds support for being able to clear listeners.\n *  New: `@BindArray` binds `String`, `CharSequence`, and `int` arrays and `TypeArray` to fields.\n *  New: `@BindBitmap` binds `Bitmap` instances from resources to fields.\n *  `@BindDrawable` now supports a `tint` field which accepts a theme attribute.\n *  The runtime and compiler are now split into two artifacts.\n\n    ```groovy\n    compile 'com.jakewharton:butterknife:8.0.0'\n    apt 'com.jakewharton:butterknife-compiler:8.0.0'\n    ```\n *  New: `apply` overloads which accept a single view and arrays of views.\n *  ProGuard rules now ship inside of the library and are included automatically.\n *  `@Optional` annotation is back to mark methods as being optional.\n\n\nVersion 7.0.1 *(2015-06-30)*\n----------------------------\n\n * Fix: Correct `ClassCastException` which occurred when `@Nullable` array bindings had missing views.\n\n\nVersion 7.0.0 *(2015-06-27)*\n----------------------------\n\n * `@Bind` replaces `@InjectView` and `@InjectViews`.\n * `ButterKnife.bind` and `ButterKnife.unbind` replaces `ButterKnife.inject` and `ButterKnife.reset`, respectively.\n * `@Optional` has been removed. Use `@Nullable` from the 'support-annotations' library, or any other annotation\n   named \"Nullable\".\n * New: Resource binding annotations!\n   * `@BindBool` binds an `R.bool` ID to a `boolean` field.\n   * `@BindColor` binds an `R.color` ID to an `int` or `ColorStateList` field.\n   * `@BindDimen` binds an `R.dimen` ID to an `int` (for pixel size) or `float` (for exact value) field.\n   * `@BindDrawable` binds an `R.drawable` ID to a `Drawable` field.\n   * `@BindInt` binds an `R.int` ID to an `int` field.\n   * `@BindString` binds an `R.string` ID to a `String` field.\n * Fix: Missing views will be filtered out from list and array bindings.\n * Note: If you are using Proguard, the generated class name has changed from being suffixed with `$$ViewInjector`\n   to `$$ViewBinder`.\n\n\nVersion 6.1.0 *(2015-01-29)*\n----------------------------\n\n * New: Support for injecting interface types everywhere that views were previously supported (e.g., `Checkable`).\n * Eliminate reflection-based method invocation for injection and resetting. This makes performance slightly faster\n   (although if you are worried about the performance of Butter Knife you have other problems). The only reflection\n   in the library is a single `Class.forName` lookup for each type.\n\n\nVersion 6.0.0 *(2014-10-27)*\n----------------------------\n\n * New: Listeners can bind to the root view being injected by omitting a view ID on the annotation.\n * New: Exceptions thrown from missing views now include the human-readable ID name (e.g., 'button1').\n * Specifying multiple fields binding to the same ID is now considered an error.\n * `findById` overload for view lookup on `Dialog` instances.\n * Experimental: Click listeners are now globally debounced per frame. This means that only a single click\n   will be processed per frame preventing race conditions due to queued input events.\n * Experimental: Multiple methods can bind to the same listener provided that listener's callback method\n   does not require a return value.\n\n\nVersion 5.1.2 *(2014-08-01)*\n----------------------------\n\n * Report an error if the annotations are on a class inside the `android.*` or `java.*`\n   package. Since we ignore these packages in the runtime, injection would never work.\n\n\nVersion 5.1.1 *(2014-06-19)*\n----------------------------\n\n * Fix: Correct rare `ClassCastException` when unwinding an `InvocationTargetException`.\n\n\nVersion 5.1.0 *(2014-05-20)*\n----------------------------\n\n * New listener!\n   * `View`: `@OnTouch`.\n * Fix: `@Optional` now correctly works for `@InjectViews` fields.\n * Fix: Correct erasure problem which may have prevented the processor from running in Eclipse.\n\n\nVersion 5.0.1 *(2014-05-04)*\n----------------------------\n\n * New: Support `Dialog` as injection source.\n * Fix: Unwrap `InvocationTargetException` causes for more helpful exceptions.\n\n\nVersion 5.0.0 *(2014-04-21)*\n----------------------------\n\n * New: `@InjectViews` annotation groups multiple IDs into a `List` or array.\n * New: `ButterKnife.apply` method applies an `Action`, `Setter`, or Android `Property` to views in\n   a list.\n * New listeners!\n   * `ViewPager`: `@OnPageChange`.\n   * `AdapterView`: `@OnItemSelected`.\n   * `TextView`: `@OnTextChanged`.\n * New: Multi-method listener support. Specify a `callback` argument to choose which method the\n   binding is for. *(See `@OnItemSelected` for an example)*\n * Fix: Support for generic types which are declared with an upper-bound.\n * Fix: Use less sophisticated method injection inspection in the annotation processor. The previous\n   method caused problems with some Eclipse configurations.\n\n\nVersion 4.0.1 *(2013-11-25)*\n----------------------------\n\n * Fix: Correct a problem preventing the annotation processor to access Android types when certain\n   `javac` configurations were used to build.\n\n\nVersion 4.0.0 *(2013-11-25)*\n----------------------------\n\n`Views` class is now named `ButterKnife`\n\n * New listeners!\n   * `View`: `@OnLongClick` and `@OnFocusChanged`.\n   * `TextView`: `@OnEditorAction`.\n   * `AdapterView`: `@OnItemClick` and `@OnItemLongClick`.\n   * `CompoundButton`: `@OnCheckedChanged`.\n * New: Views are now only checked to be `null` once if at least one of the fields and/or methods\n   lack the `@Optional` annotation.\n * Fix: Do no emit redundant casts to `View` for methods.\n\n\nVersion 3.0.1 *(2013-11-12)*\n----------------------------\n\n * Fix: Do not emit redundant casts to `View`.\n\n\nVersion 3.0.0 *(2013-09-10)*\n----------------------------\n\n * New: Injections are now required. An exception will be thrown if a view is\n   not found. Add `@Optional` annotation to suppress this verification.\n\n\nVersion 2.0.1 *(2013-07-18)*\n----------------------------\n\n * New: Control debug logging via `Views.setDebug`.\n\n\nVersion 2.0.0 *(2013-07-16)*\n----------------------------\n\n * New: `@OnClick` annotation for binding click listeners to methods!\n\n\nVersion 1.4.0 *(2013-06-03)*\n----------------------------\n\n * New: `Views.reset` for settings injections back to `null` in a fragment's\n   `onDestroyView` callback.\n * Fix: Support parent class injection when the parent class has generics.\n\n\nVersion 1.3.2 *(2013-04-27)*\n----------------------------\n\n * Multiple injections of the same view ID only require a single find call.\n * Fix: Ensure injection happens on classes who do not have any injections but\n   their superclasses do.\n\n\nVersion 1.3.1 *(2013-04-12)*\n----------------------------\n\n * Fix: Parent class inflater resolution now generates correct code.\n\n\nVersion 1.3.0 *(2013-03-26)*\n----------------------------\n\n * New: Injection on objects that have zero `@InjectView`-annotated fields will\n   no longer throw an exception.\n\n\nVersion 1.2.2 *(2013-03-11)*\n----------------------------\n\n * Fix: Prevent annotations on private classes.\n\n\nVersion 1.2.1 *(2013-03-11)*\n----------------------------\n\n * Fix: Correct generated code for parent class inflation.\n * Fix: Allow injection on `protected`-scoped fields.\n\n\nVersion 1.2.0 *(2013-05-07)*\n----------------------------\n\n * Support injection on any object using an Activity as the view root.\n * Support injection on views for their children.\n * Fix: Annotation errors now appear on the affected field in IDEs.\n\n\nVersion 1.1.1 *(2013-05-06)*\n----------------------------\n\n * Fix: Verify that the target type extends from `View`.\n * Fix: Correct package name resolution in Eclipse 4.2\n\n\nVersion 1.1.0 *(2013-03-05)*\n----------------------------\n\n * Perform injection on any object by passing a view root.\n * Fix: Correct naming of static inner-class injection points.\n * Fix: Enforce `findById` can only be used with child classes of `View`.\n\n\nVersion 1.0.0 *(2013-03-05)*\n----------------------------\n\nInitial release.\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "Butter Knife\n============\n\n**Attention**: This tool is now deprecated. Please switch to\n[view binding](https://developer.android.com/topic/libraries/view-binding).\nExisting versions will continue to work, obviously, but only critical bug fixes for integration\nwith AGP will be considered. Feature development and general bug fixes have stopped.\n\n![Logo](website/static/logo.png)\n\nField and method binding for Android views which uses annotation processing to generate boilerplate\ncode for you.\n\n * Eliminate `findViewById` calls by using `@BindView` on fields.\n * Group multiple views in a list or array. Operate on all of them at once with actions,\n   setters, or properties.\n * Eliminate anonymous inner-classes for listeners by annotating methods with `@OnClick` and others.\n * Eliminate resource lookups by using resource annotations on fields.\n\n```java\nclass ExampleActivity extends Activity {\n  @BindView(R.id.user) EditText username;\n  @BindView(R.id.pass) EditText password;\n\n  @BindString(R.string.login_error) String loginErrorMessage;\n\n  @OnClick(R.id.submit) void submit() {\n    // TODO call server...\n  }\n\n  @Override public void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.simple_activity);\n    ButterKnife.bind(this);\n    // TODO Use fields...\n  }\n}\n```\n\nFor documentation and additional information see [the website][3].\n\n__Remember: A butter knife is like a [dagger][1], only infinitely less sharp.__\n\n\n\nDownload\n--------\n\n```groovy\nandroid {\n  ...\n  // Butterknife requires Java 8.\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n}\n\ndependencies {\n  implementation 'com.jakewharton:butterknife:10.2.3'\n  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'\n}\n```\n\nIf you are using Kotlin, replace `annotationProcessor` with `kapt`.\n\nSnapshots of the development version are available in [Sonatype's `snapshots` repository][snap].\n\n\n\nLibrary projects\n--------------------\n\nTo use Butter Knife in a library, add the plugin to your `buildscript`:\n\n```groovy\nbuildscript {\n  repositories {\n    mavenCentral()\n    google()\n  }\n  dependencies {\n    classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'\n  }\n}\n```\n\nand then apply it in your module:\n\n```groovy\napply plugin: 'com.android.library'\napply plugin: 'com.jakewharton.butterknife'\n```\n\nNow make sure you use `R2` instead of `R` inside all Butter Knife annotations.\n\n```java\nclass ExampleActivity extends Activity {\n  @BindView(R2.id.user) EditText username;\n  @BindView(R2.id.pass) EditText password;\n...\n}\n```\n\n\n\nLicense\n-------\n\n    Copyright 2013 Jake Wharton\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n\n\n [1]: https://dagger.dev/\n [2]: https://search.maven.org/remote_content?g=com.jakewharton&a=butterknife&v=LATEST\n [3]: http://jakewharton.github.com/butterknife/\n [snap]: https://oss.sonatype.org/content/repositories/snapshots/\n"
  },
  {
    "path": "RELEASING.md",
    "content": "Releasing\n========\n\n 1. Change the version in `gradle.properties` to a non-SNAPSHOT version.\n 2. Update the `CHANGELOG.md` for the impending release.\n 3. Update the `README.md` with the new version.\n 4. `git commit -am \"Prepare for release X.Y.Z.\"` (where X.Y.Z is the new version)\n 5. `./gradlew clean uploadArchives`.\n 6. Visit [Sonatype Nexus](https://oss.sonatype.org/) and promote the artifact.\n 7. `git tag -a X.Y.X -m \"Version X.Y.Z\"` (where X.Y.Z is the new version)\n 8. Update the `gradle.properties` to the next SNAPSHOT version.\n 9. `git commit -am \"Prepare next development version.\"`\n 10. `git push && git push --tags`\n 11. Update the two sample modules to point to the newly released version.\n\nIf step 5 or 6 fails, drop the Sonatype repo, fix the problem, commit, and start again at step 5.\n"
  },
  {
    "path": "build.gradle",
    "content": "apply plugin: 'com.github.ben-manes.versions'\n\nbuildscript {\n  ext.versions = [\n      'minSdk': 14,\n      'compileSdk': 28,\n\n      'androidTools': '26.2.0',\n      'kotlin': '1.2.71',\n      'incap' : '0.2',\n\n      'release': '8.8.1',\n  ]\n\n  ext.deps = [\n      android: [\n          'runtime': 'com.google.android:android:4.1.1.4',\n          'gradlePlugin': \"com.android.tools.build:gradle:3.3.0\",\n      ],\n      'androidx': [\n          'core': \"androidx.core:core:1.0.0\",\n          'viewpager': \"androidx.viewpager:viewpager:1.0.0\",\n          'annotations': \"androidx.annotation:annotation:1.0.0\",\n          'test': [\n              'runner': 'androidx.test:runner:1.1.0',\n              'rules': 'androidx.test:rules:1.1.0',\n          ],\n      ],\n      'lint': [\n          'core': \"com.android.tools.lint:lint:${versions.androidTools}\",\n          'api': \"com.android.tools.lint:lint-api:${versions.androidTools}\",\n          'checks': \"com.android.tools.lint:lint-checks:${versions.androidTools}\",\n          'tests': \"com.android.tools.lint:lint-tests:${versions.androidTools}\",\n      ],\n      javapoet: 'com.squareup:javapoet:1.10.0',\n      junit: 'junit:junit:4.12',\n      truth: 'com.google.truth:truth:0.42',\n      compiletesting: 'com.google.testing.compile:compile-testing:0.15',\n      'auto': [\n          'service': 'com.google.auto.service:auto-service:1.0-rc4',\n          'common': 'com.google.auto:auto-common:0.10',\n      ],\n      'guava': 'com.google.guava:guava:24.0-jre',\n      'release': [\n          'runtime': \"com.jakewharton:butterknife:${versions.release}\",\n          'compiler': \"com.jakewharton:butterknife-compiler:${versions.release}\"\n      ],\n      'kotlin': [\n          'stdLibJdk8': \"org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}\",\n      ],\n      'incap': [\n          'runtime': \"net.ltgt.gradle.incap:incap:${versions.incap}\",\n          'processor': \"net.ltgt.gradle.incap:incap-processor:${versions.incap}\",\n      ]\n  ]\n\n  repositories {\n    mavenCentral()\n    google()\n    jcenter()\n    gradlePluginPortal()\n  }\n\n  dependencies {\n    classpath 'com.android.tools.build:gradle:3.2.0'\n    classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}\"\n    classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'\n    classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.16'\n  }\n}\n\nsubprojects { project ->\n  group = GROUP\n  version = VERSION_NAME\n\n  repositories {\n    mavenCentral()\n    google()\n    jcenter()\n  }\n\n  apply plugin: 'net.ltgt.errorprone'\n\n  dependencies {\n    errorprone 'com.google.errorprone:error_prone_core:2.3.1'\n  }\n\n  // TODO figure out why this causes codegen to fail in android tests.\n  //def nullaway = dependencies.create('com.uber.nullaway:nullaway:0.5.5')\n  //configurations.all { Configuration configuration ->\n  //  if (configuration.name.endsWith('nnotationProcessor')) {\n  //    configuration.dependencies.add(nullaway)\n  //  }\n  //}\n  //\n  //tasks.withType(JavaCompile) {\n  //  options.compilerArgs += [\n  //      '-Xep:NullAway:ERROR',\n  //      '-XepOpt:NullAway:AnnotatedPackages=butterknife',\n  //  ]\n  //}\n\n  if (!project.name.equals('butterknife-gradle-plugin')) {\n    apply plugin: 'checkstyle'\n\n    task checkstyle(type: Checkstyle) {\n      configFile rootProject.file('checkstyle.xml')\n      source 'src/main/java'\n      ignoreFailures false\n      showViolations true\n      include '**/*.java'\n\n      classpath = files()\n    }\n\n    afterEvaluate {\n      if (project.tasks.findByName('check')) {\n        check.dependsOn('checkstyle')\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  defaultConfig {\n    minSdkVersion versions.minSdk\n\n    consumerProguardFiles 'proguard-rules.txt'\n\n    testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n\n  lintOptions {\n    textReport true\n    textOutput 'stdout'\n    // We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.\n    checkReleaseBuilds false\n  }\n\n  // TODO replace with https://issuetracker.google.com/issues/72050365 once released.\n  libraryVariants.all {\n    it.generateBuildConfig.enabled = false\n  }\n}\n\ndependencies {\n  api project(':butterknife-runtime')\n\n  androidTestImplementation deps.junit\n  androidTestImplementation deps.truth\n  androidTestImplementation deps.androidx.test.runner\n  androidTestAnnotationProcessor project(':butterknife-compiler')\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife/gradle.properties",
    "content": "POM_ARTIFACT_ID=butterknife\nPOM_NAME=Butterknife\nPOM_PACKAGING=aar\n"
  },
  {
    "path": "butterknife/proguard-rules.txt",
    "content": "# Retain generated class which implement Unbinder.\n-keep public class * implements butterknife.Unbinder { public <init>(**, android.view.View); }\n\n# Prevent obfuscation of types which use ButterKnife annotations since the simple name\n# is used to reflectively look up the generated ViewBinding.\n-keep class butterknife.*\n-keepclasseswithmembernames class * { @butterknife.* <methods>; }\n-keepclasseswithmembernames class * { @butterknife.* <fields>; }\n"
  },
  {
    "path": "butterknife/src/androidTest/java/butterknife/ButterKnifeTest.java",
    "content": "package butterknife;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic class ButterKnifeTest {\n  private final Context context = InstrumentationRegistry.getContext();\n\n  @Before @After // Clear out cache of binders before and after each test.\n  public void resetViewsCache() {\n    ButterKnife.BINDINGS.clear();\n  }\n\n  @Test public void zeroBindingsBindDoesNotThrowExceptionAndCaches() {\n    class Example {\n    }\n\n    Example example = new Example();\n    View view = new View(context);\n    assertThat(ButterKnife.BINDINGS).isEmpty();\n    assertThat(ButterKnife.bind(example, view)).isSameAs(Unbinder.EMPTY);\n    assertThat(ButterKnife.BINDINGS).containsEntry(Example.class, null);\n  }\n\n  @Test public void bindingKnownPackagesIsNoOp() {\n    View view = new View(context);\n    ButterKnife.bind(view);\n    assertThat(ButterKnife.BINDINGS).isEmpty();\n    ButterKnife.bind(new Object(), view);\n    assertThat(ButterKnife.BINDINGS).isEmpty();\n  }\n}\n"
  },
  {
    "path": "butterknife/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"butterknife\"/>\n"
  },
  {
    "path": "butterknife/src/main/java/butterknife/ButterKnife.java",
    "content": "package butterknife;\n\nimport android.app.Activity;\nimport android.app.Dialog;\nimport android.util.Log;\nimport android.view.View;\nimport androidx.annotation.CheckResult;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.UiThread;\nimport androidx.annotation.VisibleForTesting;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Field and method binding for Android views. Use this class to simplify finding views and\n * attaching listeners by binding them with annotations.\n * <p>\n * Finding views from your activity is as easy as:\n * <pre><code>\n * public class ExampleActivity extends Activity {\n *   {@literal @}BindView(R.id.title) EditText titleView;\n *   {@literal @}BindView(R.id.subtitle) EditText subtitleView;\n *\n *   {@literal @}Override protected void onCreate(Bundle savedInstanceState) {\n *     super.onCreate(savedInstanceState);\n *     setContentView(R.layout.example_activity);\n *     ButterKnife.bind(this);\n *   }\n * }\n * </code></pre>\n * Binding can be performed directly on an {@linkplain #bind(Activity) activity}, a\n * {@linkplain #bind(View) view}, or a {@linkplain #bind(Dialog) dialog}. Alternate objects to\n * bind can be specified along with an {@linkplain #bind(Object, Activity) activity},\n * {@linkplain #bind(Object, View) view}, or\n * {@linkplain #bind(Object, android.app.Dialog) dialog}.\n * <p>\n * Group multiple views together into a {@link List} or array.\n * <pre><code>\n * {@literal @}BindView({R.id.first_name, R.id.middle_name, R.id.last_name})\n * List<EditText> nameViews;\n * </code></pre>\n * <p>\n * To bind listeners to your views you can annotate your methods:\n * <pre><code>\n * {@literal @}OnClick(R.id.submit) void onSubmit() {\n *   // React to button click.\n * }\n * </code></pre>\n * Any number of parameters from the listener may be used on the method.\n * <pre><code>\n * {@literal @}OnItemClick(R.id.tweet_list) void onTweetClicked(int position) {\n *   // React to tweet click.\n * }\n * </code></pre>\n * <p>\n * Be default, views are required to be present in the layout for both field and method bindings.\n * If a view is optional add a {@code @Nullable} annotation for fields (such as the one in the\n * <a href=\"http://tools.android.com/tech-docs/support-annotations\">support-annotations</a> library)\n * or the {@code @Optional} annotation for methods.\n * <pre><code>\n * {@literal @}Nullable @BindView(R.id.title) TextView subtitleView;\n * </code></pre>\n * Resources can also be bound to fields to simplify programmatically working with views:\n * <pre><code>\n * {@literal @}BindBool(R.bool.is_tablet) boolean isTablet;\n * {@literal @}BindInt(R.integer.columns) int columns;\n * {@literal @}BindColor(R.color.error_red) int errorRed;\n * </code></pre>\n */\npublic final class ButterKnife {\n  private ButterKnife() {\n    throw new AssertionError(\"No instances.\");\n  }\n\n  private static final String TAG = \"ButterKnife\";\n  private static boolean debug = false;\n\n  @VisibleForTesting\n  static final Map<Class<?>, Constructor<? extends Unbinder>> BINDINGS = new LinkedHashMap<>();\n\n  /** Control whether debug logging is enabled. */\n  public static void setDebug(boolean debug) {\n    ButterKnife.debug = debug;\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link Activity}. The current content\n   * view is used as the view root.\n   *\n   * @param target Target activity for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Activity target) {\n    View sourceView = target.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link View}. The view and its children\n   * are used as the view root.\n   *\n   * @param target Target view for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull View target) {\n    return bind(target, target);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link Dialog}. The current content\n   * view is used as the view root.\n   *\n   * @param target Target dialog for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Dialog target) {\n    View sourceView = target.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link Activity} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source Activity on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull Activity source) {\n    View sourceView = source.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link Dialog} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source Dialog on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull Dialog source) {\n    View sourceView = source.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link View} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source View root on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull View source) {\n    Class<?> targetClass = target.getClass();\n    if (debug) Log.d(TAG, \"Looking up binding for \" + targetClass.getName());\n    Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);\n\n    if (constructor == null) {\n      return Unbinder.EMPTY;\n    }\n\n    //noinspection TryWithIdenticalCatches Resolves to API 19+ only type.\n    try {\n      return constructor.newInstance(target, source);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InstantiationException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InvocationTargetException e) {\n      Throwable cause = e.getCause();\n      if (cause instanceof RuntimeException) {\n        throw (RuntimeException) cause;\n      }\n      if (cause instanceof Error) {\n        throw (Error) cause;\n      }\n      throw new RuntimeException(\"Unable to create binding instance.\", cause);\n    }\n  }\n\n  @Nullable @CheckResult @UiThread\n  private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {\n    Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);\n    if (bindingCtor != null || BINDINGS.containsKey(cls)) {\n      if (debug) Log.d(TAG, \"HIT: Cached in binding map.\");\n      return bindingCtor;\n    }\n    String clsName = cls.getName();\n    if (clsName.startsWith(\"android.\") || clsName.startsWith(\"java.\")\n        || clsName.startsWith(\"androidx.\")) {\n      if (debug) Log.d(TAG, \"MISS: Reached framework class. Abandoning search.\");\n      return null;\n    }\n    try {\n      Class<?> bindingClass = cls.getClassLoader().loadClass(clsName + \"_ViewBinding\");\n      //noinspection unchecked\n      bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class);\n      if (debug) Log.d(TAG, \"HIT: Loaded binding class and constructor.\");\n    } catch (ClassNotFoundException e) {\n      if (debug) Log.d(TAG, \"Not found. Trying superclass \" + cls.getSuperclass().getName());\n      bindingCtor = findBindingConstructorForClass(cls.getSuperclass());\n    } catch (NoSuchMethodException e) {\n      throw new RuntimeException(\"Unable to find binding constructor for \" + clsName, e);\n    }\n    BINDINGS.put(cls, bindingCtor);\n    return bindingCtor;\n  }\n}\n"
  },
  {
    "path": "butterknife/src/main/java/butterknife/package-info.java",
    "content": "/**\n * Field and method binding for Android views which uses annotation processing to generate\n * boilerplate code for you.\n * <p>\n * <ul>\n * <li>Eliminate {@link android.view.View#findViewById findViewById} calls by using\n * {@link butterknife.BindView @BindView} on fields.</li>\n * <li>Group multiple views in a {@linkplain java.util.List list} or array.\n * <li>Eliminate anonymous inner-classes for listeners by annotating methods with\n * {@link butterknife.OnClick @OnClick} and others.</li>\n * <li>Eliminate resource lookups by using resource annotations on fields.</li>\n * </ul>\n */\npackage butterknife;\n"
  },
  {
    "path": "butterknife-annotations/build.gradle",
    "content": "apply plugin: 'java-library'\napply plugin: 'checkstyle'\n\nsourceCompatibility = JavaVersion.VERSION_1_8\ntargetCompatibility = JavaVersion.VERSION_1_8\n\ncheckstyle {\n  configFile rootProject.file('checkstyle.xml')\n  showViolations true\n}\n\ndependencies {\n  compileOnly deps.android.runtime\n  api deps.androidx.annotations\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife-annotations/gradle.properties",
    "content": "POM_NAME=Butterknife Annotations\nPOM_ARTIFACT_ID=butterknife-annotations\nPOM_PACKAGING=jar\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindAnim.java",
    "content": "package butterknife;\n\nimport androidx.annotation.AnimRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified animation resource ID.\n * <pre><code>\n * {@literal @}BindAnim(R.anim.fade_in) Animation fadeIn;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindAnim {\n  /** Animation resource ID to which the field will be bound. */\n  @AnimRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindArray.java",
    "content": "package butterknife;\n\nimport androidx.annotation.ArrayRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified array resource ID. The type of array will be inferred from the\n * annotated element.\n *\n * String array:\n * <pre><code>\n * {@literal @}BindArray(R.array.countries) String[] countries;\n * </code></pre>\n *\n * Int array:\n * <pre><code>\n * {@literal @}BindArray(R.array.phones) int[] phones;\n * </code></pre>\n *\n * Text array:\n * <pre><code>\n * {@literal @}BindArray(R.array.options) CharSequence[] options;\n * </code></pre>\n *\n * {@link android.content.res.TypedArray}:\n * <pre><code>\n * {@literal @}BindArray(R.array.icons) TypedArray icons;\n * </code></pre>\n */\n@Retention(RUNTIME) @Target(FIELD)\npublic @interface BindArray {\n  /** Array resource ID to which the field will be bound. */\n  @ArrayRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindBitmap.java",
    "content": "package butterknife;\n\nimport android.graphics.Bitmap;\nimport androidx.annotation.DrawableRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to a {@link Bitmap} from the specified drawable resource ID.\n * <pre><code>\n * {@literal @}BindBitmap(R.drawable.logo) Bitmap logo;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindBitmap {\n  /** Drawable resource ID from which the {@link Bitmap} will be created. */\n  @DrawableRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindBool.java",
    "content": "package butterknife;\n\nimport androidx.annotation.BoolRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified boolean resource ID.\n * <pre><code>\n * {@literal @}BindBool(R.bool.is_tablet) boolean isTablet;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindBool {\n  /** Boolean resource ID to which the field will be bound. */\n  @BoolRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindColor.java",
    "content": "package butterknife;\n\nimport androidx.annotation.ColorRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified color resource ID. Type can be {@code int} or\n * {@link android.content.res.ColorStateList}.\n * <pre><code>\n * {@literal @}BindColor(R.color.background_green) int green;\n * {@literal @}BindColor(R.color.background_green_selector) ColorStateList greenSelector;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindColor {\n  /** Color resource ID to which the field will be bound. */\n  @ColorRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindDimen.java",
    "content": "package butterknife;\n\nimport androidx.annotation.DimenRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified dimension resource ID. Type can be {@code int} for pixel size or\n * {@code float} for exact amount.\n * <pre><code>\n * {@literal @}BindDimen(R.dimen.horizontal_gap) int gapPx;\n * {@literal @}BindDimen(R.dimen.horizontal_gap) float gap;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindDimen {\n  /** Dimension resource ID to which the field will be bound. */\n  @DimenRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindDrawable.java",
    "content": "package butterknife;\n\nimport androidx.annotation.AttrRes;\nimport androidx.annotation.DrawableRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static butterknife.internal.Constants.NO_RES_ID;\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified drawable resource ID.\n * <pre><code>\n * {@literal @}BindDrawable(R.drawable.placeholder)\n * Drawable placeholder;\n * {@literal @}BindDrawable(value = R.drawable.placeholder, tint = R.attr.colorAccent)\n * Drawable tintedPlaceholder;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindDrawable {\n  /** Drawable resource ID to which the field will be bound. */\n  @DrawableRes int value();\n\n  /** Color attribute resource ID that is used to tint the drawable. */\n  @AttrRes int tint() default NO_RES_ID;\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindFloat.java",
    "content": "package butterknife;\n\nimport androidx.annotation.DimenRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified dimension resource ID whose type is explicitly defined as float.\n * <p>\n * This is different than simply reading a normal dimension as a float value which\n * {@link BindDimen @BindDimen} supports. The resource must be defined as a float like\n * {@code <item name=\"whatever\" format=\"float\" type=\"dimen\">1.1</item>}.\n * <pre><code>\n * {@literal @}BindFloat(R.dimen.image_ratio) float imageRatio;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindFloat {\n  /** Float resource ID to which the field will be bound. */\n  @DimenRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindFont.java",
    "content": "package butterknife;\n\nimport android.graphics.Typeface;\nimport androidx.annotation.FontRes;\nimport androidx.annotation.IntDef;\nimport androidx.annotation.RestrictTo;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static androidx.annotation.RestrictTo.Scope.LIBRARY;\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified font resource ID.\n * <pre><code>\n * {@literal @}BindFont(R.font.comic_sans) Typeface comicSans;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindFont {\n  /** Font resource ID to which the field will be bound. */\n  @FontRes int value();\n\n  @TypefaceStyle int style() default Typeface.NORMAL;\n\n  @IntDef({\n      Typeface.NORMAL,\n      Typeface.BOLD,\n      Typeface.ITALIC,\n      Typeface.BOLD_ITALIC\n  })\n  @RestrictTo(LIBRARY)\n  @interface TypefaceStyle {\n  }\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindInt.java",
    "content": "package butterknife;\n\nimport androidx.annotation.IntegerRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified integer resource ID.\n * <pre><code>\n * {@literal @}BindInt(R.int.columns) int columns;\n * </code></pre>\n */\n@Target(FIELD)\n@Retention(RUNTIME)\npublic @interface BindInt {\n  /** Integer resource ID to which the field will be bound. */\n  @IntegerRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindString.java",
    "content": "package butterknife;\n\nimport androidx.annotation.StringRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the specified string resource ID.\n * <pre><code>\n * {@literal @}BindString(R.string.username_error) String usernameErrorText;\n * </code></pre>\n */\n@Retention(RUNTIME) @Target(FIELD)\npublic @interface BindString {\n  /** String resource ID to which the field will be bound. */\n  @StringRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindView.java",
    "content": "package butterknife;\n\nimport androidx.annotation.IdRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the view for the specified ID. The view will automatically be cast to the field\n * type.\n * <pre><code>\n * {@literal @}BindView(R.id.title) TextView title;\n * </code></pre>\n */\n@Retention(RUNTIME) @Target(FIELD)\npublic @interface BindView {\n  /** View ID to which the field will be bound. */\n  @IdRes int value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/BindViews.java",
    "content": "package butterknife;\n\nimport androidx.annotation.IdRes;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a field to the view for the specified ID. The view will automatically be cast to the field\n * type.\n * <pre><code>\n * {@literal @}BindViews({ R.id.title, R.id.subtitle })\n * List&lt;TextView&gt; titles;\n * </code></pre>\n */\n@Retention(RUNTIME) @Target(FIELD)\npublic @interface BindViews {\n  /** View IDs to which the field will be bound. */\n  @IdRes int[] value();\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnCheckedChanged.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.widget.CompoundButton.OnCheckedChangeListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnCheckedChangeListener OnCheckedChangeListener} on the view for\n * each ID specified.\n * <pre><code>\n * {@literal @}OnCheckedChanged(R.id.example) void onChecked(boolean checked) {\n *   Toast.makeText(this, checked ? \"Checked!\" : \"Unchecked!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)\n * onCheckedChanged} may be used on the method.\n *\n * @see OnCheckedChangeListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.widget.CompoundButton\",\n    setter = \"setOnCheckedChangeListener\",\n    type = \"android.widget.CompoundButton.OnCheckedChangeListener\",\n    method = @ListenerMethod(\n        name = \"onCheckedChanged\",\n        parameters = {\n            \"android.widget.CompoundButton\",\n            \"boolean\"\n        }\n    )\n)\npublic @interface OnCheckedChanged {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnClick.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.view.View.OnClickListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnClickListener OnClickListener} on the view for each ID specified.\n * <pre><code>\n * {@literal @}OnClick(R.id.example) void onClick() {\n *   Toast.makeText(this, \"Clicked!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnClickListener#onClick(android.view.View) onClick} may be used on the\n * method.\n *\n * @see OnClickListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.view.View\",\n    setter = \"setOnClickListener\",\n    type = \"butterknife.internal.DebouncingOnClickListener\",\n    method = @ListenerMethod(\n        name = \"doClick\",\n        parameters = \"android.view.View\"\n    )\n)\npublic @interface OnClick {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnEditorAction.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.widget.TextView.OnEditorActionListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnEditorActionListener OnEditorActionListener} on the view for each\n * ID specified.\n * <pre><code>\n * {@literal @}OnEditorAction(R.id.example) boolean onEditorAction(KeyEvent key) {\n *   Toast.makeText(this, \"Pressed: \" + key, Toast.LENGTH_SHORT).show();\n *   return true;\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnEditorActionListener#onEditorAction(android.widget.TextView, int, android.view.KeyEvent)\n * onEditorAction} may be used on the method.\n * <p>\n * If the return type of the method is {@code void}, true will be returned from the listener.\n *\n * @see OnEditorActionListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.widget.TextView\",\n    setter = \"setOnEditorActionListener\",\n    type = \"android.widget.TextView.OnEditorActionListener\",\n    method = @ListenerMethod(\n        name = \"onEditorAction\",\n        parameters = {\n            \"android.widget.TextView\",\n            \"int\",\n            \"android.view.KeyEvent\"\n        },\n        returnType = \"boolean\",\n        defaultReturn = \"true\"\n    )\n)\npublic @interface OnEditorAction {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnFocusChange.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.view.View.OnFocusChangeListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnFocusChangeListener OnFocusChangeListener} on the view for each ID\n * specified.\n * <pre><code>\n * {@literal @}OnFocusChange(R.id.example) void onFocusChanged(boolean focused) {\n *   Toast.makeText(this, focused ? \"Gained focus\" : \"Lost focus\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from {@link OnFocusChangeListener#onFocusChange(android.view.View,\n * boolean) onFocusChange} may be used on the method.\n *\n * @see OnFocusChangeListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.view.View\",\n    setter = \"setOnFocusChangeListener\",\n    type = \"android.view.View.OnFocusChangeListener\",\n    method = @ListenerMethod(\n        name = \"onFocusChange\",\n        parameters = {\n            \"android.view.View\",\n            \"boolean\"\n        }\n    )\n)\npublic @interface OnFocusChange {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnItemClick.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.widget.AdapterView.OnItemClickListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnItemClickListener OnItemClickListener} on the view for each ID\n * specified.\n * <pre><code>\n * {@literal @}OnItemClick(R.id.example_list) void onItemClick(int position) {\n *   Toast.makeText(this, \"Clicked position \" + position + \"!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from {@link OnItemClickListener#onItemClick(android.widget.AdapterView,\n * android.view.View, int, long) onItemClick} may be used on the method.\n *\n * @see OnItemClickListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.widget.AdapterView<?>\",\n    setter = \"setOnItemClickListener\",\n    type = \"android.widget.AdapterView.OnItemClickListener\",\n    method = @ListenerMethod(\n        name = \"onItemClick\",\n        parameters = {\n            \"android.widget.AdapterView<?>\",\n            \"android.view.View\",\n            \"int\",\n            \"long\"\n        }\n    )\n)\npublic @interface OnItemClick {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnItemLongClick.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.widget.AdapterView.OnItemLongClickListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnItemLongClickListener OnItemLongClickListener} on the view for each\n * ID specified.\n * <pre><code>\n * {@literal @}OnItemLongClick(R.id.example_list) boolean onItemLongClick(int position) {\n *   Toast.makeText(this, \"Long clicked position \" + position + \"!\", Toast.LENGTH_SHORT).show();\n *   return true;\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnItemLongClickListener#onItemLongClick(android.widget.AdapterView, android.view.View,\n * int, long) onItemLongClick} may be used on the method.\n * <p>\n * If the return type of the method is {@code void}, true will be returned from the listener.\n *\n * @see OnItemLongClickListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.widget.AdapterView<?>\",\n    setter = \"setOnItemLongClickListener\",\n    type = \"android.widget.AdapterView.OnItemLongClickListener\",\n    method = @ListenerMethod(\n        name = \"onItemLongClick\",\n        parameters = {\n            \"android.widget.AdapterView<?>\",\n            \"android.view.View\",\n            \"int\",\n            \"long\"\n        },\n        returnType = \"boolean\",\n        defaultReturn = \"true\"\n    )\n)\npublic @interface OnItemLongClick {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnItemSelected.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.widget.AdapterView.OnItemSelectedListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.CLASS;\n\n/**\n * Bind a method to an {@link OnItemSelectedListener OnItemSelectedListener} on the view for each\n * ID specified.\n * <pre><code>\n * {@literal @}OnItemSelected(R.id.example_list) void onItemSelected(int position) {\n *   Toast.makeText(this, \"Selected position \" + position + \"!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int,\n * long) onItemSelected} may be used on the method.\n * <p>\n * To bind to methods other than {@code onItemSelected}, specify a different {@code callback}.\n * <pre><code>\n * {@literal @}OnItemSelected(value = R.id.example_list, callback = NOTHING_SELECTED)\n * void onNothingSelected() {\n *   Toast.makeText(this, \"Nothing selected!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n *\n * @see OnItemSelectedListener\n */\n@Target(METHOD)\n@Retention(CLASS)\n@ListenerClass(\n    targetType = \"android.widget.AdapterView<?>\",\n    setter = \"setOnItemSelectedListener\",\n    type = \"android.widget.AdapterView.OnItemSelectedListener\",\n    callbacks = OnItemSelected.Callback.class\n)\npublic @interface OnItemSelected {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n\n  /** Listener callback to which the method will be bound. */\n  Callback callback() default Callback.ITEM_SELECTED;\n\n  /** {@link OnItemSelectedListener} callback methods. */\n  enum Callback {\n    /**\n     * {@link OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View,\n     * int, long)}\n     */\n    @ListenerMethod(\n        name = \"onItemSelected\",\n        parameters = {\n            \"android.widget.AdapterView<?>\",\n            \"android.view.View\",\n            \"int\",\n            \"long\"\n        }\n    )\n    ITEM_SELECTED,\n\n    /** {@link OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)} */\n    @ListenerMethod(\n        name = \"onNothingSelected\",\n        parameters = \"android.widget.AdapterView<?>\"\n    )\n    NOTHING_SELECTED\n  }\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnLongClick.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.view.View.OnLongClickListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnLongClickListener OnLongClickListener} on the view for each ID\n * specified.\n * <pre><code>\n * {@literal @}OnLongClick(R.id.example) boolean onLongClick() {\n *   Toast.makeText(this, \"Long clicked!\", Toast.LENGTH_SHORT).show();\n *   return true;\n * }\n * </code></pre>\n * Any number of parameters from {@link OnLongClickListener#onLongClick(android.view.View)} may be\n * used on the method.\n * <p>\n * If the return type of the method is {@code void}, true will be returned from the listener.\n *\n * @see OnLongClickListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.view.View\",\n    setter = \"setOnLongClickListener\",\n    type = \"android.view.View.OnLongClickListener\",\n    method = @ListenerMethod(\n        name = \"onLongClick\",\n        parameters = {\n            \"android.view.View\"\n        },\n        returnType = \"boolean\",\n        defaultReturn = \"true\"\n    )\n)\npublic @interface OnLongClick {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnPageChange.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@code OnPageChangeListener} on the view for each ID specified.\n * <pre><code>\n * {@literal @}OnPageChange(R.id.example_pager) void onPageSelected(int position) {\n *   Toast.makeText(this, \"Selected \" + position + \"!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from {@code onPageSelected} may be used on the method.\n * <p>\n * To bind to methods other than {@code onPageSelected}, specify a different {@code callback}.\n * <pre><code>\n * {@literal @}OnPageChange(value = R.id.example_pager, callback = PAGE_SCROLL_STATE_CHANGED)\n * void onPageStateChanged(int state) {\n *   Toast.makeText(this, \"State changed: \" + state + \"!\", Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"androidx.viewpager.widget.ViewPager\",\n    setter = \"addOnPageChangeListener\",\n    remover = \"removeOnPageChangeListener\",\n    type = \"androidx.viewpager.widget.ViewPager.OnPageChangeListener\",\n    callbacks = OnPageChange.Callback.class\n)\npublic @interface OnPageChange {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n\n  /** Listener callback to which the method will be bound. */\n  Callback callback() default Callback.PAGE_SELECTED;\n\n  /** {@code ViewPager.OnPageChangeListener} callback methods. */\n  enum Callback {\n    /** {@code onPageSelected(int)} */\n    @ListenerMethod(\n        name = \"onPageSelected\",\n        parameters = \"int\"\n    )\n    PAGE_SELECTED,\n\n    /** {@code onPageScrolled(int, float, int)} */\n    @ListenerMethod(\n        name = \"onPageScrolled\",\n        parameters = {\n            \"int\",\n            \"float\",\n            \"int\"\n        }\n    )\n    PAGE_SCROLLED,\n\n    /** {@code onPageScrollStateChanged(int)} */\n    @ListenerMethod(\n        name = \"onPageScrollStateChanged\",\n        parameters = \"int\"\n    )\n    PAGE_SCROLL_STATE_CHANGED,\n  }\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnTextChanged.java",
    "content": "package butterknife;\n\nimport android.text.TextWatcher;\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to a {@link TextWatcher TextWatcher} on the view for each ID specified.\n * <pre><code>\n * {@literal @}OnTextChanged(R.id.example) void onTextChanged(CharSequence text) {\n *   Toast.makeText(this, \"Text changed: \" + text, Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n * Any number of parameters from {@link TextWatcher#onTextChanged(CharSequence, int, int, int)\n * onTextChanged} may be used on the method.\n * <p>\n * To bind to methods other than {@code onTextChanged}, specify a different {@code callback}.\n * <pre><code>\n * {@literal @}OnTextChanged(value = R.id.example, callback = BEFORE_TEXT_CHANGED)\n * void onBeforeTextChanged(CharSequence text) {\n *   Toast.makeText(this, \"Before text changed: \" + text, Toast.LENGTH_SHORT).show();\n * }\n * </code></pre>\n *\n * @see TextWatcher\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.widget.TextView\",\n    setter = \"addTextChangedListener\",\n    remover = \"removeTextChangedListener\",\n    type = \"android.text.TextWatcher\",\n    callbacks = OnTextChanged.Callback.class\n)\npublic @interface OnTextChanged {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n\n  /** Listener callback to which the method will be bound. */\n  Callback callback() default Callback.TEXT_CHANGED;\n\n  /** {@link TextWatcher} callback methods. */\n  enum Callback {\n    /** {@link TextWatcher#onTextChanged(CharSequence, int, int, int)} */\n    @ListenerMethod(\n        name = \"onTextChanged\",\n        parameters = {\n            \"java.lang.CharSequence\",\n            \"int\",\n            \"int\",\n            \"int\"\n        }\n    )\n    TEXT_CHANGED,\n\n    /** {@link TextWatcher#beforeTextChanged(CharSequence, int, int, int)} */\n    @ListenerMethod(\n        name = \"beforeTextChanged\",\n        parameters = {\n            \"java.lang.CharSequence\",\n            \"int\",\n            \"int\",\n            \"int\"\n        }\n    )\n    BEFORE_TEXT_CHANGED,\n\n    /** {@link TextWatcher#afterTextChanged(android.text.Editable)} */\n    @ListenerMethod(\n        name = \"afterTextChanged\",\n        parameters = \"android.text.Editable\"\n    )\n    AFTER_TEXT_CHANGED,\n  }\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/OnTouch.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.IdRes;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static android.view.View.OnTouchListener;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Bind a method to an {@link OnTouchListener OnTouchListener} on the view for each ID specified.\n * <pre><code>\n * {@literal @}OnTouch(R.id.example) boolean onTouch() {\n *   Toast.makeText(this, \"Touched!\", Toast.LENGTH_SHORT).show();\n *   return false;\n * }\n * </code></pre>\n * Any number of parameters from\n * {@link OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) onTouch} may be used\n * on the method.\n * <p>\n * If the return type of the method is {@code void}, true will be returned from the listener.\n *\n * @see OnTouchListener\n */\n@Target(METHOD)\n@Retention(RUNTIME)\n@ListenerClass(\n    targetType = \"android.view.View\",\n    setter = \"setOnTouchListener\",\n    type = \"android.view.View.OnTouchListener\",\n    method = @ListenerMethod(\n        name = \"onTouch\",\n        parameters = {\n            \"android.view.View\",\n            \"android.view.MotionEvent\"\n        },\n        returnType = \"boolean\",\n        defaultReturn = \"true\"\n    )\n)\npublic @interface OnTouch {\n  /** View IDs to which the method will be bound. */\n  @IdRes int[] value() default { View.NO_ID };\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/Optional.java",
    "content": "package butterknife;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Denote that the view specified by the injection is not required to be present.\n * <pre><code>\n * {@literal @}Optional @OnClick(R.id.subtitle) void onSubtitleClick() {}\n * </code></pre>\n */\n@Target(METHOD)\n@Retention(RUNTIME)\npublic @interface Optional {\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/internal/Constants.java",
    "content": "package butterknife.internal;\n\npublic class Constants {\n\n  private Constants() { }\n\n  public static final int NO_RES_ID = -1;\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/internal/ListenerClass.java",
    "content": "package butterknife.internal;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n@Retention(RUNTIME) @Target(ANNOTATION_TYPE)\npublic @interface ListenerClass {\n  String targetType();\n\n  /** Name of the setter method on the {@linkplain #targetType() target type} for the listener. */\n  String setter();\n\n  /**\n   * Name of the method on the {@linkplain #targetType() target type} to remove the listener. If\n   * empty {@link #setter()} will be used by default.\n   */\n  String remover() default \"\";\n\n  /** Fully-qualified class name of the listener type. */\n  String type();\n\n  /** Enum which declares the listener callback methods. Mutually exclusive to {@link #method()}. */\n  Class<? extends Enum<?>> callbacks() default NONE.class;\n\n  /**\n   * Method data for single-method listener callbacks. Mutually exclusive with {@link #callbacks()}\n   * and an error to specify more than one value.\n   */\n  ListenerMethod[] method() default { };\n\n  /** Default value for {@link #callbacks()}. */\n  enum NONE { }\n}\n"
  },
  {
    "path": "butterknife-annotations/src/main/java/butterknife/internal/ListenerMethod.java",
    "content": "package butterknife.internal;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n@Retention(RUNTIME) @Target(FIELD)\npublic @interface ListenerMethod {\n  /** Name of the listener method for which this annotation applies. */\n  String name();\n\n  /** List of method parameters. If the type is not a primitive it must be fully-qualified. */\n  String[] parameters() default { };\n\n  /** Primitive or fully-qualified return type of the listener method. May also be {@code void}. */\n  String returnType() default \"void\";\n\n  /** If {@link #returnType()} is not {@code void} this value is returned when no binding exists. */\n  String defaultReturn() default \"null\";\n}\n"
  },
  {
    "path": "butterknife-compiler/build.gradle",
    "content": "apply plugin: 'java-library'\napply plugin: 'checkstyle'\n\nsourceCompatibility = JavaVersion.VERSION_1_8\ntargetCompatibility = JavaVersion.VERSION_1_8\n\ndependencies {\n  implementation project(':butterknife-annotations')\n  implementation deps.auto.common\n  implementation deps.guava\n  api deps.javapoet\n  compileOnly deps.auto.service\n  compileOnly files(org.gradle.internal.jvm.Jvm.current().getToolsJar())\n\n  api deps.incap.runtime\n  compileOnly deps.incap.processor\n\n  testImplementation deps.junit\n  testImplementation deps.truth\n}\n\ncheckstyle {\n  configFile rootProject.file('checkstyle.xml')\n  showViolations true\n  //Remove this when tests are less verbose, i.e. using JavaPoet\n  sourceSets = [sourceSets.main]\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife-compiler/gradle.properties",
    "content": "POM_NAME=Butterknife Compiler\nPOM_ARTIFACT_ID=butterknife-compiler\nPOM_PACKAGING=jar\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/BindingSet.java",
    "content": "package butterknife.compiler;\n\nimport butterknife.OnTouch;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport com.google.common.collect.ImmutableList;\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.MethodSpec;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport com.squareup.javapoet.TypeSpec;\nimport com.squareup.javapoet.WildcardTypeName;\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.annotation.Nullable;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.type.TypeMirror;\n\nimport static butterknife.compiler.ButterKnifeProcessor.ACTIVITY_TYPE;\nimport static butterknife.compiler.ButterKnifeProcessor.DIALOG_TYPE;\nimport static butterknife.compiler.ButterKnifeProcessor.VIEW_TYPE;\nimport static butterknife.compiler.ButterKnifeProcessor.isSubtypeOfType;\nimport static com.google.auto.common.MoreElements.getPackage;\nimport static java.util.Collections.singletonList;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.element.Modifier.FINAL;\nimport static javax.lang.model.element.Modifier.PRIVATE;\nimport static javax.lang.model.element.Modifier.PUBLIC;\n\n/** A set of all the bindings requested by a single type. */\nfinal class BindingSet implements BindingInformationProvider {\n  static final ClassName UTILS = ClassName.get(\"butterknife.internal\", \"Utils\");\n  private static final ClassName VIEW = ClassName.get(\"android.view\", \"View\");\n  private static final ClassName CONTEXT = ClassName.get(\"android.content\", \"Context\");\n  private static final ClassName RESOURCES = ClassName.get(\"android.content.res\", \"Resources\");\n  private static final ClassName UI_THREAD =\n      ClassName.get(\"androidx.annotation\", \"UiThread\");\n  private static final ClassName CALL_SUPER =\n      ClassName.get(\"androidx.annotation\", \"CallSuper\");\n  private static final ClassName SUPPRESS_LINT =\n      ClassName.get(\"android.annotation\", \"SuppressLint\");\n  private static final ClassName UNBINDER = ClassName.get(\"butterknife\", \"Unbinder\");\n  static final ClassName BITMAP_FACTORY = ClassName.get(\"android.graphics\", \"BitmapFactory\");\n  static final ClassName CONTEXT_COMPAT =\n      ClassName.get(\"androidx.core.content\", \"ContextCompat\");\n  static final ClassName ANIMATION_UTILS =\n          ClassName.get(\"android.view.animation\", \"AnimationUtils\");\n\n  private final TypeName targetTypeName;\n  private final ClassName bindingClassName;\n  private final TypeElement enclosingElement;\n  private final boolean isFinal;\n  private final boolean isView;\n  private final boolean isActivity;\n  private final boolean isDialog;\n  private final ImmutableList<ViewBinding> viewBindings;\n  private final ImmutableList<FieldCollectionViewBinding> collectionBindings;\n  private final ImmutableList<ResourceBinding> resourceBindings;\n  private final @Nullable BindingInformationProvider parentBinding;\n\n  private BindingSet(\n      TypeName targetTypeName, ClassName bindingClassName, TypeElement enclosingElement,\n      boolean isFinal, boolean isView, boolean isActivity, boolean isDialog,\n      ImmutableList<ViewBinding> viewBindings,\n      ImmutableList<FieldCollectionViewBinding> collectionBindings,\n      ImmutableList<ResourceBinding> resourceBindings,\n      @Nullable BindingInformationProvider parentBinding) {\n    this.isFinal = isFinal;\n    this.targetTypeName = targetTypeName;\n    this.bindingClassName = bindingClassName;\n    this.enclosingElement = enclosingElement;\n    this.isView = isView;\n    this.isActivity = isActivity;\n    this.isDialog = isDialog;\n    this.viewBindings = viewBindings;\n    this.collectionBindings = collectionBindings;\n    this.resourceBindings = resourceBindings;\n    this.parentBinding = parentBinding;\n  }\n\n  @Override\n  public ClassName getBindingClassName() {\n    return bindingClassName;\n  }\n\n  JavaFile brewJava(int sdk, boolean debuggable) {\n    TypeSpec bindingConfiguration = createType(sdk, debuggable);\n    return JavaFile.builder(bindingClassName.packageName(), bindingConfiguration)\n        .addFileComment(\"Generated code from Butter Knife. Do not modify!\")\n        .build();\n  }\n\n  private TypeSpec createType(int sdk, boolean debuggable) {\n    TypeSpec.Builder result = TypeSpec.classBuilder(bindingClassName.simpleName())\n        .addModifiers(PUBLIC)\n        .addOriginatingElement(enclosingElement);\n    if (isFinal) {\n      result.addModifiers(FINAL);\n    }\n\n    if (parentBinding != null) {\n      result.superclass(parentBinding.getBindingClassName());\n    } else {\n      result.addSuperinterface(UNBINDER);\n    }\n\n    if (hasTargetField()) {\n      result.addField(targetTypeName, \"target\", PRIVATE);\n    }\n\n    if (isView) {\n      result.addMethod(createBindingConstructorForView());\n    } else if (isActivity) {\n      result.addMethod(createBindingConstructorForActivity());\n    } else if (isDialog) {\n      result.addMethod(createBindingConstructorForDialog());\n    }\n    if (!constructorNeedsView()) {\n      // Add a delegating constructor with a target type + view signature for reflective use.\n      result.addMethod(createBindingViewDelegateConstructor());\n    }\n    result.addMethod(createBindingConstructor(sdk, debuggable));\n\n    if (hasViewBindings() || parentBinding == null) {\n      result.addMethod(createBindingUnbindMethod(result));\n    }\n\n    return result.build();\n  }\n\n  private MethodSpec createBindingViewDelegateConstructor() {\n    return MethodSpec.constructorBuilder()\n        .addJavadoc(\"@deprecated Use {@link #$T($T, $T)} for direct creation.\\n    \"\n                + \"Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\",\n            bindingClassName, targetTypeName, CONTEXT)\n        .addAnnotation(Deprecated.class)\n        .addAnnotation(UI_THREAD)\n        .addModifiers(PUBLIC)\n        .addParameter(targetTypeName, \"target\")\n        .addParameter(VIEW, \"source\")\n        .addStatement((\"this(target, source.getContext())\"))\n        .build();\n  }\n\n  private MethodSpec createBindingConstructorForView() {\n    MethodSpec.Builder builder = MethodSpec.constructorBuilder()\n        .addAnnotation(UI_THREAD)\n        .addModifiers(PUBLIC)\n        .addParameter(targetTypeName, \"target\");\n    if (constructorNeedsView()) {\n      builder.addStatement(\"this(target, target)\");\n    } else {\n      builder.addStatement(\"this(target, target.getContext())\");\n    }\n    return builder.build();\n  }\n\n  private MethodSpec createBindingConstructorForActivity() {\n    MethodSpec.Builder builder = MethodSpec.constructorBuilder()\n        .addAnnotation(UI_THREAD)\n        .addModifiers(PUBLIC)\n        .addParameter(targetTypeName, \"target\");\n    if (constructorNeedsView()) {\n      builder.addStatement(\"this(target, target.getWindow().getDecorView())\");\n    } else {\n      builder.addStatement(\"this(target, target)\");\n    }\n    return builder.build();\n  }\n\n  private MethodSpec createBindingConstructorForDialog() {\n    MethodSpec.Builder builder = MethodSpec.constructorBuilder()\n        .addAnnotation(UI_THREAD)\n        .addModifiers(PUBLIC)\n        .addParameter(targetTypeName, \"target\");\n    if (constructorNeedsView()) {\n      builder.addStatement(\"this(target, target.getWindow().getDecorView())\");\n    } else {\n      builder.addStatement(\"this(target, target.getContext())\");\n    }\n    return builder.build();\n  }\n\n  private MethodSpec createBindingConstructor(int sdk, boolean debuggable) {\n    MethodSpec.Builder constructor = MethodSpec.constructorBuilder()\n        .addAnnotation(UI_THREAD)\n        .addModifiers(PUBLIC);\n\n    if (hasMethodBindings()) {\n      constructor.addParameter(targetTypeName, \"target\", FINAL);\n    } else {\n      constructor.addParameter(targetTypeName, \"target\");\n    }\n\n    if (constructorNeedsView()) {\n      constructor.addParameter(VIEW, \"source\");\n    } else {\n      constructor.addParameter(CONTEXT, \"context\");\n    }\n\n    if (hasUnqualifiedResourceBindings()) {\n      // Aapt can change IDs out from underneath us, just suppress since all will work at runtime.\n      constructor.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class)\n          .addMember(\"value\", \"$S\", \"ResourceType\")\n          .build());\n    }\n\n    if (hasOnTouchMethodBindings()) {\n      constructor.addAnnotation(AnnotationSpec.builder(SUPPRESS_LINT)\n          .addMember(\"value\", \"$S\", \"ClickableViewAccessibility\")\n          .build());\n    }\n\n    if (parentBinding != null) {\n      if (parentBinding.constructorNeedsView()) {\n        constructor.addStatement(\"super(target, source)\");\n      } else if (constructorNeedsView()) {\n        constructor.addStatement(\"super(target, source.getContext())\");\n      } else {\n        constructor.addStatement(\"super(target, context)\");\n      }\n      constructor.addCode(\"\\n\");\n    }\n    if (hasTargetField()) {\n      constructor.addStatement(\"this.target = target\");\n      constructor.addCode(\"\\n\");\n    }\n\n    if (hasViewBindings()) {\n      if (hasViewLocal()) {\n        // Local variable in which all views will be temporarily stored.\n        constructor.addStatement(\"$T view\", VIEW);\n      }\n      for (ViewBinding binding : viewBindings) {\n        addViewBinding(constructor, binding, debuggable);\n      }\n      for (FieldCollectionViewBinding binding : collectionBindings) {\n        constructor.addStatement(\"$L\", binding.render(debuggable));\n      }\n\n      if (!resourceBindings.isEmpty()) {\n        constructor.addCode(\"\\n\");\n      }\n    }\n\n    if (!resourceBindings.isEmpty()) {\n      if (constructorNeedsView()) {\n        constructor.addStatement(\"$T context = source.getContext()\", CONTEXT);\n      }\n      if (hasResourceBindingsNeedingResource(sdk)) {\n        constructor.addStatement(\"$T res = context.getResources()\", RESOURCES);\n      }\n      for (ResourceBinding binding : resourceBindings) {\n        constructor.addStatement(\"$L\", binding.render(sdk));\n      }\n    }\n\n    return constructor.build();\n  }\n\n  private MethodSpec createBindingUnbindMethod(TypeSpec.Builder bindingClass) {\n    MethodSpec.Builder result = MethodSpec.methodBuilder(\"unbind\")\n        .addAnnotation(Override.class)\n        .addModifiers(PUBLIC);\n    if (!isFinal && parentBinding == null) {\n      result.addAnnotation(CALL_SUPER);\n    }\n\n    if (hasTargetField()) {\n      if (hasFieldBindings()) {\n        result.addStatement(\"$T target = this.target\", targetTypeName);\n      }\n      result.addStatement(\"if (target == null) throw new $T($S)\", IllegalStateException.class,\n          \"Bindings already cleared.\");\n      result.addStatement(\"$N = null\", hasFieldBindings() ? \"this.target\" : \"target\");\n      result.addCode(\"\\n\");\n      for (ViewBinding binding : viewBindings) {\n        if (binding.getFieldBinding() != null) {\n          result.addStatement(\"target.$L = null\", binding.getFieldBinding().getName());\n        }\n      }\n      for (FieldCollectionViewBinding binding : collectionBindings) {\n        result.addStatement(\"target.$L = null\", binding.name);\n      }\n    }\n\n    if (hasMethodBindings()) {\n      result.addCode(\"\\n\");\n      for (ViewBinding binding : viewBindings) {\n        addFieldAndUnbindStatement(bindingClass, result, binding);\n      }\n    }\n\n    if (parentBinding != null) {\n      result.addCode(\"\\n\");\n      result.addStatement(\"super.unbind()\");\n    }\n    return result.build();\n  }\n\n  private void addFieldAndUnbindStatement(TypeSpec.Builder result, MethodSpec.Builder unbindMethod,\n      ViewBinding bindings) {\n    // Only add fields to the binding if there are method bindings.\n    Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> classMethodBindings =\n        bindings.getMethodBindings();\n    if (classMethodBindings.isEmpty()) {\n      return;\n    }\n\n    String fieldName =\n        bindings.isBoundToRoot()\n            ? \"viewSource\"\n            : \"view\" + Integer.toHexString(bindings.getId().value);\n    result.addField(VIEW, fieldName, PRIVATE);\n\n    // We only need to emit the null check if there are zero required bindings.\n    boolean needsNullChecked = bindings.getRequiredBindings().isEmpty();\n    if (needsNullChecked) {\n      unbindMethod.beginControlFlow(\"if ($N != null)\", fieldName);\n    }\n\n    for (ListenerClass listenerClass : classMethodBindings.keySet()) {\n      // We need to keep a reference to the listener\n      // in case we need to unbind it via a remove method.\n      boolean requiresRemoval = !\"\".equals(listenerClass.remover());\n      String listenerField = \"null\";\n      if (requiresRemoval) {\n        TypeName listenerClassName = bestGuess(listenerClass.type());\n        listenerField = fieldName + ((ClassName) listenerClassName).simpleName();\n        result.addField(listenerClassName, listenerField, PRIVATE);\n      }\n\n      String targetType = listenerClass.targetType();\n      if (!VIEW_TYPE.equals(targetType)) {\n        unbindMethod.addStatement(\"(($T) $N).$N($N)\", bestGuess(targetType),\n            fieldName, removerOrSetter(listenerClass, requiresRemoval), listenerField);\n      } else {\n        unbindMethod.addStatement(\"$N.$N($N)\", fieldName,\n            removerOrSetter(listenerClass, requiresRemoval), listenerField);\n      }\n\n      if (requiresRemoval) {\n        unbindMethod.addStatement(\"$N = null\", listenerField);\n      }\n    }\n\n    unbindMethod.addStatement(\"$N = null\", fieldName);\n\n    if (needsNullChecked) {\n      unbindMethod.endControlFlow();\n    }\n  }\n\n  private String removerOrSetter(ListenerClass listenerClass, boolean requiresRemoval) {\n    return requiresRemoval\n        ? listenerClass.remover()\n        : listenerClass.setter();\n  }\n\n  private void addViewBinding(MethodSpec.Builder result, ViewBinding binding, boolean debuggable) {\n    if (binding.isSingleFieldBinding()) {\n      // Optimize the common case where there's a single binding directly to a field.\n      FieldViewBinding fieldBinding = requireNonNull(binding.getFieldBinding());\n      CodeBlock.Builder builder = CodeBlock.builder()\n          .add(\"target.$L = \", fieldBinding.getName());\n\n      boolean requiresCast = requiresCast(fieldBinding.getType());\n      if (!debuggable || (!requiresCast && !fieldBinding.isRequired())) {\n        if (requiresCast) {\n          builder.add(\"($T) \", fieldBinding.getType());\n        }\n        builder.add(\"source.findViewById($L)\", binding.getId().code);\n      } else {\n        builder.add(\"$T.find\", UTILS);\n        builder.add(fieldBinding.isRequired() ? \"RequiredView\" : \"OptionalView\");\n        if (requiresCast) {\n          builder.add(\"AsType\");\n        }\n        builder.add(\"(source, $L\", binding.getId().code);\n        if (fieldBinding.isRequired() || requiresCast) {\n          builder.add(\", $S\", asHumanDescription(singletonList(fieldBinding)));\n        }\n        if (requiresCast) {\n          builder.add(\", $T.class\", fieldBinding.getRawType());\n        }\n        builder.add(\")\");\n      }\n      result.addStatement(\"$L\", builder.build());\n      return;\n    }\n\n    List<MemberViewBinding> requiredBindings = binding.getRequiredBindings();\n    if (!debuggable || requiredBindings.isEmpty()) {\n      result.addStatement(\"view = source.findViewById($L)\", binding.getId().code);\n    } else if (!binding.isBoundToRoot()) {\n      result.addStatement(\"view = $T.findRequiredView(source, $L, $S)\", UTILS,\n          binding.getId().code, asHumanDescription(requiredBindings));\n    }\n\n    addFieldBinding(result, binding, debuggable);\n    addMethodBindings(result, binding, debuggable);\n  }\n\n  private void addFieldBinding(MethodSpec.Builder result, ViewBinding binding, boolean debuggable) {\n    FieldViewBinding fieldBinding = binding.getFieldBinding();\n    if (fieldBinding != null) {\n      if (requiresCast(fieldBinding.getType())) {\n        if (debuggable) {\n          result.addStatement(\"target.$L = $T.castView(view, $L, $S, $T.class)\",\n              fieldBinding.getName(), UTILS, binding.getId().code,\n              asHumanDescription(singletonList(fieldBinding)), fieldBinding.getRawType());\n        } else {\n          result.addStatement(\"target.$L = ($T) view\", fieldBinding.getName(),\n              fieldBinding.getType());\n        }\n      } else {\n        result.addStatement(\"target.$L = view\", fieldBinding.getName());\n      }\n    }\n  }\n\n  private void addMethodBindings(MethodSpec.Builder result, ViewBinding binding,\n      boolean debuggable) {\n    Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> classMethodBindings =\n        binding.getMethodBindings();\n    if (classMethodBindings.isEmpty()) {\n      return;\n    }\n\n    // We only need to emit the null check if there are zero required bindings.\n    boolean needsNullChecked = binding.getRequiredBindings().isEmpty();\n    if (needsNullChecked) {\n      result.beginControlFlow(\"if (view != null)\");\n    }\n\n    // Add the view reference to the binding.\n    String fieldName = \"viewSource\";\n    String bindName = \"source\";\n    if (!binding.isBoundToRoot()) {\n      fieldName = \"view\" + Integer.toHexString(binding.getId().value);\n      bindName = \"view\";\n    }\n    result.addStatement(\"$L = $N\", fieldName, bindName);\n\n    for (Map.Entry<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> e\n        : classMethodBindings.entrySet()) {\n      ListenerClass listener = e.getKey();\n      Map<ListenerMethod, Set<MethodViewBinding>> methodBindings = e.getValue();\n\n      TypeSpec.Builder callback = TypeSpec.anonymousClassBuilder(\"\")\n          .superclass(ClassName.bestGuess(listener.type()));\n\n      for (ListenerMethod method : getListenerMethods(listener)) {\n        MethodSpec.Builder callbackMethod = MethodSpec.methodBuilder(method.name())\n            .addAnnotation(Override.class)\n            .addModifiers(PUBLIC)\n            .returns(bestGuess(method.returnType()));\n        String[] parameterTypes = method.parameters();\n        for (int i = 0, count = parameterTypes.length; i < count; i++) {\n          callbackMethod.addParameter(bestGuess(parameterTypes[i]), \"p\" + i);\n        }\n\n        boolean hasReturnValue = false;\n        CodeBlock.Builder builder = CodeBlock.builder();\n        Set<MethodViewBinding> methodViewBindings = methodBindings.get(method);\n        if (methodViewBindings != null) {\n          for (MethodViewBinding methodBinding : methodViewBindings) {\n            if (methodBinding.hasReturnValue()) {\n              hasReturnValue = true;\n              builder.add(\"return \"); // TODO what about multiple methods?\n            }\n            builder.add(\"target.$L(\", methodBinding.getName());\n            List<Parameter> parameters = methodBinding.getParameters();\n            String[] listenerParameters = method.parameters();\n            for (int i = 0, count = parameters.size(); i < count; i++) {\n              if (i > 0) {\n                builder.add(\", \");\n              }\n\n              Parameter parameter = parameters.get(i);\n              int listenerPosition = parameter.getListenerPosition();\n\n              if (parameter.requiresCast(listenerParameters[listenerPosition])) {\n                if (debuggable) {\n                  builder.add(\"$T.castParam(p$L, $S, $L, $S, $L, $T.class)\", UTILS,\n                      listenerPosition, method.name(), listenerPosition, methodBinding.getName(), i,\n                      parameter.getType());\n                } else {\n                  builder.add(\"($T) p$L\", parameter.getType(), listenerPosition);\n                }\n              } else {\n                builder.add(\"p$L\", listenerPosition);\n              }\n            }\n            builder.add(\");\\n\");\n          }\n        }\n\n        if (!\"void\".equals(method.returnType()) && !hasReturnValue) {\n          builder.add(\"return $L;\\n\", method.defaultReturn());\n        }\n\n        callbackMethod.addCode(builder.build());\n        callback.addMethod(callbackMethod.build());\n      }\n\n      boolean requiresRemoval = listener.remover().length() != 0;\n      String listenerField = null;\n      if (requiresRemoval) {\n        TypeName listenerClassName = bestGuess(listener.type());\n        listenerField = fieldName + ((ClassName) listenerClassName).simpleName();\n        result.addStatement(\"$L = $L\", listenerField, callback.build());\n      }\n\n      String targetType = listener.targetType();\n      if (!VIEW_TYPE.equals(targetType)) {\n        result.addStatement(\"(($T) $N).$L($L)\", bestGuess(targetType), bindName,\n            listener.setter(), requiresRemoval ? listenerField : callback.build());\n      } else {\n        result.addStatement(\"$N.$L($L)\", bindName, listener.setter(),\n            requiresRemoval ? listenerField : callback.build());\n      }\n    }\n\n    if (needsNullChecked) {\n      result.endControlFlow();\n    }\n  }\n\n  private static List<ListenerMethod> getListenerMethods(ListenerClass listener) {\n    if (listener.method().length == 1) {\n      return Arrays.asList(listener.method());\n    }\n\n    try {\n      List<ListenerMethod> methods = new ArrayList<>();\n      Class<? extends Enum<?>> callbacks = listener.callbacks();\n      for (Enum<?> callbackMethod : callbacks.getEnumConstants()) {\n        Field callbackField = callbacks.getField(callbackMethod.name());\n        ListenerMethod method = callbackField.getAnnotation(ListenerMethod.class);\n        if (method == null) {\n          throw new IllegalStateException(String.format(\"@%s's %s.%s missing @%s annotation.\",\n              callbacks.getEnclosingClass().getSimpleName(), callbacks.getSimpleName(),\n              callbackMethod.name(), ListenerMethod.class.getSimpleName()));\n        }\n        methods.add(method);\n      }\n      return methods;\n    } catch (NoSuchFieldException e) {\n      throw new AssertionError(e);\n    }\n  }\n\n  static String asHumanDescription(Collection<? extends MemberViewBinding> bindings) {\n    Iterator<? extends MemberViewBinding> iterator = bindings.iterator();\n    switch (bindings.size()) {\n      case 1:\n        return iterator.next().getDescription();\n      case 2:\n        return iterator.next().getDescription() + \" and \" + iterator.next().getDescription();\n      default:\n        StringBuilder builder = new StringBuilder();\n        for (int i = 0, count = bindings.size(); i < count; i++) {\n          if (i != 0) {\n            builder.append(\", \");\n          }\n          if (i == count - 1) {\n            builder.append(\"and \");\n          }\n          builder.append(iterator.next().getDescription());\n        }\n        return builder.toString();\n    }\n  }\n\n  private static TypeName bestGuess(String type) {\n    switch (type) {\n      case \"void\": return TypeName.VOID;\n      case \"boolean\": return TypeName.BOOLEAN;\n      case \"byte\": return TypeName.BYTE;\n      case \"char\": return TypeName.CHAR;\n      case \"double\": return TypeName.DOUBLE;\n      case \"float\": return TypeName.FLOAT;\n      case \"int\": return TypeName.INT;\n      case \"long\": return TypeName.LONG;\n      case \"short\": return TypeName.SHORT;\n      default:\n        int left = type.indexOf('<');\n        if (left != -1) {\n          ClassName typeClassName = ClassName.bestGuess(type.substring(0, left));\n          List<TypeName> typeArguments = new ArrayList<>();\n          do {\n            typeArguments.add(WildcardTypeName.subtypeOf(Object.class));\n            left = type.indexOf('<', left + 1);\n          } while (left != -1);\n          return ParameterizedTypeName.get(typeClassName,\n              typeArguments.toArray(new TypeName[typeArguments.size()]));\n        }\n        return ClassName.bestGuess(type);\n    }\n  }\n\n  /** True when this type's bindings require a view hierarchy. */\n  private boolean hasViewBindings() {\n    return !viewBindings.isEmpty() || !collectionBindings.isEmpty();\n  }\n\n  /** True when this type's bindings use raw integer values instead of {@code R} references. */\n  private boolean hasUnqualifiedResourceBindings() {\n    for (ResourceBinding binding : resourceBindings) {\n      if (!binding.id().qualifed) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /** True when this type's bindings use Resource directly instead of Context. */\n  private boolean hasResourceBindingsNeedingResource(int sdk) {\n    for (ResourceBinding binding : resourceBindings) {\n      if (binding.requiresResources(sdk)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private boolean hasMethodBindings() {\n    for (ViewBinding bindings : viewBindings) {\n      if (!bindings.getMethodBindings().isEmpty()) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private boolean hasOnTouchMethodBindings() {\n    for (ViewBinding bindings : viewBindings) {\n      if (bindings.getMethodBindings()\n          .containsKey(OnTouch.class.getAnnotation(ListenerClass.class))) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private boolean hasFieldBindings() {\n    for (ViewBinding bindings : viewBindings) {\n      if (bindings.getFieldBinding() != null) {\n        return true;\n      }\n    }\n    return !collectionBindings.isEmpty();\n  }\n\n  private boolean hasTargetField() {\n    return hasFieldBindings() || hasMethodBindings();\n  }\n\n  private boolean hasViewLocal() {\n    for (ViewBinding bindings : viewBindings) {\n      if (bindings.requiresLocal()) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /** True if this binding requires a view. Otherwise only a context is needed. */\n  @Override\n  public boolean constructorNeedsView() {\n    return hasViewBindings() //\n        || (parentBinding != null && parentBinding.constructorNeedsView());\n  }\n\n  static boolean requiresCast(TypeName type) {\n    return !VIEW_TYPE.equals(type.toString());\n  }\n\n  @Override public String toString() {\n    return bindingClassName.toString();\n  }\n\n  static Builder newBuilder(TypeElement enclosingElement) {\n    TypeMirror typeMirror = enclosingElement.asType();\n\n    boolean isView = isSubtypeOfType(typeMirror, VIEW_TYPE);\n    boolean isActivity = isSubtypeOfType(typeMirror, ACTIVITY_TYPE);\n    boolean isDialog = isSubtypeOfType(typeMirror, DIALOG_TYPE);\n\n    TypeName targetType = TypeName.get(typeMirror);\n    if (targetType instanceof ParameterizedTypeName) {\n      targetType = ((ParameterizedTypeName) targetType).rawType;\n    }\n\n    ClassName bindingClassName = getBindingClassName(enclosingElement);\n\n    boolean isFinal = enclosingElement.getModifiers().contains(Modifier.FINAL);\n    return new Builder(targetType, bindingClassName, enclosingElement, isFinal, isView, isActivity,\n        isDialog);\n  }\n\n  static ClassName getBindingClassName(TypeElement typeElement) {\n    String packageName = getPackage(typeElement).getQualifiedName().toString();\n    String className = typeElement.getQualifiedName().toString().substring(\n            packageName.length() + 1).replace('.', '$');\n    return ClassName.get(packageName, className + \"_ViewBinding\");\n  }\n\n  static final class Builder {\n    private final TypeName targetTypeName;\n    private final ClassName bindingClassName;\n    private final TypeElement enclosingElement;\n    private final boolean isFinal;\n    private final boolean isView;\n    private final boolean isActivity;\n    private final boolean isDialog;\n\n    private @Nullable BindingInformationProvider parentBinding;\n\n    private final Map<Id, ViewBinding.Builder> viewIdMap = new LinkedHashMap<>();\n    private final ImmutableList.Builder<FieldCollectionViewBinding> collectionBindings =\n        ImmutableList.builder();\n    private final ImmutableList.Builder<ResourceBinding> resourceBindings = ImmutableList.builder();\n\n    private Builder(\n        TypeName targetTypeName, ClassName bindingClassName, TypeElement enclosingElement,\n        boolean isFinal, boolean isView, boolean isActivity, boolean isDialog) {\n      this.targetTypeName = targetTypeName;\n      this.bindingClassName = bindingClassName;\n      this.enclosingElement = enclosingElement;\n      this.isFinal = isFinal;\n      this.isView = isView;\n      this.isActivity = isActivity;\n      this.isDialog = isDialog;\n    }\n\n    void addField(Id id, FieldViewBinding binding) {\n      getOrCreateViewBindings(id).setFieldBinding(binding);\n    }\n\n    void addFieldCollection(FieldCollectionViewBinding binding) {\n      collectionBindings.add(binding);\n    }\n\n    boolean addMethod(\n        Id id,\n        ListenerClass listener,\n        ListenerMethod method,\n        MethodViewBinding binding) {\n      ViewBinding.Builder viewBinding = getOrCreateViewBindings(id);\n      if (viewBinding.hasMethodBinding(listener, method) && !\"void\".equals(method.returnType())) {\n        return false;\n      }\n      viewBinding.addMethodBinding(listener, method, binding);\n      return true;\n    }\n\n    void addResource(ResourceBinding binding) {\n      resourceBindings.add(binding);\n    }\n\n    void setParent(BindingInformationProvider parent) {\n      this.parentBinding = parent;\n    }\n\n    @Nullable String findExistingBindingName(Id id) {\n      ViewBinding.Builder builder = viewIdMap.get(id);\n      if (builder == null) {\n        return null;\n      }\n      FieldViewBinding fieldBinding = builder.fieldBinding;\n      if (fieldBinding == null) {\n        return null;\n      }\n      return fieldBinding.getName();\n    }\n\n    private ViewBinding.Builder getOrCreateViewBindings(Id id) {\n      ViewBinding.Builder viewId = viewIdMap.get(id);\n      if (viewId == null) {\n        viewId = new ViewBinding.Builder(id);\n        viewIdMap.put(id, viewId);\n      }\n      return viewId;\n    }\n\n    BindingSet build() {\n      ImmutableList.Builder<ViewBinding> viewBindings = ImmutableList.builder();\n      for (ViewBinding.Builder builder : viewIdMap.values()) {\n        viewBindings.add(builder.build());\n      }\n      return new BindingSet(targetTypeName, bindingClassName, enclosingElement, isFinal, isView,\n          isActivity, isDialog, viewBindings.build(), collectionBindings.build(),\n          resourceBindings.build(), parentBinding);\n    }\n  }\n}\n\ninterface BindingInformationProvider {\n  boolean constructorNeedsView();\n  ClassName getBindingClassName();\n}\n\nfinal class ClasspathBindingSet implements BindingInformationProvider {\n  private boolean constructorNeedsView;\n  private ClassName className;\n\n  ClasspathBindingSet(boolean constructorNeedsView, TypeElement classElement) {\n    this.constructorNeedsView = constructorNeedsView;\n    this.className = BindingSet.getBindingClassName(classElement);\n  }\n\n  @Override\n  public ClassName getBindingClassName() {\n    return className;\n  }\n\n  @Override\n  public boolean constructorNeedsView() {\n    return constructorNeedsView;\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java",
    "content": "package butterknife.compiler;\n\nimport butterknife.BindAnim;\nimport butterknife.BindArray;\nimport butterknife.BindBitmap;\nimport butterknife.BindBool;\nimport butterknife.BindColor;\nimport butterknife.BindDimen;\nimport butterknife.BindDrawable;\nimport butterknife.BindFloat;\nimport butterknife.BindFont;\nimport butterknife.BindInt;\nimport butterknife.BindString;\nimport butterknife.BindView;\nimport butterknife.BindViews;\nimport butterknife.OnCheckedChanged;\nimport butterknife.OnClick;\nimport butterknife.OnEditorAction;\nimport butterknife.OnFocusChange;\nimport butterknife.OnItemClick;\nimport butterknife.OnItemLongClick;\nimport butterknife.OnItemSelected;\nimport butterknife.OnLongClick;\nimport butterknife.OnPageChange;\nimport butterknife.OnTextChanged;\nimport butterknife.OnTouch;\nimport butterknife.Optional;\nimport butterknife.compiler.FieldTypefaceBinding.TypefaceStyles;\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport com.google.auto.common.SuperficialValidation;\nimport com.google.auto.service.AutoService;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.squareup.javapoet.JavaFile;\nimport com.squareup.javapoet.TypeName;\nimport com.sun.source.util.Trees;\nimport com.sun.tools.javac.code.Symbol;\nimport com.sun.tools.javac.code.Type;\nimport com.sun.tools.javac.tree.JCTree;\nimport com.sun.tools.javac.tree.TreeScanner;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.Deque;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.annotation.Nullable;\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.Filer;\nimport javax.annotation.processing.ProcessingEnvironment;\nimport javax.annotation.processing.Processor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.SourceVersion;\nimport javax.lang.model.element.AnnotationMirror;\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableElement;\nimport javax.lang.model.element.Modifier;\nimport javax.lang.model.element.Name;\nimport javax.lang.model.element.TypeElement;\nimport javax.lang.model.element.VariableElement;\nimport javax.lang.model.type.ArrayType;\nimport javax.lang.model.type.DeclaredType;\nimport javax.lang.model.type.TypeKind;\nimport javax.lang.model.type.TypeMirror;\nimport javax.lang.model.type.TypeVariable;\nimport javax.lang.model.util.Types;\nimport javax.tools.Diagnostic.Kind;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessor;\nimport net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;\n\nimport static butterknife.internal.Constants.NO_RES_ID;\nimport static java.util.Objects.requireNonNull;\nimport static javax.lang.model.element.ElementKind.CLASS;\nimport static javax.lang.model.element.ElementKind.INTERFACE;\nimport static javax.lang.model.element.ElementKind.METHOD;\nimport static javax.lang.model.element.Modifier.PRIVATE;\nimport static javax.lang.model.element.Modifier.STATIC;\n\n@AutoService(Processor.class)\n@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.DYNAMIC)\n@SuppressWarnings(\"NullAway\") // TODO fix all these...\npublic final class ButterKnifeProcessor extends AbstractProcessor {\n  // TODO remove when http://b.android.com/187527 is released.\n  private static final String OPTION_SDK_INT = \"butterknife.minSdk\";\n  private static final String OPTION_DEBUGGABLE = \"butterknife.debuggable\";\n  static final Id NO_ID = new Id(NO_RES_ID);\n  static final String VIEW_TYPE = \"android.view.View\";\n  static final String ACTIVITY_TYPE = \"android.app.Activity\";\n  static final String DIALOG_TYPE = \"android.app.Dialog\";\n  private static final String COLOR_STATE_LIST_TYPE = \"android.content.res.ColorStateList\";\n  private static final String BITMAP_TYPE = \"android.graphics.Bitmap\";\n  private static final String ANIMATION_TYPE = \"android.view.animation.Animation\";\n  private static final String DRAWABLE_TYPE = \"android.graphics.drawable.Drawable\";\n  private static final String TYPED_ARRAY_TYPE = \"android.content.res.TypedArray\";\n  private static final String TYPEFACE_TYPE = \"android.graphics.Typeface\";\n  private static final String NULLABLE_ANNOTATION_NAME = \"Nullable\";\n  private static final String STRING_TYPE = \"java.lang.String\";\n  private static final String LIST_TYPE = List.class.getCanonicalName();\n  private static final List<Class<? extends Annotation>> LISTENERS = Arrays.asList(//\n      OnCheckedChanged.class, //\n      OnClick.class, //\n      OnEditorAction.class, //\n      OnFocusChange.class, //\n      OnItemClick.class, //\n      OnItemLongClick.class, //\n      OnItemSelected.class, //\n      OnLongClick.class, //\n      OnPageChange.class, //\n      OnTextChanged.class, //\n      OnTouch.class //\n  );\n\n  private Types typeUtils;\n  private Filer filer;\n  private @Nullable Trees trees;\n\n  private int sdk = 1;\n  private boolean debuggable = true;\n\n  private final RScanner rScanner = new RScanner();\n\n  @Override public synchronized void init(ProcessingEnvironment env) {\n    super.init(env);\n\n    String sdk = env.getOptions().get(OPTION_SDK_INT);\n    if (sdk != null) {\n      try {\n        this.sdk = Integer.parseInt(sdk);\n      } catch (NumberFormatException e) {\n        env.getMessager()\n            .printMessage(Kind.WARNING, \"Unable to parse supplied minSdk option '\"\n                + sdk\n                + \"'. Falling back to API 1 support.\");\n      }\n    }\n\n    debuggable = !\"false\".equals(env.getOptions().get(OPTION_DEBUGGABLE));\n\n    typeUtils = env.getTypeUtils();\n    filer = env.getFiler();\n    try {\n      trees = Trees.instance(processingEnv);\n    } catch (IllegalArgumentException ignored) {\n      try {\n        // Get original ProcessingEnvironment from Gradle-wrapped one or KAPT-wrapped one.\n        for (Field field : processingEnv.getClass().getDeclaredFields()) {\n          if (field.getName().equals(\"delegate\") || field.getName().equals(\"processingEnv\")) {\n            field.setAccessible(true);\n            ProcessingEnvironment javacEnv = (ProcessingEnvironment) field.get(processingEnv);\n            trees = Trees.instance(javacEnv);\n            break;\n          }\n        }\n      } catch (Throwable ignored2) {\n      }\n    }\n  }\n\n  @Override public Set<String> getSupportedOptions() {\n    ImmutableSet.Builder<String> builder = ImmutableSet.builder();\n    builder.add(OPTION_SDK_INT, OPTION_DEBUGGABLE);\n    if (trees != null) {\n      builder.add(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());\n    }\n    return builder.build();\n  }\n\n  @Override public Set<String> getSupportedAnnotationTypes() {\n    Set<String> types = new LinkedHashSet<>();\n    for (Class<? extends Annotation> annotation : getSupportedAnnotations()) {\n      types.add(annotation.getCanonicalName());\n    }\n    return types;\n  }\n\n  private Set<Class<? extends Annotation>> getSupportedAnnotations() {\n    Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>();\n\n    annotations.add(BindAnim.class);\n    annotations.add(BindArray.class);\n    annotations.add(BindBitmap.class);\n    annotations.add(BindBool.class);\n    annotations.add(BindColor.class);\n    annotations.add(BindDimen.class);\n    annotations.add(BindDrawable.class);\n    annotations.add(BindFloat.class);\n    annotations.add(BindFont.class);\n    annotations.add(BindInt.class);\n    annotations.add(BindString.class);\n    annotations.add(BindView.class);\n    annotations.add(BindViews.class);\n    annotations.addAll(LISTENERS);\n\n    return annotations;\n  }\n\n  @Override public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) {\n    Map<TypeElement, BindingSet> bindingMap = findAndParseTargets(env);\n\n    for (Map.Entry<TypeElement, BindingSet> entry : bindingMap.entrySet()) {\n      TypeElement typeElement = entry.getKey();\n      BindingSet binding = entry.getValue();\n\n      JavaFile javaFile = binding.brewJava(sdk, debuggable);\n      try {\n        javaFile.writeTo(filer);\n      } catch (IOException e) {\n        error(typeElement, \"Unable to write binding for type %s: %s\", typeElement, e.getMessage());\n      }\n    }\n\n    return false;\n  }\n\n  private Map<TypeElement, BindingSet> findAndParseTargets(RoundEnvironment env) {\n    Map<TypeElement, BindingSet.Builder> builderMap = new LinkedHashMap<>();\n    Set<TypeElement> erasedTargetNames = new LinkedHashSet<>();\n\n    // Process each @BindAnim element.\n    for (Element element : env.getElementsAnnotatedWith(BindAnim.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceAnimation(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindAnim.class, e);\n      }\n    }\n\n    // Process each @BindArray element.\n    for (Element element : env.getElementsAnnotatedWith(BindArray.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceArray(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindArray.class, e);\n      }\n    }\n\n    // Process each @BindBitmap element.\n    for (Element element : env.getElementsAnnotatedWith(BindBitmap.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceBitmap(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindBitmap.class, e);\n      }\n    }\n\n    // Process each @BindBool element.\n    for (Element element : env.getElementsAnnotatedWith(BindBool.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceBool(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindBool.class, e);\n      }\n    }\n\n    // Process each @BindColor element.\n    for (Element element : env.getElementsAnnotatedWith(BindColor.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceColor(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindColor.class, e);\n      }\n    }\n\n    // Process each @BindDimen element.\n    for (Element element : env.getElementsAnnotatedWith(BindDimen.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceDimen(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindDimen.class, e);\n      }\n    }\n\n    // Process each @BindDrawable element.\n    for (Element element : env.getElementsAnnotatedWith(BindDrawable.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceDrawable(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindDrawable.class, e);\n      }\n    }\n\n    // Process each @BindFloat element.\n    for (Element element : env.getElementsAnnotatedWith(BindFloat.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceFloat(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindFloat.class, e);\n      }\n    }\n\n    // Process each @BindFont element.\n    for (Element element : env.getElementsAnnotatedWith(BindFont.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceFont(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindFont.class, e);\n      }\n    }\n\n    // Process each @BindInt element.\n    for (Element element : env.getElementsAnnotatedWith(BindInt.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceInt(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindInt.class, e);\n      }\n    }\n\n    // Process each @BindString element.\n    for (Element element : env.getElementsAnnotatedWith(BindString.class)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseResourceString(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindString.class, e);\n      }\n    }\n\n    // Process each @BindView element.\n    for (Element element : env.getElementsAnnotatedWith(BindView.class)) {\n      // we don't SuperficialValidation.validateElement(element)\n      // so that an unresolved View type can be generated by later processing rounds\n      try {\n        parseBindView(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindView.class, e);\n      }\n    }\n\n    // Process each @BindViews element.\n    for (Element element : env.getElementsAnnotatedWith(BindViews.class)) {\n      // we don't SuperficialValidation.validateElement(element)\n      // so that an unresolved View type can be generated by later processing rounds\n      try {\n        parseBindViews(element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        logParsingError(element, BindViews.class, e);\n      }\n    }\n\n    // Process each annotation that corresponds to a listener.\n    for (Class<? extends Annotation> listener : LISTENERS) {\n      findAndParseListener(env, listener, builderMap, erasedTargetNames);\n    }\n\n    Map<TypeElement, ClasspathBindingSet> classpathBindings =\n        findAllSupertypeBindings(builderMap, erasedTargetNames);\n\n    // Associate superclass binders with their subclass binders. This is a queue-based tree walk\n    // which starts at the roots (superclasses) and walks to the leafs (subclasses).\n    Deque<Map.Entry<TypeElement, BindingSet.Builder>> entries =\n        new ArrayDeque<>(builderMap.entrySet());\n    Map<TypeElement, BindingSet> bindingMap = new LinkedHashMap<>();\n    while (!entries.isEmpty()) {\n      Map.Entry<TypeElement, BindingSet.Builder> entry = entries.removeFirst();\n\n      TypeElement type = entry.getKey();\n      BindingSet.Builder builder = entry.getValue();\n\n      TypeElement parentType = findParentType(type, erasedTargetNames, classpathBindings.keySet());\n      if (parentType == null) {\n        bindingMap.put(type, builder.build());\n      } else {\n        BindingInformationProvider parentBinding = bindingMap.get(parentType);\n        if (parentBinding == null) {\n          parentBinding = classpathBindings.get(parentType);\n        }\n        if (parentBinding != null) {\n          builder.setParent(parentBinding);\n          bindingMap.put(type, builder.build());\n        } else {\n          // Has a superclass binding but we haven't built it yet. Re-enqueue for later.\n          entries.addLast(entry);\n        }\n      }\n    }\n\n    return bindingMap;\n  }\n\n  private void logParsingError(Element element, Class<? extends Annotation> annotation,\n      Exception e) {\n    StringWriter stackTrace = new StringWriter();\n    e.printStackTrace(new PrintWriter(stackTrace));\n    error(element, \"Unable to parse @%s binding.\\n\\n%s\", annotation.getSimpleName(), stackTrace);\n  }\n\n  private boolean isInaccessibleViaGeneratedCode(Class<? extends Annotation> annotationClass,\n      String targetThing, Element element) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify field or method modifiers.\n    Set<Modifier> modifiers = element.getModifiers();\n    if (modifiers.contains(PRIVATE) || modifiers.contains(STATIC)) {\n      error(element, \"@%s %s must not be private or static. (%s.%s)\",\n          annotationClass.getSimpleName(), targetThing, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify containing type.\n    if (enclosingElement.getKind() != CLASS) {\n      error(enclosingElement, \"@%s %s may only be contained in classes. (%s.%s)\",\n          annotationClass.getSimpleName(), targetThing, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify containing class visibility is not private.\n    if (enclosingElement.getModifiers().contains(PRIVATE)) {\n      error(enclosingElement, \"@%s %s may not be contained in private classes. (%s.%s)\",\n          annotationClass.getSimpleName(), targetThing, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    return hasError;\n  }\n\n  private boolean isBindingInWrongPackage(Class<? extends Annotation> annotationClass,\n      Element element) {\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n    String qualifiedName = enclosingElement.getQualifiedName().toString();\n\n    if (qualifiedName.startsWith(\"android.\")) {\n      error(element, \"@%s-annotated class incorrectly in Android framework package. (%s)\",\n          annotationClass.getSimpleName(), qualifiedName);\n      return true;\n    }\n    if (qualifiedName.startsWith(\"java.\")) {\n      error(element, \"@%s-annotated class incorrectly in Java framework package. (%s)\",\n          annotationClass.getSimpleName(), qualifiedName);\n      return true;\n    }\n\n    return false;\n  }\n\n  private void parseBindView(Element element, Map<TypeElement, BindingSet.Builder> builderMap,\n      Set<TypeElement> erasedTargetNames) {\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Start by verifying common generated code restrictions.\n    boolean hasError = isInaccessibleViaGeneratedCode(BindView.class, \"fields\", element)\n        || isBindingInWrongPackage(BindView.class, element);\n\n    // Verify that the target type extends from View.\n    TypeMirror elementType = element.asType();\n    if (elementType.getKind() == TypeKind.TYPEVAR) {\n      TypeVariable typeVariable = (TypeVariable) elementType;\n      elementType = typeVariable.getUpperBound();\n    }\n    Name qualifiedName = enclosingElement.getQualifiedName();\n    Name simpleName = element.getSimpleName();\n    if (!isSubtypeOfType(elementType, VIEW_TYPE) && !isInterface(elementType)) {\n      if (elementType.getKind() == TypeKind.ERROR) {\n        note(element, \"@%s field with unresolved type (%s) \"\n                + \"must elsewhere be generated as a View or interface. (%s.%s)\",\n            BindView.class.getSimpleName(), elementType, qualifiedName, simpleName);\n      } else {\n        error(element, \"@%s fields must extend from View or be an interface. (%s.%s)\",\n            BindView.class.getSimpleName(), qualifiedName, simpleName);\n        hasError = true;\n      }\n    }\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    int id = element.getAnnotation(BindView.class).value();\n    BindingSet.Builder builder = builderMap.get(enclosingElement);\n    Id resourceId = elementToId(element, BindView.class, id);\n    if (builder != null) {\n      String existingBindingName = builder.findExistingBindingName(resourceId);\n      if (existingBindingName != null) {\n        error(element, \"Attempt to use @%s for an already bound ID %d on '%s'. (%s.%s)\",\n            BindView.class.getSimpleName(), id, existingBindingName,\n            enclosingElement.getQualifiedName(), element.getSimpleName());\n        return;\n      }\n    } else {\n      builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    }\n\n    String name = simpleName.toString();\n    TypeName type = TypeName.get(elementType);\n    boolean required = isFieldRequired(element);\n\n    builder.addField(resourceId, new FieldViewBinding(name, type, required));\n\n    // Add the type-erased version to the valid binding targets set.\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseBindViews(Element element, Map<TypeElement, BindingSet.Builder> builderMap,\n      Set<TypeElement> erasedTargetNames) {\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Start by verifying common generated code restrictions.\n    boolean hasError = isInaccessibleViaGeneratedCode(BindViews.class, \"fields\", element)\n        || isBindingInWrongPackage(BindViews.class, element);\n\n    // Verify that the type is a List or an array.\n    TypeMirror elementType = element.asType();\n    String erasedType = doubleErasure(elementType);\n    TypeMirror viewType = null;\n    FieldCollectionViewBinding.Kind kind = null;\n    if (elementType.getKind() == TypeKind.ARRAY) {\n      ArrayType arrayType = (ArrayType) elementType;\n      viewType = arrayType.getComponentType();\n      kind = FieldCollectionViewBinding.Kind.ARRAY;\n    } else if (LIST_TYPE.equals(erasedType)) {\n      DeclaredType declaredType = (DeclaredType) elementType;\n      List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();\n      if (typeArguments.size() != 1) {\n        error(element, \"@%s List must have a generic component. (%s.%s)\",\n            BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(),\n            element.getSimpleName());\n        hasError = true;\n      } else {\n        viewType = typeArguments.get(0);\n      }\n      kind = FieldCollectionViewBinding.Kind.LIST;\n    } else {\n      error(element, \"@%s must be a List or array. (%s.%s)\", BindViews.class.getSimpleName(),\n          enclosingElement.getQualifiedName(), element.getSimpleName());\n      hasError = true;\n    }\n    if (viewType != null && viewType.getKind() == TypeKind.TYPEVAR) {\n      TypeVariable typeVariable = (TypeVariable) viewType;\n      viewType = typeVariable.getUpperBound();\n    }\n\n    // Verify that the target type extends from View.\n    if (viewType != null && !isSubtypeOfType(viewType, VIEW_TYPE) && !isInterface(viewType)) {\n      if (viewType.getKind() == TypeKind.ERROR) {\n        note(element, \"@%s List or array with unresolved type (%s) \"\n                + \"must elsewhere be generated as a View or interface. (%s.%s)\",\n            BindViews.class.getSimpleName(), viewType, enclosingElement.getQualifiedName(),\n            element.getSimpleName());\n      } else {\n        error(element, \"@%s List or array type must extend from View or be an interface. (%s.%s)\",\n            BindViews.class.getSimpleName(), enclosingElement.getQualifiedName(),\n            element.getSimpleName());\n        hasError = true;\n      }\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int[] ids = element.getAnnotation(BindViews.class).value();\n    if (ids.length == 0) {\n      error(element, \"@%s must specify at least one ID. (%s.%s)\", BindViews.class.getSimpleName(),\n          enclosingElement.getQualifiedName(), element.getSimpleName());\n      hasError = true;\n    }\n\n    Integer duplicateId = findDuplicate(ids);\n    if (duplicateId != null) {\n      error(element, \"@%s annotation contains duplicate ID %d. (%s.%s)\",\n          BindViews.class.getSimpleName(), duplicateId, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    if (hasError) {\n      return;\n    }\n\n    TypeName type = TypeName.get(requireNonNull(viewType));\n    boolean required = isFieldRequired(element);\n\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addFieldCollection(new FieldCollectionViewBinding(name, type, requireNonNull(kind),\n        new ArrayList<>(elementToIds(element, BindViews.class, ids).values()), required));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceAnimation(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is Animation.\n    if (!ANIMATION_TYPE.equals(element.asType().toString())) {\n      error(element, \"@%s field type must be 'Animation'. (%s.%s)\",\n          BindAnim.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindAnim.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindAnim.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindAnim.class).value();\n    Id resourceId = elementToId(element, BindAnim.class, id);\n\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(new FieldAnimationBinding(resourceId, name));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceBool(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is bool.\n    if (element.asType().getKind() != TypeKind.BOOLEAN) {\n      error(element, \"@%s field type must be 'boolean'. (%s.%s)\",\n          BindBool.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindBool.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindBool.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindBool.class).value();\n    Id resourceId = elementToId(element, BindBool.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(\n        new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.BOOL));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceColor(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is int or ColorStateList.\n    boolean isColorStateList = false;\n    TypeMirror elementType = element.asType();\n    if (COLOR_STATE_LIST_TYPE.equals(elementType.toString())) {\n      isColorStateList = true;\n    } else if (elementType.getKind() != TypeKind.INT) {\n      error(element, \"@%s field type must be 'int' or 'ColorStateList'. (%s.%s)\",\n          BindColor.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindColor.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindColor.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindColor.class).value();\n    Id resourceId = elementToId(element, BindColor.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n\n    FieldResourceBinding.Type colorStateList = FieldResourceBinding.Type.COLOR_STATE_LIST;\n    FieldResourceBinding.Type color = FieldResourceBinding.Type.COLOR;\n    builder.addResource(new FieldResourceBinding(\n        resourceId,\n        name,\n        isColorStateList ? colorStateList : color));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceDimen(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is int or ColorStateList.\n    boolean isInt = false;\n    TypeMirror elementType = element.asType();\n    if (elementType.getKind() == TypeKind.INT) {\n      isInt = true;\n    } else if (elementType.getKind() != TypeKind.FLOAT) {\n      error(element, \"@%s field type must be 'int' or 'float'. (%s.%s)\",\n          BindDimen.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindDimen.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindDimen.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindDimen.class).value();\n    Id resourceId = elementToId(element, BindDimen.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(new FieldResourceBinding(resourceId, name,\n        isInt ? FieldResourceBinding.Type.DIMEN_AS_INT : FieldResourceBinding.Type.DIMEN_AS_FLOAT));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceBitmap(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is Bitmap.\n    if (!BITMAP_TYPE.equals(element.asType().toString())) {\n      error(element, \"@%s field type must be 'Bitmap'. (%s.%s)\",\n          BindBitmap.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindBitmap.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindBitmap.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindBitmap.class).value();\n    Id resourceId = elementToId(element, BindBitmap.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(\n        new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.BITMAP));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceDrawable(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is Drawable.\n    if (!DRAWABLE_TYPE.equals(element.asType().toString())) {\n      error(element, \"@%s field type must be 'Drawable'. (%s.%s)\",\n          BindDrawable.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindDrawable.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindDrawable.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindDrawable.class).value();\n    int tint = element.getAnnotation(BindDrawable.class).tint();\n    Map<Integer, Id> resourceIds = elementToIds(element, BindDrawable.class, new int[] {id, tint});\n\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(new FieldDrawableBinding(resourceIds.get(id), name, resourceIds.get(tint)));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceFloat(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is float.\n    if (element.asType().getKind() != TypeKind.FLOAT) {\n      error(element, \"@%s field type must be 'float'. (%s.%s)\",\n          BindFloat.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindFloat.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindFloat.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindFloat.class).value();\n    Id resourceId = elementToId(element, BindFloat.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(\n        new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.FLOAT));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceFont(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is a Typeface.\n    if (!TYPEFACE_TYPE.equals(element.asType().toString())) {\n      error(element, \"@%s field type must be 'Typeface'. (%s.%s)\",\n          BindFont.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindFont.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindFont.class, element);\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    BindFont bindFont = element.getAnnotation(BindFont.class);\n\n    int styleValue = bindFont.style();\n    TypefaceStyles style = TypefaceStyles.fromValue(styleValue);\n    if (style == null) {\n      error(element, \"@%s style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC. (%s.%s)\",\n          BindFont.class.getSimpleName(), enclosingElement.getQualifiedName(), name);\n      hasError = true;\n    }\n\n    if (hasError) {\n      return;\n    }\n\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    Id resourceId = elementToId(element, BindFont.class, bindFont.value());\n    builder.addResource(new FieldTypefaceBinding(resourceId, name, style));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceInt(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is int.\n    if (element.asType().getKind() != TypeKind.INT) {\n      error(element, \"@%s field type must be 'int'. (%s.%s)\", BindInt.class.getSimpleName(),\n          enclosingElement.getQualifiedName(), element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindInt.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindInt.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindInt.class).value();\n    Id resourceId = elementToId(element, BindInt.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(\n        new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.INT));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceString(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is String.\n    if (!STRING_TYPE.equals(element.asType().toString())) {\n      error(element, \"@%s field type must be 'String'. (%s.%s)\",\n          BindString.class.getSimpleName(), enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindString.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindString.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindString.class).value();\n    Id resourceId = elementToId(element, BindString.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(\n        new FieldResourceBinding(resourceId, name, FieldResourceBinding.Type.STRING));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private void parseResourceArray(Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    boolean hasError = false;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Verify that the target type is supported.\n    FieldResourceBinding.Type type = getArrayResourceMethodName(element);\n    if (type == null) {\n      error(element,\n          \"@%s field type must be one of: String[], int[], CharSequence[], %s. (%s.%s)\",\n          BindArray.class.getSimpleName(), TYPED_ARRAY_TYPE, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify common generated code restrictions.\n    hasError |= isInaccessibleViaGeneratedCode(BindArray.class, \"fields\", element);\n    hasError |= isBindingInWrongPackage(BindArray.class, element);\n\n    if (hasError) {\n      return;\n    }\n\n    // Assemble information on the field.\n    String name = element.getSimpleName().toString();\n    int id = element.getAnnotation(BindArray.class).value();\n    Id resourceId = elementToId(element, BindArray.class, id);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    builder.addResource(new FieldResourceBinding(resourceId, name, requireNonNull(type)));\n\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  /**\n   * Returns a method name from the {@code android.content.res.Resources} class for array resource\n   * binding, null if the element type is not supported.\n   */\n  private static @Nullable FieldResourceBinding.Type getArrayResourceMethodName(Element element) {\n    TypeMirror typeMirror = element.asType();\n    if (TYPED_ARRAY_TYPE.equals(typeMirror.toString())) {\n      return FieldResourceBinding.Type.TYPED_ARRAY;\n    }\n    if (TypeKind.ARRAY.equals(typeMirror.getKind())) {\n      ArrayType arrayType = (ArrayType) typeMirror;\n      String componentType = arrayType.getComponentType().toString();\n      if (STRING_TYPE.equals(componentType)) {\n        return FieldResourceBinding.Type.STRING_ARRAY;\n      } else if (\"int\".equals(componentType)) {\n        return FieldResourceBinding.Type.INT_ARRAY;\n      } else if (\"java.lang.CharSequence\".equals(componentType)) {\n        return FieldResourceBinding.Type.TEXT_ARRAY;\n      }\n    }\n    return null;\n  }\n\n  /** Returns the first duplicate element inside an array, null if there are no duplicates. */\n  private static @Nullable Integer findDuplicate(int[] array) {\n    Set<Integer> seenElements = new LinkedHashSet<>();\n\n    for (int element : array) {\n      if (!seenElements.add(element)) {\n        return element;\n      }\n    }\n\n    return null;\n  }\n\n  /** Uses both {@link Types#erasure} and string manipulation to strip any generic types. */\n  private String doubleErasure(TypeMirror elementType) {\n    String name = typeUtils.erasure(elementType).toString();\n    int typeParamStart = name.indexOf('<');\n    if (typeParamStart != -1) {\n      name = name.substring(0, typeParamStart);\n    }\n    return name;\n  }\n\n  private void findAndParseListener(RoundEnvironment env,\n      Class<? extends Annotation> annotationClass,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames) {\n    for (Element element : env.getElementsAnnotatedWith(annotationClass)) {\n      if (!SuperficialValidation.validateElement(element)) continue;\n      try {\n        parseListenerAnnotation(annotationClass, element, builderMap, erasedTargetNames);\n      } catch (Exception e) {\n        StringWriter stackTrace = new StringWriter();\n        e.printStackTrace(new PrintWriter(stackTrace));\n\n        error(element, \"Unable to generate view binder for @%s.\\n\\n%s\",\n            annotationClass.getSimpleName(), stackTrace.toString());\n      }\n    }\n  }\n\n  private void parseListenerAnnotation(Class<? extends Annotation> annotationClass, Element element,\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> erasedTargetNames)\n      throws Exception {\n    // This should be guarded by the annotation's @Target but it's worth a check for safe casting.\n    if (!(element instanceof ExecutableElement) || element.getKind() != METHOD) {\n      throw new IllegalStateException(\n          String.format(\"@%s annotation must be on a method.\", annotationClass.getSimpleName()));\n    }\n\n    ExecutableElement executableElement = (ExecutableElement) element;\n    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();\n\n    // Assemble information on the method.\n    Annotation annotation = element.getAnnotation(annotationClass);\n    Method annotationValue = annotationClass.getDeclaredMethod(\"value\");\n    if (annotationValue.getReturnType() != int[].class) {\n      throw new IllegalStateException(\n          String.format(\"@%s annotation value() type not int[].\", annotationClass));\n    }\n\n    int[] ids = (int[]) annotationValue.invoke(annotation);\n    String name = executableElement.getSimpleName().toString();\n    boolean required = isListenerRequired(executableElement);\n\n    // Verify that the method and its containing class are accessible via generated code.\n    boolean hasError = isInaccessibleViaGeneratedCode(annotationClass, \"methods\", element);\n    hasError |= isBindingInWrongPackage(annotationClass, element);\n\n    Integer duplicateId = findDuplicate(ids);\n    if (duplicateId != null) {\n      error(element, \"@%s annotation for method contains duplicate ID %d. (%s.%s)\",\n          annotationClass.getSimpleName(), duplicateId, enclosingElement.getQualifiedName(),\n          element.getSimpleName());\n      hasError = true;\n    }\n\n    ListenerClass listener = annotationClass.getAnnotation(ListenerClass.class);\n    if (listener == null) {\n      throw new IllegalStateException(\n          String.format(\"No @%s defined on @%s.\", ListenerClass.class.getSimpleName(),\n              annotationClass.getSimpleName()));\n    }\n\n    for (int id : ids) {\n      if (id == NO_ID.value) {\n        if (ids.length == 1) {\n          if (!required) {\n            error(element, \"ID-free binding must not be annotated with @Optional. (%s.%s)\",\n                enclosingElement.getQualifiedName(), element.getSimpleName());\n            hasError = true;\n          }\n        } else {\n          error(element, \"@%s annotation contains invalid ID %d. (%s.%s)\",\n              annotationClass.getSimpleName(), id, enclosingElement.getQualifiedName(),\n              element.getSimpleName());\n          hasError = true;\n        }\n      }\n    }\n\n    ListenerMethod method;\n    ListenerMethod[] methods = listener.method();\n    if (methods.length > 1) {\n      throw new IllegalStateException(String.format(\"Multiple listener methods specified on @%s.\",\n          annotationClass.getSimpleName()));\n    } else if (methods.length == 1) {\n      if (listener.callbacks() != ListenerClass.NONE.class) {\n        throw new IllegalStateException(\n            String.format(\"Both method() and callback() defined on @%s.\",\n                annotationClass.getSimpleName()));\n      }\n      method = methods[0];\n    } else {\n      Method annotationCallback = annotationClass.getDeclaredMethod(\"callback\");\n      Enum<?> callback = (Enum<?>) annotationCallback.invoke(annotation);\n      Field callbackField = callback.getDeclaringClass().getField(callback.name());\n      method = callbackField.getAnnotation(ListenerMethod.class);\n      if (method == null) {\n        throw new IllegalStateException(\n            String.format(\"No @%s defined on @%s's %s.%s.\", ListenerMethod.class.getSimpleName(),\n                annotationClass.getSimpleName(), callback.getDeclaringClass().getSimpleName(),\n                callback.name()));\n      }\n    }\n\n    // Verify that the method has equal to or less than the number of parameters as the listener.\n    List<? extends VariableElement> methodParameters = executableElement.getParameters();\n    if (methodParameters.size() > method.parameters().length) {\n      error(element, \"@%s methods can have at most %s parameter(s). (%s.%s)\",\n          annotationClass.getSimpleName(), method.parameters().length,\n          enclosingElement.getQualifiedName(), element.getSimpleName());\n      hasError = true;\n    }\n\n    // Verify method return type matches the listener.\n    TypeMirror returnType = executableElement.getReturnType();\n    if (returnType instanceof TypeVariable) {\n      TypeVariable typeVariable = (TypeVariable) returnType;\n      returnType = typeVariable.getUpperBound();\n    }\n    String returnTypeString = returnType.toString();\n    boolean hasReturnValue = !\"void\".equals(returnTypeString);\n    if (!returnTypeString.equals(method.returnType()) && hasReturnValue) {\n      error(element, \"@%s methods must have a '%s' return type. (%s.%s)\",\n          annotationClass.getSimpleName(), method.returnType(),\n          enclosingElement.getQualifiedName(), element.getSimpleName());\n      hasError = true;\n    }\n\n    if (hasError) {\n      return;\n    }\n\n    Parameter[] parameters = Parameter.NONE;\n    if (!methodParameters.isEmpty()) {\n      parameters = new Parameter[methodParameters.size()];\n      BitSet methodParameterUsed = new BitSet(methodParameters.size());\n      String[] parameterTypes = method.parameters();\n      for (int i = 0; i < methodParameters.size(); i++) {\n        VariableElement methodParameter = methodParameters.get(i);\n        TypeMirror methodParameterType = methodParameter.asType();\n        if (methodParameterType instanceof TypeVariable) {\n          TypeVariable typeVariable = (TypeVariable) methodParameterType;\n          methodParameterType = typeVariable.getUpperBound();\n        }\n\n        for (int j = 0; j < parameterTypes.length; j++) {\n          if (methodParameterUsed.get(j)) {\n            continue;\n          }\n          if ((isSubtypeOfType(methodParameterType, parameterTypes[j])\n              && isSubtypeOfType(methodParameterType, VIEW_TYPE))\n              || isTypeEqual(methodParameterType, parameterTypes[j])\n              || isInterface(methodParameterType)) {\n            parameters[i] = new Parameter(j, TypeName.get(methodParameterType));\n            methodParameterUsed.set(j);\n            break;\n          }\n        }\n        if (parameters[i] == null) {\n          StringBuilder builder = new StringBuilder();\n          builder.append(\"Unable to match @\")\n              .append(annotationClass.getSimpleName())\n              .append(\" method arguments. (\")\n              .append(enclosingElement.getQualifiedName())\n              .append('.')\n              .append(element.getSimpleName())\n              .append(')');\n          for (int j = 0; j < parameters.length; j++) {\n            Parameter parameter = parameters[j];\n            builder.append(\"\\n\\n  Parameter #\")\n                .append(j + 1)\n                .append(\": \")\n                .append(methodParameters.get(j).asType().toString())\n                .append(\"\\n    \");\n            if (parameter == null) {\n              builder.append(\"did not match any listener parameters\");\n            } else {\n              builder.append(\"matched listener parameter #\")\n                  .append(parameter.getListenerPosition() + 1)\n                  .append(\": \")\n                  .append(parameter.getType());\n            }\n          }\n          builder.append(\"\\n\\nMethods may have up to \")\n              .append(method.parameters().length)\n              .append(\" parameter(s):\\n\");\n          for (String parameterType : method.parameters()) {\n            builder.append(\"\\n  \").append(parameterType);\n          }\n          builder.append(\n              \"\\n\\nThese may be listed in any order but will be searched for from top to bottom.\");\n          error(executableElement, builder.toString());\n          return;\n        }\n      }\n    }\n\n    MethodViewBinding binding =\n        new MethodViewBinding(name, Arrays.asList(parameters), required, hasReturnValue);\n    BindingSet.Builder builder = getOrCreateBindingBuilder(builderMap, enclosingElement);\n    Map<Integer, Id> resourceIds = elementToIds(element, annotationClass, ids);\n\n    for (Map.Entry<Integer, Id> entry : resourceIds.entrySet()) {\n      if (!builder.addMethod(entry.getValue(), listener, method, binding)) {\n        error(element, \"Multiple listener methods with return value specified for ID %d. (%s.%s)\",\n            entry.getKey(), enclosingElement.getQualifiedName(), element.getSimpleName());\n        return;\n      }\n    }\n\n    // Add the type-erased version to the valid binding targets set.\n    erasedTargetNames.add(enclosingElement);\n  }\n\n  private boolean isInterface(TypeMirror typeMirror) {\n    return typeMirror instanceof DeclaredType\n        && ((DeclaredType) typeMirror).asElement().getKind() == INTERFACE;\n  }\n\n  static boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) {\n    if (isTypeEqual(typeMirror, otherType)) {\n      return true;\n    }\n    if (typeMirror.getKind() != TypeKind.DECLARED) {\n      return false;\n    }\n    DeclaredType declaredType = (DeclaredType) typeMirror;\n    List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();\n    if (typeArguments.size() > 0) {\n      StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());\n      typeString.append('<');\n      for (int i = 0; i < typeArguments.size(); i++) {\n        if (i > 0) {\n          typeString.append(',');\n        }\n        typeString.append('?');\n      }\n      typeString.append('>');\n      if (typeString.toString().equals(otherType)) {\n        return true;\n      }\n    }\n    Element element = declaredType.asElement();\n    if (!(element instanceof TypeElement)) {\n      return false;\n    }\n    TypeElement typeElement = (TypeElement) element;\n    TypeMirror superType = typeElement.getSuperclass();\n    if (isSubtypeOfType(superType, otherType)) {\n      return true;\n    }\n    for (TypeMirror interfaceType : typeElement.getInterfaces()) {\n      if (isSubtypeOfType(interfaceType, otherType)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private static boolean isTypeEqual(TypeMirror typeMirror, String otherType) {\n    return otherType.equals(typeMirror.toString());\n  }\n\n  private BindingSet.Builder getOrCreateBindingBuilder(\n      Map<TypeElement, BindingSet.Builder> builderMap, TypeElement enclosingElement) {\n    BindingSet.Builder builder = builderMap.get(enclosingElement);\n    if (builder == null) {\n      builder = BindingSet.newBuilder(enclosingElement);\n      builderMap.put(enclosingElement, builder);\n    }\n    return builder;\n  }\n\n  /** Finds the parent binder type in the supplied sets, if any. */\n  private @Nullable TypeElement findParentType(\n      TypeElement typeElement, Set<TypeElement> parents, Set<TypeElement> classpathParents) {\n    while (true) {\n      typeElement = getSuperClass(typeElement);\n      if (typeElement == null || parents.contains(typeElement)\n          || classpathParents.contains(typeElement)) {\n        return typeElement;\n      }\n    }\n  }\n\n  private Map<TypeElement, ClasspathBindingSet> findAllSupertypeBindings(\n      Map<TypeElement, BindingSet.Builder> builderMap, Set<TypeElement> processedInThisRound) {\n    Map<TypeElement, ClasspathBindingSet> classpathBindings = new HashMap<>();\n\n    Set<Class<? extends Annotation>> supportedAnnotations = getSupportedAnnotations();\n    Set<Class<? extends Annotation>> requireViewInConstructor =\n        ImmutableSet.<Class<? extends Annotation>>builder()\n            .addAll(LISTENERS).add(BindView.class).add(BindViews.class).build();\n    supportedAnnotations.removeAll(requireViewInConstructor);\n\n    for (TypeElement typeElement : builderMap.keySet()) {\n      // Make sure to process superclass before subclass. This is because if there is a class that\n      // requires a View in the constructor, all subclasses need it as well.\n      Deque<TypeElement> superClasses = new ArrayDeque<>();\n      TypeElement superClass = getSuperClass(typeElement);\n      while (superClass != null && !processedInThisRound.contains(superClass)\n          && !classpathBindings.containsKey(superClass)) {\n        superClasses.addFirst(superClass);\n        superClass = getSuperClass(superClass);\n      }\n\n      boolean parentHasConstructorWithView = false;\n      while (!superClasses.isEmpty()) {\n        TypeElement superclass = superClasses.removeFirst();\n        ClasspathBindingSet classpathBinding =\n            findBindingInfoForType(superclass, requireViewInConstructor, supportedAnnotations,\n                parentHasConstructorWithView);\n        if (classpathBinding != null) {\n          parentHasConstructorWithView |= classpathBinding.constructorNeedsView();\n          classpathBindings.put(superclass, classpathBinding);\n        }\n      }\n    }\n    return ImmutableMap.copyOf(classpathBindings);\n  }\n\n  private @Nullable ClasspathBindingSet findBindingInfoForType(\n      TypeElement typeElement, Set<Class<? extends Annotation>> requireConstructorWithView,\n      Set<Class<? extends Annotation>> otherAnnotations, boolean needsConstructorWithView) {\n    boolean foundSupportedAnnotation = false;\n    for (Element enclosedElement : typeElement.getEnclosedElements()) {\n      for (Class<? extends Annotation> bindViewAnnotation : requireConstructorWithView) {\n        if (enclosedElement.getAnnotation(bindViewAnnotation) != null) {\n          return new ClasspathBindingSet(true, typeElement);\n        }\n      }\n      for (Class<? extends Annotation> supportedAnnotation : otherAnnotations) {\n        if (enclosedElement.getAnnotation(supportedAnnotation) != null) {\n          if (needsConstructorWithView) {\n            return new ClasspathBindingSet(true, typeElement);\n          }\n          foundSupportedAnnotation = true;\n        }\n      }\n    }\n    if (foundSupportedAnnotation) {\n      return new ClasspathBindingSet(false, typeElement);\n    } else {\n      return null;\n    }\n  }\n\n  private @Nullable TypeElement getSuperClass(TypeElement typeElement) {\n    TypeMirror type = typeElement.getSuperclass();\n    if (type.getKind() == TypeKind.NONE) {\n      return null;\n    }\n    return (TypeElement) ((DeclaredType) type).asElement();\n  }\n\n  @Override public SourceVersion getSupportedSourceVersion() {\n    return SourceVersion.latestSupported();\n  }\n\n  private void error(Element element, String message, Object... args) {\n    printMessage(Kind.ERROR, element, message, args);\n  }\n\n  private void note(Element element, String message, Object... args) {\n    printMessage(Kind.NOTE, element, message, args);\n  }\n\n  private void printMessage(Kind kind, Element element, String message, Object[] args) {\n    if (args.length > 0) {\n      message = String.format(message, args);\n    }\n\n    processingEnv.getMessager().printMessage(kind, message, element);\n  }\n\n  private Id elementToId(Element element, Class<? extends Annotation> annotation, int value) {\n    JCTree tree = (JCTree) trees.getTree(element, getMirror(element, annotation));\n    if (tree != null) { // tree can be null if the references are compiled types and not source\n      rScanner.reset();\n      tree.accept(rScanner);\n      if (!rScanner.resourceIds.isEmpty()) {\n        return rScanner.resourceIds.values().iterator().next();\n      }\n    }\n    return new Id(value);\n  }\n\n  private Map<Integer, Id> elementToIds(Element element, Class<? extends Annotation> annotation,\n      int[] values) {\n    Map<Integer, Id> resourceIds = new LinkedHashMap<>();\n    JCTree tree = (JCTree) trees.getTree(element, getMirror(element, annotation));\n    if (tree != null) { // tree can be null if the references are compiled types and not source\n      rScanner.reset();\n      tree.accept(rScanner);\n      resourceIds = rScanner.resourceIds;\n    }\n\n    // Every value looked up should have an Id\n    for (int value : values) {\n      resourceIds.putIfAbsent(value, new Id(value));\n    }\n    return resourceIds;\n  }\n\n  private static boolean hasAnnotationWithName(Element element, String simpleName) {\n    for (AnnotationMirror mirror : element.getAnnotationMirrors()) {\n      String annotationName = mirror.getAnnotationType().asElement().getSimpleName().toString();\n      if (simpleName.equals(annotationName)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private static boolean isFieldRequired(Element element) {\n    return !hasAnnotationWithName(element, NULLABLE_ANNOTATION_NAME);\n  }\n\n  private static boolean isListenerRequired(ExecutableElement element) {\n    return element.getAnnotation(Optional.class) == null;\n  }\n\n  private static @Nullable AnnotationMirror getMirror(Element element,\n      Class<? extends Annotation> annotation) {\n    for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {\n      if (annotationMirror.getAnnotationType().toString().equals(annotation.getCanonicalName())) {\n        return annotationMirror;\n      }\n    }\n    return null;\n  }\n\n  private static class RScanner extends TreeScanner {\n    Map<Integer, Id> resourceIds = new LinkedHashMap<>();\n\n    @Override\n    public void visitIdent(JCTree.JCIdent jcIdent) {\n      super.visitIdent(jcIdent);\n      Symbol symbol = jcIdent.sym;\n      if (symbol.type instanceof Type.JCPrimitiveType) {\n        Id id = parseId(symbol);\n        if (id != null) {\n          resourceIds.put(id.value, id);\n        }\n      }\n    }\n\n    @Override public void visitSelect(JCTree.JCFieldAccess jcFieldAccess) {\n      Symbol symbol = jcFieldAccess.sym;\n      Id id = parseId(symbol);\n      if (id != null) {\n        resourceIds.put(id.value, id);\n      }\n    }\n\n    @Nullable\n    private Id parseId(Symbol symbol) {\n      Id id = null;\n      if (symbol.getEnclosingElement() != null\n          && symbol.getEnclosingElement().getEnclosingElement() != null\n          && symbol.getEnclosingElement().getEnclosingElement().enclClass() != null) {\n        try {\n          int value = (Integer) requireNonNull(((Symbol.VarSymbol) symbol).getConstantValue());\n          id = new Id(value, symbol);\n        } catch (Exception ignored) { }\n      }\n      return id;\n    }\n\n    @Override public void visitLiteral(JCTree.JCLiteral jcLiteral) {\n      try {\n        int value = (Integer) jcLiteral.value;\n        resourceIds.put(value, new Id(value));\n      } catch (Exception ignored) { }\n    }\n\n    void reset() {\n      resourceIds.clear();\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldAnimationBinding.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.CodeBlock;\n\nimport static butterknife.compiler.BindingSet.ANIMATION_UTILS;\n\nfinal class FieldAnimationBinding implements ResourceBinding {\n  private final Id id;\n  private final String name;\n\n  FieldAnimationBinding(Id id, String name) {\n    this.id = id;\n    this.name = name;\n  }\n\n  @Override public Id id() {\n    return id;\n  }\n\n  @Override public boolean requiresResources(int sdk) {\n    return false;\n  }\n\n  @Override public CodeBlock render(int sdk) {\n    return CodeBlock.of(\"target.$L = $T.loadAnimation(context, $L)\", name, ANIMATION_UTILS,\n            id.code);\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldCollectionViewBinding.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.CodeBlock;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\nimport java.util.List;\n\nimport static butterknife.compiler.BindingSet.UTILS;\nimport static butterknife.compiler.BindingSet.requiresCast;\n\nfinal class FieldCollectionViewBinding {\n  enum Kind {\n    ARRAY(\"arrayFilteringNull\"),\n    LIST(\"listFilteringNull\");\n\n    final String factoryName;\n\n    Kind(String factoryName) {\n      this.factoryName = factoryName;\n    }\n  }\n\n  final String name;\n  private final TypeName type;\n  private final Kind kind;\n  private final boolean required;\n  private final List<Id> ids;\n\n  FieldCollectionViewBinding(String name, TypeName type, Kind kind, List<Id> ids,\n      boolean required) {\n    this.name = name;\n    this.type = type;\n    this.kind = kind;\n    this.ids = ids;\n    this.required = required;\n  }\n\n  CodeBlock render(boolean debuggable) {\n    CodeBlock.Builder builder = CodeBlock.builder()\n        .add(\"target.$L = $T.$L(\", name, UTILS, kind.factoryName);\n    for (int i = 0; i < ids.size(); i++) {\n      if (i > 0) {\n        builder.add(\", \");\n      }\n      builder.add(\"\\n\");\n\n      Id id = ids.get(i);\n      boolean requiresCast = requiresCast(type);\n      if (!debuggable) {\n        if (requiresCast) {\n          builder.add(\"($T) \", type);\n        }\n        builder.add(\"source.findViewById($L)\", id.code);\n      } else if (!requiresCast && !required) {\n        builder.add(\"source.findViewById($L)\", id.code);\n      } else {\n        builder.add(\"$T.find\", UTILS);\n        builder.add(required ? \"RequiredView\" : \"OptionalView\");\n        if (requiresCast) {\n          builder.add(\"AsType\");\n        }\n        builder.add(\"(source, $L, \\\"field '$L'\\\"\", id.code, name);\n        if (requiresCast) {\n          TypeName rawType = type;\n          if (rawType instanceof ParameterizedTypeName) {\n            rawType = ((ParameterizedTypeName) rawType).rawType;\n          }\n          builder.add(\", $T.class\", rawType);\n        }\n        builder.add(\")\");\n      }\n    }\n    return builder.add(\")\").build();\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldDrawableBinding.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.CodeBlock;\n\nimport static butterknife.compiler.BindingSet.CONTEXT_COMPAT;\nimport static butterknife.compiler.BindingSet.UTILS;\nimport static butterknife.internal.Constants.NO_RES_ID;\n\nfinal class FieldDrawableBinding implements ResourceBinding {\n  private final Id id;\n  private final String name;\n  private final Id tintAttributeId;\n\n  FieldDrawableBinding(Id id, String name, Id tintAttributeId) {\n    this.id = id;\n    this.name = name;\n    this.tintAttributeId = tintAttributeId;\n  }\n\n  @Override public Id id() {\n    return id;\n  }\n\n  @Override public boolean requiresResources(int sdk) {\n    return false;\n  }\n\n  @Override public CodeBlock render(int sdk) {\n    if (tintAttributeId.value != NO_RES_ID) {\n      return CodeBlock.of(\"target.$L = $T.getTintedDrawable(context, $L, $L)\", name, UTILS, id.code,\n          tintAttributeId.code);\n    }\n    if (sdk >= 21) {\n      return CodeBlock.of(\"target.$L = context.getDrawable($L)\", name, id.code);\n    }\n    return CodeBlock.of(\"target.$L = $T.getDrawable(context, $L)\", name, CONTEXT_COMPAT, id.code);\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldResourceBinding.java",
    "content": "package butterknife.compiler;\n\nimport androidx.annotation.Nullable;\nimport com.google.common.collect.ImmutableList;\nimport com.google.errorprone.annotations.Immutable;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nfinal class FieldResourceBinding implements ResourceBinding {\n  enum Type {\n    BITMAP(new ResourceMethod(BindingSet.BITMAP_FACTORY, \"decodeResource\", true, 1)),\n    BOOL(\"getBoolean\"),\n    COLOR(new ResourceMethod(BindingSet.CONTEXT_COMPAT, \"getColor\", false, 1),\n        new ResourceMethod(null, \"getColor\", false, 23)),\n    COLOR_STATE_LIST(new ResourceMethod(BindingSet.CONTEXT_COMPAT,\n        \"getColorStateList\", false, 1),\n        new ResourceMethod(null, \"getColorStateList\", false, 23)),\n    DIMEN_AS_INT(\"getDimensionPixelSize\"),\n    DIMEN_AS_FLOAT(\"getDimension\"),\n    FLOAT(new ResourceMethod(BindingSet.UTILS, \"getFloat\", false, 1)),\n    INT(\"getInteger\"),\n    INT_ARRAY(\"getIntArray\"),\n    STRING(\"getString\"),\n    STRING_ARRAY(\"getStringArray\"),\n    TEXT_ARRAY(\"getTextArray\"),\n    TYPED_ARRAY(\"obtainTypedArray\");\n\n    private final ImmutableList<ResourceMethod> methods;\n\n    Type(ResourceMethod... methods) {\n      List<ResourceMethod> methodList = new ArrayList<>(methods.length);\n      Collections.addAll(methodList, methods);\n      Collections.sort(methodList);\n      Collections.reverse(methodList);\n      this.methods = ImmutableList.copyOf(methodList);\n    }\n\n    Type(String methodName) {\n      methods = ImmutableList.of(new ResourceMethod(null, methodName, true, 1));\n    }\n\n    ResourceMethod methodForSdk(int sdk) {\n      for (ResourceMethod method : methods) {\n        if (method.sdk <= sdk) {\n          return method;\n        }\n      }\n      throw new AssertionError();\n    }\n  }\n\n  @Immutable\n  static final class ResourceMethod implements Comparable<ResourceMethod> {\n    @SuppressWarnings(\"Immutable\")\n    final @Nullable ClassName typeName;\n    final String name;\n    final boolean requiresResources;\n    final int sdk;\n\n    ResourceMethod(@Nullable ClassName typeName, String name, boolean requiresResources, int sdk) {\n      this.typeName = typeName;\n      this.name = name;\n      this.requiresResources = requiresResources;\n      this.sdk = sdk;\n    }\n\n    @Override public int compareTo(ResourceMethod other) {\n      return Integer.compare(sdk, other.sdk);\n    }\n  }\n\n  private final Id id;\n  private final String name;\n  private final Type type;\n\n  FieldResourceBinding(Id id, String name, Type type) {\n    this.id = id;\n    this.name = name;\n    this.type = type;\n  }\n\n  @Override public Id id() {\n    return id;\n  }\n\n  @Override public boolean requiresResources(int sdk) {\n    return type.methodForSdk(sdk).requiresResources;\n  }\n\n  @Override public CodeBlock render(int sdk) {\n    ResourceMethod method = type.methodForSdk(sdk);\n    if (method.typeName == null) {\n      if (method.requiresResources) {\n        return CodeBlock.of(\"target.$L = res.$L($L)\", name, method.name, id.code);\n      }\n      return CodeBlock.of(\"target.$L = context.$L($L)\", name, method.name, id.code);\n    }\n    if (method.requiresResources) {\n      return CodeBlock.of(\"target.$L = $T.$L(res, $L)\", name, method.typeName, method.name,\n          id.code);\n    }\n    return CodeBlock.of(\"target.$L = $T.$L(context, $L)\", name, method.typeName, method.name,\n        id.code);\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldTypefaceBinding.java",
    "content": "package butterknife.compiler;\n\nimport androidx.annotation.Nullable;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\n\nfinal class FieldTypefaceBinding implements ResourceBinding {\n  private static final ClassName RESOURCES_COMPAT =\n      ClassName.get(\"androidx.core.content.res\", \"ResourcesCompat\");\n  private static final ClassName TYPEFACE = ClassName.get(\"android.graphics\", \"Typeface\");\n\n  /** Keep in sync with {@link android.graphics.Typeface} constants. */\n  enum TypefaceStyles {\n    NORMAL(0),\n    BOLD(1),\n    ITALIC(2),\n    BOLD_ITALIC(3);\n\n    final int value;\n\n    TypefaceStyles(int value) {\n      this.value = value;\n    }\n\n    @Nullable static TypefaceStyles fromValue(int value) {\n      for (TypefaceStyles style : values()) {\n        if (style.value == value) {\n          return style;\n        }\n      }\n      return null;\n    }\n  }\n\n  private final Id id;\n  private final String name;\n  private final TypefaceStyles style;\n\n  FieldTypefaceBinding(Id id, String name, TypefaceStyles style) {\n    this.id = id;\n    this.name = name;\n    this.style = style;\n  }\n\n  @Override public Id id() {\n    return id;\n  }\n\n  @Override public boolean requiresResources(int sdk) {\n    return sdk >= 26;\n  }\n\n  @Override public CodeBlock render(int sdk) {\n    CodeBlock typeface = sdk >= 26\n        ? CodeBlock.of(\"res.getFont($L)\", id.code)\n        : CodeBlock.of(\"$T.getFont(context, $L)\", RESOURCES_COMPAT, id.code);\n    if (style != TypefaceStyles.NORMAL) {\n      typeface = CodeBlock.of(\"$1T.create($2L, $1T.$3L)\", TYPEFACE, typeface, style);\n    }\n    return CodeBlock.of(\"target.$L = $L\", name, typeface);\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/FieldViewBinding.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.ParameterizedTypeName;\nimport com.squareup.javapoet.TypeName;\n\nfinal class FieldViewBinding implements MemberViewBinding {\n  private final String name;\n  private final TypeName type;\n  private final boolean required;\n\n  FieldViewBinding(String name, TypeName type, boolean required) {\n    this.name = name;\n    this.type = type;\n    this.required = required;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public TypeName getType() {\n    return type;\n  }\n\n  public ClassName getRawType() {\n    if (type instanceof ParameterizedTypeName) {\n      return ((ParameterizedTypeName) type).rawType;\n    }\n    return (ClassName) type;\n  }\n\n  @Override public String getDescription() {\n    return \"field '\" + name + \"'\";\n  }\n\n  public boolean isRequired() {\n    return required;\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/Id.java",
    "content": "package butterknife.compiler;\n\nimport androidx.annotation.Nullable;\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapoet.CodeBlock;\nimport com.sun.tools.javac.code.Symbol;\n\n/**\n * Represents an ID of an Android resource.\n */\nfinal class Id {\n  private static final ClassName ANDROID_R = ClassName.get(\"android\", \"R\");\n  private static final String R = \"R\";\n\n  final int value;\n  final CodeBlock code;\n  final boolean qualifed;\n\n  Id(int value) {\n    this(value, null);\n  }\n\n  Id(int value, @Nullable Symbol rSymbol) {\n    this.value = value;\n    if (rSymbol != null) {\n      ClassName className = ClassName.get(rSymbol.packge().getQualifiedName().toString(), R,\n          rSymbol.enclClass().name.toString());\n      String resourceName = rSymbol.name.toString();\n\n      this.code = className.topLevelClassName().equals(ANDROID_R)\n        ? CodeBlock.of(\"$L.$N\", className, resourceName)\n        : CodeBlock.of(\"$T.$N\", className, resourceName);\n      this.qualifed = true;\n    } else {\n      this.code = CodeBlock.of(\"$L\", value);\n      this.qualifed = false;\n    }\n  }\n\n  @Override public boolean equals(Object o) {\n    return o instanceof Id && value == ((Id) o).value;\n  }\n\n  @Override public int hashCode() {\n    return value;\n  }\n\n  @Override public String toString() {\n    throw new UnsupportedOperationException(\"Please use value or code explicitly\");\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/MemberViewBinding.java",
    "content": "package butterknife.compiler;\n\n/** A field or method view binding. */\ninterface MemberViewBinding {\n  /** A description of the binding in human readable form (e.g., \"field 'foo'\"). */\n  String getDescription();\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/MethodViewBinding.java",
    "content": "package butterknife.compiler;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nfinal class MethodViewBinding implements MemberViewBinding {\n  private final String name;\n  private final List<Parameter> parameters;\n  private final boolean required;\n  private final boolean hasReturnValue;\n\n  MethodViewBinding(String name, List<Parameter> parameters, boolean required,\n      boolean hasReturnValue) {\n    this.name = name;\n    this.parameters = Collections.unmodifiableList(new ArrayList<>(parameters));\n    this.required = required;\n    this.hasReturnValue = hasReturnValue;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public List<Parameter> getParameters() {\n    return parameters;\n  }\n\n  @Override public String getDescription() {\n    return \"method '\" + name + \"'\";\n  }\n\n  public boolean isRequired() {\n    return required;\n  }\n\n  public boolean hasReturnValue() {\n    return hasReturnValue;\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/Parameter.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.TypeName;\n\n/** Represents a parameter type and its position in the listener method. */\nfinal class Parameter {\n  static final Parameter[] NONE = new Parameter[0];\n\n  private final int listenerPosition;\n  private final TypeName type;\n\n  Parameter(int listenerPosition, TypeName type) {\n    this.listenerPosition = listenerPosition;\n    this.type = type;\n  }\n\n  int getListenerPosition() {\n    return listenerPosition;\n  }\n\n  TypeName getType() {\n    return type;\n  }\n\n  public boolean requiresCast(String toType) {\n    return !type.toString().equals(toType);\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/ResourceBinding.java",
    "content": "package butterknife.compiler;\n\nimport com.squareup.javapoet.CodeBlock;\n\ninterface ResourceBinding {\n  Id id();\n\n  /** True if the code for this binding requires a 'res' variable for {@code Resources} access. */\n  boolean requiresResources(int sdk);\n\n  CodeBlock render(int sdk);\n}\n"
  },
  {
    "path": "butterknife-compiler/src/main/java/butterknife/compiler/ViewBinding.java",
    "content": "package butterknife.compiler;\n\nimport butterknife.internal.ListenerClass;\nimport butterknife.internal.ListenerMethod;\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.annotation.Nullable;\n\nfinal class ViewBinding {\n  private final Id id;\n  private final Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> methodBindings;\n  private final @Nullable FieldViewBinding fieldBinding;\n\n  ViewBinding(Id id, Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> methodBindings,\n      @Nullable FieldViewBinding fieldBinding) {\n    this.id = id;\n    this.methodBindings = methodBindings;\n    this.fieldBinding = fieldBinding;\n  }\n\n  public Id getId() {\n    return id;\n  }\n\n  public @Nullable FieldViewBinding getFieldBinding() {\n    return fieldBinding;\n  }\n\n  public Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> getMethodBindings() {\n    return methodBindings;\n  }\n\n  public List<MemberViewBinding> getRequiredBindings() {\n    List<MemberViewBinding> requiredBindings = new ArrayList<>();\n    if (fieldBinding != null && fieldBinding.isRequired()) {\n      requiredBindings.add(fieldBinding);\n    }\n    for (Map<ListenerMethod, Set<MethodViewBinding>> methodBinding : methodBindings.values()) {\n      for (Set<MethodViewBinding> set : methodBinding.values()) {\n        for (MethodViewBinding binding : set) {\n          if (binding.isRequired()) {\n            requiredBindings.add(binding);\n          }\n        }\n      }\n    }\n    return requiredBindings;\n  }\n\n  public boolean isSingleFieldBinding() {\n    return methodBindings.isEmpty() && fieldBinding != null;\n  }\n\n  public boolean requiresLocal() {\n    if (isBoundToRoot()) {\n      return false;\n    }\n    if (isSingleFieldBinding()) {\n      return false;\n    }\n    return true;\n  }\n\n  public boolean isBoundToRoot() {\n    return ButterKnifeProcessor.NO_ID.equals(id);\n  }\n\n  public static final class Builder {\n    private final Id id;\n\n    private final Map<ListenerClass, Map<ListenerMethod, Set<MethodViewBinding>>> methodBindings =\n        new LinkedHashMap<>();\n    @Nullable FieldViewBinding fieldBinding;\n\n    Builder(Id id) {\n      this.id = id;\n    }\n\n    public boolean hasMethodBinding(ListenerClass listener, ListenerMethod method) {\n      Map<ListenerMethod, Set<MethodViewBinding>> methods = methodBindings.get(listener);\n      return methods != null && methods.containsKey(method);\n    }\n\n    public void addMethodBinding(ListenerClass listener, ListenerMethod method,\n        MethodViewBinding binding) {\n      Map<ListenerMethod, Set<MethodViewBinding>> methods = methodBindings.get(listener);\n      Set<MethodViewBinding> set = null;\n      if (methods == null) {\n        methods = new LinkedHashMap<>();\n        methodBindings.put(listener, methods);\n      } else {\n        set = methods.get(method);\n      }\n      if (set == null) {\n        set = new LinkedHashSet<>();\n        methods.put(method, set);\n      }\n      set.add(binding);\n    }\n\n    public void setFieldBinding(FieldViewBinding fieldBinding) {\n      if (this.fieldBinding != null) {\n        throw new AssertionError();\n      }\n      this.fieldBinding = fieldBinding;\n    }\n\n    public ViewBinding build() {\n      return new ViewBinding(id, methodBindings, fieldBinding);\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-compiler/src/test/java/butterknife/compiler/BindingSetTest.java",
    "content": "package butterknife.compiler;\n\nimport org.junit.Test;\n\nimport static butterknife.compiler.BindingSet.asHumanDescription;\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.Arrays.asList;\nimport static java.util.Collections.singletonList;\n\npublic class BindingSetTest {\n  @Test public void humanDescriptionJoinWorks() {\n    MemberViewBinding one = new TestViewBinding(\"one\");\n    MemberViewBinding two = new TestViewBinding(\"two\");\n    MemberViewBinding three = new TestViewBinding(\"three\");\n\n    String result1 = asHumanDescription(singletonList(one));\n    assertThat(result1).isEqualTo(\"one\");\n\n    String result2 = asHumanDescription(asList(one, two));\n    assertThat(result2).isEqualTo(\"one and two\");\n\n    String result3 = asHumanDescription(asList(one, two, three));\n    assertThat(result3).isEqualTo(\"one, two, and three\");\n  }\n\n  private static class TestViewBinding implements MemberViewBinding {\n    private final String description;\n\n    private TestViewBinding(String description) {\n      this.description = description;\n    }\n\n    @Override public String getDescription() {\n      return description;\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/build.gradle",
    "content": "apply plugin: 'java-gradle-plugin'\napply plugin: 'kotlin'\n\nsourceCompatibility = JavaVersion.VERSION_1_8\ntargetCompatibility = JavaVersion.VERSION_1_8\n\ndependencies {\n  compileOnly gradleApi()\n\n  implementation deps.android.gradlePlugin\n  implementation deps.javapoet\n  implementation deps.kotlin.stdLibJdk8\n\n  testImplementation deps.junit\n  testImplementation deps.truth\n  testImplementation deps.androidx.annotations\n  testImplementation deps.compiletesting\n}\n\ntest {\n  dependsOn(':butterknife:installLocally')\n  dependsOn(':butterknife-annotations:installLocally')\n  dependsOn(':butterknife-compiler:installLocally')\n  dependsOn(':butterknife-runtime:installLocally')\n\n  systemProperty('butterknife.version', version)\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife-gradle-plugin/gradle.properties",
    "content": "POM_NAME=Butterknife Gradle Plugin\nPOM_ARTIFACT_ID=butterknife-gradle-plugin\nPOM_PACKAGING=jar\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/main/java/butterknife/plugin/ButterKnifePlugin.kt",
    "content": "package butterknife.plugin\n\nimport com.android.build.gradle.AppExtension\nimport com.android.build.gradle.AppPlugin\nimport com.android.build.gradle.FeatureExtension\nimport com.android.build.gradle.FeaturePlugin\nimport com.android.build.gradle.LibraryExtension\nimport com.android.build.gradle.LibraryPlugin\nimport com.android.build.gradle.api.BaseVariant\nimport com.android.build.gradle.internal.res.GenerateLibraryRFileTask\nimport com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask\nimport groovy.util.XmlSlurper\nimport org.gradle.api.DomainObjectSet\nimport org.gradle.api.Plugin\nimport org.gradle.api.Project\nimport org.gradle.api.plugins.ExtensionContainer\nimport java.util.concurrent.atomic.AtomicBoolean\nimport kotlin.reflect.KClass\n\nclass ButterKnifePlugin : Plugin<Project> {\n  override fun apply(project: Project) {\n    project.plugins.all {\n      when (it) {\n        is FeaturePlugin -> {\n          project.extensions[FeatureExtension::class].run {\n            configureR2Generation(project, featureVariants)\n            configureR2Generation(project, libraryVariants)\n          }\n        }\n        is LibraryPlugin -> {\n          project.extensions[LibraryExtension::class].run {\n            configureR2Generation(project, libraryVariants)\n          }\n        }\n        is AppPlugin -> {\n          project.extensions[AppExtension::class].run {\n            configureR2Generation(project, applicationVariants)\n          }\n        }\n      }\n    }\n  }\n\n  // Parse the variant's main manifest file in order to get the package id which is used to create\n  // R.java in the right place.\n  private fun getPackageName(variant : BaseVariant) : String {\n    val slurper = XmlSlurper(false, false)\n    val list = variant.sourceSets.map { it.manifestFile }\n\n    // According to the documentation, the earlier files in the list are meant to be overridden by the later ones.\n    // So the first file in the sourceSets list should be main.\n    val result = slurper.parse(list[0])\n    return result.getProperty(\"@package\").toString()\n  }\n\n  private fun configureR2Generation(project: Project, variants: DomainObjectSet<out BaseVariant>) {\n    variants.all { variant ->\n      val outputDir = project.buildDir.resolve(\n          \"generated/source/r2/${variant.dirName}\")\n\n      val rPackage = getPackageName(variant)\n      val once = AtomicBoolean()\n      variant.outputs.all { output ->\n        // Though there might be multiple outputs, their R files are all the same. Thus, we only\n        // need to configure the task once with the R.java input and action.\n        if (once.compareAndSet(false, true)) {\n          val processResources = output.processResourcesProvider.get() // TODO lazy\n\n          // TODO: switch to better API once exists in AGP (https://issuetracker.google.com/118668005)\n          val rFile =\n              project.files(\n                  when (processResources) {\n                    is GenerateLibraryRFileTask -> processResources.textSymbolOutputFile\n                    is LinkApplicationAndroidResourcesTask -> processResources.textSymbolOutputFile\n                    else -> throw RuntimeException(\n                        \"Minimum supported Android Gradle Plugin is 3.3.0\")\n                  })\n                  .builtBy(processResources)\n          val generate = project.tasks.create(\"generate${variant.name.capitalize()}R2\", R2Generator::class.java) {\n            it.outputDir = outputDir\n            it.rFile = rFile\n            it.packageName = rPackage\n            it.className = \"R2\"\n          }\n          variant.registerJavaGeneratingTask(generate, outputDir)\n        }\n      }\n    }\n  }\n\n  private operator fun <T : Any> ExtensionContainer.get(type: KClass<T>): T {\n    return getByType(type.java)\n  }\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/main/java/butterknife/plugin/FinalRClassBuilder.kt",
    "content": "package butterknife.plugin\n\nimport com.squareup.javapoet.ClassName\nimport com.squareup.javapoet.CodeBlock\nimport com.squareup.javapoet.FieldSpec\nimport com.squareup.javapoet.JavaFile\nimport com.squareup.javapoet.TypeSpec\nimport java.util.Locale\nimport javax.lang.model.element.Modifier.FINAL\nimport javax.lang.model.element.Modifier.PUBLIC\nimport javax.lang.model.element.Modifier.STATIC\n\n\nprivate const val ANNOTATION_PACKAGE = \"androidx.annotation\"\ninternal val SUPPORTED_TYPES = setOf(\"anim\", \"array\", \"attr\", \"bool\", \"color\", \"dimen\",\n    \"drawable\", \"id\", \"integer\", \"layout\", \"menu\", \"plurals\", \"string\", \"style\", \"styleable\")\n\n/**\n * Generates a class that contains all supported field names in an R file as final values.\n * Also enables adding support annotations to indicate the type of resource for every field.\n */\nclass FinalRClassBuilder(\n  private val packageName: String,\n  private val className: String\n) {\n\n  private var resourceTypes = mutableMapOf<String, TypeSpec.Builder>()\n\n  fun build(): JavaFile {\n    val result = TypeSpec.classBuilder(className)\n        .addModifiers(PUBLIC, FINAL)\n    for (type in SUPPORTED_TYPES) {\n      resourceTypes.get(type)?.let {\n        result.addType(it.build())\n      }\n    }\n    return JavaFile.builder(packageName, result.build())\n        .addFileComment(\"Generated code from Butter Knife gradle plugin. Do not modify!\")\n        .build()\n  }\n\n  fun addResourceField(type: String, fieldName: String, fieldInitializer: CodeBlock) {\n    if (type !in SUPPORTED_TYPES) {\n      return\n    }\n    val fieldSpecBuilder = FieldSpec.builder(Int::class.javaPrimitiveType, fieldName)\n        .addModifiers(PUBLIC, STATIC, FINAL)\n        .initializer(fieldInitializer)\n\n    fieldSpecBuilder.addAnnotation(getSupportAnnotationClass(type))\n\n    val resourceType =\n        resourceTypes.getOrPut(type) {\n          TypeSpec.classBuilder(type).addModifiers(PUBLIC, STATIC, FINAL)\n        }\n    resourceType.addField(fieldSpecBuilder.build())\n  }\n\n  private fun getSupportAnnotationClass(type: String): ClassName {\n    return ClassName.get(ANNOTATION_PACKAGE, type.capitalize(Locale.US) + \"Res\")\n  }\n\n  // TODO https://youtrack.jetbrains.com/issue/KT-28933\n  private fun String.capitalize(locale: Locale) = substring(0, 1).toUpperCase(locale) + substring(1)\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/main/java/butterknife/plugin/R2Generator.kt",
    "content": "package butterknife.plugin\n\nimport org.gradle.api.DefaultTask\nimport org.gradle.api.file.FileCollection\nimport org.gradle.api.tasks.CacheableTask\nimport org.gradle.api.tasks.Input\nimport org.gradle.api.tasks.InputFiles\nimport org.gradle.api.tasks.OutputDirectory\nimport org.gradle.api.tasks.PathSensitive\nimport org.gradle.api.tasks.PathSensitivity\nimport org.gradle.api.tasks.TaskAction\nimport java.io.File\n\n@CacheableTask\nopen class R2Generator : DefaultTask() {\n  @get:OutputDirectory\n  var outputDir: File? = null\n\n  @get:InputFiles\n  @get:PathSensitive(PathSensitivity.NONE)\n  var rFile: FileCollection? = null\n\n  @get:Input\n  var packageName: String? = null\n\n  @get:Input\n  var className: String? = null\n\n  @Suppress(\"unused\") // Invoked by Gradle.\n  @TaskAction\n  fun brewJava() {\n    brewJava(rFile!!.singleFile, outputDir!!, packageName!!, className!!)\n  }\n}\n\nfun brewJava(\n  rFile: File,\n  outputDir: File,\n  packageName: String,\n  className: String\n) {\n  FinalRClassBuilder(packageName, className)\n      .also { ResourceSymbolListReader(it).readSymbolTable(rFile) }\n      .build()\n      .writeTo(outputDir)\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/main/java/butterknife/plugin/ResourceSymbolListReader.kt",
    "content": "package butterknife.plugin\n\nimport com.squareup.javapoet.CodeBlock\nimport java.io.File\n\ninternal class ResourceSymbolListReader(private val builder: FinalRClassBuilder) {\n  private var idValue = 0\n\n  fun readSymbolTable(symbolTable: File) {\n    symbolTable.forEachLine { processLine(it) }\n  }\n\n  private fun processLine(line: String) {\n    val values = line.split(' ')\n    if (values.size < 4) {\n      return\n    }\n    val javaType = values[0]\n    if (javaType != \"int\") {\n      return\n    }\n    val symbolType = values[1]\n    if (symbolType !in SUPPORTED_TYPES) {\n      return\n    }\n    val name = values[2]\n    val value = CodeBlock.of(\"\\$L\", ++idValue)\n    builder.addResourceField(symbolType, name, value)\n  }\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/main/resources/META-INF/gradle-plugins/com.jakewharton.butterknife.properties",
    "content": "implementation-class=butterknife.plugin.ButterKnifePlugin\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/AndroidManifest.xml",
    "content": "<manifest package=\"com.example.butterknife\"/>\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/build.gradle",
    "content": "plugins {\n    id 'com.android.application'\n    id 'com.jakewharton.butterknife'\n}\n\nrepositories {\n    google()\n    maven {\n        url \"file://${projectDir.absolutePath}/../../../../../build/localMaven\"\n    }\n    mavenCentral()\n}\n\nandroid {\n    compileSdkVersion 28\n\n    compileOptions {\n        sourceCompatibility = JavaVersion.VERSION_1_8\n        targetCompatibility = JavaVersion.VERSION_1_8\n    }\n\n    defaultConfig {\n        // This is different than the manifest.\n        applicationId 'com.example.butterknife'\n        minSdkVersion 27\n        targetSdkVersion 27\n        versionCode 1\n        versionName '1.0.0'\n    }\n\n    // Add differing applicationIdSuffixes for debug and release to ensure that the gradle plugin\n    // finds the R.java file correctly.\n    buildTypes {\n        debug {\n            applicationIdSuffix = \".debug\"\n        }\n        release {\n            applicationIdSuffix = \".release\"\n        }\n    }\n\n    flavorDimensions \"flavorA\"\n\n    // Override the applicationId in flavors to ensure that the gradle plugin\n    // finds the R.java file correctly.\n    productFlavors {\n        flavorA {\n            applicationId \"foo.bar\"\n        }\n\n        flavorB {\n            applicationId \"bar.foo\"\n        }\n    }\n\n    lintOptions {\n        checkReleaseBuilds false\n    }\n\n}\n\ndependencies {\n    implementation \"androidx.core:core:1.0.0\"\n    implementation \"com.jakewharton:butterknife:${getProperty(\"butterknife.version\")}\"\n    annotationProcessor \"com.jakewharton:butterknife-compiler:${getProperty(\"butterknife.version\")}\"\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/fixtures/suffix_parsed_properly/src/main/java/butterknife/test/ButteryActivity.java",
    "content": "package butterknife.test;\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.widget.TextView;\nimport butterknife.ButterKnife;\nimport butterknife.BindView;\nimport com.example.butterknife.R;\nimport com.example.butterknife.R2;\n\nclass ButteryActivity extends Activity {\n\n  @BindView(R2.id.title) TextView title;\n\n  @Override protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    ButterKnife.bind(this);\n\n  }\n\n}"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/fixtures/suffix_parsed_properly/src/main/res/layout/activity_layout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:tools=\"http://schemas.android.com/tools\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:orientation=\"vertical\"\n  android:padding=\"8dp\"\n  tools:ignore=\"SelectableText\">\n  <TextView\n    android:id=\"@+id/title\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center\"\n    android:textSize=\"50sp\"/>\n</LinearLayout>\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/java/butterknife/plugin/AndroidHome.kt",
    "content": "package butterknife.plugin\n\nimport java.io.File\nimport java.util.Properties\n\n\ninternal fun androidHome(): String {\n    val env = System.getenv(\"ANDROID_HOME\")\n    if (env != null) {\n        return env\n    }\n    val localProp = File(File(System.getProperty(\"user.dir\")).parentFile, \"local.properties\")\n    if (localProp.exists()) {\n        val prop = Properties()\n        localProp.inputStream().use {\n            prop.load(it)\n        }\n        val sdkHome = prop.getProperty(\"sdk.dir\")\n        if (sdkHome != null) {\n            return sdkHome\n        }\n    }\n    throw IllegalStateException(\n            \"Missing 'ANDROID_HOME' environment variable or local.properties with 'sdk.dir'\")\n}"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/java/butterknife/plugin/BuildFilesRule.kt",
    "content": "package butterknife.plugin\n\nimport com.google.common.truth.Truth.assertThat\nimport org.junit.rules.TestRule\nimport org.junit.runner.Description\nimport org.junit.runners.model.Statement\nimport java.io.File\n\nclass BuildFilesRule(private val root: File) : TestRule {\n    override fun apply(base: Statement, description: Description): Statement {\n        return object : Statement() {\n            override fun evaluate() {\n                val settingsFile = File(root, \"settings.gradle\")\n                val hasSettingsFile = settingsFile.exists()\n                if (!hasSettingsFile) settingsFile.writeText(\"\")\n                val buildFile = File(root, \"build.gradle\")\n                val hasBuildFile = buildFile.exists()\n                if (hasBuildFile) {\n                    assertThat(buildFile.readText())\n                } else {\n                    val buildFileTemplate = File(root, \"../../build.gradle\").readText()\n                    buildFile.writeText(buildFileTemplate)\n                }\n\n                val manifestFile = File(root, \"src/main/AndroidManifest.xml\")\n                val hasManifestFile = manifestFile.exists()\n                if (!hasManifestFile) {\n                    val manifestFileTemplate = File(root, \"../../AndroidManifest.xml\").readText()\n                    manifestFile.writeText(manifestFileTemplate)\n                }\n\n                try {\n                    base.evaluate()\n                } finally {\n                    if (!hasSettingsFile) settingsFile.delete()\n                    if (!hasBuildFile) buildFile.delete()\n                    if (!hasManifestFile) manifestFile.delete()\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/java/butterknife/plugin/FinalRClassBuilderTest.kt",
    "content": "package butterknife.plugin\n\nimport com.google.common.truth.Truth.assertAbout\nimport com.google.testing.compile.JavaFileObjects\nimport com.google.testing.compile.JavaSourceSubjectFactory.javaSource\nimport org.junit.Assert.assertEquals\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.rules.TemporaryFolder\n\nclass FinalRClassBuilderTest {\n  @Rule @JvmField val tempFolder = TemporaryFolder()\n\n  @Test fun brewJava() {\n    val packageName = \"com.butterknife.example\"\n    val rFile = tempFolder.newFile(\"R.txt\").also {\n      it.writeText(javaClass.getResource(\"/fixtures/R.txt\").readText())\n    }\n\n    val outputDir = tempFolder.newFolder()\n    brewJava(rFile, outputDir, packageName, \"R2\")\n\n    val actual = outputDir.resolve(\"com/butterknife/example/R2.java\").readText()\n    val expected = javaClass.getResource(\"/fixtures/R2.java\").readText()\n\n    assertEquals(expected.trim(), actual.trim())\n\n    val actualJava = JavaFileObjects.forSourceString(\"$packageName.R2\", actual)\n    assertAbout(javaSource()).that(actualJava).compilesWithoutError()\n  }\n}\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/java/butterknife/plugin/FixturesTest.kt",
    "content": "package butterknife.plugin\n\nimport com.google.common.truth.Truth.assertThat\nimport org.gradle.testkit.runner.GradleRunner\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\nimport org.junit.runners.Parameterized\nimport org.junit.runners.Parameterized.Parameters\nimport java.io.File\n\n\n@RunWith(Parameterized::class)\nclass FixturesTest(val fixtureRoot: File, val name: String) {\n    @Suppress(\"unused\") // Used by JUnit reflectively.\n    @get:Rule val buildFilesRule = BuildFilesRule(fixtureRoot)\n\n    @Test fun execute() {\n        val androidHome = androidHome()\n        File(fixtureRoot, \"local.properties\").writeText(\"sdk.dir=$androidHome\\n\")\n\n        val butterKnifeVersion = System.getProperty(\"butterknife.version\")!!\n\n        val runner = GradleRunner.create()\n                .withProjectDir(fixtureRoot)\n                .withPluginClasspath()\n                .withArguments(\"clean\", \"assembleDebug\", \"assembleRelease\", \"--stacktrace\",\n                        \"-Pbutterknife.version=$butterKnifeVersion\")\n\n        if (File(fixtureRoot, \"ignored.txt\").exists()) {\n            println(\"Skipping ignored test $name.\")\n            return\n        }\n\n        val expectedFailure = File(fixtureRoot, \"failure.txt\")\n        if (expectedFailure.exists()) {\n            val result = runner.buildAndFail()\n            for (chunk in expectedFailure.readText().split(\"\\n\\n\")) {\n                assertThat(result.output).contains(chunk)\n            }\n        } else {\n            val result = runner.build()\n            assertThat(result.output).contains(\"BUILD SUCCESSFUL\")\n        }\n    }\n\n    companion object {\n        @Suppress(\"unused\") // Used by Parameterized JUnit runner reflectively.\n        @Parameters(name = \"{1}\")\n        @JvmStatic fun parameters() = File(\"src/test/fixtures\").listFiles()\n                .filter { it.isDirectory }\n                .map { arrayOf(it, it.name) }\n    }\n}"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/resources/fixtures/R.txt",
    "content": "int unsupported res 0x7f040000\nint anim res 0x7f040001\nint array res 0x7f040002\nint attr res 0x7f040003\nint bool res 0x7f040004\nint color res 0x7f040005\nint dimen res 0x7f040006\nint drawable res 0x7f040007\nint id res 0x7f040008\nint integer res 0x7f040009\nint layout res 0x7f040010\nint menu res 0x7f040011\nint plurals res 0x7f040012\nint string res 0x7f040013\nint style res 0x7f040014\nint[] styleable resArray { 0x7f040003 , 0x7f040015 }\nint styleable resArray_child 0\nint styleable resArray_child2 1\n"
  },
  {
    "path": "butterknife-gradle-plugin/src/test/resources/fixtures/R2.java",
    "content": "// Generated code from Butter Knife gradle plugin. Do not modify!\npackage com.butterknife.example;\n\nimport androidx.annotation.AnimRes;\nimport androidx.annotation.ArrayRes;\nimport androidx.annotation.AttrRes;\nimport androidx.annotation.BoolRes;\nimport androidx.annotation.ColorRes;\nimport androidx.annotation.DimenRes;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.IdRes;\nimport androidx.annotation.IntegerRes;\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.MenuRes;\nimport androidx.annotation.PluralsRes;\nimport androidx.annotation.StringRes;\nimport androidx.annotation.StyleRes;\nimport androidx.annotation.StyleableRes;\n\npublic final class R2 {\n  public static final class anim {\n    @AnimRes\n    public static final int res = 1;\n  }\n\n  public static final class array {\n    @ArrayRes\n    public static final int res = 2;\n  }\n\n  public static final class attr {\n    @AttrRes\n    public static final int res = 3;\n  }\n\n  public static final class bool {\n    @BoolRes\n    public static final int res = 4;\n  }\n\n  public static final class color {\n    @ColorRes\n    public static final int res = 5;\n  }\n\n  public static final class dimen {\n    @DimenRes\n    public static final int res = 6;\n  }\n\n  public static final class drawable {\n    @DrawableRes\n    public static final int res = 7;\n  }\n\n  public static final class id {\n    @IdRes\n    public static final int res = 8;\n  }\n\n  public static final class integer {\n    @IntegerRes\n    public static final int res = 9;\n  }\n\n  public static final class layout {\n    @LayoutRes\n    public static final int res = 10;\n  }\n\n  public static final class menu {\n    @MenuRes\n    public static final int res = 11;\n  }\n\n  public static final class plurals {\n    @PluralsRes\n    public static final int res = 12;\n  }\n\n  public static final class string {\n    @StringRes\n    public static final int res = 13;\n  }\n\n  public static final class style {\n    @StyleRes\n    public static final int res = 14;\n  }\n\n  public static final class styleable {\n    @StyleableRes\n    public static final int resArray_child = 15;\n\n    @StyleableRes\n    public static final int resArray_child2 = 16;\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  compileOptions {\n    sourceCompatibility = JavaVersion.VERSION_1_8\n    targetCompatibility = JavaVersion.VERSION_1_8\n  }\n\n  defaultConfig {\n    applicationId 'com.example.butterknife'\n    minSdkVersion versions.minSdk\n    targetSdkVersion versions.compileSdk\n    versionCode 1\n    versionName '1.0.0'\n\n    testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'\n  }\n\n  lintOptions {\n    textReport true\n    textOutput \"stdout\"\n    checkAllWarnings true\n    warningsAsErrors true\n    disable 'UnknownNullness'\n    showAll true\n    explainIssues true\n    // We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.\n    checkReleaseBuilds false\n  }\n\n  buildTypes {\n    debug {\n      minifyEnabled true\n      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'src/main/proguard.pro'\n      testProguardFile 'src/androidTest/proguard.pro'\n    }\n  }\n\n  productFlavors {\n    flavorDimensions 'runtime'\n\n    reflect {\n      dimension 'runtime'\n    }\n    codegen {\n      dimension 'runtime'\n    }\n  }\n\n  testOptions {\n    unitTests {\n      includeAndroidResources = true\n    }\n  }\n}\n\ndependencies {\n  reflectImplementation project(':butterknife-reflect')\n\n  codegenImplementation project(':butterknife')\n  codegenAnnotationProcessor project(':butterknife-compiler')\n  androidTestCodegenAnnotationProcessor project(':butterknife-compiler')\n\n  androidTestImplementation deps.junit\n  androidTestImplementation deps.truth\n  androidTestImplementation deps.androidx.test.runner\n  androidTestImplementation deps.androidx.test.rules\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/font_licenses.txt",
    "content": "Copyright 2006 The Inconsolata Project Authors\r\n\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindAnimTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport android.view.animation.Animation;\nimport butterknife.BindAnim;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertNotNull;\n\npublic final class BindAnimTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindAnim(android.R.anim.fade_in) Animation actual;\n  }\n\n  @Test public void anim() {\n    Target target = new Target();\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertNotNull(target.actual); // Check more?\n\n    unbinder.unbind();\n    assertNotNull(target.actual);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindArrayTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindArray;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindArrayTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class StringArrayTarget {\n    @BindArray(R.array.string_one_two_three) String[] actual;\n  }\n\n  @Test public void asStringArray() {\n    StringArrayTarget target = new StringArrayTarget();\n    String[] expected = context.getResources().getStringArray(R.array.string_one_two_three);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n\n  static class IntArrayTarget {\n    @BindArray(R.array.int_one_two_three) int[] actual;\n  }\n\n  @Test public void asIntArray() {\n    IntArrayTarget target = new IntArrayTarget();\n    int[] expected = context.getResources().getIntArray(R.array.int_one_two_three);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n\n  static class CharSequenceArrayTarget {\n    @BindArray(R.array.int_one_two_three) CharSequence[] actual;\n  }\n\n  @Test public void asCharSequenceArray() {\n    CharSequenceArrayTarget target = new CharSequenceArrayTarget();\n    CharSequence[] expected = context.getResources().getTextArray(R.array.int_one_two_three);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindBitmapTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindBitmap;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertTrue;\n\npublic final class BindBitmapTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindBitmap(R.drawable.pixel) Bitmap actual;\n  }\n\n  @Test public void asBitmap() {\n    Target target = new Target();\n    Bitmap expected = BitmapFactory.decodeResource(context.getResources(), R.drawable.pixel);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertTrue(target.actual.sameAs(expected));\n\n    unbinder.unbind();\n    assertTrue(target.actual.sameAs(expected));\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindBoolTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindBool;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindBoolTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindBool(R.bool.just_true) boolean actual;\n  }\n\n  @Test public void asBoolean() {\n    Target target = new Target();\n    boolean expected = context.getResources().getBoolean(R.bool.just_true);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindColorTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindColorTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class IntTarget {\n    @BindColor(R.color.red) int actual;\n  }\n\n  @Test public void asInt() {\n    IntTarget target = new IntTarget();\n    int expected = context.getResources().getColor(R.color.red);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n\n  static class ColorStateListTarget {\n    @BindColor(R.color.colors) ColorStateList actual;\n  }\n\n  @Test public void asColorStateList() {\n    ColorStateListTarget target = new ColorStateListTarget();\n    ColorStateList expected = context.getResources().getColorStateList(R.color.colors);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual.toString()).isEqualTo(expected.toString());\n\n    unbinder.unbind();\n    assertThat(target.actual.toString()).isEqualTo(expected.toString());\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindDimenTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindDimen;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindDimenTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class IntTarget {\n    @BindDimen(R.dimen.twelve_point_two_dp) int actual;\n  }\n\n  @Test public void asInt() {\n    IntTarget target = new IntTarget();\n    int expected = context.getResources().getDimensionPixelSize(R.dimen.twelve_point_two_dp);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n\n  static class FloatTarget {\n    @BindDimen(R.dimen.twelve_point_two_dp) float actual;\n  }\n\n  @Test public void asFloat() {\n    FloatTarget target = new FloatTarget();\n    float expected = context.getResources().getDimension(R.dimen.twelve_point_two_dp);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindDrawableTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.graphics.drawable.Drawable;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindDrawable;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindDrawableTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindDrawable(R.drawable.circle) Drawable actual;\n  }\n\n  @Test public void asDrawable() {\n    Target target = new Target();\n    Drawable expected = context.getResources().getDrawable(R.drawable.circle);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual.getConstantState()).isEqualTo(expected.getConstantState());\n\n    unbinder.unbind();\n    assertThat(target.actual.getConstantState()).isEqualTo(expected.getConstantState());\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindFloatTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.util.TypedValue;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindFloat;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindFloatTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindFloat(R.dimen.twelve_point_two) float actual;\n  }\n\n  @Test public void asFloat() {\n    Target target = new Target();\n    TypedValue value = new TypedValue();\n    context.getResources().getValue(R.dimen.twelve_point_two, value, true);\n    float expected = value.getFloat();\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindFontTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.graphics.Typeface;\nimport android.view.View;\nimport androidx.core.content.res.ResourcesCompat;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.filters.SdkSuppress;\nimport butterknife.BindFont;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static android.graphics.Typeface.BOLD;\nimport static com.google.common.truth.Truth.assertThat;\n\n@SdkSuppress(minSdkVersion = 24) // AndroidX problems on earlier versions\npublic final class BindFontTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class TargetTypeface {\n    @BindFont(R.font.inconsolata_regular) Typeface actual;\n  }\n\n  @Test public void typeface() {\n    TargetTypeface target = new TargetTypeface();\n    Typeface expected = ResourcesCompat.getFont(context, R.font.inconsolata_regular);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isSameAs(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isSameAs(expected);\n  }\n\n  static class TargetStyle {\n    @BindFont(value = R.font.inconsolata_regular, style = BOLD) Typeface actual;\n  }\n\n  @Test public void style() {\n    TargetStyle target = new TargetStyle();\n    Typeface expected =\n        Typeface.create(ResourcesCompat.getFont(context, R.font.inconsolata_regular), BOLD);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isSameAs(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isSameAs(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindIntTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindInt;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindIntTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindInt(R.integer.twelve) int actual;\n  }\n\n  @Test public void asInt() {\n    Target target = new Target();\n    int expected = context.getResources().getInteger(R.integer.twelve);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindStringTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.BindString;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindStringTest {\n  private final Context context = InstrumentationRegistry.getContext();\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindString(R.string.hey) String actual;\n  }\n\n  @Test public void simpleInt() {\n    Target target = new Target();\n    String expected = context.getString(R.string.hey);\n\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isEqualTo(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isEqualTo(expected);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindViewTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindViewTest {\n  static class TargetView {\n    @BindView(1) View actual;\n  }\n\n  @Test public void view() {\n    View tree = ViewTree.create(1);\n    View expected = tree.findViewById(1);\n\n    TargetView target = new TargetView();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).isSameAs(expected);\n\n    unbinder.unbind();\n    assertThat(target.actual).isNull();\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/BindViewsTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindViews;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport java.util.List;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class BindViewsTest {\n  static class TargetViewArray {\n    @BindViews({1, 2, 3}) View[] actual;\n  }\n\n  @Test public void array() {\n    View tree = ViewTree.create(1, 2, 3);\n    View expected1 = tree.findViewById(1);\n    View expected2 = tree.findViewById(2);\n    View expected3 = tree.findViewById(3);\n\n    TargetViewArray target = new TargetViewArray();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).asList().containsExactly(expected1, expected2, expected3).inOrder();\n\n    unbinder.unbind();\n    assertThat(target.actual).isNull();\n  }\n  static class TargetViewList {\n    @BindViews({1, 2, 3}) List<View> actual;\n  }\n\n  @Test public void list() {\n    View tree = ViewTree.create(1, 2, 3);\n    View expected1 = tree.findViewById(1);\n    View expected2 = tree.findViewById(2);\n    View expected3 = tree.findViewById(3);\n\n    TargetViewList target = new TargetViewList();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertThat(target.actual).containsExactly(expected1, expected2, expected3).inOrder();\n\n    unbinder.unbind();\n    assertThat(target.actual).isNull();\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnCheckedChangedTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.CompoundButton;\nimport android.widget.FrameLayout;\nimport android.widget.ToggleButton;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnCheckedChanged;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport com.example.butterknife.BuildConfig;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assume.assumeFalse;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnCheckedChangedTest {\n  static final class Simple {\n    int clicks = 0;\n\n    @OnCheckedChanged(1) void click() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void simple() {\n    View tree = ViewTree.create(ToggleButton.class, 1);\n    View view1 = tree.findViewById(1);\n\n    Simple target = new Simple();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performClick();\n    assertEquals(1, target.clicks);\n\n    unbinder.unbind();\n    view1.performClick();\n    assertEquals(1, target.clicks);\n  }\n\n  static final class MultipleBindings {\n    int clicks = 0;\n\n    @OnCheckedChanged(1) void click1() {\n      clicks++;\n    }\n\n    @OnCheckedChanged(1) void clicks2() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleBindings() {\n    assumeFalse(\"Not implemented\", BuildConfig.FLAVOR.equals(\"reflect\")); // TODO\n\n    View tree = ViewTree.create(ToggleButton.class, 1);\n    View view1 = tree.findViewById(1);\n\n    MultipleBindings target = new MultipleBindings();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performClick();\n    assertEquals(2, target.clicks);\n\n    unbinder.unbind();\n    view1.performClick();\n    assertEquals(2, target.clicks);\n  }\n\n  static final class Visibilities {\n    int clicks = 0;\n\n    @OnCheckedChanged(1) public void publicClick() {\n      clicks++;\n    }\n\n    @OnCheckedChanged(2) void packageClick() {\n      clicks++;\n    }\n\n    @OnCheckedChanged(3) protected void protectedClick() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void visibilities() {\n    View tree = ViewTree.create(ToggleButton.class, 1, 2, 3);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n    View view3 = tree.findViewById(3);\n\n    Visibilities target = new Visibilities();\n    ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performClick();\n    assertEquals(1, target.clicks);\n\n    view2.performClick();\n    assertEquals(2, target.clicks);\n\n    view3.performClick();\n    assertEquals(3, target.clicks);\n  }\n\n  static final class MultipleIds {\n    int clicks = 0;\n\n    @OnCheckedChanged({1, 2}) void click() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleIds() {\n    View tree = ViewTree.create(ToggleButton.class, 1, 2);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n\n    MultipleIds target = new MultipleIds();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performClick();\n    assertEquals(1, target.clicks);\n\n    view2.performClick();\n    assertEquals(2, target.clicks);\n\n    unbinder.unbind();\n    view1.performClick();\n    view2.performClick();\n    assertEquals(2, target.clicks);\n  }\n\n  static final class OptionalId {\n    int clicks = 0;\n\n    @Optional @OnCheckedChanged(1) public void click() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdPresent() {\n    View tree = ViewTree.create(ToggleButton.class, 1);\n    View view1 = tree.findViewById(1);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performClick();\n    assertEquals(1, target.clicks);\n\n    unbinder.unbind();\n    view1.performClick();\n    assertEquals(1, target.clicks);\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdAbsent() {\n    View tree = ViewTree.create(ToggleButton.class, 2);\n    View view2 = tree.findViewById(2);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view2.performClick();\n    assertEquals(0, target.clicks);\n\n    unbinder.unbind();\n    view2.performClick();\n    assertEquals(0, target.clicks);\n  }\n\n  static final class ArgumentCast {\n    interface MyInterface {}\n\n    View last;\n\n    @OnCheckedChanged(1) void clickTextView(CompoundButton view) {\n      last = view;\n    }\n\n    @OnCheckedChanged(2) void clickButton(ToggleButton view) {\n      last = view;\n    }\n\n    @OnCheckedChanged(3) void clickMyInterface(MyInterface view) {\n      last = (View) view;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void argumentCast() {\n    class MyView extends ToggleButton implements ArgumentCast.MyInterface {\n      MyView(Context context) {\n        super(context);\n      }\n    }\n\n    View view1 = new MyView(InstrumentationRegistry.getContext());\n    view1.setId(1);\n    View view2 = new MyView(InstrumentationRegistry.getContext());\n    view2.setId(2);\n    View view3 = new MyView(InstrumentationRegistry.getContext());\n    view3.setId(3);\n    ViewGroup tree = new FrameLayout(InstrumentationRegistry.getContext());\n    tree.addView(view1);\n    tree.addView(view2);\n    tree.addView(view3);\n\n    ArgumentCast target = new ArgumentCast();\n    ButterKnife.bind(target, tree);\n\n    view1.performClick();\n    assertSame(view1, target.last);\n\n    view2.performClick();\n    assertSame(view2, target.last);\n\n    view3.performClick();\n    assertSame(view3, target.last);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnClickTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.app.Instrumentation;\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Button;\nimport android.widget.FrameLayout;\nimport android.widget.TextView;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport com.example.butterknife.BuildConfig;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assume.assumeFalse;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnClickTest {\n  private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();\n\n  static final class Simple {\n    int clicks = 0;\n\n    @OnClick(1) void click() {\n      clicks++;\n    }\n  }\n\n  @Test public void simple() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    Simple target = new Simple();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      unbinder.unbind();\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n  }\n\n  static final class MultipleBindings {\n    int clicks = 0;\n\n    @OnClick(1) void click1() {\n      clicks++;\n    }\n\n    @OnClick(1) void clicks2() {\n      clicks++;\n    }\n  }\n\n  @Test public void multipleBindings() {\n    assumeFalse(\"Not implemented\", BuildConfig.FLAVOR.equals(\"reflect\")); // TODO\n\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    MultipleBindings target = new MultipleBindings();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertEquals(2, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      unbinder.unbind();\n      view1.performClick();\n      assertEquals(2, target.clicks);\n    });\n  }\n\n  static final class Visibilities {\n    int clicks = 0;\n\n    @OnClick(1) public void publicClick() {\n      clicks++;\n    }\n\n    @OnClick(2) void packageClick() {\n      clicks++;\n    }\n\n    @OnClick(3) protected void protectedClick() {\n      clicks++;\n    }\n  }\n\n  @Test public void visibilities() {\n    View tree = ViewTree.create(1, 2, 3);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n    View view3 = tree.findViewById(3);\n\n    Visibilities target = new Visibilities();\n    ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view2.performClick();\n      assertEquals(2, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view3.performClick();\n      assertEquals(3, target.clicks);\n    });\n  }\n\n  static final class MultipleIds {\n    int clicks = 0;\n\n    @OnClick({1, 2}) void click() {\n      clicks++;\n    }\n  }\n\n  @Test public void multipleIds() {\n    View tree = ViewTree.create(1, 2);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n\n    MultipleIds target = new MultipleIds();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view2.performClick();\n      assertEquals(2, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      unbinder.unbind();\n      view1.performClick();\n      view2.performClick();\n      assertEquals(2, target.clicks);\n    });\n  }\n\n  static final class OptionalId {\n    int clicks = 0;\n\n    @Optional @OnClick(1) public void click() {\n      clicks++;\n    }\n  }\n\n  @Test public void optionalIdPresent() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      unbinder.unbind();\n      view1.performClick();\n      assertEquals(1, target.clicks);\n    });\n  }\n\n  @Test public void optionalIdAbsent() {\n    View tree = ViewTree.create(2);\n    View view2 = tree.findViewById(2);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    instrumentation.runOnMainSync(() -> {\n      view2.performClick();\n      assertEquals(0, target.clicks);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      unbinder.unbind();\n      view2.performClick();\n      assertEquals(0, target.clicks);\n    });\n  }\n\n  static final class ArgumentCast {\n    interface MyInterface {}\n\n    View last;\n\n    @OnClick(1) void clickView(View view) {\n      last = view;\n    }\n\n    @OnClick(2) void clickTextView(TextView view) {\n      last = view;\n    }\n\n    @OnClick(3) void clickButton(Button view) {\n      last = view;\n    }\n\n    @OnClick(4) void clickMyInterface(MyInterface view) {\n      last = (View) view;\n    }\n  }\n\n  @Test public void argumentCast() {\n    class MyView extends Button implements ArgumentCast.MyInterface {\n      MyView(Context context) {\n        super(context);\n      }\n    }\n\n    View view1 = new MyView(InstrumentationRegistry.getContext());\n    view1.setId(1);\n    View view2 = new MyView(InstrumentationRegistry.getContext());\n    view2.setId(2);\n    View view3 = new MyView(InstrumentationRegistry.getContext());\n    view3.setId(3);\n    View view4 = new MyView(InstrumentationRegistry.getContext());\n    view4.setId(4);\n    ViewGroup tree = new FrameLayout(InstrumentationRegistry.getContext());\n    tree.addView(view1);\n    tree.addView(view2);\n    tree.addView(view3);\n    tree.addView(view4);\n\n    ArgumentCast target = new ArgumentCast();\n    ButterKnife.bind(target, tree);\n\n    instrumentation.runOnMainSync(() -> {\n      view1.performClick();\n      assertSame(view1, target.last);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view2.performClick();\n      assertSame(view2, target.last);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view3.performClick();\n      assertSame(view3, target.last);\n    });\n\n    instrumentation.runOnMainSync(() -> {\n      view4.performClick();\n      assertSame(view4, target.last);\n    });\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnItemClickTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.AbsSpinner;\nimport android.widget.AdapterView;\nimport android.widget.FrameLayout;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnItemClick;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport com.example.butterknife.BuildConfig;\nimport com.example.butterknife.library.SimpleAdapter;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assume.assumeFalse;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnItemClickTest {\n    static class TestSpinner extends AbsSpinner {\n        public TestSpinner(Context context) {\n            super(context);\n            setAdapter(new SimpleAdapter(context));\n        }\n\n        void performItemClick(int position) {\n            if (position < 0) {\n                return;\n            }\n\n            AdapterView.OnItemClickListener listener = getOnItemClickListener();\n            if (listener != null) {\n                listener.onItemClick(this, null, position, NO_ID);\n            }\n        }\n    }\n\n    static final class Simple {\n        int clickedPosition = -1;\n\n        @OnItemClick(1) void itemClick(int position) {\n            clickedPosition = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void simple() {\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        Simple target = new Simple();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner.performItemClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemClick(1);\n        assertEquals(0, target.clickedPosition);\n    }\n\n\n    static final class MultipleBindings {\n        int clickedPosition1 = -1;\n        int clickedPosition2 = -1;\n\n        @OnItemClick(1) void itemClick1(int position) {\n            clickedPosition1 = position;\n        }\n\n        @OnItemClick(1) void itemClick2(int position) {\n            clickedPosition2 = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void multipleBindings() {\n        assumeFalse(\"Not implemented\", BuildConfig.FLAVOR.equals(\"reflect\")); // TODO\n\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        MultipleBindings target = new MultipleBindings();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition1);\n        assertEquals(-1, target.clickedPosition2);\n\n        spinner.performItemClick(0);\n        assertEquals(0, target.clickedPosition1);\n        assertEquals(0, target.clickedPosition2);\n\n        unbinder.unbind();\n        spinner.performItemClick(1);\n        assertEquals(0, target.clickedPosition1);\n        assertEquals(0, target.clickedPosition2);\n    }\n\n\n    static final class Visibilities {\n        int clickedPosition = -1;\n\n        @OnItemClick(1) public void publicItemClick(int position) {\n            clickedPosition = position;\n        }\n\n        @OnItemClick(2) void packageItemClick(int position) {\n            clickedPosition = position;\n        }\n\n        @OnItemClick(3) protected void protectedItemClick(int position) {\n            clickedPosition = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void visibilities() {\n        View tree = ViewTree.create(TestSpinner.class, 1, 2, 3);\n        TestSpinner spinner1 = tree.findViewById(1);\n        TestSpinner spinner2 = tree.findViewById(2);\n        TestSpinner spinner3 = tree.findViewById(3);\n\n        Visibilities target = new Visibilities();\n        ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner1.performItemClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        spinner2.performItemClick(1);\n        assertEquals(1, target.clickedPosition);\n\n        spinner3.performItemClick(2);\n        assertEquals(2, target.clickedPosition);\n    }\n\n    static final class MultipleIds {\n        int clickedPosition = -1;\n\n        @OnItemClick({1, 2}) void itemClick(int position) {\n            clickedPosition = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void multipleIds() {\n        View tree = ViewTree.create(TestSpinner.class, 1, 2);\n        TestSpinner spinner1 = tree.findViewById(1);\n        TestSpinner spinner2 = tree.findViewById(2);\n\n        MultipleIds target = new MultipleIds();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner1.performItemClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        spinner2.performItemClick(1);\n        assertEquals(1, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner1.performItemClick(2);\n        assertEquals(1, target.clickedPosition);\n        spinner2.performItemClick(2);\n        assertEquals(1, target.clickedPosition);\n    }\n\n    static final class OptionalId {\n        int clickedPosition = -1;\n\n        @Optional @OnItemClick(1) void itemClick(int position) {\n            clickedPosition = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void optionalIdPresent() {\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        OptionalId target = new OptionalId();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner.performItemClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemClick(1);\n        assertEquals(0, target.clickedPosition);\n    }\n\n    @UiThreadTest\n    @Test public void optionalIdAbsent() {\n        View tree = ViewTree.create(TestSpinner.class, 2);\n        TestSpinner spinner = tree.findViewById(2);\n\n        OptionalId target = new OptionalId();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner.performItemClick(0);\n        assertEquals(-1, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemClick(0);\n        assertEquals(-1, target.clickedPosition);\n    }\n\n    static final class ArgumentCast {\n        interface MyInterface {}\n\n        View last;\n\n        @OnItemClick(1) void itemClickAdapterView(AdapterView<?> view) {\n            last = view;\n        }\n\n        @OnItemClick(2) void itemClickAbsSpinner(AbsSpinner view) {\n            last = view;\n        }\n\n        @OnItemClick(3) void itemClickMyInterface(ArgumentCast.MyInterface view) {\n            last = (View) view;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void argumentCast() {\n        class MySpinner extends TestSpinner implements ArgumentCast.MyInterface {\n            MySpinner(Context context) {\n                super(context);\n            }\n        }\n\n        Context context = InstrumentationRegistry.getContext();\n        TestSpinner spinner1 = new MySpinner(context);\n        spinner1.setId(1);\n        TestSpinner spinner2 = new MySpinner(context);\n        spinner2.setId(2);\n        TestSpinner spinner3 = new MySpinner(context);\n        spinner3.setId(3);\n        ViewGroup tree = new FrameLayout(context);\n        tree.addView(spinner1);\n        tree.addView(spinner2);\n        tree.addView(spinner3);\n\n        ArgumentCast target = new ArgumentCast();\n        ButterKnife.bind(target, tree);\n\n        spinner1.performItemClick(0);\n        assertSame(spinner1, target.last);\n\n        spinner2.performItemClick(0);\n        assertSame(spinner2, target.last);\n\n        spinner3.performItemClick(0);\n        assertSame(spinner3, target.last);\n    }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnItemLongClickTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.AbsSpinner;\nimport android.widget.AdapterView;\nimport android.widget.FrameLayout;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnItemLongClick;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport com.example.butterknife.library.SimpleAdapter;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assert.assertTrue;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnItemLongClickTest {\n    static class TestSpinner extends AbsSpinner {\n        public TestSpinner(Context context) {\n            super(context);\n            setAdapter(new SimpleAdapter(context));\n        }\n\n        boolean performItemLongClick(int position) {\n            if (position >= 0) {\n                AdapterView.OnItemLongClickListener listener = getOnItemLongClickListener();\n                if (listener != null) {\n                    return listener.onItemLongClick(this, null, position, NO_ID);\n                }\n            }\n\n            return false;\n        }\n    }\n\n    static final class Simple {\n        boolean returnValue = true;\n        int clickedPosition = -1;\n\n        @OnItemLongClick(1) boolean itemClick(int position) {\n            clickedPosition = position;\n            return returnValue;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void simple() {\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        Simple target = new Simple();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        assertTrue(spinner.performItemLongClick(0));\n        assertEquals(0, target.clickedPosition);\n\n        target.returnValue = false;\n        assertFalse(spinner.performItemLongClick(1));\n        assertEquals(1, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemLongClick(2);\n        assertEquals(1, target.clickedPosition);\n    }\n\n    static final class ReturnVoid {\n        int clickedPosition = -1;\n\n        @OnItemLongClick(1) void itemLongClick(int position) {\n            clickedPosition = position;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void returnVoid() {\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        ReturnVoid target = new ReturnVoid();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        assertTrue(spinner.performItemLongClick(0));\n        assertEquals(0, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemLongClick(1);\n        assertEquals(0, target.clickedPosition);\n    }\n\n    static final class Visibilities {\n        int clickedPosition = -1;\n\n        @OnItemLongClick(1) public boolean publicItemLongClick(int position) {\n            clickedPosition = position;\n            return true;\n        }\n\n        @OnItemLongClick(2) boolean packageItemLongClick(int position) {\n            clickedPosition = position;\n            return true;\n        }\n\n        @OnItemLongClick(3) protected boolean protectedItemLongClick(int position) {\n            clickedPosition = position;\n            return true;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void visibilities() {\n        View tree = ViewTree.create(TestSpinner.class, 1, 2, 3);\n        TestSpinner spinner1 = tree.findViewById(1);\n        TestSpinner spinner2 = tree.findViewById(2);\n        TestSpinner spinner3 = tree.findViewById(3);\n\n        Visibilities target = new Visibilities();\n        ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner1.performItemLongClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        spinner2.performItemLongClick(1);\n        assertEquals(1, target.clickedPosition);\n\n        spinner3.performItemLongClick(2);\n        assertEquals(2, target.clickedPosition);\n    }\n\n    static final class MultipleIds {\n        int clickedPosition = -1;\n\n        @OnItemLongClick({1, 2}) boolean itemLongClick(int position) {\n            clickedPosition = position;\n            return true;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void multipleIds() {\n        View tree = ViewTree.create(TestSpinner.class, 1, 2);\n        TestSpinner spinner1 = tree.findViewById(1);\n        TestSpinner spinner2 = tree.findViewById(2);\n\n        MultipleIds target = new MultipleIds();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner1.performItemLongClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        spinner2.performItemLongClick(1);\n        assertEquals(1, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner1.performItemLongClick(2);\n        assertEquals(1, target.clickedPosition);\n        spinner2.performItemLongClick(2);\n        assertEquals(1, target.clickedPosition);\n    }\n\n    static final class OptionalId {\n        int clickedPosition = -1;\n\n        @Optional @OnItemLongClick(1) boolean itemLongClick(int position) {\n            clickedPosition = position;\n            return true;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void optionalIdPresent() {\n        View tree = ViewTree.create(TestSpinner.class, 1);\n        TestSpinner spinner = tree.findViewById(1);\n\n        OptionalId target = new OptionalId();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner.performItemLongClick(0);\n        assertEquals(0, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemLongClick(1);\n        assertEquals(0, target.clickedPosition);\n    }\n\n    @UiThreadTest\n    @Test public void optionalIdAbsent() {\n        View tree = ViewTree.create(TestSpinner.class, 2);\n        TestSpinner spinner = tree.findViewById(2);\n\n        OptionalId target = new OptionalId();\n        Unbinder unbinder = ButterKnife.bind(target, tree);\n        assertEquals(-1, target.clickedPosition);\n\n        spinner.performItemLongClick(0);\n        assertEquals(-1, target.clickedPosition);\n\n        unbinder.unbind();\n        spinner.performItemLongClick(0);\n        assertEquals(-1, target.clickedPosition);\n    }\n\n    static final class ArgumentCast {\n        interface MyInterface {}\n\n        View last;\n\n        @OnItemLongClick(1) boolean itemLongClickAdapterView(AdapterView<?> view) {\n            last = view;\n            return true;\n        }\n\n        @OnItemLongClick(2) boolean itemLongClickAbsSpinner(AbsSpinner view) {\n            last = view;\n            return true;\n        }\n\n        @OnItemLongClick(3) boolean itemLongClickMyInterface(ArgumentCast.MyInterface view) {\n            last = (View) view;\n            return true;\n        }\n    }\n\n    @UiThreadTest\n    @Test public void argumentCast() {\n        class MySpinner extends TestSpinner implements ArgumentCast.MyInterface {\n            MySpinner(Context context) {\n                super(context);\n            }\n        }\n\n        Context context = InstrumentationRegistry.getContext();\n        TestSpinner spinner1 = new MySpinner(context);\n        spinner1.setId(1);\n        TestSpinner spinner2 = new MySpinner(context);\n        spinner2.setId(2);\n        TestSpinner spinner3 = new MySpinner(context);\n        spinner3.setId(3);\n        ViewGroup tree = new FrameLayout(context);\n        tree.addView(spinner1);\n        tree.addView(spinner2);\n        tree.addView(spinner3);\n\n        ArgumentCast target = new ArgumentCast();\n        ButterKnife.bind(target, tree);\n\n        spinner1.performItemLongClick(0);\n        assertSame(spinner1, target.last);\n\n        spinner2.performItemLongClick(0);\n        assertSame(spinner2, target.last);\n\n        spinner3.performItemLongClick(0);\n        assertSame(spinner3, target.last);\n    }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnItemSelectedTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.AbsSpinner;\nimport android.widget.AdapterView;\nimport android.widget.FrameLayout;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnItemSelected;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport com.example.butterknife.BuildConfig;\nimport com.example.butterknife.library.SimpleAdapter;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assume.assumeFalse;\n\n@SuppressWarnings(\"unused\") // Used by code gen.\npublic final class OnItemSelectedTest {\n  static class TestSpinner extends AbsSpinner {\n    public TestSpinner(Context context) {\n      super(context);\n      setAdapter(new SimpleAdapter(context));\n    }\n\n    void performSelection(int position) {\n      if (position < 0) {\n        return;\n      }\n\n      AdapterView.OnItemSelectedListener listener = getOnItemSelectedListener();\n      if (listener != null) {\n        listener.onItemSelected(this, null, position, NO_ID);\n      }\n    }\n\n    void clearSelection() {\n      AdapterView.OnItemSelectedListener listener = getOnItemSelectedListener();\n      if (listener != null) {\n        listener.onNothingSelected(this);\n      }\n    }\n  }\n\n  @Before public void ignoreIfReflect() {\n    assumeFalse(\"Not implemented\", BuildConfig.FLAVOR.equals(\"reflect\")); // TODO\n  }\n\n  static final class Simple {\n    int selectedPosition = -1;\n\n    @OnItemSelected(1) void select(int position) {\n      selectedPosition = position;\n    }\n\n    @OnItemSelected(value = 1, callback = NOTHING_SELECTED) void clear() {\n      selectedPosition = -1;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void simple() {\n    View tree = ViewTree.create(TestSpinner.class, 1);\n    TestSpinner spinner = tree.findViewById(1);\n\n    Simple target = new Simple();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(-1, target.selectedPosition);\n\n    spinner.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner.performSelection(1);\n    unbinder.unbind();\n    spinner.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n    spinner.clearSelection();\n    assertEquals(1, target.selectedPosition);\n  }\n\n  static final class MultipleBindings {\n    int selectedPosition1 = -1;\n    int selectedPosition2 = -1;\n\n    @OnItemSelected(1) void select1(int position) {\n      selectedPosition1 = position;\n    }\n\n    @OnItemSelected(1) void select2(int position) {\n      selectedPosition2 = position;\n    }\n\n    @OnItemSelected(value = 1, callback = NOTHING_SELECTED) void clear1() {\n      selectedPosition1 = -1;\n    }\n\n    @OnItemSelected(value = 1, callback = NOTHING_SELECTED) void clear2() {\n      selectedPosition2 = -1;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleBindings() {\n    View tree = ViewTree.create(TestSpinner.class, 1);\n    TestSpinner spinner = tree.findViewById(1);\n\n    MultipleBindings target = new MultipleBindings();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(-1, target.selectedPosition1);\n    assertEquals(-1, target.selectedPosition2);\n\n    spinner.performSelection(0);\n    assertEquals(0, target.selectedPosition1);\n    assertEquals(0, target.selectedPosition2);\n\n    spinner.clearSelection();\n    assertEquals(-1, target.selectedPosition1);\n    assertEquals(-1, target.selectedPosition2);\n\n    spinner.performSelection(1);\n    unbinder.unbind();\n    spinner.performSelection(0);\n    assertEquals(1, target.selectedPosition1);\n    assertEquals(1, target.selectedPosition2);\n    spinner.clearSelection();\n    assertEquals(1, target.selectedPosition1);\n    assertEquals(1, target.selectedPosition2);\n  }\n\n  static final class Visibilities {\n    int selectedPosition = -1;\n\n    @OnItemSelected(1) public void publicSelect(int position) {\n      selectedPosition = position;\n    }\n\n    @OnItemSelected(2) void packageSelect(int position) {\n      selectedPosition = position;\n    }\n\n    @OnItemSelected(3) protected void protectedSelect(int position) {\n      selectedPosition = position;\n    }\n\n    @OnItemSelected(value = 1, callback = NOTHING_SELECTED) public void publicClear() {\n      selectedPosition = -1;\n    }\n\n    @OnItemSelected(value = 2, callback = NOTHING_SELECTED) void packageClear() {\n      selectedPosition = -1;\n    }\n\n    @OnItemSelected(value = 3, callback = NOTHING_SELECTED) protected void protectedClear() {\n      selectedPosition = -1;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void visibilities() {\n    View tree = ViewTree.create(TestSpinner.class, 1, 2, 3);\n    TestSpinner spinner1 = tree.findViewById(1);\n    TestSpinner spinner2 = tree.findViewById(2);\n    TestSpinner spinner3 = tree.findViewById(3);\n\n    Visibilities target = new Visibilities();\n    ButterKnife.bind(target, tree);\n    assertEquals(-1, target.selectedPosition);\n\n    spinner1.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner1.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner2.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner2.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner3.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner3.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n  }\n\n  static final class MultipleIdPermutation {\n    int selectedPosition = -1;\n\n    @OnItemSelected({1, 2}) void select(int position) {\n      selectedPosition = position;\n    }\n\n    @OnItemSelected(value = {1, 3}, callback = NOTHING_SELECTED) void clear() {\n      selectedPosition = -1;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleIdPermutation() {\n    View tree = ViewTree.create(TestSpinner.class, 1, 2, 3);\n    TestSpinner spinner1 = tree.findViewById(1);\n    TestSpinner spinner2 = tree.findViewById(2);\n    TestSpinner spinner3 = tree.findViewById(3);\n\n    MultipleIdPermutation target = new MultipleIdPermutation();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(-1, target.selectedPosition);\n\n    spinner1.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner1.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner2.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner2.clearSelection();\n    assertEquals(0, target.selectedPosition);\n\n    spinner3.performSelection(1);\n    assertEquals(0, target.selectedPosition);\n\n    spinner3.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner1.performSelection(1);\n    unbinder.unbind();\n    spinner1.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n    spinner2.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n    spinner3.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n    spinner1.clearSelection();\n    assertEquals(1, target.selectedPosition);\n    spinner2.clearSelection();\n    assertEquals(1, target.selectedPosition);\n    spinner3.clearSelection();\n    assertEquals(1, target.selectedPosition);\n  }\n\n  static final class OptionalId {\n    int selectedPosition = -1;\n\n    @Optional @OnItemSelected(1) void select(int position) {\n      selectedPosition = position;\n    }\n\n    @Optional @OnItemSelected(value = 1, callback = NOTHING_SELECTED) void clear() {\n      selectedPosition = -1;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdPresent() {\n    View tree = ViewTree.create(TestSpinner.class, 1);\n    TestSpinner spinner = tree.findViewById(1);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(-1, target.selectedPosition);\n\n    spinner.performSelection(0);\n    assertEquals(0, target.selectedPosition);\n\n    spinner.clearSelection();\n    assertEquals(-1, target.selectedPosition);\n\n    spinner.performSelection(1);\n    unbinder.unbind();\n    spinner.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n    spinner.clearSelection();\n    assertEquals(1, target.selectedPosition);\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdAbsent() {\n    View tree = ViewTree.create(TestSpinner.class, 2);\n    TestSpinner spinner = tree.findViewById(2);\n\n    OptionalId target = new OptionalId();\n    target.selectedPosition = 1;\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(1, target.selectedPosition);\n\n    spinner.performSelection(0);\n    assertEquals(1, target.selectedPosition);\n\n    spinner.clearSelection();\n    assertEquals(1, target.selectedPosition);\n\n    unbinder.unbind();\n    spinner.performSelection(1);\n    assertEquals(1, target.selectedPosition);\n    spinner.clearSelection();\n    assertEquals(1, target.selectedPosition);\n  }\n\n  static final class ArgumentCast {\n    interface MyInterface {}\n\n    View last;\n\n    @OnItemSelected(1) void selectAdapterView(AdapterView<?> view) {\n      last = view;\n    }\n\n    @OnItemSelected(2) void selectAbsSpinner(AbsSpinner view) {\n      last = view;\n    }\n\n    @OnItemSelected(3) void selectMyInterface(MyInterface view) {\n      last = (View) view;\n    }\n\n    @OnItemSelected(value = 1, callback = NOTHING_SELECTED)\n    void clearAdapterView(AdapterView<?> view) {\n      last = view;\n    }\n\n    @OnItemSelected(value = 2, callback = NOTHING_SELECTED)\n    void clearAbsSpinner(AbsSpinner view) {\n      last = view;\n    }\n\n    @OnItemSelected(value = 3, callback = NOTHING_SELECTED)\n    void clearMyInterface(MyInterface view) {\n      last = (View) view;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void argumentCast() {\n    class MySpinner extends TestSpinner implements ArgumentCast.MyInterface {\n      MySpinner(Context context) {\n        super(context);\n      }\n    }\n\n    Context context = InstrumentationRegistry.getContext();\n    TestSpinner spinner1 = new MySpinner(context);\n    spinner1.setId(1);\n    TestSpinner spinner2 = new MySpinner(context);\n    spinner2.setId(2);\n    TestSpinner spinner3 = new MySpinner(context);\n    spinner3.setId(3);\n    ViewGroup tree = new FrameLayout(context);\n    tree.addView(spinner1);\n    tree.addView(spinner2);\n    tree.addView(spinner3);\n\n    ArgumentCast target = new ArgumentCast();\n    ButterKnife.bind(target, tree);\n\n    spinner1.performSelection(0);\n    assertSame(spinner1, target.last);\n\n    spinner2.performSelection(0);\n    assertSame(spinner2, target.last);\n\n    spinner3.performSelection(0);\n    assertSame(spinner3, target.last);\n\n    spinner1.clearSelection();\n    assertSame(spinner1, target.last);\n\n    spinner2.clearSelection();\n    assertSame(spinner2, target.last);\n\n    spinner3.clearSelection();\n    assertSame(spinner3, target.last);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnLongClickTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Button;\nimport android.widget.FrameLayout;\nimport android.widget.TextView;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnLongClick;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assert.assertTrue;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnLongClickTest {\n  static final class Simple {\n    boolean returnValue = true;\n    int clicks = 0;\n\n    @OnLongClick(1) boolean click() {\n      clicks++;\n      return returnValue;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void simple() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    Simple target = new Simple();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    assertTrue(view1.performLongClick());\n    assertEquals(1, target.clicks);\n\n    target.returnValue = false;\n    assertFalse(view1.performLongClick());\n    assertEquals(2, target.clicks);\n\n    unbinder.unbind();\n    view1.performLongClick();\n    assertEquals(2, target.clicks);\n  }\n\n  static final class ReturnVoid {\n    int clicks = 0;\n\n    @OnLongClick(1) void click() {\n      clicks++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void returnVoid() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    ReturnVoid target = new ReturnVoid();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    assertTrue(view1.performLongClick());\n    assertEquals(1, target.clicks);\n\n    unbinder.unbind();\n    view1.performLongClick();\n    assertEquals(1, target.clicks);\n  }\n\n  static final class Visibilities {\n    int clicks = 0;\n\n    @OnLongClick(1) public boolean publicClick() {\n      clicks++;\n      return true;\n    }\n\n    @OnLongClick(2) boolean packageClick() {\n      clicks++;\n      return true;\n    }\n\n    @OnLongClick(3) protected boolean protectedClick() {\n      clicks++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void visibilities() {\n    View tree = ViewTree.create(1, 2, 3);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n    View view3 = tree.findViewById(3);\n\n    Visibilities target = new Visibilities();\n    ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performLongClick();\n    assertEquals(1, target.clicks);\n\n    view2.performLongClick();\n    assertEquals(2, target.clicks);\n\n    view3.performLongClick();\n    assertEquals(3, target.clicks);\n  }\n\n  static final class MultipleIds {\n    int clicks = 0;\n\n    @OnLongClick({1, 2}) boolean click() {\n      clicks++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleIds() {\n    View tree = ViewTree.create(1, 2);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n\n    MultipleIds target = new MultipleIds();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performLongClick();\n    assertEquals(1, target.clicks);\n\n    view2.performLongClick();\n    assertEquals(2, target.clicks);\n\n    unbinder.unbind();\n    view1.performLongClick();\n    view2.performLongClick();\n    assertEquals(2, target.clicks);\n  }\n\n  static final class OptionalId {\n    int clicks = 0;\n\n    @Optional @OnLongClick(1) public boolean click() {\n      clicks++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdPresent() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view1.performLongClick();\n    assertEquals(1, target.clicks);\n\n    unbinder.unbind();\n    view1.performLongClick();\n    assertEquals(1, target.clicks);\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdAbsent() {\n    View tree = ViewTree.create(2);\n    View view2 = tree.findViewById(2);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.clicks);\n\n    view2.performLongClick();\n    assertEquals(0, target.clicks);\n\n    unbinder.unbind();\n    view2.performLongClick();\n    assertEquals(0, target.clicks);\n  }\n\n  static final class ArgumentCast {\n    interface MyInterface {}\n\n    View last;\n\n    @OnLongClick(1) boolean clickView(View view) {\n      last = view;\n      return true;\n    }\n\n    @OnLongClick(2) boolean clickTextView(TextView view) {\n      last = view;\n      return true;\n    }\n\n    @OnLongClick(3) boolean clickButton(Button view) {\n      last = view;\n      return true;\n    }\n\n    @OnLongClick(4) boolean clickMyInterface(MyInterface view) {\n      last = (View) view;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void argumentCast() {\n    class MyView extends Button implements ArgumentCast.MyInterface {\n      MyView(Context context) {\n        super(context);\n      }\n    }\n\n    View view1 = new MyView(InstrumentationRegistry.getContext());\n    view1.setId(1);\n    View view2 = new MyView(InstrumentationRegistry.getContext());\n    view2.setId(2);\n    View view3 = new MyView(InstrumentationRegistry.getContext());\n    view3.setId(3);\n    View view4 = new MyView(InstrumentationRegistry.getContext());\n    view4.setId(4);\n    ViewGroup tree = new FrameLayout(InstrumentationRegistry.getContext());\n    tree.addView(view1);\n    tree.addView(view2);\n    tree.addView(view3);\n    tree.addView(view4);\n\n    ArgumentCast target = new ArgumentCast();\n    ButterKnife.bind(target, tree);\n\n    view1.performLongClick();\n    assertSame(view1, target.last);\n\n    view2.performLongClick();\n    assertSame(view2, target.last);\n\n    view3.performLongClick();\n    assertSame(view3, target.last);\n\n    view4.performLongClick();\n    assertSame(view4, target.last);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/OnTouchTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Button;\nimport android.widget.FrameLayout;\nimport android.widget.TextView;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.annotation.UiThreadTest;\nimport butterknife.ButterKnife;\nimport butterknife.OnTouch;\nimport butterknife.Optional;\nimport butterknife.Unbinder;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assert.assertTrue;\n\n@SuppressWarnings(\"unused\") // Used reflectively / by code gen.\npublic final class OnTouchTest {\n  static final class Simple {\n    boolean returnValue = true;\n    int touches = 0;\n\n    @OnTouch(1) boolean touch() {\n      touches++;\n      return returnValue;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void simple() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    Simple target = new Simple();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    assertTrue(performTouch(view1));\n    assertEquals(1, target.touches);\n\n    target.returnValue = false;\n    assertFalse(performTouch(view1));\n    assertEquals(2, target.touches);\n\n    unbinder.unbind();\n    performTouch(view1);\n    assertEquals(2, target.touches);\n  }\n\n  static final class Arguments {\n    int touches = 0;\n\n    @OnTouch(1) boolean touch(View v) {\n      touches++;\n      return true;\n    }\n\n    @OnTouch(2) boolean touch(View v, MotionEvent event) {\n      touches++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void arguments() {\n    View tree = ViewTree.create(1, 2);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n\n    Arguments target = new Arguments();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    assertTrue(performTouch(view1));\n    assertEquals(1, target.touches);\n\n    assertTrue(performTouch(view2));\n    assertEquals(2, target.touches);\n\n    unbinder.unbind();\n    performTouch(view1);\n    assertEquals(2, target.touches);\n  }\n\n  static final class ReturnVoid {\n    int touches = 0;\n\n    @OnTouch(1) void touch() {\n      touches++;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void returnVoid() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    ReturnVoid target = new ReturnVoid();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    assertTrue(performTouch(view1));\n    assertEquals(1, target.touches);\n\n    unbinder.unbind();\n    performTouch(view1);\n    assertEquals(1, target.touches);\n  }\n\n  static final class Visibilities {\n    int touches = 0;\n\n    @OnTouch(1) public boolean publicTouch() {\n      touches++;\n      return true;\n    }\n\n    @OnTouch(2) boolean packageTouch() {\n      touches++;\n      return true;\n    }\n\n    @OnTouch(3) protected boolean protectedTouch() {\n      touches++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void visibilities() {\n    View tree = ViewTree.create(1, 2, 3);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n    View view3 = tree.findViewById(3);\n\n    Visibilities target = new Visibilities();\n    ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    performTouch(view1);\n    assertEquals(1, target.touches);\n\n    performTouch(view2);\n    assertEquals(2, target.touches);\n\n    performTouch(view3);\n    assertEquals(3, target.touches);\n  }\n\n  static final class MultipleIds {\n    int touches = 0;\n\n    @OnTouch({1, 2}) boolean touch() {\n      touches++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void multipleIds() {\n    View tree = ViewTree.create(1, 2);\n    View view1 = tree.findViewById(1);\n    View view2 = tree.findViewById(2);\n\n    MultipleIds target = new MultipleIds();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    performTouch(view1);\n    assertEquals(1, target.touches);\n\n    performTouch(view2);\n    assertEquals(2, target.touches);\n\n    unbinder.unbind();\n    performTouch(view1);\n    performTouch(view2);\n    assertEquals(2, target.touches);\n  }\n\n  static final class OptionalId {\n    int touches = 0;\n\n    @Optional @OnTouch(1) public boolean touch() {\n      touches++;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdPresent() {\n    View tree = ViewTree.create(1);\n    View view1 = tree.findViewById(1);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    performTouch(view1);\n    assertEquals(1, target.touches);\n\n    unbinder.unbind();\n    performTouch(view1);\n    assertEquals(1, target.touches);\n  }\n\n  @UiThreadTest\n  @Test public void optionalIdAbsent() {\n    View tree = ViewTree.create(2);\n    View view2 = tree.findViewById(2);\n\n    OptionalId target = new OptionalId();\n    Unbinder unbinder = ButterKnife.bind(target, tree);\n    assertEquals(0, target.touches);\n\n    performTouch(view2);\n    assertEquals(0, target.touches);\n\n    unbinder.unbind();\n    performTouch(view2);\n    assertEquals(0, target.touches);\n  }\n\n  static final class ArgumentCast {\n    interface MyInterface {}\n\n    View last;\n\n    @OnTouch(1) boolean touchView(View view) {\n      last = view;\n      return true;\n    }\n\n    @OnTouch(2) boolean touchTextView(TextView view) {\n      last = view;\n      return true;\n    }\n\n    @OnTouch(3) boolean touchButton(Button view) {\n      last = view;\n      return true;\n    }\n\n    @OnTouch(4) boolean touchMyInterface(ArgumentCast.MyInterface view) {\n      last = (View) view;\n      return true;\n    }\n  }\n\n  @UiThreadTest\n  @Test public void argumentCast() {\n    class MyView extends Button implements ArgumentCast.MyInterface {\n      MyView(Context context) {\n        super(context);\n      }\n    }\n\n    Context context = InstrumentationRegistry.getContext();\n    View view1 = new MyView(context);\n    view1.setId(1);\n    View view2 = new MyView(context);\n    view2.setId(2);\n    View view3 = new MyView(context);\n    view3.setId(3);\n    View view4 = new MyView(context);\n    view4.setId(4);\n    ViewGroup tree = new FrameLayout(context);\n    tree.addView(view1);\n    tree.addView(view2);\n    tree.addView(view3);\n    tree.addView(view4);\n\n    ArgumentCast target = new ArgumentCast();\n    ButterKnife.bind(target, tree);\n\n    performTouch(view1);\n    assertSame(view1, target.last);\n\n    performTouch(view2);\n    assertSame(view2, target.last);\n\n    performTouch(view3);\n    assertSame(view3, target.last);\n\n    performTouch(view4);\n    assertSame(view4, target.last);\n  }\n\n  private static boolean performTouch(View view) {\n    MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);\n    return view.dispatchTouchEvent(event);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/functional/ViewTree.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.FrameLayout;\nimport androidx.test.InstrumentationRegistry;\nimport java.lang.reflect.InvocationTargetException;\n\nfinal class ViewTree {\n  static View create(int... ids) {\n    return create(View.class, ids);\n  }\n\n  static View create(Class<? extends View> cls, int... ids) {\n    Context context = InstrumentationRegistry.getContext();\n    ViewGroup group = new FrameLayout(context);\n    for (int id : ids) {\n      View view;\n      try {\n        view = cls.getConstructor(Context.class).newInstance(context);\n      } catch (IllegalAccessException | InstantiationException | NoSuchMethodException e) {\n        throw new RuntimeException(e);\n      } catch (InvocationTargetException e) {\n        Throwable cause = e.getCause();\n        if (cause instanceof RuntimeException) throw (RuntimeException) cause;\n        if (cause instanceof Error) throw (Error) cause;\n        throw new RuntimeException(cause);\n      }\n\n      view.setId(id);\n      group.addView(view);\n    }\n    return group;\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/library/SimpleActivityTest.java",
    "content": "package com.example.butterknife.library;\n\nimport androidx.test.rule.ActivityTestRule;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport com.example.butterknife.R;\nimport org.junit.Rule;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class SimpleActivityTest {\n  @Rule public final ActivityTestRule<SimpleActivity> activityRule =\n      new ActivityTestRule<>(SimpleActivity.class);\n\n  @Test public void verifyContentViewBinding() {\n    SimpleActivity activity = activityRule.getActivity();\n\n    Unbinder unbinder = ButterKnife.bind(activity);\n    verifySimpleActivityBound(activity);\n    unbinder.unbind();\n    verifySimpleActivityUnbound(activity);\n  }\n\n  protected static void verifySimpleActivityBound(SimpleActivity activity) {\n    assertThat(activity.title.getId()).isEqualTo(R.id.titleTv);\n    assertThat(activity.subtitle.getId()).isEqualTo(R.id.subtitle);\n    assertThat(activity.hello.getId()).isEqualTo(R.id.hello);\n    assertThat(activity.listOfThings.getId()).isEqualTo(R.id.list_of_things);\n    assertThat(activity.footer.getId()).isEqualTo(R.id.footer);\n  }\n\n  protected static void verifySimpleActivityUnbound(SimpleActivity activity) {\n    assertThat(activity.title).isNull();\n    assertThat(activity.subtitle).isNull();\n    assertThat(activity.hello).isNull();\n    assertThat(activity.listOfThings).isNull();\n    assertThat(activity.footer).isNull();\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/library/SimpleAdapterTest.java",
    "content": "package com.example.butterknife.library;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport com.example.butterknife.R;\nimport org.junit.Test;\n\nimport static com.example.butterknife.library.SimpleAdapter.ViewHolder;\nimport static com.google.common.truth.Truth.assertThat;\n\npublic class SimpleAdapterTest {\n  @Test public void verifyViewHolderViews() {\n    Context context = InstrumentationRegistry.getTargetContext();\n\n    View root = View.inflate(context, R.layout.simple_list_item, null);\n    ViewHolder holder = new ViewHolder(root);\n\n    assertThat(holder.word.getId()).isEqualTo(R.id.word);\n    assertThat(holder.length.getId()).isEqualTo(R.id.length);\n    assertThat(holder.position.getId()).isEqualTo(R.id.position);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/java/com/example/butterknife/unbinder/UnbinderTest.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.content.Context;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.FrameLayout;\nimport androidx.test.InstrumentationRegistry;\nimport butterknife.ButterKnife;\nimport butterknife.Unbinder;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class UnbinderTest {\n  private final Context context = InstrumentationRegistry.getContext();\n\n  @Test public void verifyContentViewBinding() {\n    FrameLayout frameLayout = new FrameLayout(context);\n    Button button1 = new Button(context);\n    button1.setId(android.R.id.button1);\n    frameLayout.addView(button1);\n    Button button2 = new Button(context);\n    button2.setId(android.R.id.button2);\n    frameLayout.addView(button2);\n    Button button3 = new Button(context);\n    button3.setId(android.R.id.button3);\n    frameLayout.addView(button3);\n    View content = new View(context);\n    content.setId(android.R.id.content);\n    frameLayout.addView(content);\n    H h = new H(frameLayout);\n\n    Unbinder unbinder = ButterKnife.bind(h, frameLayout);\n    verifyHBound(h);\n    unbinder.unbind();\n    verifyHUnbound(h);\n  }\n\n  private void verifyHBound(H h) {\n    assertThat(h.button1).isNotNull();\n    assertThat(h.button2).isNotNull();\n    assertThat(h.button3).isNotNull();\n  }\n\n  private void verifyHUnbound(H h) {\n    assertThat(h.button1).isNull();\n    assertThat(h.button2).isNull();\n    assertThat(h.button3).isNull();\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/proguard.pro",
    "content": "-dontoptimize\n-dontobfuscate\n-dontshrink\n-dontnote **\n-dontwarn **\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/res/color/colors.xml",
    "content": "<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item\n      android:color=\"#ffff0000\"\n      android:state_pressed=\"true\"\n      />\n  <item\n      android:color=\"#ff0000ff\"\n      android:state_focused=\"true\"\n      />\n  <item android:color=\"#ff000000\"/>\n</selector>\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/res/drawable/circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\"\n    >\n  <size\n      android:height=\"10px\"\n      android:width=\"10px\"\n      />\n  <solid\n      android:color=\"#fff\"\n      />\n</shape>\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTest/res/values/values.xml",
    "content": "<resources>\n  <bool name=\"just_true\">true</bool>\n  <color name=\"red\">#ffff0000</color>\n  <integer name=\"twelve\">12</integer>\n  <dimen name=\"twelve_point_two_dp\">12.2dp</dimen>\n  <item name=\"twelve_point_two\" format=\"float\" type=\"dimen\">12.2</item>\n  <string name=\"hey\">Hey</string>\n  <string-array name=\"string_one_two_three\">\n    <item>One</item>\n    <item>Two</item>\n    <item>Three</item>\n  </string-array>\n  <integer-array name=\"int_one_two_three\">\n    <item>1</item>\n    <item>2</item>\n    <item>3</item>\n  </integer-array>\n</resources>\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindAnimFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindAnim;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindAnimFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindAnim(1) String actual;\n  }\n\n  @Test public void typeMustBeAnimation() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindAnim field type must be 'Animation'. \"\n              + \"(com.example.butterknife.functional.BindAnimFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindArrayFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindArray;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindArrayFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindArray(1) String actual;\n  }\n\n  @Test public void typeMustBeSupported() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindArray field type must be one of: \"\n              + \"String[], int[], CharSequence[], android.content.res.TypedArray. \"\n              + \"(com.example.butterknife.functional.BindArrayFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindBitmapFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindBitmap;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindBitmapFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindBitmap(1) String actual;\n  }\n\n  @Test public void typeMustBeBitmap() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindBitmap field type must be 'Bitmap'. \"\n              + \"(com.example.butterknife.functional.BindBitmapFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindBoolFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindBool;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindBoolFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindBool(1) String actual;\n  }\n\n  @Test public void typeMustBeBool() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindBool field type must be 'boolean'. \"\n              + \"(com.example.butterknife.functional.BindBoolFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindColorFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindColorFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindColor(1) String actual;\n  }\n\n  @Test public void typeMustBeIntOrColorStateList() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindColor field type must be 'int' or 'ColorStateList'. \"\n              + \"(com.example.butterknife.functional.BindColorFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindDimenFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindDimen;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindDimenFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindDimen(1) String actual;\n  }\n\n  @Test public void typeMustBeIntOrFloat() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindDimen field type must be 'int' or 'float'. \"\n              + \"(com.example.butterknife.functional.BindDimenFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindDrawableFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindDrawable;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindDrawableFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindDrawable(1) String actual;\n  }\n\n  @Test public void typeMustBeDrawable() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindDrawable field type must be 'Drawable'. \"\n              + \"(com.example.butterknife.functional.BindDrawableFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindFloatFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindFloat;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindFloatFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindFloat(1) String actual;\n  }\n\n  @Test public void typeMustBeFloat() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindFloat field type must be 'float'. \"\n              + \"(com.example.butterknife.functional.BindFloatFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindFontFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.graphics.Typeface;\nimport android.view.View;\nimport androidx.test.filters.SdkSuppress;\nimport butterknife.BindFont;\nimport butterknife.ButterKnife;\nimport com.example.butterknife.test.R;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindFontFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class TargetType {\n    @BindFont(1) String actual;\n  }\n\n  @Test public void typeMustBeTypeface() {\n    TargetType target = new TargetType();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindFont field type must be 'Typeface'. \"\n              + \"(com.example.butterknife.functional.BindFontFailureTest$TargetType.actual)\");\n    }\n  }\n\n  static class TargetStyle {\n    @BindFont(value = R.font.inconsolata_regular, style = 5) Typeface actual;\n  }\n\n  @SdkSuppress(minSdkVersion = 24) // AndroidX problems on earlier versions\n  @Test public void styleMustBeValid() {\n    TargetStyle target = new TargetStyle();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindFont style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC. \"\n              + \"(com.example.butterknife.functional.BindFontFailureTest$TargetStyle.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindIntFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindInt;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindIntFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindInt(1) String actual;\n  }\n\n  @Test public void typeMustBeInt() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindInt field type must be 'int'. \"\n              + \"(com.example.butterknife.functional.BindIntFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindStringFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindString;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindStringFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class Target {\n    @BindString(1) boolean actual;\n  }\n\n  @Test public void typeMustBeString() {\n    Target target = new Target();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindString field type must be 'String'. \"\n              + \"(com.example.butterknife.functional.BindStringFailureTest$Target.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindViewFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindViewFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class NotView {\n    @BindView(1) String actual;\n  }\n\n  @Test public void failsIfNotView() {\n    NotView target = new NotView();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindView fields must extend from View or be an interface. \"\n              + \"(com.example.butterknife.functional.BindViewFailureTest$NotView.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/androidTestReflect/java/com/example/butterknife/functional/BindViewsFailureTest.java",
    "content": "package com.example.butterknife.functional;\n\nimport android.view.View;\nimport butterknife.BindViews;\nimport butterknife.ButterKnife;\nimport java.util.Deque;\nimport java.util.List;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class BindViewsFailureTest {\n  private final View tree = ViewTree.create(1);\n\n  static class NoIds {\n    @BindViews({}) View[] actual;\n  }\n\n  @Test public void failsIfNoIds() {\n    NoIds target = new NoIds();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindViews must specify at least one ID. \"\n              + \"(com.example.butterknife.functional.BindViewsFailureTest$NoIds.actual)\");\n    }\n  }\n\n  static class NoGenericType {\n    @BindViews(1) List actual;\n  }\n\n  @Test public void failsIfNoGenericType() {\n    NoGenericType target = new NoGenericType();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindViews List must have a generic component. \"\n              + \"(com.example.butterknife.functional.BindViewsFailureTest$NoGenericType.actual)\");\n    }\n  }\n\n  static class BadCollection {\n    @BindViews(1) Deque<View> actual;\n  }\n\n  @Test public void failsIfUnsupportedCollection() {\n    BadCollection target = new BadCollection();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindViews must be a List or array. \"\n              + \"(com.example.butterknife.functional.BindViewsFailureTest$BadCollection.actual)\");\n    }\n  }\n\n  static class ListNotView {\n    @BindViews(1) List<String> actual;\n  }\n\n  @Test public void failsIfGenericNotView() {\n    ListNotView target = new ListNotView();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindViews List or array type must extend from View or be an interface. \"\n              + \"(com.example.butterknife.functional.BindViewsFailureTest$ListNotView.actual)\");\n    }\n  }\n\n  static class ArrayNotView {\n    @BindViews(1) List<String> actual;\n  }\n\n  @Test public void failsIfArrayNotView() {\n    ArrayNotView target = new ArrayNotView();\n\n    try {\n      ButterKnife.bind(target, tree);\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessageThat()\n          .isEqualTo(\"@BindViews List or array type must extend from View or be an interface. \"\n              + \"(com.example.butterknife.functional.BindViewsFailureTest$ArrayNotView.actual)\");\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.example.butterknife\">\n\n  <application\n      android:allowBackup=\"false\"\n      android:fullBackupContent=\"false\"\n      android:label=\"@string/app_name\"\n      android:name=\".SimpleApp\"\n      tools:ignore=\"MissingApplicationIcon,UnusedAttribute,GoogleAppIndexingWarning\">\n\n    <activity\n        android:label=\"@string/app_name\"\n        android:name=\".library.SimpleActivity\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.MAIN\"/>\n\n        <category android:name=\"android.intent.category.LAUNCHER\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n  </application>\n</manifest>\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/SimpleApp.java",
    "content": "package com.example.butterknife;\n\nimport android.app.Application;\nimport butterknife.ButterKnife;\n\npublic class SimpleApp extends Application {\n  @Override public void onCreate() {\n    super.onCreate();\n    ButterKnife.setDebug(BuildConfig.DEBUG);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/library/SimpleActivity.java",
    "content": "package com.example.butterknife.library;\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.view.animation.AlphaAnimation;\nimport android.widget.Button;\nimport android.widget.ListView;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport butterknife.Action;\nimport butterknife.BindString;\nimport butterknife.BindView;\nimport butterknife.BindViews;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport butterknife.OnItemClick;\nimport butterknife.OnLongClick;\nimport butterknife.ViewCollections;\nimport com.example.butterknife.R;\nimport static com.example.butterknife.R.id.titleTv;\nimport java.util.List;\n\nimport static android.widget.Toast.LENGTH_SHORT;\n\npublic class SimpleActivity extends Activity {\n  private static final Action<View> ALPHA_FADE = (view, index) -> {\n    AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);\n    alphaAnimation.setFillBefore(true);\n    alphaAnimation.setDuration(500);\n    alphaAnimation.setStartOffset(index * 100);\n    view.startAnimation(alphaAnimation);\n  };\n\n  @BindView(titleTv) TextView title;\n  @BindView(R.id.subtitle) TextView subtitle;\n  @BindView(R.id.hello) Button hello;\n  @BindView(R.id.list_of_things) ListView listOfThings;\n  @BindView(R.id.footer) TextView footer;\n  @BindString(R.string.app_name) String butterKnife;\n  @BindString(R.string.field_method) String fieldMethod;\n  @BindString(R.string.by_jake_wharton) String byJakeWharton;\n  @BindString(R.string.say_hello) String sayHello;\n\n  @BindViews({ titleTv, R.id.subtitle, R.id.hello }) List<View> headerViews;\n\n  private SimpleAdapter adapter;\n\n  @OnClick(R.id.hello) void sayHello() {\n    Toast.makeText(this, \"Hello, views!\", LENGTH_SHORT).show();\n    ViewCollections.run(headerViews, ALPHA_FADE);\n  }\n\n  @OnLongClick(R.id.hello) boolean sayGetOffMe() {\n    Toast.makeText(this, \"Let go of me!\", LENGTH_SHORT).show();\n    return true;\n  }\n\n  @OnItemClick(R.id.list_of_things) void onItemClick(int position) {\n    Toast.makeText(this, \"You clicked: \" + adapter.getItem(position), LENGTH_SHORT).show();\n  }\n\n  @Override protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.simple_activity);\n    ButterKnife.bind(this);\n\n    // Contrived code to use the bound fields.\n    title.setText(butterKnife);\n    subtitle.setText(fieldMethod);\n    footer.setText(byJakeWharton);\n    hello.setText(sayHello);\n\n    adapter = new SimpleAdapter(this);\n    listOfThings.setAdapter(adapter);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/library/SimpleAdapter.java",
    "content": "package com.example.butterknife.library;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.BaseAdapter;\nimport android.widget.TextView;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport com.example.butterknife.R;\n\nimport java.util.Locale;\n\npublic class SimpleAdapter extends BaseAdapter {\n  private static final String[] CONTENTS = \"The quick brown fox jumps over the lazy dog\".split(\" \");\n\n  private final LayoutInflater inflater;\n\n  public SimpleAdapter(Context context) {\n    inflater = LayoutInflater.from(context);\n  }\n\n  @Override public int getCount() {\n    return CONTENTS.length;\n  }\n\n  @Override public String getItem(int position) {\n    return CONTENTS[position];\n  }\n\n  @Override public long getItemId(int position) {\n    return position;\n  }\n\n  @Override public View getView(int position, View view, ViewGroup parent) {\n    ViewHolder holder;\n    if (view != null) {\n      holder = (ViewHolder) view.getTag();\n    } else {\n      view = inflater.inflate(R.layout.simple_list_item, parent, false);\n      holder = new ViewHolder(view);\n      view.setTag(holder);\n    }\n\n    String word = getItem(position);\n    holder.word.setText(String.format(Locale.getDefault(), \"Word: %s\", word));\n    holder.length.setText(String.format(Locale.getDefault(), \"Length: %d\", word.length()));\n    holder.position.setText(String.format(Locale.getDefault(), \"Position: %d\", position));\n    // Note: don't actually do string concatenation like this in an adapter's getView.\n\n    return view;\n  }\n\n  static final class ViewHolder {\n    @BindView(R.id.word) TextView word;\n    @BindView(R.id.length) TextView length;\n    @BindView(R.id.position) TextView position;\n\n    ViewHolder(View view) {\n      ButterKnife.bind(this, view);\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/A.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class A {\n\n  @BindColor(android.R.color.black) @ColorInt int blackColor;\n\n  public A(View view) {\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/B.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class B extends A {\n\n  @BindColor(android.R.color.white) @ColorInt int whiteColor;\n\n  public B(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/C.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\npublic class C extends B {\n\n  @BindColor(android.R.color.transparent) @ColorInt int transparentColor;\n  @BindView(android.R.id.button1) View button1;\n\n  public C(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/D.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class D extends C {\n\n  @BindColor(android.R.color.darker_gray) @ColorInt int grayColor;\n\n  public D(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/E.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class E extends C {\n\n  @BindColor(android.R.color.background_dark) @ColorInt int backgroundDarkColor;\n\n  public E(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/F.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic final class F extends D {\n\n  @BindColor(android.R.color.background_light) @ColorInt int backgroundLightColor;\n\n  public F(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/G.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport static android.R.color.darker_gray;\n\npublic class G extends E {\n\n  @BindColor(darker_gray) @ColorInt int grayColor;\n  @BindView(android.R.id.button2) View button2;\n\n  public G(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n\n  @OnClick(android.R.id.content) public void onClick() {\n\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/java/com/example/butterknife/unbinder/H.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport android.view.View;\nimport androidx.annotation.ColorInt;\nimport butterknife.BindColor;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\npublic class H extends G {\n\n  @BindColor(android.R.color.holo_green_dark) @ColorInt int holoGreenDark;\n  @BindView(android.R.id.button3) View button3;\n\n  public H(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/proguard.pro",
    "content": "-dontoptimize\n-dontobfuscate\n-dontnote **\n-dontwarn **\n\n# STUFF USED BY TESTS:\n\n-keep class butterknife.internal.Utils {\n  <methods>;\n}\n\n-keep class butterknife.Unbinder {\n  void unbind();\n}\n\n-keep class com.example.butterknife.unbinder.H {\n  <init>(...);\n}\n\n-keep class androidx.core.** {\n  <methods>;\n}\n"
  },
  {
    "path": "butterknife-integration-test/src/main/res/layout/simple_activity.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              xmlns:tools=\"http://schemas.android.com/tools\"\n              android:layout_width=\"match_parent\"\n              android:layout_height=\"match_parent\"\n              android:orientation=\"vertical\"\n              android:padding=\"8dp\"\n              tools:ignore=\"SelectableText\">\n    <TextView\n            android:id=\"@+id/titleTv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:textSize=\"50sp\"/>\n    <TextView\n            android:id=\"@+id/subtitle\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:textSize=\"20sp\"/>\n    <Button\n            android:id=\"@+id/hello\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:layout_margin=\"10dp\"/>\n    <ListView\n            android:id=\"@+id/list_of_things\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:layout_margin=\"10dp\"/>\n    <TextView\n            android:id=\"@+id/footer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:textSize=\"17sp\"\n            android:textStyle=\"italic\"/>\n</LinearLayout>\n"
  },
  {
    "path": "butterknife-integration-test/src/main/res/layout/simple_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              xmlns:tools=\"http://schemas.android.com/tools\"\n              android:layout_width=\"match_parent\"\n              android:layout_height=\"match_parent\"\n              android:orientation=\"vertical\"\n              tools:ignore=\"SelectableText\">\n    <TextView\n            android:id=\"@+id/word\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"/>\n    <TextView\n            android:id=\"@+id/length\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"/>\n    <TextView\n            android:id=\"@+id/position\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"/>\n</LinearLayout>\n"
  },
  {
    "path": "butterknife-integration-test/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<resources>\n  <string name=\"app_name\">Butter Knife</string>\n  <string name=\"field_method\">Field and method binding for Android views.</string>\n  <string name=\"by_jake_wharton\">by Jake Wharton</string>\n  <string name=\"say_hello\">Say Hello</string>\n</resources>\n"
  },
  {
    "path": "butterknife-lint/build.gradle",
    "content": "apply plugin: 'java-library'\napply plugin: 'checkstyle'\n\nsourceCompatibility = JavaVersion.VERSION_1_8\ntargetCompatibility = JavaVersion.VERSION_1_8\n\ndependencies {\n  compileOnly deps.lint.api\n  compileOnly deps.lint.checks\n\n  testImplementation deps.junit\n  testImplementation deps.lint.core\n  testImplementation deps.lint.tests\n  testImplementation(deps.truth) {\n    exclude group: 'com.google.guava', module: 'guava'\n  }\n}\n\njar {\n  manifest {\n    attributes 'Lint-Registry-v2': 'butterknife.lint.LintRegistry'\n  }\n}\n\ncheckstyle {\n  configFile rootProject.file('checkstyle.xml')\n  showViolations true\n  sourceSets = [sourceSets.main]\n}\n"
  },
  {
    "path": "butterknife-lint/src/main/java/butterknife/lint/InvalidR2UsageDetector.java",
    "content": "package butterknife.lint;\n\nimport com.android.tools.lint.client.api.UElementHandler;\nimport com.android.tools.lint.detector.api.Category;\nimport com.android.tools.lint.detector.api.Detector;\nimport com.android.tools.lint.detector.api.Implementation;\nimport com.android.tools.lint.detector.api.Issue;\nimport com.android.tools.lint.detector.api.JavaContext;\nimport com.android.tools.lint.detector.api.LintUtils;\nimport com.android.tools.lint.detector.api.Scope;\nimport com.android.tools.lint.detector.api.Severity;\nimport com.google.common.collect.ImmutableSet;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport org.jetbrains.uast.UAnnotation;\nimport org.jetbrains.uast.UClass;\nimport org.jetbrains.uast.UElement;\nimport org.jetbrains.uast.UExpression;\nimport org.jetbrains.uast.UFile;\nimport org.jetbrains.uast.UQualifiedReferenceExpression;\nimport org.jetbrains.uast.USimpleNameReferenceExpression;\nimport org.jetbrains.uast.visitor.AbstractUastVisitor;\n\n/**\n * Custom lint rule to make sure that generated R2 is not referenced outside annotations.\n */\npublic class InvalidR2UsageDetector extends Detector implements Detector.UastScanner {\n  private static final String LINT_ERROR_BODY = \"R2 should only be used inside annotations\";\n  private static final String LINT_ERROR_TITLE = \"Invalid usage of R2\";\n  private static final String ISSUE_ID = \"InvalidR2Usage\";\n  private static final Set<String> SUPPORTED_TYPES =\n      ImmutableSet.of(\"array\", \"attr\", \"bool\", \"color\", \"dimen\", \"drawable\", \"id\", \"integer\",\n          \"string\");\n\n  static final Issue ISSUE =\n      Issue.create(ISSUE_ID, LINT_ERROR_TITLE, LINT_ERROR_BODY, Category.CORRECTNESS, 6,\n          Severity.ERROR, new Implementation(InvalidR2UsageDetector.class, Scope.JAVA_FILE_SCOPE));\n\n  private static final String R2 = \"R2\";\n\n  @Override public List<Class<? extends UElement>> getApplicableUastTypes() {\n    return Collections.singletonList(UClass.class);\n  }\n\n  @Override public UElementHandler createUastHandler(final JavaContext context) {\n    return new UElementHandler() {\n      @Override public void visitClass(UClass node) {\n        node.accept(new R2UsageVisitor(context));\n      }\n    };\n  }\n\n  private static class R2UsageVisitor extends AbstractUastVisitor {\n    private final JavaContext context;\n\n    R2UsageVisitor(JavaContext context) {\n      this.context = context;\n    }\n\n    @Override public boolean visitAnnotation(UAnnotation annotation) {\n      // skip annotations\n      return true;\n    }\n\n    @Override public boolean visitQualifiedReferenceExpression(UQualifiedReferenceExpression node) {\n      detectR2(context, node);\n      return super.visitQualifiedReferenceExpression(node);\n    }\n\n    @Override\n    public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {\n      detectR2(context, node);\n      return super.visitSimpleNameReferenceExpression(node);\n    }\n\n    private static void detectR2(JavaContext context, UElement node) {\n      UFile sourceFile = context.getUastFile();\n      List<UClass> classes = sourceFile.getClasses();\n      if (!classes.isEmpty() && classes.get(0).getName() != null) {\n        String qualifiedName = classes.get(0).getName();\n        if (qualifiedName.contains(\"_ViewBinder\")\n            || qualifiedName.contains(\"_ViewBinding\")\n            || qualifiedName.equals(R2)) {\n          // skip generated files and R2\n          return;\n        }\n      }\n      boolean isR2 = isR2Expression(node);\n      if (isR2 && !context.isSuppressedWithComment(node, ISSUE)) {\n        context.report(ISSUE, node, context.getLocation(node), LINT_ERROR_BODY);\n      }\n    }\n\n    private static boolean isR2Expression(UElement node) {\n      UElement parentNode = node.getUastParent();\n      if (parentNode == null) {\n        return false;\n      }\n      String text = node.asSourceString();\n      UElement parent = LintUtils.skipParentheses(parentNode);\n      return (text.equals(R2) || text.contains(\".R2\"))\n          && parent instanceof UExpression\n          && endsWithAny(parent.asSourceString(), SUPPORTED_TYPES);\n    }\n\n    private static boolean endsWithAny(String text, Set<String> possibleValues) {\n      String[] tokens = text.split(\"\\\\.\");\n      return tokens.length > 1 && possibleValues.contains(tokens[tokens.length - 1]);\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-lint/src/main/java/butterknife/lint/LintRegistry.java",
    "content": "package butterknife.lint;\n\nimport com.android.tools.lint.client.api.IssueRegistry;\nimport com.android.tools.lint.detector.api.ApiKt;\nimport com.android.tools.lint.detector.api.Issue;\nimport com.google.common.collect.ImmutableList;\nimport java.util.List;\n\n/**\n * Contains references to all custom lint checks for butterknife.\n */\npublic class LintRegistry extends IssueRegistry {\n\n  @Override public List<Issue> getIssues() {\n    return ImmutableList.of(InvalidR2UsageDetector.ISSUE);\n  }\n\n  @Override public int getApi() {\n    return ApiKt.CURRENT_API;\n  }\n}\n"
  },
  {
    "path": "butterknife-lint/src/test/java/butterknife/lint/InvalidR2UsageDetectorTest.java",
    "content": "package butterknife.lint;\n\nimport com.android.tools.lint.checks.infrastructure.TestFile;\nimport org.junit.Test;\n\nimport static com.android.tools.lint.checks.infrastructure.TestFiles.java;\nimport static com.android.tools.lint.checks.infrastructure.TestLintTask.lint;\n\npublic final class InvalidR2UsageDetectorTest {\n  private static final TestFile BIND_TEST = java(\"\"\n      + \"package sample.r2;\\n\"\n      + \"\\n\"\n      + \"import java.lang.annotation.ElementType;\\n\"\n      + \"import java.lang.annotation.Retention;\\n\"\n      + \"import java.lang.annotation.RetentionPolicy;\\n\"\n      + \"import java.lang.annotation.Target;\\n\"\n      + \"\\n\"\n      + \"@Retention(RetentionPolicy.SOURCE) @Target({ ElementType.FIELD, ElementType.METHOD })\\n\"\n      + \"public @interface BindTest {\\n\"\n      + \"  int value();\\n\"\n      + \"}\\n\");\n\n  private static final TestFile R2 = java(\"\"\n      + \"package sample.r2;\\n\"\n      + \"\\n\"\n      + \"public final class R2 {\\n\"\n      + \"  public static final class array {\\n\"\n      + \"    public static final int res = 0x7f040001;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class attr {\\n\"\n      + \"    public static final int res = 0x7f040002;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class bool {\\n\"\n      + \"    public static final int res = 0x7f040003;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class color {\\n\"\n      + \"    public static final int res = 0x7f040004;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class dimen {\\n\"\n      + \"    public static final int res = 0x7f040005;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class drawable {\\n\"\n      + \"    public static final int res = 0x7f040006;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class id {\\n\"\n      + \"    public static final int res = 0x7f040007;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class integer {\\n\"\n      + \"    public static final int res = 0x7f040008;\\n\"\n      + \"  }\\n\"\n      + \"\\n\"\n      + \"  public static final class string {\\n\"\n      + \"    public static final int res = 0x7f040009;\\n\"\n      + \"  }\\n\"\n      + \"}\");\n\n  @Test public void noR2Usage() {\n    lint() //\n        .files(R2, //\n            java(\"\" //\n                + \"package sample;\\n\" //\n                + \"class NoR2Usage {}\\n\")) //\n        .issues(InvalidR2UsageDetector.ISSUE) //\n        .run() //\n        .expectClean();\n  }\n\n  @Test public void usesR2InAnnotations() {\n    lint() //\n        .files(R2, BIND_TEST, //\n            java(\"\"\n                + \"package sample.r2;\\n\"\n                + \"\\n\"\n                + \"public class R2UsageInAnnotations {\\n\"\n                + \"\\n\"\n                + \"  @BindTest(sample.r2.R2.string.res) String test;\\n\"\n                + \"\\n\"\n                + \"  @BindTest(R2.id.res) public void foo() {}\\n\"\n                + \"}\\n\") //\n        ) //\n        .issues(InvalidR2UsageDetector.ISSUE) //\n        .run() //\n        .expectClean();\n  }\n\n  @Test public void usesR2OutsideAnnotations() {\n    lint() //\n        .files(R2, //\n            java(\"\"\n                + \"package sample.r2;\\n\"\n                + \"\\n\"\n                + \"public class R2UsageOutsideAnnotations {\\n\"\n                + \"\\n\"\n                + \"  int array = sample.r2.R2.array.res;\\n\"\n                + \"\\n\"\n                + \"  public void foo(int color) {}\\n\"\n                + \"\\n\"\n                + \"  public void bar() {\\n\"\n                + \"    foo(R2.color.res);\\n\"\n                + \"  }\\n\"\n                + \"}\\n\" //\n            )) //\n        .issues(InvalidR2UsageDetector.ISSUE) //\n        .run() //\n        .expectErrorCount(2) //\n        .expectWarningCount(0);\n  }\n\n  @Test public void usesR2WithSuppression() {\n    lint() //\n        .files(R2, java(\"\"\n            + \"package sample.r2;\\n\"\n            + \"\\n\"\n            + \"public class R2UsageWithSuppression {\\n\"\n            + \"\\n\"\n            + \"  @SuppressWarnings(\\\"InvalidR2Usage\\\")\\n\"\n            + \"  int bool = sample.r2.R2.bool.res;\\n\"\n            + \"\\n\"\n            + \"  public void foo(int attr) {}\\n\"\n            + \"\\n\"\n            + \"  @SuppressWarnings(\\\"InvalidR2Usage\\\")\\n\"\n            + \"  public void bar() {\\n\"\n            + \"    foo(R2.attr.res);\\n\"\n            + \"  }\\n\"\n            + \"}\\n\")) //\n        .issues(InvalidR2UsageDetector.ISSUE) //\n        .run() //\n        .expectClean();\n  }\n}\n"
  },
  {
    "path": "butterknife-lint/src/test/java/butterknife/lint/LintRegistryTest.java",
    "content": "package butterknife.lint;\n\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\n\npublic final class LintRegistryTest {\n  @Test public void issues() {\n    assertThat(new LintRegistry().getIssues()).contains(InvalidR2UsageDetector.ISSUE);\n  }\n}\n"
  },
  {
    "path": "butterknife-reflect/README.md",
    "content": "ButterKnife Reflect\n===================\n\nThe `butterknife-reflect` artifact is an API-compatible replacement for `butterknife` which uses\n100% reflection to fulfill field and method bindings for use during development.\n\n\nEr, what? Why would I want this?\n--------------------------------\n\nThe normal `butterknife` artifact requires the use of `butterknife-compiler` as an annotation\nprocessor for compile-time validation of your bindings and code generation for runtime performance.\nThis is a desirable feature for your CI and release builds, but it slows down iterative development.\nBy using `butterknife-reflect` for only your IDE builds, you have one less annotation processor\nsitting between you and your running app. This is especially important for Kotlin-only or\nJava/Kotlin mixed projects using KAPT. And if `butterknife-compiler` is your only annotation\nprocessor for a module, using `butterknife-reflect` means that **zero** annotation processors run\nduring development.\n\n\nCan I use this in production?\n-----------------------------\n\nNo.\n\nWell technically you _can_, but don't. It's slow, inefficient, and lacks the level of validation\nthat normal Butter Knife usage provides.\n\n\nUsage\n-----\n\nKotlin modules:\n```groovy\ndependencies {\n  if (properties.containsKey('android.injected.invoked.from.ide')) {\n    implementation 'com.jakewharton:butterknife-reflect:<version>'\n  } else {\n    implementation 'com.jakewharton:butterknife:<version>'\n    kapt 'com.jakewharton:butterknife-compiler:<version>'\n  }\n}\n```\n\nJava modules:\n```groovy\ndependencies {\n  if (properties.containsKey('android.injected.invoked.from.ide')) {\n    implementation 'com.jakewharton:butterknife-reflect:<version>'\n  } else {\n    implementation 'com.jakewharton:butterknife:<version>'\n    annotationProcessor 'com.jakewharton:butterknife-compiler:<version>'\n  }\n}\n```\n\n_(Replacing `<version>` with whatever version you are using.)_\n\nIf you have a dedicated variant for development you can skip the `if` check and simply add\n`butterknife-reflect` to that variant and `butterknife`+`butterknife-compiler` for the regular\nvariants.\n"
  },
  {
    "path": "butterknife-reflect/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  defaultConfig {\n    minSdkVersion versions.minSdk\n\n    consumerProguardFiles 'proguard-rules.txt'\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n\n  lintOptions {\n    textReport true\n    textOutput 'stdout'\n    // We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.\n    checkReleaseBuilds false\n  }\n\n  // TODO replace with https://issuetracker.google.com/issues/72050365 once released.\n  libraryVariants.all {\n    it.generateBuildConfig.enabled = false\n  }\n}\n\ndependencies {\n  api project(':butterknife-runtime')\n  api deps.androidx.viewpager\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife-reflect/gradle.properties",
    "content": "POM_ARTIFACT_ID=butterknife-reflect\nPOM_NAME=ButterKnife Reflect\nPOM_PACKAGING=aar\n"
  },
  {
    "path": "butterknife-reflect/proguard-rules.txt",
    "content": "-keepclassmembers class * { @butterknife.* <methods>; }\n-keepclassmembers class * { @butterknife.* <fields>; }\n"
  },
  {
    "path": "butterknife-reflect/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"butterknife.reflect\"/>\n"
  },
  {
    "path": "butterknife-reflect/src/main/java/butterknife/ButterKnife.java",
    "content": "package butterknife;\n\nimport android.app.Activity;\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.content.res.Resources;\nimport android.content.res.TypedArray;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Typeface;\nimport android.graphics.drawable.Drawable;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.animation.Animation;\nimport android.view.animation.AnimationUtils;\nimport android.widget.AdapterView;\nimport android.widget.CompoundButton;\nimport android.widget.TextView;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.UiThread;\nimport androidx.core.content.ContextCompat;\nimport androidx.core.content.res.ResourcesCompat;\nimport androidx.viewpager.widget.ViewPager;\nimport butterknife.internal.Constants;\nimport butterknife.internal.Utils;\nimport java.lang.reflect.AccessibleObject;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Member;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport static java.lang.reflect.Modifier.PRIVATE;\nimport static java.lang.reflect.Modifier.PUBLIC;\nimport static java.lang.reflect.Modifier.STATIC;\nimport static java.util.Collections.singletonList;\n\npublic final class ButterKnife {\n  private ButterKnife() {\n    throw new AssertionError();\n  }\n\n  private static final String TAG = \"ButterKnife\";\n  private static boolean debug = false;\n\n  /** Control whether debug logging is enabled. */\n  public static void setDebug(boolean debug) {\n    ButterKnife.debug = debug;\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link Activity}. The current content\n   * view is used as the view root.\n   *\n   * @param target Target activity for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Activity target) {\n    View sourceView = target.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link View}. The view and its children\n   * are used as the view root.\n   *\n   * @param target Target view for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull View target) {\n    return bind(target, target);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@link Dialog}. The current content\n   * view is used as the view root.\n   *\n   * @param target Target dialog for view binding.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Dialog target) {\n    View sourceView = target.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link Activity} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source Activity on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull Activity source) {\n    View sourceView = source.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link Dialog} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source Dialog on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull Dialog source) {\n    View sourceView = source.getWindow().getDecorView();\n    return bind(target, sourceView);\n  }\n\n  /**\n   * BindView annotated fields and methods in the specified {@code target} using the {@code source}\n   * {@link View} as the view root.\n   *\n   * @param target Target class for view binding.\n   * @param source View root on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull View source) {\n    List<Unbinder> unbinders = new ArrayList<>();\n    Class<?> targetClass = target.getClass();\n    if ((targetClass.getModifiers() & PRIVATE) != 0) {\n      throw new IllegalArgumentException(targetClass.getName() + \" must not be private.\");\n    }\n\n    while (true) {\n      String clsName = targetClass.getName();\n      if (clsName.startsWith(\"android.\") || clsName.startsWith(\"java.\")\n          || clsName.startsWith(\"androidx.\")) {\n        break;\n      }\n\n      for (Field field : targetClass.getDeclaredFields()) {\n        int unbinderStartingSize = unbinders.size();\n        Unbinder unbinder;\n\n        unbinder = parseBindView(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindViews(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindAnim(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindArray(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindBitmap(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindBool(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindColor(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindDimen(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindDrawable(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindFloat(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindFont(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindInt(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseBindString(target, field, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        if (unbinders.size() - unbinderStartingSize > 1) {\n          throw new IllegalStateException(\n              \"More than one bind annotation on \" + targetClass.getName() + \".\" + field.getName());\n        }\n      }\n\n      for (Method method : targetClass.getDeclaredMethods()) {\n        Unbinder unbinder;\n\n        unbinder = parseOnCheckedChanged(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnClick(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnEditorAction(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnFocusChange(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnItemClick(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnItemLongClick(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnLongClick(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnPageChange(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnTextChanged(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n\n        unbinder = parseOnTouch(target, method, source);\n        if (unbinder != null) unbinders.add(unbinder);\n      }\n\n      targetClass = targetClass.getSuperclass();\n    }\n\n    if (unbinders.isEmpty()) {\n      if (debug) Log.d(TAG, \"MISS: Reached framework class. Abandoning search.\");\n      return Unbinder.EMPTY;\n    }\n\n    if (debug) Log.d(TAG, \"HIT: Reflectively found \" + unbinders.size() + \" bindings.\");\n    return new CompositeUnbinder(unbinders);\n  }\n\n  private static @Nullable Unbinder parseBindView(Object target, Field field, View source) {\n    BindView bindView = field.getAnnotation(BindView.class);\n    if (bindView == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindView.value();\n    Class<?> viewClass = field.getType();\n    if (!View.class.isAssignableFrom(viewClass) && !viewClass.isInterface()) {\n      throw new IllegalStateException(\n          \"@BindView fields must extend from View or be an interface. (\"\n              + field.getDeclaringClass().getName()\n              + '.'\n              + field.getName()\n              + ')');\n    }\n\n    String who = \"field '\" + field.getName() + \"'\";\n    Object view = Utils.findOptionalViewAsType(source, id, who, viewClass);\n    trySet(field, target, view);\n\n    return new FieldUnbinder(target, field);\n  }\n\n  private static @Nullable Unbinder parseBindViews(Object target, Field field, View source) {\n    BindViews bindViews = field.getAnnotation(BindViews.class);\n    if (bindViews == null) {\n      return null;\n    }\n    validateMember(field);\n\n    Class<?> fieldClass = field.getType();\n    Class<?> viewClass;\n    boolean isArray = fieldClass.isArray();\n    if (isArray) {\n      viewClass = fieldClass.getComponentType();\n    } else if (fieldClass == List.class) {\n      Type fieldType = field.getGenericType();\n      if (fieldType instanceof ParameterizedType) {\n        Type viewType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];\n        // TODO real rawType impl!!!!\n        viewClass = (Class<?>) viewType;\n      } else {\n        throw new IllegalStateException(\"@BindViews List must have a generic component. (\"\n            + field.getDeclaringClass().getName()\n            + '.'\n            + field.getName()\n            + ')');\n      }\n    } else {\n      throw new IllegalStateException(\"@BindViews must be a List or array. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    if (!View.class.isAssignableFrom(viewClass) && !viewClass.isInterface()) {\n      throw new IllegalStateException(\n          \"@BindViews List or array type must extend from View or be an interface. (\"\n              + field.getDeclaringClass().getName()\n              + '.'\n              + field.getName()\n              + ')');\n    }\n\n    int[] ids = bindViews.value();\n    if (ids.length == 0) {\n      throw new IllegalStateException(\"@BindViews must specify at least one ID. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n\n    List<Object> views = new ArrayList<>(ids.length);\n    String who = \"field '\" + field.getName() + \"'\";\n    for (int id : ids) {\n      Object view = Utils.findOptionalViewAsType(source, id, who, viewClass);\n      if (view != null) {\n        views.add(view);\n      }\n    }\n\n    Object value;\n    if (isArray) {\n      Object[] viewArray = (Object[]) Array.newInstance(viewClass, views.size());\n      value = views.toArray(viewArray);\n    } else {\n      value = views;\n    }\n\n    trySet(field, target, value);\n    return new FieldUnbinder(target, field);\n  }\n\n  private static @Nullable Unbinder parseBindAnim(Object target, Field field, View source) {\n    BindAnim bindAnim = field.getAnnotation(BindAnim.class);\n    if (bindAnim == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindAnim.value();\n    Context context = source.getContext();\n\n    Object value;\n    Class<?> fieldType = field.getType();\n    if (fieldType == Animation.class) {\n      value = AnimationUtils.loadAnimation(context, id);\n    } else {\n      throw new IllegalStateException(\"@BindAnim field type must be 'Animation'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindArray(Object target, Field field, View source) {\n    BindArray bindArray = field.getAnnotation(BindArray.class);\n    if (bindArray == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindArray.value();\n    Resources resources = source.getContext().getResources();\n\n    Object value;\n    Class<?> fieldType = field.getType();\n    if (fieldType == TypedArray.class) {\n      value = resources.obtainTypedArray(id);\n    } else if (fieldType.isArray()) {\n      Class<?> componentType = fieldType.getComponentType();\n      if (componentType == String.class) {\n        value = resources.getStringArray(id);\n      } else if (componentType == int.class) {\n        value = resources.getIntArray(id);\n      } else if (componentType == CharSequence.class) {\n        value = resources.getTextArray(id);\n      } else {\n        throw new IllegalStateException(\"@BindArray field type must be one of: \"\n            + \"String[], int[], CharSequence[], android.content.res.TypedArray. (\"\n            + field.getDeclaringClass().getName()\n            + '.'\n            + field.getName()\n            + ')');\n      }\n    } else {\n      throw new IllegalStateException(\"@BindArray field type must be one of: \"\n          + \"String[], int[], CharSequence[], android.content.res.TypedArray. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindBitmap(Object target, Field field, View source) {\n    BindBitmap bindBitmap = field.getAnnotation(BindBitmap.class);\n    if (bindBitmap == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindBitmap.value();\n    Resources resources = source.getContext().getResources();\n\n    Object value;\n    Class<?> fieldType = field.getType();\n    if (fieldType == Bitmap.class) {\n      value = BitmapFactory.decodeResource(resources, id);\n    } else {\n      throw new IllegalStateException(\"@BindBitmap field type must be 'Bitmap'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindBool(Object target, Field field, View source) {\n    BindBool bindBool = field.getAnnotation(BindBool.class);\n    if (bindBool == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindBool.value();\n    Resources resources = source.getContext().getResources();\n\n    Object value;\n    Class<?> fieldType = field.getType();\n    if (fieldType == boolean.class) {\n      value = resources.getBoolean(id);\n    } else {\n      throw new IllegalStateException(\"@BindBool field type must be 'boolean'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindColor(Object target, Field field, View source) {\n    BindColor bindColor = field.getAnnotation(BindColor.class);\n    if (bindColor == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindColor.value();\n    Context context = source.getContext();\n\n    Object value;\n    Class<?> fieldType = field.getType();\n    if (fieldType == int.class) {\n      value = ContextCompat.getColor(context, id);\n    } else if (fieldType == ColorStateList.class) {\n      value = ContextCompat.getColorStateList(context, id);\n    } else {\n      throw new IllegalStateException(\"@BindColor field type must be 'int' or 'ColorStateList'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindDimen(Object target, Field field, View source) {\n    BindDimen bindDimen = field.getAnnotation(BindDimen.class);\n    if (bindDimen == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindDimen.value();\n    Resources resources = source.getContext().getResources();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == int.class) {\n      value = resources.getDimensionPixelSize(id);\n    } else if (fieldType == float.class) {\n      value = resources.getDimension(id);\n    } else {\n      throw new IllegalStateException(\"@BindDimen field type must be 'int' or 'float'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindDrawable(Object target, Field field, View source) {\n    BindDrawable bindDrawable = field.getAnnotation(BindDrawable.class);\n    if (bindDrawable == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindDrawable.value();\n    int tint = bindDrawable.tint();\n    Context context = source.getContext();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == Drawable.class) {\n      value = tint != Constants.NO_RES_ID\n          ? Utils.getTintedDrawable(context, id, tint)\n          : ContextCompat.getDrawable(context, id);\n    } else {\n      throw new IllegalStateException(\"@BindDrawable field type must be 'Drawable'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindFloat(Object target, Field field, View source) {\n    BindFloat bindInt = field.getAnnotation(BindFloat.class);\n    if (bindInt == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindInt.value();\n    Context context = source.getContext();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == float.class) {\n      value = Utils.getFloat(context, id);\n    } else {\n      throw new IllegalStateException(\"@BindFloat field type must be 'float'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindFont(Object target, Field field, View source) {\n    BindFont bindFont = field.getAnnotation(BindFont.class);\n    if (bindFont == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindFont.value();\n    int style = bindFont.style();\n    Context context = source.getContext();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == Typeface.class) {\n      Typeface font = ResourcesCompat.getFont(context, id);\n      switch (style) {\n        case Typeface.NORMAL:\n          value = font;\n          break;\n        case Typeface.BOLD:\n        case Typeface.ITALIC:\n        case Typeface.BOLD_ITALIC:\n          value = Typeface.create(font, style);\n          break;\n        default:\n          throw new IllegalStateException(\n              \"@BindFont style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC. (\"\n                  + field.getDeclaringClass().getName()\n                  + '.'\n                  + field.getName()\n                  + ')');\n      }\n    } else {\n      throw new IllegalStateException(\"@BindFont field type must be 'Typeface'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindInt(Object target, Field field, View source) {\n    BindInt bindInt = field.getAnnotation(BindInt.class);\n    if (bindInt == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindInt.value();\n    Resources resources = source.getContext().getResources();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == int.class) {\n      value = resources.getInteger(id);\n    } else {\n      throw new IllegalStateException(\"@BindInt field type must be 'int'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseBindString(Object target, Field field, View source) {\n    BindString bindString = field.getAnnotation(BindString.class);\n    if (bindString == null) {\n      return null;\n    }\n    validateMember(field);\n\n    int id = bindString.value();\n    Context context = source.getContext();\n\n    Class<?> fieldType = field.getType();\n    Object value;\n    if (fieldType == String.class) {\n      value = context.getString(id);\n    } else {\n      throw new IllegalStateException(\"@BindString field type must be 'String'. (\"\n          + field.getDeclaringClass().getName()\n          + '.'\n          + field.getName()\n          + ')');\n    }\n    trySet(field, target, value);\n\n    return Unbinder.EMPTY;\n  }\n\n  private static @Nullable Unbinder parseOnCheckedChanged(final Object target, final Method method,\n      View source) {\n    OnCheckedChanged onCheckedChanged = method.getAnnotation(OnCheckedChanged.class);\n    if (onCheckedChanged == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_CHECKED_CHANGED_TYPES);\n\n    List<CompoundButton> views =\n        findViews(source, onCheckedChanged.value(), isRequired(method), method.getName(),\n            CompoundButton.class);\n\n    ViewCollections.set(views, ON_CHECKED_CHANGE,\n        (buttonView, isChecked) -> tryInvoke(method, target,\n            argumentTransformer.transform(buttonView, isChecked)));\n\n    return new ListenerUnbinder<>(views, ON_CHECKED_CHANGE);\n  }\n\n  private static @Nullable Unbinder parseOnClick(final Object target, final Method method,\n      View source) {\n    OnClick onClick = method.getAnnotation(OnClick.class);\n    if (onClick == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_CLICK_TYPES);\n\n    List<View> views =\n        findViews(source, onClick.value(), isRequired(method), method.getName(), View.class);\n\n    ViewCollections.set(views, ON_CLICK,\n        v -> tryInvoke(method, target, argumentTransformer.transform(v)));\n\n    return new ListenerUnbinder<>(views, ON_CLICK);\n  }\n\n  private static @Nullable Unbinder parseOnEditorAction(final Object target, final Method method,\n      View source) {\n    OnEditorAction onEditorAction = method.getAnnotation(OnEditorAction.class);\n    if (onEditorAction == null) {\n      return null;\n    }\n    validateMember(method);\n    final boolean propagateReturn = validateReturnType(method, boolean.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_EDITOR_ACTION_TYPES);\n\n    List<TextView> views =\n        findViews(source, onEditorAction.value(), isRequired(method), method.getName(),\n            TextView.class);\n\n    ViewCollections.set(views, ON_EDITOR_ACTION, (v, actionId, event) -> {\n      Object value = tryInvoke(method, target, argumentTransformer.transform(v, actionId, event));\n      //noinspection SimplifiableConditionalExpression\n      return propagateReturn\n          ? (boolean) value\n          : true;\n    });\n\n    return new ListenerUnbinder<>(views, ON_EDITOR_ACTION);\n  }\n\n  private static @Nullable Unbinder parseOnFocusChange(final Object target, final Method method,\n      View source) {\n    OnFocusChange onFocusChange = method.getAnnotation(OnFocusChange.class);\n    if (onFocusChange == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_FOCUS_CHANGE_TYPES);\n\n    List<View> views =\n        findViews(source, onFocusChange.value(), isRequired(method), method.getName(), View.class);\n\n    ViewCollections.set(views, ON_FOCUS_CHANGE,\n        (v, hasFocus) -> tryInvoke(method, target, argumentTransformer.transform(v, hasFocus)));\n\n    return new ListenerUnbinder<>(views, ON_FOCUS_CHANGE);\n  }\n\n  private static @Nullable Unbinder parseOnItemClick(final Object target, final Method method,\n      View source) {\n    OnItemClick onItemClick = method.getAnnotation(OnItemClick.class);\n    if (onItemClick == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_ITEM_CLICK_TYPES);\n\n    List<AdapterView<?>> views =\n        findViews(source, onItemClick.value(), isRequired(method), method.getName(),\n            AdapterView.class);\n\n    ViewCollections.set(views, ON_ITEM_CLICK,\n        (parent, view, position, id) -> tryInvoke(method, target,\n            argumentTransformer.transform(parent, view, position, id)));\n\n    return new ListenerUnbinder<>(views, ON_ITEM_CLICK);\n  }\n\n  private static @Nullable Unbinder parseOnItemLongClick(final Object target, final Method method,\n      View source) {\n    OnItemLongClick onItemLongClick = method.getAnnotation(OnItemLongClick.class);\n    if (onItemLongClick == null) {\n      return null;\n    }\n    validateMember(method);\n    final boolean propagateReturn = validateReturnType(method, boolean.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_ITEM_LONG_CLICK_TYPES);\n\n    List<AdapterView<?>> views =\n        findViews(source, onItemLongClick.value(), isRequired(method), method.getName(),\n            AdapterView.class);\n\n    ViewCollections.set(views, ON_ITEM_LONG_CLICK, (parent, view, position, id) -> {\n      Object value =\n          tryInvoke(method, target, argumentTransformer.transform(parent, view, position, id));\n      //noinspection SimplifiableConditionalExpression\n      return propagateReturn\n          ? (boolean) value\n          : true;\n    });\n\n    return new ListenerUnbinder<>(views, ON_ITEM_LONG_CLICK);\n  }\n\n  private static @Nullable Unbinder parseOnLongClick(final Object target, final Method method,\n      View source) {\n    OnLongClick onLongClick = method.getAnnotation(OnLongClick.class);\n    if (onLongClick == null) {\n      return null;\n    }\n    validateMember(method);\n    final boolean propagateReturn = validateReturnType(method, boolean.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_LONG_CLICK_TYPES);\n\n    List<View> views =\n        findViews(source, onLongClick.value(), isRequired(method), method.getName(), View.class);\n\n    ViewCollections.set(views, ON_LONG_CLICK, v -> {\n      Object returnValue = tryInvoke(method, target, argumentTransformer.transform(v));\n      //noinspection SimplifiableConditionalExpression\n      return propagateReturn\n          ? (boolean) returnValue\n          : true;\n    });\n\n    return new ListenerUnbinder<>(views, ON_LONG_CLICK);\n  }\n\n  private static @Nullable Unbinder parseOnPageChange(final Object target, final Method method,\n      View source) {\n    OnPageChange onPageChange = method.getAnnotation(OnPageChange.class);\n    if (onPageChange == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n\n    List<ViewPager> views =\n        findViews(source, onPageChange.value(), isRequired(method), method.getName(),\n            ViewPager.class);\n\n    ViewPager.OnPageChangeListener listener;\n    switch (onPageChange.callback()) {\n      case PAGE_SCROLLED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, ON_PAGE_SCROLLED_TYPES);\n        listener = new ViewPager.SimpleOnPageChangeListener() {\n          @Override public void onPageScrolled(int position, float positionOffset,\n              int positionOffsetPixels) {\n            tryInvoke(method, target,\n                argumentTransformer.transform(position, positionOffset, positionOffsetPixels));\n          }\n        };\n        break;\n      }\n      case PAGE_SELECTED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, ON_PAGE_SELECTED_TYPES);\n        listener = new ViewPager.SimpleOnPageChangeListener() {\n          @Override public void onPageSelected(int position) {\n            tryInvoke(method, target, argumentTransformer.transform(position));\n          }\n        };\n        break;\n      }\n      case PAGE_SCROLL_STATE_CHANGED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, ON_PAGE_SCROLL_STATE_CHANGED_TYPES);\n        listener = new ViewPager.SimpleOnPageChangeListener() {\n          @Override public void onPageScrollStateChanged(int state) {\n            tryInvoke(method, target, argumentTransformer.transform(state));\n          }\n        };\n        break;\n      }\n      default:\n        throw new AssertionError();\n    }\n\n    ViewCollections.set(views, ADD_ON_PAGE_CHANGE, listener);\n    return new ListenerUnbinder<>(views, REMOVE_ON_PAGE_CHANGE, listener);\n  }\n\n  private static @Nullable Unbinder parseOnTextChanged(Object target, Method method, View source) {\n    OnTextChanged onTextChanged = method.getAnnotation(OnTextChanged.class);\n    if (onTextChanged == null) {\n      return null;\n    }\n    validateMember(method);\n    validateReturnType(method, void.class);\n\n    List<TextView> views =\n        findViews(source, onTextChanged.value(), isRequired(method), method.getName(), View.class);\n\n    TextWatcher textWatcher;\n    switch (onTextChanged.callback()) {\n      case TEXT_CHANGED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, ON_TEXT_CHANGED_TYPES);\n        textWatcher = new EmptyTextWatcher() {\n          @Override public void onTextChanged(CharSequence s, int start, int before, int count) {\n            tryInvoke(method, target, argumentTransformer.transform(s, start, before, count));\n          }\n        };\n        break;\n      }\n      case BEFORE_TEXT_CHANGED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, BEFORE_TEXT_CHANGED_TYPES);\n        textWatcher = new EmptyTextWatcher() {\n          @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n            tryInvoke(method, target, argumentTransformer.transform(s, start, count, after));\n          }\n        };\n        break;\n      }\n      case AFTER_TEXT_CHANGED: {\n        ArgumentTransformer argumentTransformer =\n            createArgumentTransformer(method, AFTER_TEXT_CHANGED_TYPES);\n        textWatcher = new EmptyTextWatcher() {\n          @Override public void afterTextChanged(Editable s) {\n            tryInvoke(method, target, argumentTransformer.transform(s));\n          }\n        };\n        break;\n      }\n      default:\n        throw new AssertionError();\n    }\n\n    ViewCollections.set(views, ADD_TEXT_WATCHER, textWatcher);\n    return new ListenerUnbinder<>(views, REMOVE_TEXT_WATCHER, textWatcher);\n  }\n\n  private static @Nullable Unbinder parseOnTouch(final Object target, final Method method,\n      View source) {\n    OnTouch onTouch = method.getAnnotation(OnTouch.class);\n    if (onTouch == null) {\n      return null;\n    }\n    validateMember(method);\n    final boolean propagateReturn = validateReturnType(method, boolean.class);\n    final ArgumentTransformer argumentTransformer =\n        createArgumentTransformer(method, ON_TOUCH_TYPES);\n\n    List<View> views =\n        findViews(source, onTouch.value(), isRequired(method), method.getName(), View.class);\n\n    ViewCollections.set(views, ON_TOUCH, (v, event) -> {\n      Object returnValue = tryInvoke(method, target, argumentTransformer.transform(v, event));\n      //noinspection SimplifiableConditionalExpression\n      return propagateReturn\n          ? (boolean) returnValue\n          : true;\n    });\n\n    return new ListenerUnbinder<>(views, ON_TOUCH);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static <T extends View> List<T> findViews(View source, int[] ids, boolean isRequired,\n      String name, Class<? extends View> cls) {\n    if (ids.length == 1 && ids[0] == View.NO_ID) {\n      return singletonList((T) cls.cast(source));\n    }\n\n    String who = \"method '\" + name + \"'\";\n    List<T> views = new ArrayList<>(ids.length);\n    for (int id : ids) {\n      if (isRequired) {\n        views.add((T) Utils.findRequiredViewAsType(source, id, who, cls));\n      } else {\n        T view = (T) Utils.findOptionalViewAsType(source, id, who, cls);\n        if (view != null) {\n          views.add(view);\n        }\n      }\n    }\n    return views;\n  }\n\n  private static <T extends AccessibleObject & Member> void validateMember(T object) {\n    int modifiers = object.getModifiers();\n    if ((modifiers & (PRIVATE | STATIC)) != 0) {\n      throw new IllegalStateException(object.getDeclaringClass().getName()\n          + \".\"\n          + object.getName()\n          + \" must not be private or static\");\n    }\n    if ((modifiers & PUBLIC) == 0) {\n      object.setAccessible(true);\n    }\n  }\n\n  /** Returns true when the return value should be propagated. Use a default otherwise. */\n  private static boolean validateReturnType(Method method, Class<?> expected) {\n    Class<?> returnType = method.getReturnType();\n    if (returnType == void.class) {\n      return false;\n    }\n    if (returnType != expected) {\n      String expectedType = \"'\" + expected.getName() + \"'\";\n      if (expected != void.class) {\n        expectedType = \"'void' or \" + expectedType;\n      }\n      throw new IllegalStateException(method.getDeclaringClass().getName()\n          + \".\"\n          + method.getName()\n          + \" must have return type of \"\n          + expectedType);\n    }\n    return true;\n  }\n\n  private static boolean isRequired(Method method) {\n    return method.getAnnotation(Optional.class) == null;\n  }\n\n  private static ArgumentTransformer createArgumentTransformer(Method method,\n      Class<?>[] callbackParameterTypes) {\n    Class<?>[] targetParameterTypes = method.getParameterTypes();\n\n    int targetParameterLength = targetParameterTypes.length;\n    if (targetParameterLength == 0) {\n      // Special case the common case of no arguments.\n      return ArgumentTransformer.EMPTY;\n    }\n\n    int callbackParameterLength = callbackParameterTypes.length;\n    if (targetParameterLength > callbackParameterLength) {\n      throw new IllegalStateException(method.getDeclaringClass().getName()\n          + \".\"\n          + method.getName()\n          + \" must have at most \"\n          + callbackParameterLength\n          + \" parameter(s).\");\n    }\n\n    if (Arrays.equals(targetParameterTypes, callbackParameterTypes)) {\n      // Special case the common case of exact argument match.\n      return ArgumentTransformer.IDENTITY;\n    }\n\n    boolean[] callbackIndexUsed = new boolean[callbackParameterLength];\n    final int[] indexMap = new int[targetParameterLength];\n    nextTarget: for (int targetIndex = 0; targetIndex < targetParameterLength; targetIndex++) {\n      Class<?> targetParameterType = targetParameterTypes[targetIndex];\n      for (int callbackIndex = 0; callbackIndex < callbackParameterLength; callbackIndex++) {\n        if (callbackIndexUsed[callbackIndex]) {\n          continue; // We have already used this callback argument.\n        }\n        Class<?> callbackParameterType = callbackParameterTypes[callbackIndex];\n\n        if (/* exact match */\n            callbackParameterType.equals(targetParameterType)\n            /* or subtype of view */\n            || (View.class.isAssignableFrom(callbackParameterType)\n                && callbackParameterType.isAssignableFrom(targetParameterType))\n            /* or interface (like Checkable) */\n            || targetParameterType.isInterface()) {\n          indexMap[targetIndex] = callbackIndex;\n          callbackIndexUsed[callbackIndex] = true;\n          continue nextTarget; // This avoids the error handling code if loop exits normally.\n        }\n      }\n\n      StringBuilder builder = new StringBuilder();\n      builder.append(\"Unable to match \")\n          .append(method.getDeclaringClass().getName())\n          .append('.')\n          .append(method.getName())\n          .append(\" method arguments.\");\n      for (int i = 0; i < targetParameterLength; i++) {\n        builder.append(\"\\n\\n  Parameter #\")\n            .append(i + 1)\n            .append(\": \")\n            .append(targetParameterTypes[i].getName())\n            .append(\"\\n    \");\n        if (i < targetIndex) {\n          builder.append(\"matched listener parameter #\")\n              .append(indexMap[i])\n              .append(\": \")\n              .append(callbackParameterTypes[indexMap[i]].getName());\n        } else {\n          builder.append(\"did not match any listener parameters\");\n        }\n      }\n      builder.append(\"\\n\\nMethods may have up to \")\n          .append(callbackParameterLength)\n          .append(\" parameter(s):\\n\");\n      for (Class<?> callbackParameter : callbackParameterTypes) {\n        builder.append(\"\\n  \").append(callbackParameter.getName());\n      }\n      builder.append(\n          \"\\n\\nThese may be listed in any order but will be searched for from top to bottom.\");\n      throw new IllegalStateException(builder.toString());\n    }\n\n    return new ArgumentTransformer() {\n      @Override public Object[] transform(Object... arguments) {\n        Object[] newArguments = new Object[indexMap.length];\n        for (int i = 0; i < indexMap.length; i++) {\n          newArguments[i] = arguments[indexMap[i]];\n        }\n        return newArguments;\n      }\n\n      @Override public String toString() {\n        StringBuilder builder = new StringBuilder(\"ArgumentTransformer[\");\n        for (int i = 0; i < indexMap.length; i++) {\n          if (i > 0) {\n            builder.append(\", \");\n          }\n          builder.append(i).append(\" => \").append(indexMap[i]);\n        }\n        return builder.append(']').toString();\n      }\n    };\n  }\n\n  static void trySet(Field field, Object target, @Nullable Object value) {\n    try {\n      field.set(target, value);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Unable to assign \" + value + \" to \" + field + \" on \" + target, e);\n    }\n  }\n\n  private static Object tryInvoke(Method method, Object target, Object... arguments) {\n    Throwable cause;\n    try {\n      return method.invoke(target, arguments);\n    } catch (IllegalAccessException e) {\n      cause = e;\n    } catch (InvocationTargetException e) {\n      cause = e;\n    }\n    throw new RuntimeException(\n        \"Unable to invoke \" + method + \" on \" + target + \" with arguments \"\n            + Arrays.toString(arguments), cause);\n  }\n\n  private static final Setter<CompoundButton, CompoundButton.OnCheckedChangeListener>\n      ON_CHECKED_CHANGE = (view, value, index) -> view.setOnCheckedChangeListener(value);\n  private static final Setter<View, View.OnClickListener> ON_CLICK =\n      (view, value, index) -> view.setOnClickListener(value);\n  private static final Setter<TextView, TextView.OnEditorActionListener> ON_EDITOR_ACTION =\n      (view, value, index) -> view.setOnEditorActionListener(value);\n  private static final Setter<View, View.OnFocusChangeListener> ON_FOCUS_CHANGE =\n      (view, value, index) -> view.setOnFocusChangeListener(value);\n  private static final Setter<AdapterView<?>, AdapterView.OnItemClickListener> ON_ITEM_CLICK =\n      (view, value, index) -> view.setOnItemClickListener(value);\n  private static final Setter<AdapterView<?>, AdapterView.OnItemLongClickListener>\n      ON_ITEM_LONG_CLICK = (view, value, index) -> view.setOnItemLongClickListener(value);\n  private static final Setter<View, View.OnLongClickListener> ON_LONG_CLICK =\n      (view, value, index) -> view.setOnLongClickListener(value);\n  private static final Setter<View, View.OnTouchListener> ON_TOUCH =\n      (view, value, index) -> view.setOnTouchListener(value);\n  private static final Setter<ViewPager, ViewPager.OnPageChangeListener> ADD_ON_PAGE_CHANGE =\n      (view, value, index) -> view.addOnPageChangeListener(value);\n  private static final Setter<ViewPager, ViewPager.OnPageChangeListener> REMOVE_ON_PAGE_CHANGE =\n      (view, value, index) -> view.removeOnPageChangeListener(value);\n  private static final Setter<TextView, TextWatcher> ADD_TEXT_WATCHER =\n      (view, value, index) -> view.addTextChangedListener(value);\n  private static final Setter<TextView, TextWatcher> REMOVE_TEXT_WATCHER =\n      (view, value, index) -> view.removeTextChangedListener(value);\n\n  private static final Class<?>[] ON_CHECKED_CHANGED_TYPES =\n      { CompoundButton.class, boolean.class };\n  private static final Class<?>[] ON_CLICK_TYPES = { View.class };\n  private static final Class<?>[] ON_EDITOR_ACTION_TYPES =\n      { TextView.class, int.class, KeyEvent.class };\n  private static final Class<?>[] ON_FOCUS_CHANGE_TYPES = { View.class, boolean.class };\n  private static final Class<?>[] ON_ITEM_CLICK_TYPES =\n      { AdapterView.class, View.class, int.class, long.class };\n  private static final Class<?>[] ON_ITEM_LONG_CLICK_TYPES = ON_ITEM_CLICK_TYPES;\n  private static final Class<?>[] ON_LONG_CLICK_TYPES = ON_CLICK_TYPES;\n  private static final Class<?>[] ON_PAGE_SCROLLED_TYPES = { int.class, float.class, int.class };\n  private static final Class<?>[] ON_PAGE_SELECTED_TYPES = { int.class };\n  private static final Class<?>[] ON_PAGE_SCROLL_STATE_CHANGED_TYPES = { int.class };\n  private static final Class<?>[] ON_TEXT_CHANGED_TYPES =\n      { CharSequence.class, int.class, int.class, int.class };\n  private static final Class<?>[] BEFORE_TEXT_CHANGED_TYPES = ON_TEXT_CHANGED_TYPES;\n  private static final Class<?>[] AFTER_TEXT_CHANGED_TYPES = { Editable.class };\n  private static final Class<?>[] ON_TOUCH_TYPES = { View.class, MotionEvent.class };\n\n  private interface ArgumentTransformer {\n    ArgumentTransformer EMPTY = new ArgumentTransformer() {\n      private final Object[] empty = new Object[0];\n\n      @Override public Object[] transform(Object... arguments) {\n        return empty;\n      }\n\n      @Override public String toString() {\n        return \"ArgumentTransformer[empty]\";\n      }\n    };\n    ArgumentTransformer IDENTITY = new ArgumentTransformer() {\n      @Override public Object[] transform(Object... arguments) {\n        return arguments;\n      }\n\n      @Override public String toString() {\n        return \"ArgumentTransformer[identity]\";\n      }\n    };\n\n    Object[] transform(Object... arguments);\n  }\n}\n"
  },
  {
    "path": "butterknife-reflect/src/main/java/butterknife/CompositeUnbinder.java",
    "content": "package butterknife;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport java.util.List;\n\nfinal class CompositeUnbinder implements Unbinder {\n  private @Nullable List<Unbinder> unbinders;\n\n  CompositeUnbinder(@NonNull List<Unbinder> unbinders) {\n    this.unbinders = unbinders;\n  }\n\n  @Override public void unbind() {\n    if (unbinders == null) {\n      throw new IllegalStateException(\"Bindings already cleared.\");\n    }\n    for (Unbinder unbinder : unbinders) {\n      unbinder.unbind();\n    }\n    unbinders = null;\n  }\n}\n"
  },
  {
    "path": "butterknife-reflect/src/main/java/butterknife/EmptyTextWatcher.java",
    "content": "package butterknife;\n\nimport android.text.Editable;\nimport android.text.TextWatcher;\n\nclass EmptyTextWatcher implements TextWatcher {\n  @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n  }\n\n  @Override public void onTextChanged(CharSequence s, int start, int before, int count) {\n  }\n\n  @Override public void afterTextChanged(Editable s) {\n  }\n}\n"
  },
  {
    "path": "butterknife-reflect/src/main/java/butterknife/FieldUnbinder.java",
    "content": "package butterknife;\n\nimport java.lang.reflect.Field;\n\nimport static butterknife.ButterKnife.trySet;\n\nfinal class FieldUnbinder implements Unbinder {\n  private final Object target;\n  private final Field field;\n\n  FieldUnbinder(Object target, Field field) {\n    this.target = target;\n    this.field = field;\n  }\n\n  @Override public void unbind() {\n    trySet(field, target, null);\n  }\n}\n"
  },
  {
    "path": "butterknife-reflect/src/main/java/butterknife/ListenerUnbinder.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport java.util.List;\n\nfinal class ListenerUnbinder<V extends View, L> implements Unbinder {\n  private final List<V> targets;\n  private final Setter<V, L> setter;\n  private final L listener;\n\n  ListenerUnbinder(List<V> targets, Setter<V, L> setter) {\n    this.targets = targets;\n    this.setter = setter;\n    this.listener = null;\n  }\n\n  ListenerUnbinder(List<V> targets, Setter<V, L> setter, L listener) {\n    this.targets = targets;\n    this.setter = setter;\n    this.listener = listener;\n  }\n\n  @Override public void unbind() {\n    ViewCollections.set(targets, setter, listener);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  defaultConfig {\n    minSdkVersion versions.minSdk\n\n    testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'\n\n    javaCompileOptions {\n      annotationProcessorOptions {\n        includeCompileClasspath = true\n      }\n    }\n  }\n\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n\n  lintOptions {\n    textReport true\n    textOutput 'stdout'\n    // We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.\n    checkReleaseBuilds false\n  }\n\n  // TODO replace with https://issuetracker.google.com/issues/72050365 once released.\n  libraryVariants.all {\n    it.generateBuildConfig.enabled = false\n  }\n}\n\ndependencies {\n  api project(':butterknife-annotations')\n  api deps.androidx.core\n\n  lintChecks project(':butterknife-lint')\n\n  androidTestImplementation deps.junit\n  androidTestImplementation deps.truth\n  androidTestImplementation deps.androidx.test.runner\n  androidTestAnnotationProcessor project(':butterknife-compiler')\n\n  testImplementation deps.junit\n  testImplementation deps.truth\n  testImplementation deps.compiletesting\n  testImplementation files(getRuntimeJar())\n  testImplementation files(org.gradle.internal.jvm.Jvm.current().getToolsJar())\n  testImplementation project(':butterknife-compiler')\n  testImplementation deps.androidx.annotations\n}\n\ndef getRuntimeJar() {\n  try {\n    final File javaBase = new File(System.getProperty(\"java.home\")).getCanonicalFile();\n    File runtimeJar = new File(javaBase, \"lib/rt.jar\");\n    if (runtimeJar.exists()) {\n      return runtimeJar;\n    }\n    runtimeJar = new File(javaBase, \"jre/lib/rt.jar\");\n    return runtimeJar.exists() ? runtimeJar : null;\n  } catch (IOException e) {\n    throw new RuntimeException(e);\n  }\n}\n\napply from: rootProject.file('gradle/gradle-mvn-push.gradle')\n"
  },
  {
    "path": "butterknife-runtime/gradle.properties",
    "content": "POM_ARTIFACT_ID=butterknife-runtime\nPOM_NAME=ButterKnife Runtime\nPOM_PACKAGING=aar\n"
  },
  {
    "path": "butterknife-runtime/src/androidTest/java/butterknife/ViewCollectionsTest.java",
    "content": "package butterknife;\n\nimport android.content.Context;\nimport android.util.Property;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport java.util.List;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static java.util.Arrays.asList;\n\npublic class ViewCollectionsTest {\n  private static final Property<View, Boolean> PROPERTY_ENABLED =\n      new Property<View, Boolean>(Boolean.class, \"enabled\") {\n        @Override public Boolean get(View view) {\n          return view.isEnabled();\n        }\n\n        @Override public void set(View view, Boolean enabled) {\n          view.setEnabled(enabled);\n        }\n      };\n  private static final Setter<View, Boolean> SETTER_ENABLED =\n      (view, value, index) -> view.setEnabled(value);\n  private static final Action<View> ACTION_DISABLE = (view, index) -> view.setEnabled(false);\n  private static final Action<View> ACTION_ZERO_ALPHA = (view, index) -> view.setAlpha(0f);\n\n  private final Context context = InstrumentationRegistry.getContext();\n\n  @Test public void propertyAppliedToView() {\n    View view = new View(context);\n    assertThat(view.isEnabled()).isTrue();\n\n    ViewCollections.set(view, PROPERTY_ENABLED, false);\n    assertThat(view.isEnabled()).isFalse();\n  }\n\n  @Test public void propertyAppliedToEveryViewInList() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    List<View> views = asList(view1, view2, view3);\n    ViewCollections.set(views, PROPERTY_ENABLED, false);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n\n  @Test public void propertyAppliedToEveryViewInArray() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    View[] views = new View[] { view1, view2, view3 };\n    ViewCollections.set(views, PROPERTY_ENABLED, false);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n\n  @Test public void actionAppliedToView() {\n    View view = new View(context);\n    assertThat(view.isEnabled()).isTrue();\n\n    ViewCollections.run(view, ACTION_DISABLE);\n\n    assertThat(view.isEnabled()).isFalse();\n  }\n\n  @Test public void actionsAppliedToView() {\n    View view = new View(context);\n    assertThat(view.isEnabled()).isTrue();\n    assertThat(view.getAlpha()).isEqualTo(1f);\n\n    ViewCollections.run(view, ACTION_DISABLE, ACTION_ZERO_ALPHA);\n    assertThat(view.isEnabled()).isFalse();\n    assertThat(view.getAlpha()).isEqualTo(0f);\n  }\n\n  @Test public void actionAppliedToEveryViewInList() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    List<View> views = asList(view1, view2, view3);\n    ViewCollections.run(views, ACTION_DISABLE);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n\n  @Test public void actionAppliedToEveryViewInArray() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    View[] views = new View[] { view1, view2, view3 };\n    ViewCollections.run(views, ACTION_DISABLE);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n\n  @Test public void actionsAppliedToEveryViewInList() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n    assertThat(view1.getAlpha()).isEqualTo(1f);\n    assertThat(view2.getAlpha()).isEqualTo(1f);\n    assertThat(view3.getAlpha()).isEqualTo(1f);\n\n    List<View> views = asList(view1, view2, view3);\n    ViewCollections.run(views, ACTION_DISABLE, ACTION_ZERO_ALPHA);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n    assertThat(view1.getAlpha()).isEqualTo(0f);\n    assertThat(view2.getAlpha()).isEqualTo(0f);\n    assertThat(view3.getAlpha()).isEqualTo(0f);\n  }\n\n  @Test public void actionsAppliedToEveryViewInArray() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n    assertThat(view1.getAlpha()).isEqualTo(1f);\n    assertThat(view2.getAlpha()).isEqualTo(1f);\n    assertThat(view3.getAlpha()).isEqualTo(1f);\n\n    View[] views = new View[] { view1, view2, view3 };\n    ViewCollections.run(views, ACTION_DISABLE, ACTION_ZERO_ALPHA);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n    assertThat(view1.getAlpha()).isEqualTo(0f);\n    assertThat(view2.getAlpha()).isEqualTo(0f);\n    assertThat(view3.getAlpha()).isEqualTo(0f);\n  }\n\n  @Test public void setterAppliedToView() {\n    View view = new View(context);\n    assertThat(view.isEnabled()).isTrue();\n\n    ViewCollections.set(view, SETTER_ENABLED, false);\n\n    assertThat(view.isEnabled()).isFalse();\n  }\n\n  @Test public void setterAppliedToEveryViewInList() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    List<View> views = asList(view1, view2, view3);\n    ViewCollections.set(views, SETTER_ENABLED, false);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n\n  @Test public void setterAppliedToEveryViewInArray() {\n    View view1 = new View(context);\n    View view2 = new View(context);\n    View view3 = new View(context);\n    assertThat(view1.isEnabled()).isTrue();\n    assertThat(view2.isEnabled()).isTrue();\n    assertThat(view3.isEnabled()).isTrue();\n\n    View[] views = new View[] { view1, view2, view3 };\n    ViewCollections.set(views, SETTER_ENABLED, false);\n\n    assertThat(view1.isEnabled()).isFalse();\n    assertThat(view2.isEnabled()).isFalse();\n    assertThat(view3.isEnabled()).isFalse();\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/androidTest/java/butterknife/internal/UtilsTest.java",
    "content": "package butterknife.internal;\n\nimport android.content.Context;\nimport android.view.View;\nimport androidx.test.InstrumentationRegistry;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class UtilsTest {\n  @Test public void finderThrowsNiceError() {\n    Context context = InstrumentationRegistry.getContext();\n    View view = new View(context);\n    try {\n      Utils.findRequiredView(view, android.R.id.button1, \"yo mama\");\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessage(\"Required view 'button1' with ID \"\n          + android.R.id.button1\n          + \" for yo mama was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.\");\n    }\n  }\n\n  @Test public void finderThrowsLessNiceErrorInEditMode() {\n    Context context = InstrumentationRegistry.getContext();\n    View view = new EditModeView(context);\n    try {\n      Utils.findRequiredView(view, android.R.id.button1, \"yo mama\");\n      fail();\n    } catch (IllegalStateException e) {\n      assertThat(e).hasMessage(\"Required view '<unavailable while editing>' \"\n          + \"with ID \" + android.R.id.button1\n          + \" for yo mama was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.\");\n    }\n  }\n\n  static final class EditModeView extends View {\n    EditModeView(Context context) {\n      super(context);\n    }\n\n    @Override public boolean isInEditMode() {\n      return true;\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"butterknife.runtime\"/>\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/Action.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.UiThread;\n\n/** An action that can be applied to a list of views. */\npublic interface Action<T extends View> {\n  /** Apply the action on the {@code view} which is at {@code index} in the list. */\n  @UiThread void apply(@NonNull T view, int index);\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/Setter.java",
    "content": "package butterknife;\n\nimport android.view.View;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.UiThread;\n\n/** A setter that can apply a value to a list of views. */\npublic interface Setter<T extends View, V> {\n  /** Set the {@code value} on the {@code view} which is at {@code index} in the list. */\n  @UiThread void set(@NonNull T view, @Nullable V value, int index);\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/Unbinder.java",
    "content": "package butterknife;\n\nimport androidx.annotation.UiThread;\n\n/** An unbinder contract that will unbind views when called. */\npublic interface Unbinder {\n  @UiThread void unbind();\n\n  Unbinder EMPTY = () -> { };\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/ViewCollections.java",
    "content": "package butterknife;\n\nimport android.util.Property;\nimport android.view.View;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.UiThread;\nimport java.util.List;\n\n/** Convenience methods for working with view collections. */\npublic final class ViewCollections {\n  /** Apply the specified {@code actions} across the {@code list} of views. */\n  @UiThread\n  @SafeVarargs public static <T extends View> void run(@NonNull List<T> list,\n      @NonNull Action<? super T>... actions) {\n    for (int i = 0, count = list.size(); i < count; i++) {\n      for (Action<? super T> action : actions) {\n        action.apply(list.get(i), i);\n      }\n    }\n  }\n\n  /** Apply the specified {@code actions} across the {@code array} of views. */\n  @UiThread\n  @SafeVarargs public static <T extends View> void run(@NonNull T[] array,\n      @NonNull Action<? super T>... actions) {\n    for (int i = 0, count = array.length; i < count; i++) {\n      for (Action<? super T> action : actions) {\n        action.apply(array[i], i);\n      }\n    }\n  }\n\n  /** Apply the specified {@code action} across the {@code list} of views. */\n  @UiThread\n  public static <T extends View> void run(@NonNull List<T> list,\n      @NonNull Action<? super T> action) {\n    for (int i = 0, count = list.size(); i < count; i++) {\n      action.apply(list.get(i), i);\n    }\n  }\n\n  /** Apply the specified {@code action} across the {@code array} of views. */\n  @UiThread\n  public static <T extends View> void run(@NonNull T[] array, @NonNull Action<? super T> action) {\n    for (int i = 0, count = array.length; i < count; i++) {\n      action.apply(array[i], i);\n    }\n  }\n\n  /** Apply {@code actions} to {@code view}. */\n  @UiThread\n  @SafeVarargs public static <T extends View> void run(@NonNull T view,\n      @NonNull Action<? super T>... actions) {\n    for (Action<? super T> action : actions) {\n      action.apply(view, 0);\n    }\n  }\n\n  /** Apply {@code action} to {@code view}. */\n  @UiThread\n  public static <T extends View> void run(@NonNull T view, @NonNull Action<? super T> action) {\n    action.apply(view, 0);\n  }\n\n  /** Set the {@code value} using the specified {@code setter} across the {@code list} of views. */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull List<T> list,\n      @NonNull Setter<? super T, V> setter, @Nullable V value) {\n    for (int i = 0, count = list.size(); i < count; i++) {\n      setter.set(list.get(i), value, i);\n    }\n  }\n\n  /** Set the {@code value} using the specified {@code setter} across the {@code array} of views. */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull T[] array,\n      @NonNull Setter<? super T, V> setter, @Nullable V value) {\n    for (int i = 0, count = array.length; i < count; i++) {\n      setter.set(array[i], value, i);\n    }\n  }\n\n  /** Set {@code value} on {@code view} using {@code setter}. */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull T view,\n      @NonNull Setter<? super T, V> setter, @Nullable V value) {\n    setter.set(view, value, 0);\n  }\n\n  /**\n   * Apply the specified {@code value} across the {@code list} of views using the {@code property}.\n   */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull List<T> list,\n      @NonNull Property<? super T, V> setter, @Nullable V value) {\n    //noinspection ForLoopReplaceableByForEach\n    for (int i = 0, count = list.size(); i < count; i++) {\n      setter.set(list.get(i), value);\n    }\n  }\n\n  /**\n   * Apply the specified {@code value} across the {@code array} of views using the {@code property}.\n   */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull T[] array,\n      @NonNull Property<? super T, V> setter, @Nullable V value) {\n    //noinspection ForLoopReplaceableByForEach\n    for (int i = 0, count = array.length; i < count; i++) {\n      setter.set(array[i], value);\n    }\n  }\n\n  /** Apply {@code value} to {@code view} using {@code property}. */\n  @UiThread\n  public static <T extends View, V> void set(@NonNull T view,\n      @NonNull Property<? super T, V> setter, @Nullable V value) {\n    setter.set(view, value);\n  }\n\n  private ViewCollections() {\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/internal/DebouncingOnClickListener.java",
    "content": "package butterknife.internal;\n\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.view.View;\n\n/**\n * A {@linkplain View.OnClickListener click listener} that debounces multiple clicks posted in the\n * same frame. A click on one button disables all buttons for that frame.\n */\npublic abstract class DebouncingOnClickListener implements View.OnClickListener {\n  private static final Runnable ENABLE_AGAIN = () -> enabled = true;\n  private static final Handler MAIN = new Handler(Looper.getMainLooper());\n\n  static boolean enabled = true;\n\n  @Override public final void onClick(View v) {\n    if (enabled) {\n      enabled = false;\n\n      // Post to the main looper directly rather than going through the view.\n      // Ensure that ENABLE_AGAIN will be executed, avoid static field {@link #enabled}\n      // staying in false state.\n      MAIN.post(ENABLE_AGAIN);\n\n      doClick(v);\n    }\n  }\n\n  public abstract void doClick(View v);\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/internal/ImmutableList.java",
    "content": "package butterknife.internal;\n\nimport java.util.AbstractList;\nimport java.util.RandomAccess;\n\n/**\n * An immutable list of views which is lighter than {@code\n * Collections.unmodifiableList(new ArrayList<>(Arrays.asList(foo, bar)))}.\n */\nfinal class ImmutableList<T> extends AbstractList<T> implements RandomAccess {\n  private final T[] views;\n\n  ImmutableList(T[] views) {\n    this.views = views;\n  }\n\n  @Override public T get(int index) {\n    return views[index];\n  }\n\n  @Override public int size() {\n    return views.length;\n  }\n\n  @Override public boolean contains(Object o) {\n    for (T view : views) {\n      if (view == o) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/main/java/butterknife/internal/Utils.java",
    "content": "package butterknife.internal;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.drawable.Drawable;\nimport android.util.TypedValue;\nimport android.view.View;\nimport androidx.annotation.AttrRes;\nimport androidx.annotation.DimenRes;\nimport androidx.annotation.DrawableRes;\nimport androidx.annotation.IdRes;\nimport androidx.annotation.UiThread;\nimport androidx.core.content.ContextCompat;\nimport androidx.core.graphics.drawable.DrawableCompat;\nimport java.util.Arrays;\nimport java.util.List;\n\n@SuppressWarnings(\"WeakerAccess\") // Used by generated code.\npublic final class Utils {\n  private static final TypedValue VALUE = new TypedValue();\n\n  @UiThread // Implicit synchronization for use of shared resource VALUE.\n  public static Drawable getTintedDrawable(Context context,\n      @DrawableRes int id, @AttrRes int tintAttrId) {\n    boolean attributeFound = context.getTheme().resolveAttribute(tintAttrId, VALUE, true);\n    if (!attributeFound) {\n      throw new Resources.NotFoundException(\"Required tint color attribute with name \"\n          + context.getResources().getResourceEntryName(tintAttrId)\n          + \" and attribute ID \"\n          + tintAttrId\n          + \" was not found.\");\n    }\n\n    Drawable drawable = ContextCompat.getDrawable(context, id);\n    drawable = DrawableCompat.wrap(drawable.mutate());\n    int color = ContextCompat.getColor(context, VALUE.resourceId);\n    DrawableCompat.setTint(drawable, color);\n    return drawable;\n  }\n\n  @UiThread // Implicit synchronization for use of shared resource VALUE.\n  public static float getFloat(Context context, @DimenRes int id) {\n    TypedValue value = VALUE;\n    context.getResources().getValue(id, value, true);\n    if (value.type == TypedValue.TYPE_FLOAT) {\n      return value.getFloat();\n    }\n    throw new Resources.NotFoundException(\"Resource ID #0x\" + Integer.toHexString(id)\n        + \" type #0x\" + Integer.toHexString(value.type) + \" is not valid\");\n  }\n\n  @SafeVarargs\n  public static <T> T[] arrayFilteringNull(T... views) {\n    int end = 0;\n    int length = views.length;\n    for (int i = 0; i < length; i++) {\n      T view = views[i];\n      if (view != null) {\n        views[end++] = view;\n      }\n    }\n    return end == length\n        ? views\n        : Arrays.copyOf(views, end);\n  }\n\n  @SafeVarargs\n  public static <T> List<T> listFilteringNull(T... views) {\n    return new ImmutableList<>(arrayFilteringNull(views));\n  }\n\n  public static <T> T findOptionalViewAsType(View source, @IdRes int id, String who,\n      Class<T> cls) {\n    View view = source.findViewById(id);\n    return castView(view, id, who, cls);\n  }\n\n  public static View findRequiredView(View source, @IdRes int id, String who) {\n    View view = source.findViewById(id);\n    if (view != null) {\n      return view;\n    }\n    String name = getResourceEntryName(source, id);\n    throw new IllegalStateException(\"Required view '\"\n        + name\n        + \"' with ID \"\n        + id\n        + \" for \"\n        + who\n        + \" was not found. If this view is optional add '@Nullable' (fields) or '@Optional'\"\n        + \" (methods) annotation.\");\n  }\n\n  public static <T> T findRequiredViewAsType(View source, @IdRes int id, String who,\n      Class<T> cls) {\n    View view = findRequiredView(source, id, who);\n    return castView(view, id, who, cls);\n  }\n\n  public static <T> T castView(View view, @IdRes int id, String who, Class<T> cls) {\n    try {\n      return cls.cast(view);\n    } catch (ClassCastException e) {\n      String name = getResourceEntryName(view, id);\n      throw new IllegalStateException(\"View '\"\n          + name\n          + \"' with ID \"\n          + id\n          + \" for \"\n          + who\n          + \" was of the wrong type. See cause for more info.\", e);\n    }\n  }\n\n  public static <T> T castParam(Object value, String from, int fromPos, String to, int toPos,\n      Class<T> cls) {\n    try {\n      return cls.cast(value);\n    } catch (ClassCastException e) {\n      throw new IllegalStateException(\"Parameter #\"\n          + (fromPos + 1)\n          + \" of method '\"\n          + from\n          + \"' was of the wrong type for parameter #\"\n          + (toPos + 1)\n          + \" of method '\"\n          + to\n          + \"'. See cause for more info.\", e);\n    }\n  }\n\n  private static String getResourceEntryName(View view, @IdRes int id) {\n    if (view.isInEditMode()) {\n      return \"<unavailable while editing>\";\n    }\n    return view.getContext().getResources().getResourceEntryName(id);\n  }\n\n  private Utils() {\n    throw new AssertionError(\"No instances.\");\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindAnimTest.java",
    "content": "package butterknife;\n\nimport com.google.testing.compile.JavaFileObjects;\n\nimport org.junit.Test;\n\nimport javax.tools.JavaFileObject;\n\nimport butterknife.compiler.ButterKnifeProcessor;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class BindAnimTest {\n  @Test public void typeMustBeAnimation() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindAnim;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindAnim(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindAnim field type must be 'Animation'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindArrayTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindArrayTest {\n  @Test public void typedArray() throws Exception {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindArray;\\n\"\n        + \"import android.content.res.TypedArray;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindArray(1) TypedArray one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.obtainTypedArray(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void typeMustBeSupported() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindArray;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindArray(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindArray field type must be one of: String[], int[], CharSequence[], \"\n                + \"android.content.res.TypedArray. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindBitmapTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindBitmapTest {\n  @Test public void typeMustBeBitmap() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindBitmap;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindBitmap(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindBitmap field type must be 'Bitmap'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindBoolTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindBoolTest {\n  @Test public void typeMustBeBoolean() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindBool;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindBool(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindBool field type must be 'boolean'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindColorTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindColorTest {\n  @Test public void simpleIntSdk23() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindColor(1) int one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    target.one = context.getColor(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.minSdk=23\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void simpleColorStateListSdk23() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.res.ColorStateList;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindColor(1) ColorStateList one;\\n\"\n        +\"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    target.one = context.getColorStateList(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.minSdk=23\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void typeMustBeIntOrColorStateList() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindColor(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindColor field type must be 'int' or 'ColorStateList'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindDimenTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindDimenTest {\n  @Test public void typeMustBeIntOrFloat() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindDimen;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindDimen(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindDimen field type must be 'int' or 'float'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindDrawableTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindDrawableTest {\n  @Test public void simpleSdk21() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.graphics.drawable.Drawable;\\n\"\n        + \"import butterknife.BindDrawable;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindDrawable(1) Drawable one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    target.one = context.getDrawable(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.minSdk=21\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void withTint() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.graphics.drawable.Drawable;\\n\"\n        + \"import butterknife.BindDrawable;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindDrawable(value = 1, tint = 2) Drawable one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    target.one = Utils.getTintedDrawable(context, 1, 2);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void typeMustBeDrawable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindDrawable;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindDrawable(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindDrawable field type must be 'Drawable'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindFloatTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindFloatTest {\n  @Test public void typeMustBeFloat() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindFloat;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFloat(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindFloat field type must be 'float'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindFontTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class BindFontTest {\n  @Test public void simpleIntSdk26() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.graphics.Typeface;\\n\"\n        + \"import butterknife.BindFont;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFont(1) Typeface one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.getFont(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.minSdk=26\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void styleSdk26() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.graphics.Typeface;\\n\"\n        + \"import butterknife.BindFont;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFont(value = 1, style = Typeface.BOLD) Typeface one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.graphics.Typeface;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = Typeface.create(res.getFont(1), Typeface.BOLD);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.minSdk=26\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void typeMustBeTypeface() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindFont;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFont(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindFont field type must be 'Typeface'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void styleMustBeValid() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.graphics.Typeface;\\n\"\n        + \"import butterknife.BindFont;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFont(value = 1, style = 5) Typeface one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindFont style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC. (test.Test.one)\")\n        .in(source).onLine(5);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindIntTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindIntTest {\n  @Test public void typeMustBeInt() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindInt;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindInt(1) String one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindInt field type must be 'int'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindStringTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic final class BindStringTest {\n  @Test public void typeMustBeString() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindString;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindString(1) boolean one;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindString field type must be 'String'. (test.Test.one)\")\n        .in(source).onLine(4);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindViewTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.common.collect.ImmutableList;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardLocation;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\nimport static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;\nimport static java.util.Arrays.asList;\n\npublic class BindViewTest {\n  @Test public void bindingViewNonDebuggable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = source.findViewById(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.debuggable=false\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingViewSubclassNonDebuggable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) TextView thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = (TextView) source.findViewById(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.debuggable=false\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingGeneratedView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"@PerformGeneration\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) GeneratedView thing;\\n\"\n        + \"}\"\n    );\n\n    // w/o the GeneratingProcessor it can't find `class GeneratedView`\n    assertAbout(javaSources()).that(ImmutableList.of(source, TestGeneratingProcessor.ANNOTATION))\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"cannot find symbol\");\n\n    // now the GeneratingProcessor should let it compile\n    assertAbout(javaSources()).that(ImmutableList.of(source, TestGeneratingProcessor.ANNOTATION))\n        .processedWith(new ButterKnifeProcessor(), new TestGeneratingProcessor(\"GeneratedView\",\n            \"package test;\",\n            \"import android.content.Context;\",\n            \"import android.view.View;\",\n            \"public class GeneratedView extends View {\",\n            \"  public GeneratedView(Context context) {\",\n            \"    super(context);\",\n            \"  }\",\n            \"}\"\n        ))\n        .compilesWithoutError()\n        .withNoteContaining(\"@BindView field with unresolved type (GeneratedView)\").and()\n        .withNoteContaining(\"must elsewhere be generated as a View or interface\").and()\n        .and()\n        .generatesFileNamed(StandardLocation.CLASS_OUTPUT, \"test\", \"Test_ViewBinding.class\");\n  }\n\n  @Test public void bindingViewFinalClass() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public final class Test {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public final class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingViewFinalClassWithBaseClass() {\n    JavaFileObject baseSource = JavaFileObjects.forSourceString(\"test.Base\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Base {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n    JavaFileObject testSource = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public final class Test extends Base {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingBaseSource = JavaFileObjects.forSourceString(\"test/Base_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Base_ViewBinding implements Unbinder {\\n\"\n        + \"  private Base target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Base_ViewBinding(Base target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Base target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingTestSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public final class Test_ViewBinding extends Base_ViewBinding {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(baseSource, testSource))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingBaseSource, bindingTestSource);\n  }\n\n  @Test public void bindingViewUppercasePackageName() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"com.Example.Test\", \"\"\n        + \"package com.Example;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package com.Example;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingInterface() throws Exception {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    interface TestInterface {}\\n\"\n        + \"    @BindView(1) TestInterface thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredViewAsType(source, 1, \\\"field 'thing'\\\", Test.TestInterface.class);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void genericType() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.widget.EditText;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"class Test<T extends TextView> {\\n\"\n        + \"    @BindView(1) T thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredViewAsType(source, 1, \\\"field 'thing'\\\", TextView.class);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        // found raw type: test.Test\n        //   missing type arguments for generic class test.Test<T>\n        .compilesWithoutError()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void oneFindPerId() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View thing1;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"field 'thing1' and method 'doStuff'\\\");\\n\"\n        + \"    target.thing1 = view;\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing1 = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void oneFindPerIdWithCast() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.widget.Button;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) Button thing1;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.Button;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"field 'thing1' and method 'doStuff'\\\");\\n\"\n        + \"    target.thing1 = Utils.castView(view, 1, \\\"field 'thing1'\\\", Button.class);\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing1 = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutError()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void fieldVisibility() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) public View thing1;\\n\"\n        + \"  @BindView(2) View thing2;\\n\"\n        + \"  @BindView(3) protected View thing3;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings();\n  }\n\n  @Test public void nullable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @interface Nullable {}\\n\"\n        + \"  @Nullable @BindView(1) View view;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.view = source.findViewById(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void superclass() {\n    JavaFileObject source1 = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source2 = JavaFileObjects.forSourceString(\"test.TestOne\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class TestOne extends Test {\\n\"\n        + \"  @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source3 = JavaFileObjects.forSourceString(\"test.TestTwo\", \"\"\n        + \"package test;\\n\"\n        + \"public class TestTwo extends Test {\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding1Source = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.view = Utils.findRequiredView(source, 1, \\\"field 'view'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding2Source = JavaFileObjects.forSourceString(\"test/TestOne_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class TestOne_ViewBinding extends Test_ViewBinding {\\n\"\n        + \"  private TestOne target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public TestOne_ViewBinding(TestOne target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    TestOne target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source1, source2, source3))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(binding1Source, binding2Source);\n  }\n\n  @Test public void genericSuperclass() {\n    JavaFileObject source1 = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test<T> {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source2 = JavaFileObjects.forSourceString(\"test.TestOne\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class TestOne extends Test<String> {\\n\"\n        + \"  @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source3 = JavaFileObjects.forSourceString(\"test.TestTwo\", \"\"\n        + \"package test;\\n\"\n        + \"public class TestTwo extends Test<Object> {\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding1Source = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.view = Utils.findRequiredView(source, 1, \\\"field 'view'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding2Source = JavaFileObjects.forSourceString(\"test/TestOne_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class TestOne_ViewBinding extends Test_ViewBinding {\\n\"\n        + \"  private TestOne target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public TestOne_ViewBinding(TestOne target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.findRequiredView(source, 1, \\\"field 'thing'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    TestOne target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source1, source2, source3))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        // found raw type: test.Test\n        //   missing type arguments for generic class test.Test<T>\n        .compilesWithoutError()\n        .and()\n        .generatesSources(binding1Source, binding2Source);\n  }\n\n  @Test public void failsInJavaPackage() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package java.test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindView-annotated class incorrectly in Java framework package. (java.test.Test)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsInAndroidPackage() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package android.test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindView-annotated class incorrectly in Android framework package. (android.test.Test)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfInPrivateClass() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  private static class Inner {\\n\"\n        + \"    @BindView(1) View thing;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindView fields may not be contained in private classes. (test.Test.Inner.thing)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfNotView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) String thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindView fields must extend from View or be an interface. (test.Test.thing)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsIfInInterface() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public interface Test {\\n\"\n        + \"    @BindView(1) View thing = null;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindView fields may only be contained in classes. (test.Test.thing)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsIfPrivate() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) private View thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindView fields must not be private or static. (test.Test.thing)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfStatic() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) static View thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindView fields must not be private or static. (test.Test.thing)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void duplicateBindingFails() throws Exception {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindView(1) View thing1;\\n\"\n        + \"    @BindView(1) View thing2;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"Attempt to use @BindView for an already bound ID 1 on 'thing1'. (test.Test.thing2)\")\n        .in(source).onLine(6);\n  }\n\n  @Test public void failsOptionalRootViewBinding() throws Exception {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"import butterknife.Optional;\\n\"\n        + \"public class Test extends View {\\n\"\n        + \"  @Optional @OnClick void doStuff() {}\\n\"\n        + \"  public Test(Context context) {\\n\"\n        + \"    super(context);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource())\n        .that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"ID-free binding must not be annotated with @Optional. (test.Test.doStuff)\")\n        .in(source)\n        .onLine(7);\n  }\n\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/BindViewsTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardLocation;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\nimport static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;\n\npublic class BindViewsTest {\n  @Test public void bindingArrayWithGenerics() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test<T extends View> {\\n\"\n        + \"    @BindViews({1, 2, 3}) T[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        Utils.findRequiredView(source, 1, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, 2, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, 3, \\\"field 'thing'\\\"));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        // found raw type: test.Test\n        //   missing type arguments for generic class test.Test<T>\n        .compilesWithoutError()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingArrayWithCast() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({1, 2, 3}) TextView[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        Utils.findRequiredViewAsType(source, 1, \\\"field 'thing'\\\", TextView.class), \\n\"\n        + \"        Utils.findRequiredViewAsType(source, 2, \\\"field 'thing'\\\", TextView.class), \\n\"\n        + \"        Utils.findRequiredViewAsType(source, 3, \\\"field 'thing'\\\", TextView.class));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingArrayNonDebuggable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({1, 2, 3}) View[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        source.findViewById(1), \\n\"\n        + \"        source.findViewById(2), \\n\"\n        + \"        source.findViewById(3));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.debuggable=false\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingArrayWithCastNonDebuggable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({1, 2, 3}) TextView[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        (TextView) source.findViewById(1), \\n\"\n        + \"        (TextView) source.findViewById(2), \\n\"\n        + \"        (TextView) source.findViewById(3));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.debuggable=false\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingGeneratedView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"@PerformGeneration\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({1, 2}) List<GeneratedView> things;\\n\"\n        + \"}\"\n    );\n\n    // w/o the GeneratingProcessor it can't find `class GeneratedView`\n    assertAbout(javaSources()).that(ImmutableList.of(source, TestGeneratingProcessor.ANNOTATION))\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"cannot find symbol\");\n\n    // now the GeneratingProcessor should let it compile\n    assertAbout(javaSources()).that(ImmutableList.of(source, TestGeneratingProcessor.ANNOTATION))\n        .processedWith(new ButterKnifeProcessor(), new TestGeneratingProcessor(\"GeneratedView\",\n            \"package test;\",\n            \"import android.content.Context;\",\n            \"import android.view.View;\",\n            \"public class GeneratedView extends View {\",\n            \"  public GeneratedView(Context context) {\",\n            \"    super(context);\",\n            \"  }\",\n            \"}\"\n        ))\n        .compilesWithoutError()\n        .withNoteContaining(\"@BindViews List or array with unresolved type (GeneratedView)\").and()\n        .withNoteContaining(\"must elsewhere be generated as a View or interface\").and()\n        .and()\n        .generatesFileNamed(StandardLocation.CLASS_OUTPUT, \"test\", \"Test_ViewBinding.class\");\n  }\n\n  @Test public void bindingListOfInterface() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"    interface TestInterface {}\\n\"\n        + \"    @BindViews({1, 2, 3}) List<TestInterface> thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.listFilteringNull(\\n\"\n        + \"        Utils.findRequiredViewAsType(source, 1, \\\"field 'thing'\\\", Test.TestInterface.class), \\n\"\n        + \"        Utils.findRequiredViewAsType(source, 2, \\\"field 'thing'\\\", Test.TestInterface.class), \\n\"\n        + \"        Utils.findRequiredViewAsType(source, 3, \\\"field 'thing'\\\", Test.TestInterface.class));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingListWithGenerics() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test<T extends View> {\\n\"\n        + \"    @BindViews({1, 2, 3}) List<T> thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.listFilteringNull(\\n\"\n        + \"        Utils.findRequiredView(source, 1, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, 2, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, 3, \\\"field 'thing'\\\"));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        // found raw type: test.Test\n        //   missing type arguments for generic class test.Test<T>\n        .compilesWithoutError()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void nullableList() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @interface Nullable {}\\n\"\n        + \"    @Nullable @BindViews({1, 2, 3}) List<View> thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.listFilteringNull(\\n\"\n        + \"        source.findViewById(1), \\n\"\n        + \"        source.findViewById(2), \\n\"\n        + \"        source.findViewById(3));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources( bindingSource);\n  }\n\n  @Test public void failsIfNoIds() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindViews({}) List<View> thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindViews must specify at least one ID. (test.Test.thing)\")\n        .in(source).onLine(6);\n  }\n\n  @Test public void failsIfNoGenericType() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindViews(1) List thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindViews List must have a generic component. (test.Test.thing)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfUnsupportedCollection() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.Deque;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindViews(1) Deque<View> thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindViews must be a List or array. (test.Test.thing)\")\n        .in(source).onLine(6);\n  }\n\n  @Test public void failsIfGenericNotView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindViews(1) List<String> thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindViews List or array type must extend from View or be an interface. (test.Test.thing)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfArrayNotView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindViews(1) String[] thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@BindViews List or array type must extend from View or be an interface. (test.Test.thing)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsIfContainsDuplicateIds() throws Exception {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"import java.util.List;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({1, 1}) List<View> thing;\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@BindViews annotation contains duplicate ID 1. (test.Test.thing)\")\n        .in(source).onLine(6);\n  }\n\n  @Test public void bindingArrayWithRScanner() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.R;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({R.color.black, R.color.white}) View[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        Utils.findRequiredView(source, android.R.color.black, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, android.R.color.white, \\\"field 'thing'\\\"));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void bindingArrayWithMixedRAndLiteral() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.R;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindViews;\\n\"\n        + \"public class Test {\\n\"\n        + \"    @BindViews({R.color.black, 2, R.color.white}) View[] thing;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.thing = Utils.arrayFilteringNull(\\n\"\n        + \"        Utils.findRequiredView(source, android.R.color.black, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, 2, \\\"field 'thing'\\\"), \\n\"\n        + \"        Utils.findRequiredView(source, android.R.color.white, \\\"field 'thing'\\\"));\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.thing = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/ClasspathParentBindTest.java",
    "content": "package butterknife;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.testing.compile.JavaFileObjects;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.Arrays;\nimport java.util.Locale;\n\nimport javax.tools.JavaCompiler;\nimport javax.tools.JavaFileObject;\nimport javax.tools.StandardJavaFileManager;\nimport javax.tools.ToolProvider;\n\nimport butterknife.compiler.ButterKnifeProcessor;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\nimport static java.nio.charset.StandardCharsets.UTF_8;\n\n/** Tests binding generation when superclasses are from classpath.  */\npublic class ClasspathParentBindTest {\n  @Rule\n  public TemporaryFolder tmp = new TemporaryFolder();\n\n  @Test\n  public void parentBindingInClasspath() throws IOException {\n    JavaFileObject baseClassSource = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"import butterknife.OnLongClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"  @BindView(2) View view2;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"  @OnLongClick(1) boolean doMoreStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject subClassSource = JavaFileObjects.forSourceString(\"test.SubClass\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class SubClass extends Test {\\n\"\n        + \"  @BindView(3) View view3;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/SubClass_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class SubClass_ViewBinding extends Test_ViewBinding {\\n\"\n        + \"  private SubClass target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public SubClass_ViewBinding(SubClass target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.view3 = Utils.findRequiredView(source, 3, \\\"field 'view3'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    SubClass target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view3 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    File classesOut = tmp.newFolder(\"classes-output\");\n    File sourcesOut = tmp.newFolder(\"sources-output\");\n    compileSources(classesOut, sourcesOut, baseClassSource);\n\n    try (URLClassLoader compilationClasspath = new URLClassLoader(\n        new URL[]{classesOut.toURI().toURL()}, this.getClass().getClassLoader())) {\n      assertAbout(javaSource()).that(subClassSource)\n          .withCompilerOptions(\"-Xlint:-processing\")\n          .withClasspathFrom(compilationClasspath)\n          .processedWith(new ButterKnifeProcessor())\n          .compilesWithoutWarnings()\n          .and()\n          .generatesSources(bindingSource);\n    }\n  }\n\n  @Test\n  public void indirectViewRequiredInConstructor() throws IOException {\n    JavaFileObject classpathClass = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"import butterknife.OnLongClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"  @BindView(2) View view2;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"  @OnLongClick(1) boolean doMoreStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject subclassInClasspath = JavaFileObjects.forSourceString(\"test.SubClassTest\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindFloat;\\n\"\n        + \"public class SubClassTest extends Test{\\n\"\n        + \"  @BindFloat(1) float value;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject toProcessSource = JavaFileObjects.forSourceString(\"test.ToProcess\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class ToProcess extends SubClassTest {\\n\"\n        + \"  @BindView(3) View view3;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/ToProcess_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class ToProcess_ViewBinding extends SubClassTest_ViewBinding {\\n\"\n        + \"  private ToProcess target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public ToProcess_ViewBinding(ToProcess target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.view3 = Utils.findRequiredView(source, 3, \\\"field 'view3'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    ToProcess target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view3 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    File classesOut = tmp.newFolder(\"classes-output\");\n    File sourcesOut = tmp.newFolder(\"sources-output\");\n    compileSources(classesOut, sourcesOut, classpathClass, subclassInClasspath);\n\n    try (URLClassLoader compilationClasspath = new URLClassLoader(\n        new URL[]{classesOut.toURI().toURL()}, this.getClass().getClassLoader())) {\n      assertAbout(javaSource()).that(toProcessSource)\n          .withCompilerOptions(\"-Xlint:-processing\")\n          .withClasspathFrom(compilationClasspath)\n          .processedWith(new ButterKnifeProcessor())\n          .compilesWithoutWarnings()\n          .and()\n          .generatesSources(bindingSource);\n    }\n  }\n\n  @Test\n  public void viewNotRequiredInConstructor() throws IOException {\n    JavaFileObject baseClass = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindFloat;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindFloat(1) float one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject subClassSource = JavaFileObjects.forSourceString(\"test.SubClass\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindFloat;\\n\"\n        + \"public class SubClass extends Test {\\n\"\n        + \"  @BindFloat(2) float two;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/SubClass_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class SubClass_ViewBinding extends Test_ViewBinding {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #SubClass_ViewBinding(SubClass, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public SubClass_ViewBinding(SubClass target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public SubClass_ViewBinding(SubClass target, Context context) {\\n\"\n        + \"    super(target, context);\\n\"\n        + \"    target.two = Utils.getFloat(context, 2);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    File classesOut = tmp.newFolder(\"classes-output\");\n    File sourcesOut = tmp.newFolder(\"sources-output\");\n    compileSources(classesOut, sourcesOut, baseClass);\n\n    try (URLClassLoader compilationClasspath = new URLClassLoader(\n        new URL[]{classesOut.toURI().toURL()}, this.getClass().getClassLoader())) {\n      assertAbout(javaSource()).that(subClassSource)\n          .withCompilerOptions(\"-Xlint:-processing\")\n          .withClasspathFrom(compilationClasspath)\n          .processedWith(new ButterKnifeProcessor())\n          .compilesWithoutWarnings()\n          .and()\n          .generatesSources(bindingSource);\n    }\n  }\n\n  private void compileSources(File classesOut, File sourcesOut, JavaFileObject... sources) {\n    JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();\n    try {\n      try (StandardJavaFileManager fileManager =\n               javaCompiler.getStandardFileManager(null, Locale.getDefault(), UTF_8)) {\n        JavaCompiler.CompilationTask javaCompilerTask = javaCompiler.getTask(null,\n            fileManager,\n            null,\n            ImmutableList.of(\"-d\", classesOut.getCanonicalPath(), \"-s\", sourcesOut.getCanonicalPath()),\n            ImmutableList.of(),\n            Arrays.asList(sources));\n        javaCompilerTask.setProcessors(ImmutableList.of(new ButterKnifeProcessor()));\n        javaCompilerTask.call();\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/ExtendActivityTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class ExtendActivityTest {\n  @Test public void onlyResources() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.app.Activity;\"\n        + \"import android.content.Context;\"\n        + \"import butterknife.BindBool;\"\n        + \"public class Test extends Activity {\"\n        + \"  @BindBool(1) boolean one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target);\\n\"\n        + \"  }\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.getBoolean(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void views() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.app.Activity;\"\n        + \"import android.content.Context;\"\n        + \"import android.view.View;\"\n        + \"import butterknife.BindView;\"\n        + \"public class Test extends Activity {\"\n        + \"  @BindView(1) View one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target.getWindow().getDecorView());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.one = Utils.findRequiredView(source, 1, \\\"field 'one'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.one = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/ExtendDialogTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class ExtendDialogTest {\n  @Test public void onlyResources() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.app.Dialog;\"\n        + \"import android.content.Context;\"\n        + \"import butterknife.BindBool;\"\n        + \"public class Test extends Dialog {\"\n        + \"  Test(Context context) {\"\n        + \"    super(context);\"\n        + \"  }\"\n        + \"  @BindBool(1) boolean one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.getBoolean(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void views() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.app.Dialog;\"\n        + \"import android.content.Context;\"\n        + \"import android.view.View;\"\n        + \"import butterknife.BindView;\"\n        + \"public class Test extends Dialog {\"\n        + \"  Test(Context context) {\"\n        + \"    super(context);\"\n        + \"  }\"\n        + \"  @BindView(1) View one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target.getWindow().getDecorView());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.one = Utils.findRequiredView(source, 1, \\\"field 'one'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.one = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/ExtendViewTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class ExtendViewTest {\n  @Test public void onlyResources() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.content.Context;\"\n        + \"import android.view.View;\"\n        + \"import butterknife.BindBool;\"\n        + \"public class Test extends View {\"\n        + \"  Test(Context context) {\"\n        + \"    super(context);\"\n        + \"  }\"\n        + \"  @BindBool(1) boolean one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"import java.lang.SuppressWarnings;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressWarnings(\\\"ResourceType\\\")\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.getBoolean(1);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void views() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import android.content.Context;\"\n        + \"import android.view.View;\"\n        + \"import butterknife.BindView;\"\n        + \"public class Test extends View {\"\n        + \"  Test(Context context) {\"\n        + \"    super(context);\"\n        + \"  }\"\n        + \"  @BindView(1) View one;\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target);\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.one = Utils.findRequiredView(source, 1, \\\"field 'one'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.one = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnClickTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnClickTest {\n  @Test public void findOnlyCalledOnce() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"field 'view' and method 'doStuff'\\\");\\n\"\n        + \"    target.view = view;\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void methodCastsArgumentNonDebuggable() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.Button;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  interface TestInterface {}\\n\"\n        + \"  @OnClick(0) void click0() {}\\n\"\n        + \"  @OnClick(1) void click1(View view) {}\\n\"\n        + \"  @OnClick(2) void click2(TextView view) {}\\n\"\n        + \"  @OnClick(3) void click3(Button button) {}\\n\"\n        + \"  @OnClick(4) void click4(TestInterface thing) {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.Button;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view0;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  private View view2;\\n\"\n        + \"  private View view3;\\n\"\n        + \"  private View view4;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = source.findViewById(0);\\n\"\n        + \"    view0 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.click0();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = source.findViewById(1);\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.click1(p0);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = source.findViewById(2);\\n\"\n        + \"    view2 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.click2((TextView) p0);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = source.findViewById(3);\\n\"\n        + \"    view3 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.click3((Button) p0);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = source.findViewById(4);\\n\"\n        + \"    view4 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.click4((Test.TestInterface) p0);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view0.setOnClickListener(null);\\n\"\n        + \"    view0 = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"    view2.setOnClickListener(null);\\n\"\n        + \"    view2 = null;\\n\"\n        + \"    view3.setOnClickListener(null);\\n\"\n        + \"    view3 = null;\\n\"\n        + \"    view4.setOnClickListener(null);\\n\"\n        + \"    view4 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\", \"-Abutterknife.debuggable=false\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void optionalAndRequiredSkipsNullCheck() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"import butterknife.Optional;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"  @Optional @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"field 'view'\\\");\\n\"\n        + \"    target.view = view;\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void failsInJavaPackage() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package java.test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@OnClick-annotated class incorrectly in Java framework package. (java.test.Test)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsInAndroidPackage() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package android.test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@OnClick-annotated class incorrectly in Android framework package. (android.test.Test)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsIfHasReturnType() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  public String doStuff() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@OnClick methods must have a 'void' return type. (test.Test.doStuff)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfPrivateMethod() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  private void doStuff() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@OnClick methods must not be private or static. (test.Test.doStuff)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfStatic() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  public static void doStuff() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@OnClick methods must not be private or static. (test.Test.doStuff)\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfParameterNotView() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  public void doStuff(String thing) {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"\"\n            + \"Unable to match @OnClick method arguments. (test.Test.doStuff)\\n\"\n            + \"  \\n\"\n            + \"    Parameter #1: java.lang.String\\n\"\n            + \"      did not match any listener parameters\\n\"\n            + \"  \\n\"\n            + \"  Methods may have up to 1 parameter(s):\\n\"\n            + \"  \\n\"\n            + \"    android.view.View\\n\"\n            + \"  \\n\"\n            + \"  These may be listed in any order but will be searched for from top to bottom.\")\n        .in(source).onLine(5);\n  }\n\n  @Test public void failsIfMoreThanOneParameter() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  public void doStuff(View thing, View otherThing) {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@OnClick methods can have at most 1 parameter(s). (test.Test.doStuff)\")\n        .in(source).onLine(6);\n  }\n\n  @Test public void failsIfInInterface() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public interface Test {\\n\"\n        + \"  @OnClick(1)\\n\"\n        + \"  void doStuff();\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@OnClick methods may only be contained in classes. (test.Test.doStuff)\")\n        .in(source).onLine(3);\n  }\n\n  @Test public void failsIfHasDuplicateIds() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick({1, 2, 3, 1})\\n\"\n        + \"  void doStuff() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"@OnClick annotation for method contains duplicate ID 1. (test.Test.doStuff)\")\n        .in(source).onLine(5);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnEditorActionTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnEditorActionTest {\n  @Test public void editorAction() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnEditorAction;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnEditorAction(1) boolean doStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.KeyEvent;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((TextView) view).setOnEditorActionListener(new TextView.OnEditorActionListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onEditorAction(TextView p0, int p1, KeyEvent p2) {\\n\"\n        + \"        return target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((TextView) view1).setOnEditorActionListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void defaultReturnValue() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnEditorAction;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnEditorAction(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.KeyEvent;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((TextView) view).setOnEditorActionListener(new TextView.OnEditorActionListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onEditorAction(TextView p0, int p1, KeyEvent p2) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"        return true;\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((TextView) view1).setOnEditorActionListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnFocusChangeTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnFocusChangeTest {\n  @Test public void focusChange() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnFocusChange;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnFocusChange(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnFocusChangeListener(new View.OnFocusChangeListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onFocusChange(View p0, boolean p1) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view1.setOnFocusChangeListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnItemClickTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\n/** This augments {@link OnClickTest} with tests that exercise callbacks with parameters. */\npublic class OnItemClickTest {\n  @Test public void onItemClickBinding() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import butterknife.OnItemClick;\"\n        + \"public class Test {\"\n        + \"  @OnItemClick(1) void doStuff() {}\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void onItemClickBindingWithParameters() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemClick(1) void doStuff(\\n\"\n        + \"    AdapterView<?> parent,\\n\"\n        + \"    View view,\\n\"\n        + \"    int position,\\n\"\n        + \"    long id\\n\"\n        + \"  ) {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff(p0, p1, p2, p3);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void onItemClickBindingWithParameterSubset() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.ListView;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemClick(1) void doStuff(\\n\"\n        + \"    ListView parent,\\n\"\n        + \"    int position\\n\"\n        + \"  ) {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import android.widget.ListView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff(Utils.castParam(p0, \\\"onItemClick\\\", 0, \\\"doStuff\\\", 0, ListView.class), p2);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void onItemClickBindingWithParameterSubsetAndGenerics() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.ListView;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test<T extends ListView> {\\n\"\n        + \"  @OnItemClick(1) void doStuff(\\n\"\n        + \"    T parent,\\n\"\n        + \"    int position\\n\"\n        + \"  ) {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import android.widget.ListView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff(Utils.castParam(p0, \\\"onItemClick\\\", 0, \\\"doStuff\\\", 0, ListView.class)\\n\"\n        + \"        , p2);\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        // found raw type: test.Test\n        //   missing type arguments for generic class test.Test<T>\n        .compilesWithoutError()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void onClickRootViewBinding() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.widget.ListView;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test extends ListView {\\n\"\n        + \"  @OnItemClick void doStuff() {}\\n\"\n        + \"  public Test(Context context) {\\n\"\n        + \"    super(context);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View viewSource;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target);\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    viewSource = source;\\n\"\n        + \"    ((AdapterView<?>) source).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) viewSource).setOnItemClickListener(null);\\n\"\n        + \"    viewSource = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void onClickRootViewAnyTypeBinding() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemClick void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View viewSource;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    viewSource = source;\\n\"\n        + \"    ((AdapterView<?>) source).setOnItemClickListener(new AdapterView.OnItemClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) viewSource).setOnItemClickListener(null);\\n\"\n        + \"    viewSource = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void failsWithInvalidId() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemClick({1, -1}) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"@OnItemClick annotation contains invalid ID -1. (test.Test.doStuff)\")\n        .in(source).onLine(4);\n  }\n\n  @Test public void failsWithInvalidParameterConfiguration() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import butterknife.OnItemClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemClick(1) void doStuff(\\n\"\n        + \"    AdapterView<?> parent,\\n\"\n        + \"    View view,\\n\"\n        + \"    View whatIsThis\\n\"\n        + \"  ) {}\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\"\"\n            + \"Unable to match @OnItemClick method arguments. (test.Test.doStuff)\\n\"\n            + \"  \\n\"\n            + \"    Parameter #1: android.widget.AdapterView<?>\\n\"\n            + \"      matched listener parameter #1: android.widget.AdapterView<?>\\n\"\n            + \"  \\n\"\n            + \"    Parameter #2: android.view.View\\n\"\n            + \"      matched listener parameter #2: android.view.View\\n\"\n            + \"  \\n\"\n            + \"    Parameter #3: android.view.View\\n\"\n            + \"      did not match any listener parameters\\n\"\n            + \"  \\n\"\n            + \"  Methods may have up to 4 parameter(s):\\n\"\n            + \"  \\n\"\n            + \"    android.widget.AdapterView<?>\\n\"\n            + \"    android.view.View\\n\"\n            + \"    int\\n\"\n            + \"    long\\n\"\n            + \"  \\n\"\n            + \"  These may be listed in any order but will be searched for from top to bottom.\")\n        .in(source).onLine(6);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnItemLongClickTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnItemLongClickTest {\n  @Test public void itemLongClick() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnItemLongClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemLongClick(1) boolean doStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onItemLongClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        return target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemLongClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void defaultReturnValue() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnItemLongClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemLongClick(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onItemLongClick(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"        return true;\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemLongClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnItemSelectedTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\n/** This augments {@link OnClickTest} with tests that exercise callbacks with multiple methods. */\npublic class OnItemSelectedTest {\n  @Test public void defaultMethod() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnItemSelected;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnItemSelected(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemSelectedListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void nonDefaultMethod() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import butterknife.OnItemSelected;\"\n        + \"import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;\"\n        + \"public class Test {\"\n        + \"  @OnItemSelected(value = 1, callback = NOTHING_SELECTED)\"\n        + \"  void doStuff() {}\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemSelectedListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void allMethods() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import butterknife.OnItemSelected;\"\n        + \"import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;\"\n        + \"public class Test {\"\n        + \"  @OnItemSelected(1)\"\n        + \"  void onItemSelected() {}\"\n        + \"  @OnItemSelected(value = 1, callback = NOTHING_SELECTED)\"\n        + \"  void onNothingSelected() {}\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'onItemSelected' and method 'onNothingSelected'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.onItemSelected();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"        target.onNothingSelected();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemSelectedListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void multipleBindingPermutation() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\"\n        + \"import butterknife.OnItemSelected;\"\n        + \"import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;\"\n        + \"public class Test {\"\n        + \"  @OnItemSelected({ 1, 2 })\"\n        + \"  void onItemSelected() {}\"\n        + \"  @OnItemSelected(value = { 1, 3 }, callback = NOTHING_SELECTED)\"\n        + \"  void onNothingSelected() {}\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.AdapterView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  private View view2;\\n\"\n        + \"  private View view3;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'onItemSelected' and method 'onNothingSelected'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.onItemSelected();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"        target.onNothingSelected();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = Utils.findRequiredView(source, 2, \\\"method 'onItemSelected'\\\");\\n\"\n        + \"    view2 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"        target.onItemSelected();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view = Utils.findRequiredView(source, 3, \\\"method 'onNothingSelected'\\\");\\n\"\n        + \"    view3 = view;\\n\"\n        + \"    ((AdapterView<?>) view).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onItemSelected(AdapterView<?> p0, View p1, int p2, long p3) {\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onNothingSelected(AdapterView<?> p0) {\\n\"\n        + \"        target.onNothingSelected();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((AdapterView<?>) view1).setOnItemSelectedListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"    ((AdapterView<?>) view2).setOnItemSelectedListener(null);\\n\"\n        + \"    view2 = null;\\n\"\n        + \"    ((AdapterView<?>) view3).setOnItemSelectedListener(null);\\n\"\n        + \"    view3 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnPageChangeTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static butterknife.TestStubs.ANDROIDX_VIEW_PAGER;\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;\nimport static java.util.Arrays.asList;\n\npublic class OnPageChangeTest {\n  @Test public void pageChange() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnPageChange;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnPageChange(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.viewpager.widget.ViewPager;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  private ViewPager.OnPageChangeListener view1OnPageChangeListener;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view1OnPageChangeListener = new ViewPager.OnPageChangeListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onPageSelected(int p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onPageScrolled(int p0, float p1, int p2) {\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onPageScrollStateChanged(int p0) {\\n\"\n        + \"      }\\n\"\n        + \"    };\\n\"\n        + \"    ((ViewPager) view).addOnPageChangeListener(view1OnPageChangeListener);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((ViewPager) view1).removeOnPageChangeListener(view1OnPageChangeListener);\\n\"\n        + \"    view1OnPageChangeListener = null;\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources())\n        .that(asList(source, ANDROIDX_VIEW_PAGER))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnTextChangedTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnTextChangedTest {\n  @Test public void textChanged() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnTextChanged;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnTextChanged(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.text.Editable;\\n\"\n        + \"import android.text.TextWatcher;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.widget.TextView;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.CharSequence;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  private TextWatcher view1TextWatcher;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view1TextWatcher = new TextWatcher() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void onTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void beforeTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n        + \"      }\\n\"\n        + \"      @Override\\n\"\n        + \"      public void afterTextChanged(Editable p0) {\\n\"\n        + \"      }\\n\"\n        + \"    };\\n\"\n        + \"    ((TextView) view).addTextChangedListener(view1TextWatcher);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    ((TextView) view1).removeTextChangedListener(view1TextWatcher);\\n\"\n        + \"    view1TextWatcher = null;\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void textChangedWithParameter() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n            + \"package test;\\n\"\n            + \"import butterknife.OnTextChanged;\\n\"\n            + \"public class Test {\\n\"\n            + \"  @OnTextChanged(1) void doStuff(CharSequence p0) {}\\n\"\n            + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n            + \"package test;\\n\"\n            + \"import android.text.Editable;\\n\"\n            + \"import android.text.TextWatcher;\\n\"\n            + \"import android.view.View;\\n\"\n            + \"import android.widget.TextView;\\n\"\n            + \"import androidx.annotation.CallSuper;\\n\"\n            + \"import androidx.annotation.UiThread;\\n\"\n            + \"import butterknife.Unbinder;\\n\"\n            + \"import butterknife.internal.Utils;\\n\"\n            + \"import java.lang.CharSequence;\\n\"\n            + \"import java.lang.IllegalStateException;\\n\"\n            + \"import java.lang.Override;\\n\"\n            + \"public class Test_ViewBinding implements Unbinder {\\n\"\n            + \"  private Test target;\\n\"\n            + \"  private View view1;\\n\"\n            + \"  private TextWatcher view1TextWatcher;\\n\"\n            + \"  @UiThread\\n\"\n            + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n            + \"    this.target = target;\\n\"\n            + \"    View view;\\n\"\n            + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n            + \"    view1 = view;\\n\"\n            + \"    view1TextWatcher = new TextWatcher() {\\n\"\n            + \"      @Override\\n\"\n            + \"      public void onTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n            + \"        target.doStuff(p0);\\n\"\n            + \"      }\\n\"\n            + \"      @Override\\n\"\n            + \"      public void beforeTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n            + \"      }\\n\"\n            + \"      @Override\\n\"\n            + \"      public void afterTextChanged(Editable p0) {\\n\"\n            + \"      }\\n\"\n            + \"    };\\n\"\n            + \"    ((TextView) view).addTextChangedListener(view1TextWatcher);\\n\"\n            + \"  }\\n\"\n            + \"  @Override\\n\"\n            + \"  @CallSuper\\n\"\n            + \"  public void unbind() {\\n\"\n            + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n            + \"    target = null;\\n\"\n            + \"    ((TextView) view1).removeTextChangedListener(view1TextWatcher);\\n\"\n            + \"    view1TextWatcher = null;\\n\"\n            + \"    view1 = null;\\n\"\n            + \"  }\\n\"\n            + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n            .withCompilerOptions(\"-Xlint:-processing\")\n            .processedWith(new ButterKnifeProcessor())\n            .compilesWithoutWarnings()\n            .and()\n            .generatesSources(bindingSource);\n  }\n\n  @Test public void textChangedWithParameters() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n            + \"package test;\\n\"\n            + \"import butterknife.OnTextChanged;\\n\"\n            + \"public class Test {\\n\"\n            + \"  @OnTextChanged(1) void doStuff(CharSequence p0, int p1, int p2, int p3) {}\\n\"\n            + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n            + \"package test;\\n\"\n            + \"import android.text.Editable;\\n\"\n            + \"import android.text.TextWatcher;\\n\"\n            + \"import android.view.View;\\n\"\n            + \"import android.widget.TextView;\\n\"\n            + \"import androidx.annotation.CallSuper;\\n\"\n            + \"import androidx.annotation.UiThread;\\n\"\n            + \"import butterknife.Unbinder;\\n\"\n            + \"import butterknife.internal.Utils;\\n\"\n            + \"import java.lang.CharSequence;\\n\"\n            + \"import java.lang.IllegalStateException;\\n\"\n            + \"import java.lang.Override;\\n\"\n            + \"public class Test_ViewBinding implements Unbinder {\\n\"\n            + \"  private Test target;\\n\"\n            + \"  private View view1;\\n\"\n            + \"  private TextWatcher view1TextWatcher;\\n\"\n            + \"  @UiThread\\n\"\n            + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n            + \"    this.target = target;\\n\"\n            + \"    View view;\\n\"\n            + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n            + \"    view1 = view;\\n\"\n            + \"    view1TextWatcher = new TextWatcher() {\\n\"\n            + \"      @Override\\n\"\n            + \"      public void onTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n            + \"        target.doStuff(p0, p1, p2, p3);\\n\"\n            + \"      }\\n\"\n            + \"      @Override\\n\"\n            + \"      public void beforeTextChanged(CharSequence p0, int p1, int p2, int p3) {\\n\"\n            + \"      }\\n\"\n            + \"      @Override\\n\"\n            + \"      public void afterTextChanged(Editable p0) {\\n\"\n            + \"      }\\n\"\n            + \"    };\\n\"\n            + \"    ((TextView) view).addTextChangedListener(view1TextWatcher);\\n\"\n            + \"  }\\n\"\n            + \"  @Override\\n\"\n            + \"  @CallSuper\\n\"\n            + \"  public void unbind() {\\n\"\n            + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n            + \"    target = null;\\n\"\n            + \"    ((TextView) view1).removeTextChangedListener(view1TextWatcher);\\n\"\n            + \"    view1TextWatcher = null;\\n\"\n            + \"    view1 = null;\\n\"\n            + \"  }\\n\"\n            + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n            .withCompilerOptions(\"-Xlint:-processing\")\n            .processedWith(new ButterKnifeProcessor())\n            .compilesWithoutWarnings()\n            .and()\n            .generatesSources(bindingSource);\n  }\n\n  @Test public void textChangedWithWrongParameter() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n            + \"package test;\\n\"\n            + \"import butterknife.OnTextChanged;\\n\"\n            + \"public class Test {\\n\"\n            + \"  @OnTextChanged(1) void doStuff(String p0, int p1, int p2, int p3) {}\\n\"\n            + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n            .withCompilerOptions(\"-Xlint:-processing\")\n            .processedWith(new ButterKnifeProcessor())\n            .failsToCompile();\n  }\n\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/OnTouchTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\n\npublic class OnTouchTest {\n  @Test public void touch() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnTouch;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnTouch(1) boolean doStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.annotation.SuppressLint;\\n\"\n        + \"import android.view.MotionEvent;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressLint(\\\"ClickableViewAccessibility\\\")\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnTouchListener(new View.OnTouchListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onTouch(View p0, MotionEvent p1) {\\n\"\n        + \"        return target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view1.setOnTouchListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void defaultReturnValue() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnTouch;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnTouch(1) void doStuff() {}\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.annotation.SuppressLint;\\n\"\n        + \"import android.view.MotionEvent;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  @SuppressLint(\\\"ClickableViewAccessibility\\\")\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnTouchListener(new View.OnTouchListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onTouch(View p0, MotionEvent p1) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"        return true;\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view1.setOnTouchListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void failsMultipleListenersWithReturnValue() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnTouch;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnTouch(1) boolean doStuff1() {}\\n\"\n        + \"  @OnTouch(1) boolean doStuff2() {}\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .processedWith(new ButterKnifeProcessor())\n        .failsToCompile()\n        .withErrorContaining(\n            \"Multiple listener methods with return value specified for ID 1. (test.Test.doStuff2)\")\n        .in(source).onLine(5);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/RClassTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;\nimport static java.util.Arrays.asList;\n\npublic class RClassTest {\n\n  private static final JavaFileObject NON_FINAL_R = JavaFileObjects.forSourceString(\"test.R\", \"\"\n      + \"package test;\\n\"\n      + \"public final class R {\\n\"\n      + \"  public static final class array {\\n\"\n      + \"    public static int res = 0x7f040001;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class bool {\\n\"\n      + \"    public static int res = 0x7f040002;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class color {\\n\"\n      + \"    public static int res = 0x7f040003;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class integer {\\n\"\n      + \"    public static int res = 0x7f040004;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class styleable {\\n\"\n      + \"    public static int[] ActionBar = { 0x7f010001, 0x7f010003 };\\n\"\n      + \"  }\\n\"\n      + \"}\"\n  );\n\n  private static final JavaFileObject FINAL_R = JavaFileObjects.forSourceString(\"test.R\", \"\"\n      + \"package test;\\n\"\n      + \"public final class R {\\n\"\n      + \"  public static final class array {\\n\"\n      + \"    public static final int res = 0x7f040001;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class bool {\\n\"\n      + \"    public static final int res = 0x7f040002;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class color {\\n\"\n      + \"    public static final int res = 0x7f040003;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class integer {\\n\"\n      + \"    public static final int res = 0x7f040004;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class string {\\n\"\n      + \"    public static final int res = 0x7f040005;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class styleable {\\n\"\n      + \"    public static final int[] ActionBar = { 0x7f010001, 0x7f010003 };\\n\"\n      + \"  }\\n\"\n      + \"}\"\n  );\n\n  private static final JavaFileObject R2 = JavaFileObjects.forSourceString(\"test.R2\", \"\"\n      + \"package test;\\n\"\n      + \"public final class R2 {\\n\"\n      + \"  public static final class array {\\n\"\n      + \"    public static final int res = 0x7f040001;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class bool {\\n\"\n      + \"    public static final int res = 0x7f040002;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class color {\\n\"\n      + \"    public static final int res = 0x7f040003;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class integer {\\n\"\n      + \"    public static final int res = 0x7f040004;\\n\"\n      + \"  }\\n\"\n      + \"  public static final class string {\\n\"\n      + \"    public static final int res = 0x7f040005;\\n\"\n      + \"  }\\n\"\n      + \"}\"\n  );\n\n  @Test public void library() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindInt;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindInt(R2.integer.res) int one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.one = res.getInteger(R.integer.res);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source, NON_FINAL_R, R2))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void issue779() {\n    JavaFileObject r2Bar = JavaFileObjects.forSourceString(\"test.bar.R2\", \"\"\n        + \"package test.bar;\\n\"\n        + \"public final class R2 {\\n\"\n        + \"  public static final class array {\\n\"\n        + \"    public static final int res = 0x7f040001;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class bool {\\n\"\n        + \"    public static final int res = 0x7f040002;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class color {\\n\"\n        + \"    public static final int res = 0x7f040003;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class id {\\n\"\n        + \"    public static final int res = 0x7f040004;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class string {\\n\"\n        + \"    public static final int res = 0x7f040005;\\n\"\n        + \"  }\\n\"\n        + \"}\");\n\n    JavaFileObject nonFinalRBar = JavaFileObjects.forSourceString(\"test.bar.R\", \"\"\n        + \"package test.bar;\\n\"\n        + \"public final class R {\\n\"\n        + \"  public static final class array {\\n\"\n        + \"    public static int res = 0x7f040001;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class bool {\\n\"\n        + \"    public static int res = 0x7f040002;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class color {\\n\"\n        + \"    public static int res = 0x7f040003;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class id {\\n\"\n        + \"    public static int res = 0x7f040004;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class styleable {\\n\"\n        + \"    public static int[] ActionBar = { 0x7f010001, 0x7f010003 };\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject nonFinalRFoo = JavaFileObjects.forSourceString(\"test.foo.R\", \"\"\n        + \"package test.foo;\\n\"\n        + \"public final class R {\\n\"\n        + \"  public static final class array {\\n\"\n        + \"    public static int res = 0x7f040001;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class bool {\\n\"\n        + \"    public static int res = 0x7f040002;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class color {\\n\"\n        + \"    public static int res = 0x7f040003;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class id {\\n\"\n        + \"    public static int bogus = 0x7f040004;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class styleable {\\n\"\n        + \"    public static int[] ActionBar = { 0x7f010001, 0x7f010003 };\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject r2Foo = JavaFileObjects.forSourceString(\"test.foo.R2\", \"\"\n        + \"package test.foo;\\n\"\n        + \"public final class R2 {\\n\"\n        + \"  public static final class array {\\n\"\n        + \"    public static final int res = 0x7f040001;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class bool {\\n\"\n        + \"    public static final int res = 0x7f040002;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class color {\\n\"\n        + \"    public static final int res = 0x7f040003;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class id {\\n\"\n        + \"    public static final int bogus = 0x7f040004;\\n\"\n        + \"  }\\n\"\n        + \"  public static final class string {\\n\"\n        + \"    public static final int res = 0x7f040005;\\n\"\n        + \"  }\\n\"\n        + \"}\");\n\n    JavaFileObject fooSource = JavaFileObjects.forSourceString(\"test.foo.FooTest\", \"\"\n        + \"package test.foo;\\n\"\n        + \"import android.app.Activity;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class FooTest extends Activity {\\n\"\n        + \"  @BindView(R2.id.bogus) View one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject barSource = JavaFileObjects.forSourceString(\"test.bar.Test\", \"\"\n        + \"package test.bar;\\n\"\n        + \"import android.app.Activity;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"public class Test extends Activity {\\n\"\n        + \"  @BindView(R2.id.res) CustomView one;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject customView = JavaFileObjects.forSourceString(\"test.bar.CustomView\", \"\"\n        + \"package test.bar;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"public class CustomView extends View {\\n\"\n        + \"  public CustomView(Context context) {\\n\"\n        + \"    super(context);\"\n        + \"  }\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSourceBar = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test.bar;\\n\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target) {\\n\"\n        + \"    this(target, target.getWindow().getDecorView());\\n\"\n        + \"  }\\n\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.one = Utils.findRequiredViewAsType(source, R.id.res, \\\"field 'one'\\\", \" +\n        \"CustomView.class);\\n\"\n        + \"  }\\n\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        +\n        \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\\n\"\n        + \"    target.one = null;\\n\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSourceFoo = JavaFileObjects.forSourceString(\"test/FooTest_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test.foo;\\n\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class FooTest_ViewBinding implements Unbinder {\\n\"\n        + \"  private FooTest target;\\n\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public FooTest_ViewBinding(FooTest target) {\\n\"\n        + \"    this(target, target.getWindow().getDecorView());\\n\"\n        + \"  }\\n\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(FooTest target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.one = Utils.findRequiredView(source, R.id.bogus, \\\"field 'one'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    FooTest target = this.target;\\n\"\n        +\n        \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\\n\"\n        + \"    this.target = null;\\n\\n\"\n        + \"    target.one = null;\\n\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources())\n        .that(asList(customView, fooSource, barSource, nonFinalRBar, nonFinalRFoo, r2Bar, r2Foo))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSourceBar);\n\n    assertAbout(javaSources())\n        .that(asList(customView, fooSource, barSource, nonFinalRBar, nonFinalRFoo, r2Bar, r2Foo))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSourceFoo);\n  }\n\n  @Test public void app() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindBool;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindBool(R.bool.res) boolean bool;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.content.res.Resources;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    Resources res = context.getResources();\\n\"\n        + \"    target.bool = res.getBoolean(R.bool.res);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source, FINAL_R))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void compiledRClass() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindColor(android.R.color.black) int black;\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(Test, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(Test target, Context context) {\\n\"\n        + \"    target.black = ContextCompat.getColor(context, android.R.color.black);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source, NON_FINAL_R))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/TestGeneratingProcessor.java",
    "content": "package butterknife;\n\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.testing.compile.JavaFileObjects;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.Set;\n\nimport javax.annotation.processing.AbstractProcessor;\nimport javax.annotation.processing.RoundEnvironment;\nimport javax.lang.model.element.TypeElement;\nimport javax.tools.JavaFileObject;\n\n/**\n * A test {@link javax.annotation.processing.Processor} that produces one file.\n *\n * To use it, include {@link #ANNOTATION} in your source set and\n * mark something with @PerformGeneration so the processor has something to latch onto\n */\npublic class TestGeneratingProcessor extends AbstractProcessor {\n\n  public static final JavaFileObject ANNOTATION = JavaFileObjects.forSourceString(\"test.PerformGeneration\", \"\"\n          + \"package test;\\n\"\n          + \"import java.lang.annotation.*;\\n\"\n          + \"@Target(ElementType.TYPE)\\n\"\n          + \"public @interface PerformGeneration {\\n\"\n          + \"}\");\n\n  private final String generatedClassName;\n  private final String generatedSource;\n  private boolean processed;\n\n  TestGeneratingProcessor(String generatedClassName, String... source) {\n    this.generatedClassName = generatedClassName;\n    this.generatedSource = Joiner.on(\"\\n\").join(source);\n  }\n\n  @Override\n  public Set<String> getSupportedAnnotationTypes() {\n    return ImmutableSet.of(\"test.PerformGeneration\");\n  }\n\n  @Override\n  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {\n    if (!processed) {\n      processed = true;\n      try (Writer writer = processingEnv.getFiler()\n          .createSourceFile(generatedClassName)\n          .openWriter()) {\n        writer.append(generatedSource);\n      } catch (IOException e) {\n        throw new RuntimeException(e);\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/TestStubs.java",
    "content": "package butterknife;\n\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\n\nfinal class TestStubs {\n  static final JavaFileObject ANDROIDX_CONTEXT_COMPAT =\n      JavaFileObjects.forSourceString(\"androidx.core.content.ContextCompat\", \"\"\n          + \"package androidx.core.content;\\n\"\n          + \"public class ContextCompat {}\");\n\n  static final JavaFileObject ANDROIDX_VIEW_PAGER =\n      JavaFileObjects.forSourceString(\"androidx.viewpager.widget.ViewPager\", \"\"\n          + \"package androidx.viewpager.widget;\\n\"\n          + \"\\n\"\n          + \"public interface ViewPager {\\n\"\n          + \"  void addOnPageChangeListener(OnPageChangeListener listener);\\n\"\n          + \"  void removeOnPageChangeListener(OnPageChangeListener listener);\\n\"\n          + \"  interface OnPageChangeListener {\\n\"\n          + \"    void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);\\n\"\n          + \"    void onPageSelected(int position);\\n\"\n          + \"    void onPageScrollStateChanged(int state);\\n\"\n          + \"  }\\n\"\n          + \"}\\n\");\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/UnbinderTest.java",
    "content": "package butterknife;\n\nimport butterknife.compiler.ButterKnifeProcessor;\nimport com.google.testing.compile.JavaFileObjects;\nimport javax.tools.JavaFileObject;\nimport org.junit.Test;\n\nimport static com.google.common.truth.Truth.assertAbout;\nimport static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;\nimport static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;\nimport static java.util.Arrays.asList;\n\npublic class UnbinderTest {\n  @Test public void multipleBindings() {\n    JavaFileObject source = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"import butterknife.OnLongClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @BindView(1) View view;\\n\"\n        + \"  @BindView(2) View view2;\\n\"\n        + \"  @OnClick(1) void doStuff() {}\\n\"\n        + \"  @OnLongClick(1) boolean doMoreStuff() { return false; }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingSource = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"field 'view', method 'doStuff', and method 'doMoreStuff'\\\");\\n\"\n        + \"    target.view = view;\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    view.setOnLongClickListener(new View.OnLongClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public boolean onLongClick(View p0) {\\n\"\n        + \"        return target.doMoreStuff();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    target.view2 = Utils.findRequiredView(source, 2, \\\"field 'view2'\\\");\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    Test target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.view = null;\\n\"\n        + \"    target.view2 = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1.setOnLongClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSource()).that(source)\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(bindingSource);\n  }\n\n  @Test public void unbindingThroughAbstractChild() {\n    JavaFileObject source1 = JavaFileObjects.forSourceString(\"test.Test\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class Test {\\n\"\n        + \"  @OnClick(1) void doStuff1() { }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source2 = JavaFileObjects.forSourceString(\"test.TestOne\", \"\"\n        + \"package test;\\n\"\n        + \"public abstract class TestOne extends Test {\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject source3 = JavaFileObjects.forSourceString(\"test.TestTwo\", \"\"\n        + \"package test;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"class TestTwo extends TestOne {\\n\"\n        + \"  @OnClick(1) void doStuff2() { }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding1Source = JavaFileObjects.forSourceString(\"test/Test_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class Test_ViewBinding implements Unbinder {\\n\"\n        + \"  private Test target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(final Test target, View source) {\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff1'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff1();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject binding2Source = JavaFileObjects.forSourceString(\"test/TestTwo_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class TestTwo_ViewBinding extends Test_ViewBinding {\\n\"\n        + \"  private TestTwo target;\\n\"\n        + \"  private View view1;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public TestTwo_ViewBinding(final TestTwo target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    view = Utils.findRequiredView(source, 1, \\\"method 'doStuff2'\\\");\\n\"\n        + \"    view1 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.doStuff2();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    target = null;\\n\"\n        + \"    view1.setOnClickListener(null);\\n\"\n        + \"    view1 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources()).that(asList(source1, source2, source3))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(binding1Source, binding2Source);\n  }\n\n  @Test public void fullIntegration() {\n    JavaFileObject sourceA = JavaFileObjects.forSourceString(\"test.A\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class A {\\n\"\n        + \"  @BindColor(android.R.color.black) @ColorInt int blackColor;\\n\"\n        + \"  public A(View view) {\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceB = JavaFileObjects.forSourceString(\"test.B\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class B extends A {\\n\"\n        + \"  @BindColor(android.R.color.white) @ColorInt int whiteColor;\\n\"\n        + \"  public B(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceC = JavaFileObjects.forSourceString(\"test.C\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class C extends B {\\n\"\n        + \"  @BindColor(android.R.color.transparent) @ColorInt int transparentColor;\\n\"\n        + \"  @BindView(android.R.id.button1) View button1;\\n\"\n        + \"  public C(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceD = JavaFileObjects.forSourceString(\"test.D\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class D extends C {\\n\"\n        + \"  @BindColor(android.R.color.darker_gray) @ColorInt int grayColor;\\n\"\n        + \"  public D(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceE = JavaFileObjects.forSourceString(\"test.E\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class E extends C {\\n\"\n        + \"  @BindColor(android.R.color.background_dark) @ColorInt int backgroundDarkColor;\\n\"\n        + \"  public E(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceF = JavaFileObjects.forSourceString(\"test.F\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class F extends D {\\n\"\n        + \"  @BindColor(android.R.color.background_light) @ColorInt int backgroundLightColor;\\n\"\n        + \"  public F(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceG = JavaFileObjects.forSourceString(\"test.G\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"import butterknife.OnClick;\\n\"\n        + \"public class G extends E {\\n\"\n        + \"  @BindColor(android.R.color.darker_gray) @ColorInt int grayColor;\\n\"\n        + \"  @BindView(android.R.id.button2) View button2;\\n\"\n        + \"  public G(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"  @OnClick(android.R.id.content) public void onClick() {\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject sourceH = JavaFileObjects.forSourceString(\"test.H\", \"\"\n        + \"package test;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.ColorInt;\\n\"\n        + \"import butterknife.BindView;\\n\"\n        + \"import butterknife.BindColor;\\n\"\n        + \"public class H extends G {\\n\"\n        + \"  @BindColor(android.R.color.holo_green_dark) @ColorInt int holoGreenDark;\\n\"\n        + \"  @BindView(android.R.id.button3) View button3;\\n\"\n        + \"  public H(View view) {\\n\"\n        + \"    super(view);\\n\"\n        + \"  }\\n\"\n        + \"}\\n\");\n\n    JavaFileObject bindingASource = JavaFileObjects.forSourceString(\"test/A_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.CallSuper;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import butterknife.Unbinder;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class A_ViewBinding implements Unbinder {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(A, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(A target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public A_ViewBinding(A target, Context context) {\\n\"\n        + \"    target.blackColor = ContextCompat.getColor(context, android.R.color.black);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  @CallSuper\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingBSource = JavaFileObjects.forSourceString(\"test/B_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import java.lang.Deprecated;\\n\"\n        + \"public class B_ViewBinding extends A_ViewBinding {\\n\"\n        + \"  /**\\n\"\n        + \"   * @deprecated Use {@link #Test_ViewBinding(B, Context)} for direct creation.\\n\"\n        + \"   *     Only present for runtime invocation through {@code ButterKnife.bind()}.\\n\"\n        + \"   */\\n\"\n        + \"  @Deprecated\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public Test_ViewBinding(B target, View source) {\\n\"\n        + \"    this(target, source.getContext());\\n\"\n        + \"  }\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public B_ViewBinding(B target, Context context) {\\n\"\n        + \"    super(target, context);\\n\"\n        + \"    target.whiteColor = ContextCompat.getColor(context, android.R.color.white);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingCSource = JavaFileObjects.forSourceString(\"test/C_ViewBinding\", \"\"\n        + \"// Generated code from Butter Knife. Do not modify!\\n\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class C_ViewBinding extends B_ViewBinding {\\n\"\n        + \"  private C target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public C_ViewBinding(C target, View source) {\\n\"\n        + \"    super(target, source.getContext());\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.button1 = Utils.findRequiredView(source, android.R.id.button1, \\\"field 'button1'\\\");\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.transparentColor = ContextCompat.getColor(context, android.R.color.transparent);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    C target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.button1 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingDSource = JavaFileObjects.forSourceString(\"test/D_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"public class D_ViewBinding extends C_ViewBinding {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public D_ViewBinding(D target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.grayColor = ContextCompat.getColor(context, android.R.color.darker_gray);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingESource = JavaFileObjects.forSourceString(\"test/E_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"public class E_ViewBinding extends C_ViewBinding {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public E_ViewBinding(E target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.backgroundDarkColor = ContextCompat.getColor(context, android.R.color.background_dark);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingFSource = JavaFileObjects.forSourceString(\"test/F_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"public class F_ViewBinding extends D_ViewBinding {\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public F_ViewBinding(F target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.backgroundLightColor = ContextCompat.getColor(context, android.R.color.background_light);\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingGSource = JavaFileObjects.forSourceString(\"test/G_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import butterknife.internal.DebouncingOnClickListener;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class G_ViewBinding extends E_ViewBinding {\\n\"\n        + \"  private G target;\\n\"\n        + \"  private View view1020002;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public G_ViewBinding(final G target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    View view;\\n\"\n        + \"    target.button2 = Utils.findRequiredView(source, android.R.id.button2, \\\"field 'button2'\\\");\\n\"\n        + \"    view = Utils.findRequiredView(source, android.R.id.content, \\\"method 'onClick'\\\");\\n\"\n        + \"    view1020002 = view;\\n\"\n        + \"    view.setOnClickListener(new DebouncingOnClickListener() {\\n\"\n        + \"      @Override\\n\"\n        + \"      public void doClick(View p0) {\\n\"\n        + \"        target.onClick();\\n\"\n        + \"      }\\n\"\n        + \"    });\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.grayColor = ContextCompat.getColor(context, android.R.color.darker_gray);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    G target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null\\n\"\n        + \"    target.button2 = null;\\n\"\n        + \"    view1020002.setOnClickListener(null);\\n\"\n        + \"    view1020002 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    JavaFileObject bindingHSource = JavaFileObjects.forSourceString(\"test/H_ViewBinding\", \"\"\n        + \"package test;\\n\"\n        + \"import android.content.Context;\\n\"\n        + \"import android.view.View;\\n\"\n        + \"import androidx.annotation.UiThread;\\n\"\n        + \"import androidx.core.content.ContextCompat;\\n\"\n        + \"import butterknife.internal.Utils;\\n\"\n        + \"import java.lang.IllegalStateException;\\n\"\n        + \"import java.lang.Override;\\n\"\n        + \"public class H_ViewBinding extends G_ViewBinding {\\n\"\n        + \"  private H target;\\n\"\n        + \"  @UiThread\\n\"\n        + \"  public H_ViewBinding(H target, View source) {\\n\"\n        + \"    super(target, source);\\n\"\n        + \"    this.target = target;\\n\"\n        + \"    target.button3 = Utils.findRequiredView(source, android.R.id.button3, \\\"field 'button3'\\\");\\n\"\n        + \"    Context context = source.getContext();\\n\"\n        + \"    target.holoGreenDark = ContextCompat.getColor(context, android.R.color.holo_green_dark);\\n\"\n        + \"  }\\n\"\n        + \"  @Override\\n\"\n        + \"  public void unbind() {\\n\"\n        + \"    H target = this.target;\\n\"\n        + \"    if (target == null) throw new IllegalStateException(\\\"Bindings already cleared.\\\");\\n\"\n        + \"    this.target = null;\\n\"\n        + \"    target.button3 = null;\\n\"\n        + \"    super.unbind();\\n\"\n        + \"  }\\n\"\n        + \"}\"\n    );\n\n    assertAbout(javaSources())\n        .that(asList(\n            sourceA,\n            sourceB,\n            sourceC,\n            sourceD,\n            sourceE,\n            sourceF,\n            sourceG,\n            sourceH))\n        .withCompilerOptions(\"-Xlint:-processing\")\n        .processedWith(new ButterKnifeProcessor())\n        .compilesWithoutWarnings()\n        .and()\n        .generatesSources(\n            bindingASource,\n            bindingBSource,\n            bindingCSource,\n            bindingDSource,\n            bindingESource,\n            bindingFSource,\n            bindingGSource,\n            bindingHSource);\n  }\n}\n"
  },
  {
    "path": "butterknife-runtime/src/test/java/butterknife/UtilsTest.java",
    "content": "package butterknife;\n\nimport butterknife.internal.Utils;\nimport org.junit.Test;\n\nimport static butterknife.internal.Utils.arrayFilteringNull;\nimport static butterknife.internal.Utils.listFilteringNull;\nimport static com.google.common.truth.Truth.assertThat;\nimport static org.junit.Assert.fail;\n\npublic final class UtilsTest {\n  @Test public void listOfFiltersNull() {\n    assertThat(listFilteringNull(null, null, null)).isEmpty();\n    assertThat(listFilteringNull(\"One\", null, null)).containsExactly(\"One\");\n    assertThat(listFilteringNull(null, \"One\", null)).containsExactly(\"One\");\n    assertThat(listFilteringNull(null, null, \"One\")).containsExactly(\"One\");\n    assertThat(listFilteringNull(\"One\", \"Two\", null)).containsExactly(\"One\", \"Two\");\n    assertThat(listFilteringNull(\"One\", null, \"Two\")).containsExactly(\"One\", \"Two\");\n    assertThat(listFilteringNull(null, \"One\", \"Two\")).containsExactly(\"One\", \"Two\");\n    assertThat(listFilteringNull(\"One\", \"Two\", \"Three\")).containsExactly(\"One\", \"Two\", \"Three\");\n  }\n\n  @Test public void arrayFilteringNullRemovesNulls() {\n    assertThat(arrayFilteringNull(null, null, null)).isEmpty();\n    assertThat(arrayFilteringNull(\"One\", null, null)).asList().containsExactly(\"One\");\n    assertThat(arrayFilteringNull(null, \"One\", null)).asList().containsExactly(\"One\");\n    assertThat(arrayFilteringNull(null, null, \"One\")).asList().containsExactly(\"One\");\n    assertThat(arrayFilteringNull(\"One\", \"Two\", null)).asList().containsExactly(\"One\", \"Two\");\n    assertThat(arrayFilteringNull(\"One\", null, \"Two\")).asList().containsExactly(\"One\", \"Two\");\n    assertThat(arrayFilteringNull(null, \"One\", \"Two\")).asList().containsExactly(\"One\", \"Two\");\n  }\n\n  @Test public void arrayFilteringNullReturnsOriginalWhenNoNulls() {\n    String[] input = { \"One\", \"Two\", \"Three\" };\n    String[] actual = arrayFilteringNull(input);\n    assertThat(actual).isSameAs(input);\n    // Even though we got the same reference back check to ensure its contents weren't mutated.\n    assertThat(actual).asList().containsExactly(\"One\", \"Two\", \"Three\");\n  }\n\n  @Test public void testCastParam() {\n    try {\n      Utils.castParam(\"abc\", \"Foo\", 3, \"foo()\", 4, Integer.class);\n      fail();\n    } catch (IllegalStateException ise) {\n      assertThat(ise.getMessage()).isEqualTo(\n          \"Parameter #4 of method 'Foo' was of the wrong type for parameter #5 of method 'foo()'. See cause for more info.\");\n    }\n  }\n}\n"
  },
  {
    "path": "checkstyle.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\"\n    \"http://checkstyle.sourceforge.net/dtds/configuration_1_3.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)\\b[^ ]\"/>\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      <property name=\"tokens\" value=\"INC, DEC, UNARY_MINUS, UNARY_PLUS, BNOT, LNOT, DOT, ARRAY_DECLARATOR, INDEX_OP\"/>\n    </module>\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        <property name=\"allowInSwitchCase\" value=\"true\"/>\n    </module>\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=\"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  </module>\n</module>\n"
  },
  {
    "path": "deploy_website.sh",
    "content": "#!/bin/bash\n\nset -ex\n\nREPO=\"https://github.com/JakeWharton/butterknife.git\"\nGROUP_ID=\"com.jakewharton\"\nARTIFACT_ID=\"butterknife\"\n\nDIR=temp-clone\n\n# Delete any existing temporary website clone\nrm -rf $DIR\n\n# Clone the current repo into temp folder\ngit clone $REPO $DIR\n\n# Move working directory into temp folder\ncd $DIR\n\n# Checkout and track the gh-pages branch\ngit checkout -t origin/gh-pages\n\n# Delete everything\nrm -rf *\n\n# Copy website files from real repo\ncp -R ../website/* .\n\n# Download the latest javadoc\ncurl -L \"http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=$GROUP_ID&a=$ARTIFACT_ID&v=LATEST&c=javadoc\" > javadoc.zip\nmkdir javadoc\nunzip javadoc.zip -d javadoc\nrm javadoc.zip\n\n# Stage all files in git and create a commit\ngit add .\ngit add -u\ngit commit -m \"Website at $(date)\"\n\n# Push the new files up to GitHub\ngit push origin gh-pages\n\n# Delete our temp folder\ncd ..\nrm -rf $DIR\n"
  },
  {
    "path": "gradle/gradle-mvn-push.gradle",
    "content": "/*\n * Copyright 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 */\n\napply plugin: 'maven'\napply plugin: 'signing'\n\nversion = VERSION_NAME\ngroup = GROUP\n\ndef isReleaseBuild() {\n  return VERSION_NAME.contains(\"SNAPSHOT\") == false\n}\n\ndef getReleaseRepositoryUrl() {\n  return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL\n      : \"https://oss.sonatype.org/service/local/staging/deploy/maven2/\"\n}\n\ndef getSnapshotRepositoryUrl() {\n  return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL\n      : \"https://oss.sonatype.org/content/repositories/snapshots/\"\n}\n\ndef getRepositoryUsername() {\n  return hasProperty('SONATYPE_NEXUS_USERNAME') ? SONATYPE_NEXUS_USERNAME : \"\"\n}\n\ndef getRepositoryPassword() {\n  return hasProperty('SONATYPE_NEXUS_PASSWORD') ? SONATYPE_NEXUS_PASSWORD : \"\"\n}\n\ndef configurePom(pom) {\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\nafterEvaluate { project ->\n  uploadArchives {\n    repositories {\n      mavenDeployer {\n        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }\n\n        repository(url: getReleaseRepositoryUrl()) {\n          authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())\n        }\n        snapshotRepository(url: getSnapshotRepositoryUrl()) {\n          authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())\n        }\n\n        configurePom(pom)\n      }\n    }\n  }\n\n  tasks.create(\"installLocally\", Upload) {\n    configuration = configurations.archives\n\n    repositories {\n      mavenDeployer {\n        repository(url: \"file://${rootProject.buildDir}/localMaven\")\n\n        configurePom(pom)\n      }\n    }\n  }\n\n  signing {\n    required { isReleaseBuild() && 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    task install(type: Upload, dependsOn: assemble) {\n      repositories.mavenInstaller {\n        configuration = configurations.archives\n\n        configurePom(pom)\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        configurePom(pom)\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      from javadoc.destinationDir\n    }\n  }\n\n  if (JavaVersion.current().isJava8Compatible()) {\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"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.10.3-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "GROUP=com.jakewharton\nVERSION_NAME=10.2.4-SNAPSHOT\n\nPOM_DESCRIPTION=Field and method binding for Android views.\n\nPOM_URL=https://github.com/JakeWharton/butterknife/\nPOM_SCM_URL=https://github.com/JakeWharton/butterknife/\nPOM_SCM_CONNECTION=scm:git:git://github.com/JakeWharton/butterknife.git\nPOM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/JakeWharton/butterknife.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=jakewharton\nPOM_DEVELOPER_NAME=Jake Wharton\n\norg.gradle.jvmargs=-Xmx1536M\n\n# TODO https://issuetracker.google.com/issues/73450622\nandroid.enableAapt2=false\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": "sample/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  compileOptions {\n    sourceCompatibility = JavaVersion.VERSION_1_7\n    targetCompatibility = JavaVersion.VERSION_1_7\n  }\n\n  defaultConfig {\n    applicationId 'com.example.butterknife'\n    minSdkVersion versions.minSdk\n    targetSdkVersion versions.compileSdk\n    versionCode 1\n    versionName '1.0.0'\n  }\n\n  lintOptions {\n    textReport true\n    textOutput 'stdout'\n  }\n\n  buildTypes {\n    debug {\n      minifyEnabled true\n    }\n  }\n}\n\ndependencies {\n  implementation deps.release.runtime\n  annotationProcessor deps.release.compiler\n\n  implementation project(':sample:library')\n\n  testImplementation deps.junit\n  testImplementation deps.truth\n}\n\nafterEvaluate {\n  tasks.withType(com.android.build.gradle.internal.tasks.AndroidTestTask) { task ->\n    task.doFirst {\n      logging.level = LogLevel.INFO\n    }\n    task.doLast {\n      logging.level = LogLevel.LIFECYCLE\n    }\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.example.butterknife\">\n\n  <application\n      android:allowBackup=\"false\"\n      android:label=\"@string/app_name\"\n      android:name=\".SimpleApp\"\n      tools:ignore=\"GoogleAppIndexingWarning,MissingApplicationIcon\">\n\n    <activity\n        android:label=\"@string/app_name\"\n        android:name=\".library.SimpleActivity\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.MAIN\"/>\n\n        <category android:name=\"android.intent.category.LAUNCHER\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n  </application>\n</manifest>\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/SimpleApp.java",
    "content": "package com.example.butterknife;\n\nimport android.app.Application;\nimport butterknife.ButterKnife;\n\npublic class SimpleApp extends Application {\n  @Override public void onCreate() {\n    super.onCreate();\n    ButterKnife.setDebug(BuildConfig.DEBUG);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/A.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class A {\n\n  @BindColor(android.R.color.black) @ColorInt int blackColor;\n\n  public A(View view) {\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/B.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class B extends A {\n\n  @BindColor(android.R.color.white) @ColorInt int whiteColor;\n\n  public B(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/C.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindView;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class C extends B {\n\n  @BindColor(android.R.color.transparent) @ColorInt int transparentColor;\n  @BindView(android.R.id.button1) View button1;\n\n  public C(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/D.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class D extends C {\n\n  @BindColor(android.R.color.darker_gray) @ColorInt int grayColor;\n\n  public D(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/E.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class E extends C {\n\n  @BindColor(android.R.color.background_dark) @ColorInt int backgroundDarkColor;\n\n  public E(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/F.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic final class F extends D {\n\n  @BindColor(android.R.color.background_light) @ColorInt int backgroundLightColor;\n\n  public F(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/G.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindView;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\n\npublic class G extends E {\n\n  @BindColor(android.R.color.darker_gray) @ColorInt int grayColor;\n  @BindView(android.R.id.button2) View button2;\n\n  public G(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n\n  @OnClick(android.R.id.content) public void onClick() {\n\n  }\n}\n"
  },
  {
    "path": "sample/app/src/main/java/com/example/butterknife/unbinder/H.java",
    "content": "package com.example.butterknife.unbinder;\n\nimport androidx.annotation.ColorInt;\nimport android.view.View;\n\nimport butterknife.BindView;\nimport butterknife.BindColor;\nimport butterknife.ButterKnife;\n\npublic class H extends G {\n\n  @BindColor(android.R.color.primary_text_dark) @ColorInt int grayColor;\n  @BindView(android.R.id.button3) View button3;\n\n  public H(View view) {\n    super(view);\n    ButterKnife.bind(this, view);\n  }\n}\n"
  },
  {
    "path": "sample/library/build.gradle",
    "content": "buildscript {\n  repositories {\n    mavenCentral()\n    jcenter()\n    google()\n  }\n\n  dependencies {\n    classpath \"com.jakewharton:butterknife-gradle-plugin:${versions.release}\"\n  }\n}\n\napply plugin: 'com.android.library'\napply plugin: 'com.jakewharton.butterknife'\n\nandroid {\n  compileSdkVersion versions.compileSdk\n\n  defaultConfig {\n    minSdkVersion versions.minSdk\n  }\n}\n\ndependencies {\n  implementation deps.release.runtime\n  annotationProcessor deps.release.compiler\n\n  testImplementation deps.junit\n  testImplementation deps.truth\n}\n"
  },
  {
    "path": "sample/library/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"com.example.butterknife.library\"/>\n"
  },
  {
    "path": "sample/library/src/main/java/com/example/butterknife/library/SimpleActivity.java",
    "content": "package com.example.butterknife.library;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport android.os.Bundle;\nimport androidx.annotation.NonNull;\nimport android.view.View;\nimport android.view.animation.AlphaAnimation;\nimport android.widget.Button;\nimport android.widget.ListView;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport butterknife.BindView;\nimport butterknife.BindViews;\nimport butterknife.ButterKnife;\nimport butterknife.OnClick;\nimport butterknife.OnItemClick;\nimport butterknife.OnLongClick;\nimport java.util.List;\n\nimport static android.widget.Toast.LENGTH_SHORT;\n\npublic class SimpleActivity extends Activity {\n  private static final ButterKnife.Action<View> ALPHA_FADE = new ButterKnife.Action<View>() {\n    @Override public void apply(@NonNull View view, int index) {\n      AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);\n      alphaAnimation.setFillBefore(true);\n      alphaAnimation.setDuration(500);\n      alphaAnimation.setStartOffset(index * 100);\n      view.startAnimation(alphaAnimation);\n    }\n  };\n\n  @BindView(R2.id.title) TextView title;\n  @BindView(R2.id.subtitle) TextView subtitle;\n  @BindView(R2.id.hello) Button hello;\n  @BindView(R2.id.list_of_things) ListView listOfThings;\n  @BindView(R2.id.footer) TextView footer;\n\n  @BindViews({ R2.id.title, R2.id.subtitle, R2.id.hello }) List<View> headerViews;\n\n  private SimpleAdapter adapter;\n\n  @OnClick(R2.id.hello) void sayHello() {\n    Toast.makeText(this, \"Hello, views!\", LENGTH_SHORT).show();\n    ButterKnife.apply(headerViews, ALPHA_FADE);\n  }\n\n  @OnLongClick(R2.id.hello) boolean sayGetOffMe() {\n    Toast.makeText(this, \"Let go of me!\", LENGTH_SHORT).show();\n    return true;\n  }\n\n  @OnItemClick(R2.id.list_of_things) void onItemClick(int position) {\n    Toast.makeText(this, \"You clicked: \" + adapter.getItem(position), LENGTH_SHORT).show();\n  }\n\n  @SuppressLint(\"SetTextI18n\") //\n  @Override protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.simple_activity);\n    ButterKnife.bind(this);\n\n    // Contrived code to use the bound fields.\n    title.setText(\"Butter Knife\");\n    subtitle.setText(\"Field and method binding for Android views.\");\n    footer.setText(\"by Jake Wharton\");\n    hello.setText(\"Say Hello\");\n\n    adapter = new SimpleAdapter(this);\n    listOfThings.setAdapter(adapter);\n  }\n}\n"
  },
  {
    "path": "sample/library/src/main/java/com/example/butterknife/library/SimpleAdapter.java",
    "content": "package com.example.butterknife.library;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.BaseAdapter;\nimport android.widget.TextView;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\npublic class SimpleAdapter extends BaseAdapter {\n  private static final String[] CONTENTS = \"The quick brown fox jumps over the lazy dog\".split(\" \");\n\n  private final LayoutInflater inflater;\n\n  public SimpleAdapter(Context context) {\n    inflater = LayoutInflater.from(context);\n  }\n\n  @Override public int getCount() {\n    return CONTENTS.length;\n  }\n\n  @Override public String getItem(int position) {\n    return CONTENTS[position];\n  }\n\n  @Override public long getItemId(int position) {\n    return position;\n  }\n\n  @SuppressLint(\"SetTextI18n\") //\n  @Override public View getView(int position, View view, ViewGroup parent) {\n    ViewHolder holder;\n    if (view != null) {\n      holder = (ViewHolder) view.getTag();\n    } else {\n      view = inflater.inflate(R.layout.simple_list_item, parent, false);\n      holder = new ViewHolder(view);\n      view.setTag(holder);\n    }\n\n    String word = getItem(position);\n    holder.word.setText(\"Word: \" + word);\n    holder.length.setText(\"Length: \" + word.length());\n    holder.position.setText(\"Position: \" + position);\n    // Note: don't actually do string concatenation like this in an adapter's getView.\n\n    return view;\n  }\n\n  static final class ViewHolder {\n    @BindView(R2.id.word) TextView word;\n    @BindView(R2.id.length) TextView length;\n    @BindView(R2.id.position) TextView position;\n\n    ViewHolder(View view) {\n      ButterKnife.bind(this, view);\n    }\n  }\n}\n"
  },
  {
    "path": "sample/library/src/main/res/layout/simple_activity.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n  <TextView\n      android:id=\"@+id/title\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:gravity=\"center\"\n      android:textSize=\"50sp\"\n      />\n  <TextView\n      android:id=\"@+id/subtitle\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:gravity=\"center\"\n      android:textSize=\"20sp\"\n      />\n  <Button\n      android:id=\"@+id/hello\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"0dp\"\n      android:layout_weight=\"1\"\n      android:layout_margin=\"10dp\"\n      />\n  <ListView\n      android:id=\"@+id/list_of_things\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"0dp\"\n      android:layout_weight=\"1\"\n      android:layout_margin=\"10dp\"\n      />\n  <TextView\n      android:id=\"@+id/footer\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:gravity=\"center\"\n      android:textSize=\"17sp\"\n      android:textStyle=\"italic\"\n      />\n</LinearLayout>\n"
  },
  {
    "path": "sample/library/src/main/res/layout/simple_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n  <TextView\n      android:id=\"@+id/word\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      />\n  <TextView\n      android:id=\"@+id/length\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      />\n  <TextView\n      android:id=\"@+id/position\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      />\n</LinearLayout>"
  },
  {
    "path": "sample/library/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<resources>\n  <string name=\"app_name\">Butter Knife</string>\n</resources>"
  },
  {
    "path": "settings.gradle",
    "content": "include ':butterknife'\ninclude ':butterknife-annotations'\ninclude ':butterknife-compiler'\ninclude ':butterknife-gradle-plugin'\ninclude ':butterknife-integration-test'\ninclude ':butterknife-lint'\ninclude ':butterknife-reflect'\ninclude ':butterknife-runtime'\n\n//include ':sample:app'\n//include ':sample:library'\n\nrootProject.name = 'butterknife-parent'\n"
  },
  {
    "path": "website/ide-eclipse.html",
    "content": "<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Butter Knife</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"Field and method binding for Android views.\">\n    <link href=\"http://fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold\" rel=\"stylesheet\" title=\"roboto\">\n    <link href=\"static/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"static/bootstrap-responsive.min.css\" rel=\"stylesheet\">\n    <link href=\"static/prettify.css\" rel=\"stylesheet\">\n    <link href=\"static/app.css\" rel=\"stylesheet\">\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"span4 side\">\n          <img src=\"static/logo.png\">\n          <h1>Butter Knife</h1>\n          <h2>Field and method binding for Android views</h2>\n        </div>\n        <div class=\"offset4 span8 main\">\n          <div class=\"main-inner\">\n            <p><a href=\"index.html\">&laquo; Back to Butter Knife</a></p>\n\n            <h3 id=\"introduction\">Eclipse Configuration</h3>\n            <ol>\n              <li>\n                <p>Right click on your project in the <em>Package Explorer</em>, go to <em>Properties</em>, head to <em>Java Compiler &rarr; Annotation Processing</em> and check <em>\"Enable project specific settings\"</em>.<p>\n                <p>Ensure the other annotation processing settings are the same as shown below:</p>\n                <p><img src=\"static/ide-eclipse1.png\"/></p>\n              </li>\n              <li>\n                <p>Expand the <em>Annotation Processing</em> section and select <em>Factory Path</em>. Check <em>\"Enable project specific settings\"</em> and then click <em>\"Add JARs…\"</em>. Navigate to the project's <code>libs/</code> folder and select the Butter Knife jar.</p>\n                <p><img src=\"static/ide-eclipse2.png\"/></p>\n              </li>\n              <li>Click <em>\"Ok\"</em> to save the new settings. Eclipse will ask you to rebuild your project to which you should click <em>\"Yes\"</em></li>\n              <li>Make sure that the <code>.apt_generated/</code> folder is in your project root. It should contain files like <code>YOURACTIVITY$$ViewBinder.java</code>. If these files are not present trigger a clean build by selected <em>Project &rarr; Clean</em>. This folder and files should not be checked into revision control.\n              <li>Lastly, under <em>\"Java Compiler\"</em>, make sure that the <em>Compiler compliance level</em> is set to Java version 1.6 at minimum.</li>\n            </ol>\n\n            <a id=\"ribbon\" href=\"https://github.com/JakeWharton/butterknife\"><img src=\"static/ribbon.png\" alt=\"Fork me on GitHub\"></a>\n          </div>\n        </div>\n      </div>\n    </div>\n    <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js\"></script>\n    <script src=\"static/jquery-maven-artifact.min.js\"></script>\n    <script src=\"static/prettify.js\"></script>\n    <script>\n      prettyPrint();\n      $.fn.artifactVersion('com.jakewharton', 'butterknife', function(version, url) {\n        $('.version').text(version);\n        $('#download-btn').text('Butter Knife v' + version + ' JAR').attr('href', url);\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "website/ide-idea.html",
    "content": "<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Butter Knife</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"Field and method binding for Android views.\">\n    <link href=\"http://fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold\" rel=\"stylesheet\" title=\"roboto\">\n    <link href=\"static/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"static/bootstrap-responsive.min.css\" rel=\"stylesheet\">\n    <link href=\"static/prettify.css\" rel=\"stylesheet\">\n    <link href=\"static/app.css\" rel=\"stylesheet\">\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"span4 side\">\n          <img src=\"static/logo.png\">\n          <h1>Butter Knife</h1>\n          <h2>Field and method binding for Android views</h2>\n        </div>\n        <div class=\"offset4 span8 main\">\n          <div class=\"main-inner\">\n            <p><a href=\"index.html\">&laquo; Back to Butter Knife</a></p>\n\n            <h3 id=\"introduction\">IntelliJ IDEA Configuration</h3>\n            <p>Open IDEA's preference and navigate to <em>Compiler &rarr; Annotation Processors</em>. Check <em>\"Enable annotation processing\"</em>.<p>\n            <p><img src=\"static/ide-idea1.png\"/></p>\n\n            <a id=\"ribbon\" href=\"https://github.com/JakeWharton/butterknife\"><img src=\"static/ribbon.png\" alt=\"Fork me on GitHub\"></a>\n          </div>\n        </div>\n      </div>\n    </div>\n    <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js\"></script>\n    <script src=\"static/jquery-maven-artifact.min.js\"></script>\n    <script src=\"static/prettify.js\"></script>\n    <script>\n      prettyPrint();\n      $.fn.artifactVersion('com.jakewharton', 'butterknife', function(version, url) {\n        $('.version').text(version);\n        $('#download-btn').text('Butter Knife v' + version + ' JAR').attr('href', url);\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "website/index.html",
    "content": "<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Butter Knife</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta name=\"description\" content=\"Field and method binding for Android views.\">\n    <link href=\"https://fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold\" rel=\"stylesheet\" title=\"roboto\">\n    <link href=\"static/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"static/bootstrap-responsive.min.css\" rel=\"stylesheet\">\n    <link href=\"static/prettify.css\" rel=\"stylesheet\">\n    <link href=\"static/app.css\" rel=\"stylesheet\">\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"span4 side\">\n          <img src=\"static/logo.png\">\n          <h1>Butter Knife</h1>\n          <h2>Field and method binding for Android views</h2>\n          <p><a href=\"javadoc/\">Javadoc</a> &middot; <a href=\"http://stackoverflow.com/questions/ask?tags=butterknife\">StackOverflow</a></p>\n        </div>\n        <div class=\"offset4 span8 main\">\n          <div class=\"main-inner\">\n            <h3 id=\"deprecation\">Deprecation Notice</h3>\n            <p>This tool is now deprecated. Please switch to <a href=\"https://developer.android.com/topic/libraries/view-binding\">view binding</a>. Existing versions will continue to work, obviously, but only critical bug fixes for integration with AGP will be considered. Feature development and general bug fixes have stopped.</p>\n            <h3 id=\"introduction\">Introduction</h3>\n            <p>Annotate fields with <code>@BindView</code> and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout.</p>\n            <pre class=\"prettyprint\">class ExampleActivity extends Activity {\n  @BindView(R.id.title) TextView title;\n  @BindView(R.id.subtitle) TextView subtitle;\n  @BindView(R.id.footer) TextView footer;\n\n  @Override public void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.simple_activity);\n    ButterKnife.bind(this);\n    // TODO Use fields...\n  }\n}</pre>\n            <p>Instead of slow reflection, code is generated to perform the view look-ups. Calling <code>bind</code> delegates to this generated code that you can see and debug.</p>\n            <p>The generated code for the above example is roughly equivalent to the following:</p>\n            <pre class=\"prettyprint\">public void bind(ExampleActivity activity) {\n  activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);\n  activity.footer = (android.widget.TextView) activity.findViewById(2130968579);\n  activity.title = (android.widget.TextView) activity.findViewById(2130968577);\n}</pre>\n\n            <h4 id=\"resource\">Resource Binding</h4>\n            <p>Bind pre-defined resources with <code>@BindBool</code>, <code>@BindColor</code>, <code>@BindDimen</code>, <code>@BindDrawable</code>, <code>@BindInt</code>, <code>@BindString</code>, which binds an <code>R.bool</code> ID (or your specified type) to its corresponding field.</p>\n            <pre class=\"prettyprint\">class ExampleActivity extends Activity {\n  @BindString(R.string.title) String title;\n  @BindDrawable(R.drawable.graphic) Drawable graphic;\n  @BindColor(R.color.red) int red; // int or ColorStateList field\n  @BindDimen(R.dimen.spacer) float spacer; // int (for pixel size) or float (for exact value) field\n  // ...\n}</pre>\n\n            <h4 id=\"non-activity\">Non-Activity Binding</h4>\n            <p>You can also perform binding on arbitrary objects by supplying your own view root.</p>\n            <pre class=\"prettyprint\">public class FancyFragment extends Fragment {\n  @BindView(R.id.button1) Button button1;\n  @BindView(R.id.button2) Button button2;\n\n  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    View view = inflater.inflate(R.layout.fancy_fragment, container, false);\n    ButterKnife.bind(this, view);\n    // TODO Use fields...\n    return view;\n  }\n}</pre>\n            <p>Another use is simplifying the view holder pattern inside of a list adapter.</p>\n            <pre class=\"prettyprint\">public class MyAdapter extends BaseAdapter {\n  @Override public View getView(int position, View view, ViewGroup parent) {\n    ViewHolder holder;\n    if (view != null) {\n      holder = (ViewHolder) view.getTag();\n    } else {\n      view = inflater.inflate(R.layout.whatever, parent, false);\n      holder = new ViewHolder(view);\n      view.setTag(holder);\n    }\n\n    holder.name.setText(\"John Doe\");\n    // etc...\n\n    return view;\n  }\n\n  static class ViewHolder {\n    @BindView(R.id.title) TextView name;\n    @BindView(R.id.job_title) TextView jobTitle;\n\n    public ViewHolder(View view) {\n      ButterKnife.bind(this, view);\n    }\n  }\n}</pre>\n            <p>You can see this implementation in action in the provided sample.</p>\n            <p>Calls to <code>ButterKnife.bind</code> can be made anywhere you would otherwise put <code>findViewById</code> calls.</p>\n            <p>Other provided binding APIs:</p>\n            <ul>\n              <li>Bind arbitrary objects using an activity as the view root. If you use a pattern like MVC you can bind the controller using its activity with <code>ButterKnife.bind(this, activity)</code>.</li>\n              <li>Bind a view's children into fields using <code>ButterKnife.bind(this)</code>. If you use <code>&lt;merge></code> tags in a layout and inflate in a custom view constructor you can\n   call this immediately after. Alternatively, custom view types inflated from\n   XML can use it in the <code>onFinishInflate()</code> callback.</li>\n            </ul>\n\n            <h4 id=\"view-lists\">View Lists</h4>\n            <p>You can group multiple views into a <code>List</code> or array.</p>\n            <pre class=\"prettyprint\">@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })\nList&lt;EditText> nameViews;</pre>\n            <p>The <code>apply</code> method allows you to act on all the views in a list at once.</p>\n            <pre class=\"prettyprint\">ButterKnife.apply(nameViews, DISABLE);\nButterKnife.apply(nameViews, ENABLED, false);</pre>\n            <p><code>Action</code> and <code>Setter</code> interfaces allow specifying simple behavior.</p>\n            <pre class=\"prettyprint\">static final ButterKnife.Action&lt;View> DISABLE = new ButterKnife.Action&lt;View>() {\n  @Override public void apply(View view, int index) {\n    view.setEnabled(false);\n  }\n};\nstatic final ButterKnife.Setter&lt;View, Boolean> ENABLED = new ButterKnife.Setter&lt;View, Boolean>() {\n  @Override public void set(View view, Boolean value, int index) {\n    view.setEnabled(value);\n  }\n};</pre>\n            <p>An Android <a href=\"https://developer.android.com/reference/android/util/Property.html\"><code>Property</code></a> can also be used with the <code>apply</code> method.</p>\n            <pre class=\"prettyprint\">ButterKnife.apply(nameViews, View.ALPHA, 0.0f);</pre>\n\n            <h4 id=\"listener-binding\">Listener Binding</h4>\n            <p>Listeners can also automatically be configured onto methods.</p>\n            <pre class=\"prettyprint\">@OnClick(R.id.submit)\npublic void submit(View view) {\n  // TODO submit data to server...\n}</pre>\n            <p>All arguments to the listener method are optional.</p>\n            <pre class=\"prettyprint\">@OnClick(R.id.submit)\npublic void submit() {\n  // TODO submit data to server...\n}</pre>\n            <p>Define a specific type and it will automatically be cast.</p>\n            <pre class=\"prettyprint\">@OnClick(R.id.submit)\npublic void sayHi(Button button) {\n  button.setText(\"Hello!\");\n}</pre>\n            <p>Specify multiple IDs in a single binding for common event handling.</p>\n            <pre class=\"prettyprint\">@OnClick({ R.id.door1, R.id.door2, R.id.door3 })\npublic void pickDoor(DoorView door) {\n  if (door.hasPrizeBehind()) {\n    Toast.makeText(this, \"You win!\", LENGTH_SHORT).show();\n  } else {\n    Toast.makeText(this, \"Try again\", LENGTH_SHORT).show();\n  }\n}</pre>\n            <p>Custom views can bind to their own listeners by not specifying an ID.</p>\n            <pre class=\"prettyprint\">public class FancyButton extends Button {\n  @OnClick\n  public void onClick() {\n    // TODO do something!\n  }\n}\n</pre>\n\n            <h4 id=\"reset\">Binding Reset</h4>\n            <p>Fragments have a different view lifecycle than activities. When binding a fragment in <code>onCreateView</code>, set the views to <code>null</code> in <code>onDestroyView</code>. Butter Knife returns an <code>Unbinder</code> instance when you call <code>bind</code> to do this for you. Call its <code>unbind</code> method in the appropriate lifecycle callback.</p>\n            <pre class=\"prettyprint\">public class FancyFragment extends Fragment {\n  @BindView(R.id.button1) Button button1;\n  @BindView(R.id.button2) Button button2;\n  private Unbinder unbinder;\n\n  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    View view = inflater.inflate(R.layout.fancy_fragment, container, false);\n    unbinder = ButterKnife.bind(this, view);\n    // TODO Use fields...\n    return view;\n  }\n\n  @Override public void onDestroyView() {\n    super.onDestroyView();\n    unbinder.unbind();\n  }\n}</pre>\n\n            <h4 id=\"optional\">Optional Bindings</h4>\n            <p>By default, both <code>@Bind</code> and listener bindings are required. An exception will be thrown if the target view cannot be found.</p>\n            <p>To suppress this behavior and create an optional binding, add a <code>@Nullable</code> annotation to fields or the <code>@Optional</code> annotation to methods.</p>\n            <p>Note: Any annotation named <code>@Nullable</code> can be used for fields. It is encouraged to use the <code>@Nullable</code> annotation from <a href=\"http://tools.android.com/tech-docs/support-annotations\">Android's \"support-annotations\" library</a>.</p>\n            <pre class=\"prettyprint\">@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere;\n\n@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {\n  // TODO ...\n}</pre>\n\n            <h4 id=\"multi-method-listeners\">Multi-Method Listeners</h4>\n            <p>Method annotations whose corresponding listener has multiple callbacks can be used to bind to any one of them. Each annotation has a default callback that it binds to. Specify an alternate using the <code>callback</code> parameter.</p>\n            <pre class=\"prettyprint\">@OnItemSelected(R.id.list_view)\nvoid onItemSelected(int position) {\n  // TODO ...\n}\n\n@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)\nvoid onNothingSelected() {\n  // TODO ...\n}</pre>\n\n            <h3 id=\"download\">Download</h3>\n            <h4>Gradle</h4>\n            <pre class=\"prettyprint\">implementation 'com.jakewharton:butterknife:<span class=\"version\"><em>(insert latest version)</em></span>'\nannotationProcessor 'com.jakewharton:butterknife-compiler:<span class=\"version\"><em>(insert latest version)</em></span>'</pre>\n\n            <h3 id=\"license\">License</h3>\n            <pre class=\"license\">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.</pre>\n\n            <a id=\"ribbon\" href=\"https://github.com/JakeWharton/butterknife\"><img src=\"static/ribbon.png\" alt=\"Fork me on GitHub\"></a>\n          </div>\n        </div>\n      </div>\n    </div>\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js\"></script>\n    <script src=\"static/jquery-maven-artifact.min.js\"></script>\n    <script src=\"static/prettify.js\"></script>\n    <script>\n      prettyPrint();\n      $.fn.artifactVersion('com.jakewharton', 'butterknife', function(version, url) {\n        $('.version').text(version);\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "website/static/app.css",
    "content": "body {\n  background: #fff url('bg.png') repeat fixed;\n  margin-top: 40px;\n  color: #222;\n  font: 14px/19px Roboto, sans-serif;\n  font-weight: 400;\n  letter-spacing: .1\n}\n\n.downloads {\n  margin-bottom: 20px;\n}\n\nli {\n  margin-bottom: 10px;\n}\n\ncode, pre {\n  color: #444;\n  background: none;\n  border: none;\n}\npre {\n  padding: 0;\n  overflow: auto;\n  word-wrap: normal;\n  white-space: pre;\n}\ncode {\n  white-space: nowrap;\n}\n\n.side {\n  text-align: center;\n}\n.side h1 {\n  font-size: 50px;\n  line-height: 50px;\n  font-weight: 300;\n  margin-top: 30px;\n  margin-bottom: 10px;\n  text-shadow: 0px 0px 5px #fff;\n}\n.side h2 {\n  font-size: 18px;\n  line-height: 25px;\n  font-weight: 400;\n  margin-bottom: 40px;\n  text-shadow: 0px 0px 3px #fff;\n}\n.side a {\n  color: #555;\n  padding: 5px;\n}\n\n.main {\n    padding: 20px;\n    margin-bottom: 50px;\n    background-color: rgba(255, 255, 255, 0.9);\n}\n.main h3 {\n    padding-top: 40px;\n    margin-top: 0;\n    margin-bottom: 10px;\n    font-weight: 300;\n    font-size: 20px;\n    font-style: italic;\n    color: #555;\n}\n.main h4 {\n    padding-top: 20px;\n    margin-top: 0;\n    margin-bottom: 8px;\n    text-transform: uppercase;\n    font-weight: 400;\n    font-size: 13px;\n    line-height: 14px;\n    font-style: italic;\n    color: #555;\n}\n.main h4:first-child, .main h3:first-child {\n    padding-top: 0;\n}\n.main h5 {\n    font-size: 12px;\n    margin-top: 14px;\n    margin-bottom: 4px;\n    text-transform: uppercase;\n}\n\n#ribbon img {\n    position: absolute;\n    top: 0;\n    right: 0;\n    border: 0;\n}\n\n.btn-large {\n  font-weight: 200;\n}\n.btn-inverse, .btn-inverse:hover {\n  color: #e0e0e0;\n}\n\n@media(min-width:768px) {\n    body {\n        margin-top: 60px;\n    }\n    .side {\n        position: fixed;\n    }\n    .side h1 {\n      font-size: 40px;\n      line-height: 40px;\n    }\n    #ribbon img {\n        position: fixed;\n    }\n}\n\n@media(min-width: 980px) {\n    .side h1 {\n        font-size: 50px;\n        line-height: 50px;\n    }\n}\n"
  },
  {
    "path": "website/static/prettify.css",
    "content": ".com { color: #93a1a1; }\n.lit { color: #195f91; }\n.pun, .opn, .clo { color: #93a1a1; }\n.fun { color: #dc322f; }\n.str, .atv { color: #195f91; }\n.kwd, .linenums, .tag { color: #1e347b; }\n.typ, .atn, .dec, .var { color: teal; }\n.pln { color: #48484c; }\n"
  },
  {
    "path": "website/static/prettify.js",
    "content": "var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;\n(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:\"0\"<=b&&b<=\"7\"?parseInt(a.substring(1),8):b===\"u\"||b===\"x\"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?\"\\\\x0\":\"\\\\x\")+a.toString(16);a=String.fromCharCode(a);if(a===\"\\\\\"||a===\"-\"||a===\"[\"||a===\"]\")a=\"\\\\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\\\u[\\dA-Fa-f]{4}|\\\\x[\\dA-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\S\\s]|[^\\\\]/g),a=\n[],b=[],o=f[0]===\"^\",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&\"-\"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=[\"[\"];o&&b.push(\"^\");b.push.apply(b,a);for(c=0;c<\nf.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push(\"-\"),b.push(e(i[1])));b.push(\"]\");return b.join(\"\")}function y(a){for(var f=a.source.match(/\\[(?:[^\\\\\\]]|\\\\[\\S\\s])*]|\\\\u[\\dA-Fa-f]{4}|\\\\x[\\dA-Fa-f]{2}|\\\\\\d+|\\\\[^\\dux]|\\(\\?[!:=]|[()^]|[^()[\\\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j===\"(\"?++i:\"\\\\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j===\"(\"?(++i,d[i]===void 0&&(f[c]=\"(?:\")):\"\\\\\"===j.charAt(0)&&\n(j=+j.substring(1))&&j<=i&&(f[c]=\"\\\\\"+d[i]);for(i=c=0;c<b;++c)\"^\"===f[c]&&\"^\"!==f[c+1]&&(f[c]=\"\");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a===\"[\"?f[c]=h(j):a!==\"\\\\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return\"[\"+String.fromCharCode(a&-33,a|32)+\"]\"}));return f.join(\"\")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\\\u[\\da-f]{4}|\\\\x[\\da-f]{2}|\\\\[^UXux]/gi,\"\"))){s=!0;l=!1;break}}for(var r=\n{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(\"\"+g);n.push(\"(?:\"+y(g)+\")\")}return RegExp(n.join(\"|\"),l?\"gi\":\"g\")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if(\"BR\"===g||\"LI\"===g)h[s]=\"\\n\",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\\r\\n?/g,\"\\n\"):g.replace(/[\\t\\n\\r ]+/g,\" \"),h[s]=g,t[s<<1]=y,y+=g.length,\nt[s++<<1|1]=a)}}var e=/(?:^|\\s)nocode(?:\\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue(\"white-space\"));var p=l&&\"pre\"===l.substring(0,3);m(a);return{a:h.join(\"\").replace(/\\n$/,\"\"),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,\"pln\"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===\n\"string\")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b=\"pln\")}if((c=b.length>=5&&\"lang-\"===b.substring(0,5))&&!(o&&typeof o[1]===\"string\"))c=!1,b=\"src\";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),\nl=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=\"\"+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\\S\\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push([\"str\",/^(?:'''(?:[^'\\\\]|\\\\[\\S\\s]|''?(?=[^']))*(?:'''|$)|\"\"\"(?:[^\"\\\\]|\\\\[\\S\\s]|\"\"?(?=[^\"]))*(?:\"\"\"|$)|'(?:[^'\\\\]|\\\\[\\S\\s])*(?:'|$)|\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$))/,q,\"'\\\"\"]):a.multiLineStrings?m.push([\"str\",/^(?:'(?:[^'\\\\]|\\\\[\\S\\s])*(?:'|$)|\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$)|`(?:[^\\\\`]|\\\\[\\S\\s])*(?:`|$))/,\nq,\"'\\\"`\"]):m.push([\"str\",/^(?:'(?:[^\\n\\r'\\\\]|\\\\.)*(?:'|$)|\"(?:[^\\n\\r\"\\\\]|\\\\.)*(?:\"|$))/,q,\"\\\"'\"]);a.verbatimStrings&&e.push([\"str\",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push([\"com\",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,\"#\"]):m.push([\"com\",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\\b|[^\\n\\r]*)/,q,\"#\"]),e.push([\"str\",/^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h|[a-z]\\w*)>/,q])):m.push([\"com\",/^#[^\\n\\r]*/,\nq,\"#\"]));a.cStyleComments&&(e.push([\"com\",/^\\/\\/[^\\n\\r]*/,q]),e.push([\"com\",/^\\/\\*[\\S\\s]*?(?:\\*\\/|$)/,q]));a.regexLiterals&&e.push([\"lang-regex\",/^(?:^^\\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|,|-=|->|\\/|\\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\\^=|\\^\\^|\\^\\^=|{|\\||\\|=|\\|\\||\\|\\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*(\\/(?=[^*/])(?:[^/[\\\\]|\\\\[\\S\\s]|\\[(?:[^\\\\\\]]|\\\\[\\S\\s])*(?:]|$))+\\/)/]);(h=a.types)&&e.push([\"typ\",h]);a=(\"\"+a.keywords).replace(/^ | $/g,\n\"\");a.length&&e.push([\"kwd\",RegExp(\"^(?:\"+a.replace(/[\\s,]+/g,\"|\")+\")\\\\b\"),q]);m.push([\"pln\",/^\\s+/,q,\" \\r\\n\\t\\xa0\"]);e.push([\"lit\",/^@[$_a-z][\\w$@]*/i,q],[\"typ\",/^(?:[@_]?[A-Z]+[a-z][\\w$@]*|\\w+_t\\b)/,q],[\"pln\",/^[$_a-z][\\w$@]*/i,q],[\"lit\",/^(?:0x[\\da-f]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+-]?\\d+)?)[a-z]*/i,q,\"0123456789\"],[\"pln\",/^\\\\[\\S\\s]?/,q],[\"pun\",/^.[^\\s\\w\"-$'./@\\\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if(\"BR\"===a.nodeName)h(a),\na.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}\nfor(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\\s)nocode(?:\\s|$)/,t=/\\r\\n?|\\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue(\"white-space\"));var p=l&&\"pre\"===l.substring(0,3);for(l=s.createElement(\"LI\");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute(\"value\",\nm);var r=s.createElement(\"OL\");r.className=\"linenums\";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className=\"L\"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode(\"\\xa0\")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn(\"cannot override language handler %s\",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\\s*</.test(m)?\"default-markup\":\"default-code\";return A[a]}function E(a){var m=\na.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\\bMSIE\\b/.test(navigator.userAgent),m=/\\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,\"\\r\"));i.nodeValue=\nj;var u=i.ownerDocument,v=u.createElement(\"SPAN\");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){\"console\"in window&&console.log(w&&w.stack?w.stack:w)}}var v=[\"break,continue,do,else,for,if,return,while\"],w=[[v,\"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile\"],\n\"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof\"],F=[w,\"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where\"],G=[w,\"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient\"],\nH=[G,\"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var\"],w=[w,\"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN\"],I=[v,\"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None\"],\nJ=[v,\"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END\"],v=[v,\"case,done,elif,esac,eval,fi,function,in,local,set,then,until\"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\\d*)/,N=/\\S/,O=u({keywords:[F,H,w,\"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END\"+\nI,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,[\"default-code\"]);k(x([],[[\"pln\",/^[^<?]+/],[\"dec\",/^<!\\w[^>]*(?:>|$)/],[\"com\",/^<\\!--[\\S\\s]*?(?:--\\>|$)/],[\"lang-\",/^<\\?([\\S\\s]+?)(?:\\?>|$)/],[\"lang-\",/^<%([\\S\\s]+?)(?:%>|$)/],[\"pun\",/^(?:<[%?]|[%?]>)/],[\"lang-\",/^<xmp\\b[^>]*>([\\S\\s]+?)<\\/xmp\\b[^>]*>/i],[\"lang-js\",/^<script\\b[^>]*>([\\S\\s]*?)(<\\/script\\b[^>]*>)/i],[\"lang-css\",/^<style\\b[^>]*>([\\S\\s]*?)(<\\/style\\b[^>]*>)/i],[\"lang-in.tag\",/^(<\\/?[a-z][^<>]*>)/i]]),\n[\"default-markup\",\"htm\",\"html\",\"mxml\",\"xhtml\",\"xml\",\"xsl\"]);k(x([[\"pln\",/^\\s+/,q,\" \\t\\r\\n\"],[\"atv\",/^(?:\"[^\"]*\"?|'[^']*'?)/,q,\"\\\"'\"]],[[\"tag\",/^^<\\/?[a-z](?:[\\w-.:]*\\w)?|\\/?>$/i],[\"atn\",/^(?!style[\\s=]|on)[a-z](?:[\\w:-]*\\w)?/i],[\"lang-uq.val\",/^=\\s*([^\\s\"'>]*(?:[^\\s\"'/>]|\\/(?=\\s)))/],[\"pun\",/^[/<->]+/],[\"lang-js\",/^on\\w+\\s*=\\s*\"([^\"]+)\"/i],[\"lang-js\",/^on\\w+\\s*=\\s*'([^']+)'/i],[\"lang-js\",/^on\\w+\\s*=\\s*([^\\s\"'>]+)/i],[\"lang-css\",/^style\\s*=\\s*\"([^\"]+)\"/i],[\"lang-css\",/^style\\s*=\\s*'([^']+)'/i],[\"lang-css\",\n/^style\\s*=\\s*([^\\s\"'>]+)/i]]),[\"in.tag\"]);k(x([],[[\"atv\",/^[\\S\\s]+/]]),[\"uq.val\"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),[\"c\",\"cc\",\"cpp\",\"cxx\",\"cyc\",\"m\"]);k(u({keywords:\"null,true,false\"}),[\"json\"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),[\"cs\"]);k(u({keywords:G,cStyleComments:!0}),[\"java\"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),[\"bsh\",\"csh\",\"sh\"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),\n[\"cv\",\"py\"]);k(u({keywords:\"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END\",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),[\"perl\",\"pl\",\"pm\"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),[\"rb\"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),[\"js\"]);k(u({keywords:\"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes\",\nhashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),[\"coffee\"]);k(x([],[[\"str\",/^[\\S\\s]+/]]),[\"regex\"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement(\"PRE\");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf(\"prettyprint\")>=0){var k=k.match(g),f,b;if(b=\n!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&\"CODE\"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName===\"pre\"||o.tagName===\"code\"||o.tagName===\"xmp\")&&o.className&&o.className.indexOf(\"prettyprint\")>=0){b=!0;break}b||((b=(b=n.className.match(/\\blinenums\\b(?::(\\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,\n250):a&&a()}for(var e=[document.getElementsByTagName(\"pre\"),document.getElementsByTagName(\"code\"),document.getElementsByTagName(\"xmp\")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\\blang(?:uage)?-([\\w.]+)(?!\\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:\"atn\",PR_ATTRIB_VALUE:\"atv\",PR_COMMENT:\"com\",PR_DECLARATION:\"dec\",PR_KEYWORD:\"kwd\",PR_LITERAL:\"lit\",\nPR_NOCODE:\"nocode\",PR_PLAIN:\"pln\",PR_PUNCTUATION:\"pun\",PR_SOURCE:\"src\",PR_STRING:\"str\",PR_TAG:\"tag\",PR_TYPE:\"typ\"}})();\n"
  }
]