[
  {
    "path": ".hgignore",
    "content": "syntax: glob\r\n*/target/*\r\ntarget/*\r\n*/build\r\nbuild\r\n*/.project\r\n*/.classpath\r\n*/.*\r\n\r\n.*\r\n*.bak\r\n*.orig\r\n*/nb-configuration.xml\r\n*.iml\r\n*.ipr\r\n*.iws\r\n*~\r\n\r\n"
  },
  {
    "path": ".hgtags",
    "content": "9361e645790f70de30f5ca05bff21f55ecddaddc 0.0.6\n4713eec717a35774e6d34ac0819982d2bc34bdc5 0.0.7\n6743b6bb8a38b17fe13ca54edec6727f76cd8ad3 0.0.7.1\n5de91e5a0e9537e02fe47f044b23776757594d4e 0.0.7.2\n98cb7e78cfaf68667f150cf7eefe671bad1ac5e7 0.0.7.3\nf415c01ff9255523595e1675e63e4761cf5ec370 0.0.7.4\n9605cc1f3139c57763040fd30281dcdc81cafb3d 0.0.7.5\n45e1e724eee2e630e589896c55ac86d910e498e1 0.0.7.6\ncb85fc62c81871c3054493b036094a8aeebd08d4 0.0.7.7\n9bb7ad84eace90e5702592db47407a6eae8baa6e 0.0.7.8\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: java\njdk:\n- openjdk8\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\r\n                                 Apache License\r\n                           Version 2.0, January 2004\r\n                        http://www.apache.org/licenses/\r\n\r\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction,\r\n      and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by\r\n      the copyright owner that is granting the License.\r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all\r\n      other entities that control, are controlled by, or are under common\r\n      control with that entity. For the purposes of this definition,\r\n      \"control\" means (i) the power, direct or indirect, to cause the\r\n      direction or management of such entity, whether by contract or\r\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n      outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n      exercising permissions granted by this License.\r\n\r\n      \"Source\" form shall mean the preferred form for making modifications,\r\n      including but not limited to software source code, documentation\r\n      source, and configuration files.\r\n\r\n      \"Object\" form shall mean any form resulting from mechanical\r\n      transformation or translation of a Source form, including but\r\n      not limited to compiled object code, generated documentation,\r\n      and conversions to other media types.\r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or\r\n      Object form, made available under the License, as indicated by a\r\n      copyright notice that is included in or attached to the work\r\n      (an example is provided in the Appendix below).\r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object\r\n      form, that is based on (or derived from) the Work and for which the\r\n      editorial revisions, annotations, elaborations, or other modifications\r\n      represent, as a whole, an original work of authorship. For the purposes\r\n      of this License, Derivative Works shall not include works that remain\r\n      separable from, or merely link (or bind by name) to the interfaces of,\r\n      the Work and Derivative Works thereof.\r\n\r\n      \"Contribution\" shall mean any work of authorship, including\r\n      the original version of the Work and any modifications or additions\r\n      to that Work or Derivative Works thereof, that is intentionally\r\n      submitted to Licensor for inclusion in the Work by the copyright owner\r\n      or by an individual or Legal Entity authorized to submit on behalf of\r\n      the copyright owner. For the purposes of this definition, \"submitted\"\r\n      means any form of electronic, verbal, or written communication sent\r\n      to the Licensor or its representatives, including but not limited to\r\n      communication on electronic mailing lists, source code control systems,\r\n      and issue tracking systems that are managed by, or on behalf of, the\r\n      Licensor for the purpose of discussing and improving the Work, but\r\n      excluding communication that is conspicuously marked or otherwise\r\n      designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n      on behalf of whom a Contribution has been received by Licensor and\r\n      subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      copyright license to reproduce, prepare Derivative Works of,\r\n      publicly display, publicly perform, sublicense, and distribute the\r\n      Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      (except as stated in this section) patent license to make, have made,\r\n      use, offer to sell, sell, import, and otherwise transfer the Work,\r\n      where such license applies only to those patent claims licensable\r\n      by such Contributor that are necessarily infringed by their\r\n      Contribution(s) alone or by combination of their Contribution(s)\r\n      with the Work to which such Contribution(s) was submitted. If You\r\n      institute patent litigation against any entity (including a\r\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n      or a Contribution incorporated within the Work constitutes direct\r\n      or contributory patent infringement, then any patent licenses\r\n      granted to You under this License for that Work shall terminate\r\n      as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the\r\n      Work or Derivative Works thereof in any medium, with or without\r\n      modifications, and in Source or Object form, provided that You\r\n      meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or\r\n          Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices\r\n          stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works\r\n          that You distribute, all copyright, patent, trademark, and\r\n          attribution notices from the Source form of the Work,\r\n          excluding those notices that do not pertain to any part of\r\n          the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its\r\n          distribution, then any Derivative Works that You distribute must\r\n          include a readable copy of the attribution notices contained\r\n          within such NOTICE file, excluding those notices that do not\r\n          pertain to any part of the Derivative Works, in at least one\r\n          of the following places: within a NOTICE text file distributed\r\n          as part of the Derivative Works; within the Source form or\r\n          documentation, if provided along with the Derivative Works; or,\r\n          within a display generated by the Derivative Works, if and\r\n          wherever such third-party notices normally appear. The contents\r\n          of the NOTICE file are for informational purposes only and\r\n          do not modify the License. You may add Your own attribution\r\n          notices within Derivative Works that You distribute, alongside\r\n          or as an addendum to the NOTICE text from the Work, provided\r\n          that such additional attribution notices cannot be construed\r\n          as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and\r\n      may provide additional or different license terms and conditions\r\n      for use, reproduction, or distribution of Your modifications, or\r\n      for any such Derivative Works as a whole, provided Your use,\r\n      reproduction, and distribution of the Work otherwise complies with\r\n      the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise,\r\n      any Contribution intentionally submitted for inclusion in the Work\r\n      by You to the Licensor shall be under the terms and conditions of\r\n      this License, without any additional terms or conditions.\r\n      Notwithstanding the above, nothing herein shall supersede or modify\r\n      the terms of any separate license agreement you may have executed\r\n      with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade\r\n      names, trademarks, service marks, or product names of the Licensor,\r\n      except as required for reasonable and customary use in describing the\r\n      origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or\r\n      agreed to in writing, Licensor provides the Work (and each\r\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n      implied, including, without limitation, any warranties or conditions\r\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n      PARTICULAR PURPOSE. You are solely responsible for determining the\r\n      appropriateness of using or redistributing the Work and assume any\r\n      risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory,\r\n      whether in tort (including negligence), contract, or otherwise,\r\n      unless required by applicable law (such as deliberate and grossly\r\n      negligent acts) or agreed to in writing, shall any Contributor be\r\n      liable to You for damages, including any direct, indirect, special,\r\n      incidental, or consequential damages of any character arising as a\r\n      result of this License or out of the use or inability to use the\r\n      Work (including but not limited to damages for loss of goodwill,\r\n      work stoppage, computer failure or malfunction, or any and all\r\n      other commercial damages or losses), even if such Contributor\r\n      has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing\r\n      the Work or Derivative Works thereof, You may choose to offer,\r\n      and charge a fee for, acceptance of support, warranty, indemnity,\r\n      or other liability obligations and/or rights consistent with this\r\n      License. However, in accepting such obligations, You may act only\r\n      on Your own behalf and on Your sole responsibility, not on behalf\r\n      of any other Contributor, and only if You agree to indemnify,\r\n      defend, and hold each Contributor harmless for any liability\r\n      incurred by, or claims asserted against, such Contributor by reason\r\n      of your accepting any such warranty or additional liability.\r\n\r\n   END OF TERMS AND CONDITIONS\r\n\r\n   APPENDIX: How to apply the Apache License to your work.\r\n\r\n      To apply the Apache License to your work, attach the following\r\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n      replaced with your own identifying information. (Don't include\r\n      the brackets!)  The text should be enclosed in the appropriate\r\n      comment syntax for the file format. We also recommend that a\r\n      file or class name and description of purpose be included on the\r\n      same \"printed page\" as the copyright notice for easier\r\n      identification within third-party archives.\r\n\r\n   Copyright [yyyy] [name of copyright owner]\r\n\r\n   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n   you may not use this file except in compliance with the License.\r\n   You may obtain a copy of the License at\r\n\r\n       http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n   Unless required by applicable law or agreed to in writing, software\r\n   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n   See the License for the specific language governing permissions and\r\n   limitations under the License.\r\n\r\n"
  },
  {
    "path": "NOTICE.txt",
    "content": "dex2jar - Tools to work with android .dex and java .class files\r\nCopyright (c) 2009-2014 Panxiaobo\r\n\r\ncontributors\r\n  - Bob Pan <pxb1988#gmail.com>\r\n  - Enea Stanzani <aeneas.ltr#gmail.com>\r\n  - t3stwhat <t3stwhat#gmail.com>\r\n  - paulhooijenga <paulhooijenga#gmail.com>\r\n  - yyjdelete <yyjdelete#gmail.com>\r\n  - jcmdev0 <jcmdev0#gmail.com>\r\n"
  },
  {
    "path": "README.md",
    "content": "**Project move to [SourceForge](https://sourceforge.net/p/dex2jar) and [Bitbucket](https://bitbucket.org/pxb1988/dex2jar) and [Github](https://github.com/pxb1988/dex2jar)**\r\n\r\n| _ | Mirror | Wiki | Downloads | Issues |\r\n|--:|:-----|:----:|:---------:|:------:|\r\n| sf | https://sourceforge.net/p/dex2jar | [Wiki](https://sourceforge.net/p/dex2jar/wiki) | [Downloads](https://sourceforge.net/projects/dex2jar/files/) | [Tickets](https://sourceforge.net/p/dex2jar/tickets/) |\r\n| bb | https://bitbucket.org/pxb1988/dex2jar | [Wiki](https://bitbucket.org/pxb1988/dex2jar/wiki) | [Downloads](https://bitbucket.org/pxb1988/dex2jar/downloads) | [Issues](https://bitbucket.org/pxb1988/dex2jar/issues) |\r\n| gh | https://github.com/pxb1988/dex2jar | [Wiki](https://github.com/pxb1988/dex2jar/wiki) | [Releases](https://github.com/pxb1988/dex2jar/releases) | [Issues](https://github.com/pxb1988/dex2jar/issues) |\r\n| gc | https://code.google.com/p/dex2jar | [old](http://code.google.com/p/dex2jar/w/list) | [old](http://code.google.com/p/dex2jar/downloads/list) | [old](http://code.google.com/p/dex2jar/issues/list)|\r\n\r\n\r\n#dex2jar [![Build Status](https://travis-ci.org/pxb1988/dex2jar.svg?branch=2.x)](https://travis-ci.org/pxb1988/dex2jar)\r\nTools to work with android .dex and java .class files\r\n\r\n1. dex-reader/writer:\r\n    Read/write the Dalvik Executable (.dex) file. It has a [light weight API similar with ASM](https://sourceforge.net/p/dex2jar/wiki/Faq#markdown-header-want-to-read-dex-file-using-dex2jar).\r\n2. d2j-dex2jar:\r\n    Convert .dex file to .class files (zipped as jar)\r\n3. smali/baksmali:\r\n    disassemble dex to smali files and assemble dex from smali files. different implementation to [smali/baksmali](http://code.google.com/p/smali), same syntax, but we support escape in type desc \"Lcom/dex2jar\\t\\u1234;\"\r\n4. other tools:\r\n    [d2j-decrypt-string](https://sourceforge.net/p/dex2jar/wiki/DecryptStrings)\r\n\r\n## Usage\r\n\r\n> sh d2j-dex2jar.sh -f ~/path/to/apk_to_decompile.apk\r\n\r\nAnd the output file will be `apk_to_decompile-dex2jar.jar`.\r\n\r\n## Need help ?\r\nsend email to dex2jar@googlegroups.com \r\n\r\nor post on issue trackers list above.\r\n\r\n## License\r\n[Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)\r\n\r\n"
  },
  {
    "path": "build.gradle",
    "content": "allprojects  {\n  apply plugin: 'maven'\n  apply plugin: 'idea'\n  apply plugin: 'eclipse'\n  group = 'com.googlecode.d2j'\n  version = '2.1-SNAPSHOT'\n}\n\ndefaultTasks('clean','distZip')\n\nsubprojects {\n  apply plugin: 'java'\n  apply plugin: 'maven'\n  sourceCompatibility = 1.7\n  targetCompatibility = 1.7\n\n  task packageSources(type: Jar) {\n    classifier = 'sources'\n    from sourceSets.main.allSource\n  }\n  artifacts.archives packageSources\n  repositories {\n    mavenCentral()\n  }\n\n// == support provided scope\n  configurations {\n    provided\n  }\n  sourceSets {\n      main { compileClasspath += configurations.provided }\n      test {\n        compileClasspath += configurations.provided\n      }\n  }\n// == end\n\n  [compileJava, compileTestJava]*.options.collect {options ->options.encoding = 'UTF-8'}\n\n  dependencies {\n    testCompile group: 'junit', name: 'junit', version:'4.11'\n    compile fileTree(dir: 'libs', include: '*.jar')\n  }\n\n  jar {\n    manifest {\n      attributes(\"Implementation-Title\": project.name,\n                 \"Implementation-Version\": project.version,\n                 \"Build-Time\": new Date().format(\"yyyy-MM-dd'T'HH:mm:ssZ\"),\n                 \"Revision\":\"${getRevision()}\",\n                 \"Build-Number\": System.env.BUILD_NUMBER?System.env.BUILD_NUMBER:\"-1\",\n      )\n    }\n    from (project.parent.projectDir)  {\n      include 'NOTICE.txt'\n      include 'LICENSE.txt'\n      into('META-INF')\n    }\n  }\n}\n\ndef getRevision() {\n  if (System.env.BUILD_REVISION) {\n    return System.env.BUILD_REVISION\n  }\n  if (System.env.GIT_REVISION) {\n    return System.env.GIT_REVISION\n  }\n  if (System.env.MERCURIAL_REVISION) {\n    System.env.MERCURIAL_REVISION\n  }\n\n  def ver = null;\n  try {\n    ver = 'git rev-parse --short HEAD'.execute().text.trim()\n  } catch (e) {\n    // ignore\n  }\n  if (!ver) {\n    try {\n      ver = 'hg id -i -b -t'.execute().text.split(' ')[0];\n    } catch (e) {\n      // ignore\n    }\n  }\n  if (!ver) {\n    ver = \"HEAD\"\n  }\n  return ver\n}\n"
  },
  {
    "path": "d2j-base-cmd/build.gradle",
    "content": "description = 'a simple cmd parser'\n\ndependencies {\n}\n"
  },
  {
    "path": "d2j-base-cmd/src/main/java/com/googlecode/dex2jar/tools/BaseCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.*;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.nio.file.spi.FileSystemProvider;\nimport java.util.*;\n\npublic abstract class BaseCmd {\n    public static String getBaseName(String fn) {\n        int x = fn.lastIndexOf('.');\n        return x >= 0 ? fn.substring(0, x) : fn;\n    }\n\n    public static String getBaseName(Path fn) {\n        return getBaseName(fn.getFileName().toString());\n    }\n\n    public interface FileVisitorX {\n        // change the relative from Path to String\n        // java.nio.file.ProviderMismatchException on jdk8\n        void visitFile(Path file, String relative) throws IOException;\n    }\n\n    public static void walkFileTreeX(final Path base, final FileVisitorX fv) throws IOException {\n        Files.walkFileTree(base, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                fv.visitFile(file, base.relativize(file).toString());\n                return super.visitFile(file, attrs);\n            }\n        });\n    }\n\n    public static void walkJarOrDir(final Path in, final FileVisitorX fv) throws IOException {\n        if (Files.isDirectory(in)) {\n            walkFileTreeX(in, fv);\n        } else {\n            try (FileSystem inputFileSystem = openZip(in)) {\n                walkFileTreeX(inputFileSystem.getPath(\"/\"), fv);\n            }\n        }\n    }\n\n    public static void createParentDirectories(Path p) throws IOException {\n        // merge patch from t3stwhat, fix crash on save to windows path like 'C:\\\\abc.jar'\n        Path parent = p.getParent();\n        if (parent != null && !Files.exists(parent)) {\n            Files.createDirectories(parent);\n        }\n    }\n\n    public static FileSystem createZip(Path output) throws IOException {\n        Map<String, Object> env = new HashMap<>();\n        env.put(\"create\", \"true\");\n        Files.deleteIfExists(output);\n\n        createParentDirectories(output);\n\n        for (FileSystemProvider p : FileSystemProvider.installedProviders()) {\n            String s = p.getScheme();\n            if (\"jar\".equals(s) || \"zip\".equalsIgnoreCase(s)) {\n                return p.newFileSystem(output, env);\n            }\n        }\n        throw new IOException(\"cant find zipfs support\");\n    }\n\n    public static FileSystem openZip(Path in) throws IOException {\n        for (FileSystemProvider p : FileSystemProvider.installedProviders()) {\n            String s = p.getScheme();\n            if (\"jar\".equals(s) || \"zip\".equalsIgnoreCase(s)) {\n                return p.newFileSystem(in, new HashMap<String, Object>());\n            }\n        }\n        throw new IOException(\"cant find zipfs support\");\n    }\n\n    @SuppressWarnings(\"serial\")\n    protected static class HelpException extends RuntimeException {\n\n        public HelpException() {\n            super();\n        }\n\n        public HelpException(String message) {\n            super(message);\n        }\n\n    }\n\n    @Retention(value = RetentionPolicy.RUNTIME)\n    @Target(value = { ElementType.FIELD })\n    static public @interface Opt {\n        String argName() default \"\";\n\n        String description() default \"\";\n\n        boolean hasArg() default true;\n\n        String longOpt() default \"\";\n\n        String opt() default \"\";\n\n        boolean required() default false;\n    }\n\n    static protected class Option implements Comparable<Option> {\n        public String argName = \"arg\";\n        public String description;\n        public Field field;\n        public boolean hasArg = true;\n        public String longOpt;\n        public String opt;\n        public boolean required = false;\n\n        @Override\n        public int compareTo(Option o) {\n            int result = s(this.opt, o.opt);\n            if (result == 0) {\n                result = s(this.longOpt, o.longOpt);\n                if (result == 0) {\n                    result = s(this.argName, o.argName);\n                    if (result == 0) {\n                        result = s(this.description, o.description);\n                    }\n                }\n            }\n            return result;\n        }\n\n        private static int s(String a, String b) {\n            if (a != null && b != null) {\n                return a.compareTo(b);\n            } else if (a != null) {\n                return 1;\n            } else if (b != null) {\n                return -1;\n            } else {\n                return 0;\n            }\n        }\n\n        public String getOptAndLongOpt() {\n            StringBuilder sb = new StringBuilder();\n            boolean havePrev = false;\n            if (opt != null && opt.length() > 0) {\n            sb.append(\"-\").append(opt);\n                havePrev = true;\n            }\n            if (longOpt != null && longOpt.length() > 0) {\n                if (havePrev) {\n                sb.append(\",\");\n            }\n                sb.append(\"--\").append(longOpt);\n            }\n            return sb.toString();\n        }\n\n    }\n\n    @Retention(value = RetentionPolicy.RUNTIME)\n    @Target(value = { ElementType.TYPE })\n    static public @interface Syntax {\n\n        String cmd();\n\n        String desc() default \"\";\n\n        String onlineHelp() default \"\";\n\n        String syntax() default \"\";\n    }\n\n    private String cmdLineSyntax;\n\n    private String cmdName;\n    private String desc;\n    private String onlineHelp;\n\n    protected Map<String, Option> optMap = new HashMap<String, Option>();\n\n    @Opt(opt = \"h\", longOpt = \"help\", hasArg = false, description = \"Print this help message\")\n    private boolean printHelp = false;\n\n    protected String remainingArgs[];\n    protected String orginalArgs[];\n\n    public BaseCmd() {\n    }\n\n    public BaseCmd(String cmdLineSyntax, String header) {\n        super();\n        int i = cmdLineSyntax.indexOf(' ');\n        if (i > 0) {\n            this.cmdName = cmdLineSyntax.substring(0, i);\n            this.cmdLineSyntax = cmdLineSyntax.substring(i + 1);\n        }\n        this.desc = header;\n    }\n\n    public BaseCmd(String cmdName, String cmdSyntax, String header) {\n        super();\n        this.cmdName = cmdName;\n        this.cmdLineSyntax = cmdSyntax;\n        this.desc = header;\n    }\n\n    private Set<Option> collectRequriedOptions(Map<String, Option> optMap) {\n        Set<Option> options = new HashSet<Option>();\n        for (Map.Entry<String, Option> e : optMap.entrySet()) {\n            Option option = e.getValue();\n            if (option.required) {\n                options.add(option);\n            }\n        }\n        return options;\n    }\n\n    @SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n    protected Object convert(String value, Class type) {\n        if (type.equals(String.class)) {\n            return value;\n        }\n        if (type.equals(int.class) || type.equals(Integer.class)) {\n            return Integer.parseInt(value);\n        }\n        if (type.equals(long.class) || type.equals(Long.class)) {\n            return Long.parseLong(value);\n        }\n        if (type.equals(float.class) || type.equals(Float.class)) {\n            return Float.parseFloat(value);\n        }\n        if (type.equals(double.class) || type.equals(Double.class)) {\n            return Double.parseDouble(value);\n        }\n        if (type.equals(boolean.class) || type.equals(Boolean.class)) {\n            return Boolean.parseBoolean(value);\n        }\n        if (type.equals(File.class)) {\n            return new File(value);\n        }\n        if (type.equals(Path.class)) {\n            return new File(value).toPath();\n        }\n        try {\n            type.asSubclass(Enum.class);\n            return Enum.valueOf(type, value);\n        } catch (Exception e) {\n        }\n\n        throw new RuntimeException(\"can't convert [\" + value + \"] to type \" + type);\n    }\n\n    ;\n\n    protected abstract void doCommandLine() throws Exception;\n\n    public void doMain(String... args) {\n        try {\n            initOptions();\n            parseSetArgs(args);\n            doCommandLine();\n        } catch (HelpException e) {\n            String msg = e.getMessage();\n            if (msg != null && msg.length() > 0) {\n                System.err.println(\"ERROR: \" + msg);\n            }\n            usage();\n        } catch (Exception e) {\n            e.printStackTrace(System.err);\n        }\n    }\n\n    protected String getVersionString() {\n        return getClass().getPackage().getImplementationVersion();\n    }\n\n    protected void initOptionFromClass(Class<?> clz) {\n        if (clz == null) {\n            return;\n        } else {\n            initOptionFromClass(clz.getSuperclass());\n        }\n\n        Syntax syntax = clz.getAnnotation(Syntax.class);\n        if (syntax != null) {\n            this.cmdLineSyntax = syntax.syntax();\n            this.cmdName = syntax.cmd();\n            this.desc = syntax.desc();\n            this.onlineHelp = syntax.onlineHelp();\n        }\n\n        Field[] fs = clz.getDeclaredFields();\n        for (Field f : fs) {\n            Opt opt = f.getAnnotation(Opt.class);\n            if (opt != null) {\n                f.setAccessible(true);\n                Option option = new Option();\n                option.field = f;\n                option.description = opt.description();\n                option.hasArg = opt.hasArg();\n                option.required = opt.required();\n                if (\"\".equals(opt.longOpt()) && \"\".equals(opt.opt())) {   // into automode\n                    option.longOpt = fromCamel(f.getName());\n                    if (f.getType().equals(boolean.class)) {\n                        option.hasArg=false;\n                        try {\n                            if (f.getBoolean(this)) {\n                                throw new RuntimeException(\"the value of \" + f + \" must be false, as it is declared as no args\");\n                            }\n                        } catch (IllegalAccessException e) {\n                            throw new RuntimeException(e);\n                        }\n                    }\n                    checkConflict(option, \"--\" + option.longOpt);\n                    continue;\n                }\n                if (!opt.hasArg()) {\n                    if (!f.getType().equals(boolean.class)) {\n                        throw new RuntimeException(\"the type of \" + f\n                                + \" must be boolean, as it is declared as no args\");\n                    }\n\n                    try {\n                        if (f.getBoolean(this)) {\n                            throw new RuntimeException(\"the value of \" + f + \" must be false, as it is declared as no args\");\n                        }\n                    } catch (IllegalAccessException e) {\n                        throw new RuntimeException(e);\n                    }\n                }\n                boolean haveLongOpt = false;\n                if (!\"\".equals(opt.longOpt())) {\n                    option.longOpt = opt.longOpt();\n                    checkConflict(option, \"--\" + option.longOpt);\n                    haveLongOpt = true;\n                }\n                if (!\"\".equals(opt.argName())) {\n                    option.argName = opt.argName();\n                }\n                if (!\"\".equals(opt.opt())) {\n                    option.opt = opt.opt();\n                    checkConflict(option, \"-\" + option.opt);\n                } else {\n                    if (!haveLongOpt) {\n                        throw new RuntimeException(\"opt or longOpt is not set in @Opt(...) \" + f);\n                    }\n                }\n            }\n        }\n    }\n\n    private static String fromCamel(String name) {\n        if (name.length() == 0) {\n            return \"\";\n        }\n        StringBuilder sb = new StringBuilder();\n        char[] charArray = name.toCharArray();\n        sb.append(Character.toLowerCase(charArray[0]));\n        for (int i = 1; i < charArray.length; i++) {\n            char c = charArray[i];\n            if (Character.isUpperCase(c)) {\n                sb.append(\"-\").append(Character.toLowerCase(c));\n            } else {\n                sb.append(c);\n            }\n        }\n        return sb.toString();\n    }\n\n    private void checkConflict(Option option, String key) {\n        if (optMap.containsKey(key)) {\n            Option preOption = optMap.get(key);\n            throw new RuntimeException(String.format(\"[@Opt(...) %s] conflict with [@Opt(...) %s]\",\n                    preOption.field.toString(), option.field\n            ));\n        }\n        optMap.put(key, option);\n    }\n\n    protected void initOptions() {\n        initOptionFromClass(this.getClass());\n    }\n\n    public static void main(String... args) throws Exception {\n        if (args.length < 1) {\n            System.err.println(\"d2j-run <class> [args]\");\n            return;\n        }\n        Class<?> clz = Class.forName(args[0]);\n        String newArgs[] = new String[args.length - 1];\n        System.arraycopy(args, 1, newArgs, 0, newArgs.length);\n        if (BaseCmd.class.isAssignableFrom(clz)) {\n            BaseCmd baseCmd = (BaseCmd) clz.newInstance();\n            baseCmd.doMain(newArgs);\n        } else {\n            Method m = clz.getMethod(\"main\",String[].class);\n            m.setAccessible(true);\n            m.invoke(null, (Object)newArgs);\n        }\n    }\n    \n    protected void parseSetArgs(String... args) throws IllegalArgumentException, IllegalAccessException {\n        this.orginalArgs = args;\n        List<String> remainsOptions = new ArrayList<String>();\n        Set<Option> requiredOpts = collectRequriedOptions(optMap);\n        Option needArgOpt = null;\n        for (String s : args) {\n            if (needArgOpt != null) {\n                needArgOpt.field.set(this, convert(s, needArgOpt.field.getType()));\n                needArgOpt = null;\n            } else if (s.startsWith(\"-\")) {// its a short or long option\n                Option opt = optMap.get(s);\n                requiredOpts.remove(opt);\n                if (opt == null) {\n                    System.err.println(\"ERROR: Unrecognized option: \" + s);\n                    throw new HelpException();\n                } else {\n                    if (opt.hasArg) {\n                        needArgOpt = opt;\n                    } else {\n                        opt.field.set(this, true);\n                    }\n                }\n            } else {\n                remainsOptions.add(s);\n            }\n        }\n\n        if (needArgOpt != null) {\n            System.err.println(\"ERROR: Option \" + needArgOpt.getOptAndLongOpt() + \" need an argument value\");\n            throw new HelpException();\n        }\n        this.remainingArgs = remainsOptions.toArray(new String[remainsOptions.size()]);\n        if (this.printHelp) {\n            throw new HelpException();\n        }\n        if (!requiredOpts.isEmpty()) {\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"ERROR: Options: \");\n            boolean first = true;\n            for (Option option : requiredOpts) {\n                if (first) {\n                    first = false;\n                } else {\n                    sb.append(\" and \");\n                }\n                sb.append(option.getOptAndLongOpt());\n            }\n            sb.append(\" is required\");\n            System.err.println(sb.toString());\n            throw new HelpException();\n        }\n\n    }\n\n    protected void usage() {\n        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.err, StandardCharsets.UTF_8), true);\n\n        final int maxLength = 80;\n        final int maxPaLength = 40;\n        out.println(this.cmdName + \" -- \" + desc);\n        out.println(\"usage: \" + this.cmdName + \" \" + cmdLineSyntax);\n        if (this.optMap.size() > 0) {\n            out.println(\"options:\");\n        }\n        // [PART.A.........][Part.B\n        // .-a,--aa.<arg>...desc1\n        // .................desc2\n        // .-b,--bb\n        TreeSet<Option> options = new TreeSet<Option>(this.optMap.values());\n        int palength = -1;\n        for (Option option : options) {\n            int pa = 4 + option.getOptAndLongOpt().length();\n            if (option.hasArg) {\n                pa += 3 + option.argName.length();\n            }\n            if (pa < maxPaLength) {\n                if (pa > palength) {\n                    palength = pa;\n                }\n            }\n        }\n        int pblength = maxLength - palength;\n\n        StringBuilder sb = new StringBuilder();\n        for (Option option : options) {\n            sb.setLength(0);\n            sb.append(\" \").append(option.getOptAndLongOpt());\n            if (option.hasArg) {\n                sb.append(\" <\").append(option.argName).append(\">\");\n            }\n            String desc = option.description;\n            if (desc == null || desc.length() == 0) {// no description\n                out.println(sb);\n            } else {\n                for (int i = palength - sb.length(); i > 0; i--) {\n                    sb.append(' ');\n                }\n                if (sb.length() > maxPaLength) {// to huge part A\n                    out.println(sb);\n                    sb.setLength(0);\n                    for (int i = 0; i < palength; i++) {\n                        sb.append(' ');\n                    }\n                }\n                int nextStart = 0;\n                while (nextStart < desc.length()) {\n                    if (desc.length() - nextStart < pblength) {// can put in one line\n                        sb.append(desc.substring(nextStart));\n                        out.println(sb);\n                        nextStart = desc.length();\n                        sb.setLength(0);\n                    } else {\n                        sb.append(desc.substring(nextStart, nextStart + pblength));\n                        out.println(sb);\n                        nextStart += pblength;\n                        sb.setLength(0);\n                        if (nextStart < desc.length()) {\n                            for (int i = 0; i < palength; i++) {\n                                sb.append(' ');\n                            }\n                        }\n                    }\n                }\n                if (sb.length() > 0) {\n                    out.println(sb);\n                    sb.setLength(0);\n                }\n            }\n        }\n        String ver = getVersionString();\n        if (ver != null && !\"\".equals(ver)) {\n            out.println(\"version: \" + ver);\n        }\n        if (onlineHelp != null && !\"\".equals(onlineHelp)) {\n            if (onlineHelp.length() + \"online help: \".length() > maxLength) {\n                out.println(\"online help: \");\n                out.println(onlineHelp);\n            } else {\n                out.println(\"online help: \" + onlineHelp);\n            }\n        }\n        out.flush();\n    }\n}\n"
  },
  {
    "path": "d2j-j6/README.md",
    "content": "# j6 Generate dex2jar for jdk6\ndex2jar 2.0 change the compile jdk to version 1.7, but there still requirement for running dex2jar on jdk6. this project is try make dex2jar runnable on jdk6.\n\n## jdk7 vs jdk6\n\n### the major version of class file is changed\njdk6 can not run class file build for jdk7\n\n### new package java.nio.file\njdk7 add the java.nio.file package for file processing, and dex2jar heavy based on it, \n\n#### Related new Class\n * java.nio.file.\\*\\*\n\n#### Related new method\n * File.toPath()\n\n\n### try-with-resource\nThis is a good improvement for coding, i can' stop using it.\nthe AutoCloseable interface is used for close the resource, and addSuppressed/getSuppressed is Throwable is used for save the Exception during close resource.\n\n#### Related new Class\n * java.lang.AutoCloseable\n\n#### Related new method\n * Throwable.addSuppressed()\n * Throwable.getSuppressed()\n \n### other improvement\n\n#### Related new Class\n * java.nio.charset.StandardCharsets\n\n## Solution\n * For each missing class, create a new class with prefixed 'pxb.' in this project.\n * For each missing method, create a static method in this project and use the d2j-jar-weave feature of dex2jar to static weave the code into the origianl jar.\n```\nr Ljava/io/File;.toPath=Lj6/Files;.toPath(Ljava/io/File;)Ljava/lang/Object;\nr Ljava/lang/Throwable;.addSuppressed(Ljava/lang/Throwable;)=Lj6/Thro;.addSuppressed(Ljava/lang/Throwable;Ljava/lang/Throwable;)V;\nr [Ljava/lang/Throwable;.getSuppressed()=Lj6/Thro;.getSuppressed(Ljava/lang/Throwable;)[Ljava/lang/Throwable;\n```\n * Replace the following reference in original jar by the tool jarjar\n```\nrule java.nio.file.** pxb.@0\nrule java.nio.charset.StandardCharsets pxb.java.nio.charset.StandardCharsets\nrule java.lang.AutoCloseable java.io.Closeable\n```\n * Modify the version of all .class file to java6\n \n## Test\nthis the following VM have been tested (only the cmd d2j-dex2jar)\n\n * Oracle jdk 1.6.0_45, on 64bit linux\n * Dalvik VM on android 4.4.2 armv7a with '-Xmx512m' to increase memory\n\n\n"
  },
  {
    "path": "d2j-j6/build.gradle",
    "content": "configurations {\n    jarjar\n    proguard\n}\ndependencies {\n    compile project(':dex-tools')\n    jarjar 'com.googlecode.jarjar:jarjar:1.3'\n    proguard 'net.sf.proguard:proguard-base:5.2.1'\n}\ntask allinone(type: Jar, dependsOn: jar) {\n    archiveName = 'all-in-one.jar'\n    def deps = configurations.runtime\n    def depClasses = { deps.collect { it.isDirectory() ? it : zipTree(it) } }\n    from(depClasses) {\n        exclude 'META-INF/**'\n    }\n    from(sourceSets.main.output)\n    manifest {\n        attributes 'Main-Class': 'com.googlecode.dex2jar.tools.Dex2jarCmd'\n        attributes(\"Implementation-Title\": project.name,\n                \"Implementation-Version\": project.version,\n                \"Build-Time\": new Date().format(\"yyyy-MM-dd'T'HH:mm:ssZ\"),\n                \"Revision\":\"${getRevision()}\",\n                \"Build-Number\": System.env.BUILD_NUMBER?System.env.BUILD_NUMBER:\"-1\",\n        )\n    }\n}\n\ntask j6version(type: JavaExec, dependsOn: allinone) {\n    classpath sourceSets.main.runtimeClasspath\n    main='com.googlecode.dex2jar.tools.ClassVersionSwitch'\n    args=[\"6\",\"$allinone.destinationDir/$allinone.archiveName\", \"$allinone.destinationDir/j6.jar\"]\n}\n\ntask j6weave(type: JavaExec, dependsOn: j6version) {\n    classpath sourceSets.main.runtimeClasspath\n    main='com.googlecode.dex2jar.tools.JarWeaverCmd'\n    args=[\"-c\", \"$projectDir/j6-weave.txt\", \"$allinone.destinationDir/j6.jar\", \"-o\", \"$allinone.destinationDir/weaved.jar\"]\n}\n\ntask j6jarjar(type: JavaExec, dependsOn: j6weave) {\n    classpath configurations.jarjar\n    main='com.tonicsystems.jarjar.Main'\n    args=[\"process\", \"$projectDir/jarjar-rules.txt\", \"$allinone.destinationDir/weaved.jar\", \"$projectDir/build/dex2jar-for-jdk6.jar\"]\n}\n\ntask j6proguard(type: JavaExec, dependsOn: j6jarjar) {\n    classpath=configurations.proguard\n    main='proguard.ProGuard'\n    args=['-injars', \"$projectDir/build/dex2jar-for-jdk6.jar\" , '-outjars',\"$projectDir/build/dex2jar-for-jdk6-obfuscated.jar\", \"-printmapping\", \"$projectDir/build/dex2jar-for-jdk6-mapping.txt\", \"@$projectDir/proguard.txt\"]\n}\n\ntask jdk6 {\n    dependsOn j6jarjar\n    dependsOn j6proguard\n}"
  },
  {
    "path": "d2j-j6/j6-weave.txt",
    "content": "#\nr Ljava/io/File;.toPath=Lj6/Files;.toPath(Ljava/io/File;)Ljava/lang/Object;\nr Ljava/lang/Throwable;.addSuppressed(Ljava/lang/Throwable;)=Lj6/Thro;.addSuppressed(Ljava/lang/Throwable;Ljava/lang/Throwable;)V;\nr [Ljava/lang/Throwable;.getSuppressed()=Lj6/Thro;.getSuppressed(Ljava/lang/Throwable;)[Ljava/lang/Throwable;\n"
  },
  {
    "path": "d2j-j6/jarjar-rules.txt",
    "content": "rule java.nio.file.** pxb.@0\nrule java.nio.charset.StandardCharsets pxb.java.nio.charset.StandardCharsets\nrule java.lang.AutoCloseable java.io.Closeable\n"
  },
  {
    "path": "d2j-j6/proguard.txt",
    "content": "-libraryjars <java.home>/lib/rt.jar\n-keepattributes AnnotationDefault,RuntimeVisible*Annotations,Signature\n-repackageclasses d2j\n-allowaccessmodification\n#-dontobfuscate\n-keep public class com.googlecode.dex2jar.tools.Dex2jarCmd {public static void main(java.lang.String[]);}\n-keep,allowobfuscation public class com.googlecode.dex2jar.tools.Dex2jarCmd {@com.googlecode.dex2jar.tools.BaseCmd$Opt <fields>;}\n\n-dontwarn **\n"
  },
  {
    "path": "d2j-j6/src/main/java/j6/Files.java",
    "content": "package j6;\n\nimport pxb.java.nio.file.spi.FileSystemProvider;\n\nimport java.io.File;\n\npublic class Files {\n    public static Object toPath(File file) throws Throwable {\n        return new FileSystemProvider.DefPath(file);\n    }\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/j6/Thro.java",
    "content": "package j6;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Thro {\n\n    static Map<Throwable, List<Throwable>> aa = new HashMap<>();\n\n    public static void addSuppressed(Throwable a, Throwable b) {\n        List<Throwable> list = aa.get(a);\n        if (list == null) {\n            list = new ArrayList<>();\n            aa.put(a, list);\n        }\n        list.add(b);\n    }\n\n    public static Throwable[] getSuppressed(Throwable a) {\n        List<Throwable> list = aa.remove(a);\n        if (list == null) {\n            return null;\n        }\n        return list.toArray(new Throwable[list.size()]);\n    }\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/charset/StandardCharsets.java",
    "content": "package pxb.java.nio.charset;\n\nimport java.nio.charset.Charset;\n\npublic class StandardCharsets {\n    public static Charset UTF_8 = Charset.forName(\"UTF-8\");\n    public static Charset ISO_8859_1 = Charset.forName(\"iso-8859-1\");\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/CopyOption.java",
    "content": "package pxb.java.nio.file;\n\npublic interface CopyOption {\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/FileSystem.java",
    "content": "package pxb.java.nio.file;\n\nimport java.io.Closeable;\n\npublic abstract class FileSystem implements Closeable {\n    public abstract Path getPath(String first, String... more);\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/FileVisitResult.java",
    "content": "package pxb.java.nio.file;\n\n\npublic enum  FileVisitResult {\n    CONTINUE,TERMINATE,SKIP_SUBTREE, SKIP_SIBLINGS;\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/FileVisitor.java",
    "content": "package pxb.java.nio.file;\n\nimport java.io.IOException;\nimport pxb.java.nio.file.attribute.BasicFileAttributes;\n\npublic interface  FileVisitor<T> {\n\n    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)\n            throws IOException;\n\n    FileVisitResult visitFile(T file, BasicFileAttributes attrs)\n            throws IOException;\n\n    FileVisitResult visitFileFailed(T file, IOException exc)\n            throws IOException;\n\n    FileVisitResult postVisitDirectory(T dir, IOException exc)\n            throws IOException;\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/Files.java",
    "content": "package pxb.java.nio.file;\n\n\nimport pxb.java.nio.file.attribute.FileAttribute;\nimport pxb.java.nio.file.spi.FileSystemProvider;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\npublic class Files {\n    public static Path write(Path path, byte[] bytes, OpenOption... options)\n            throws IOException {\n        path._write(bytes);\n        return path;\n    }\n\n    public static byte[] readAllBytes(Path path) throws IOException {\n        return path._readAllBytes();\n    }\n\n    public static boolean isDirectory(Path path, LinkOption... options) {\n        return path._isDirectory();\n    }\n\n    public static boolean exists(Path path, LinkOption... options) {\n        return path._exists();\n    }\n\n    public static OutputStream newOutputStream(Path path, OpenOption... options)\n            throws IOException {\n        return path._newOutputStream();\n    }\n\n    public static InputStream newInputStream(Path path, OpenOption... options)\n            throws IOException {\n        return path._newInputStream();\n    }\n\n    public static boolean deleteIfExists(Path path) throws IOException {\n        return path._deleteIfExists();\n    }\n\n    public static Path createDirectories(Path dir, FileAttribute... attrs)\n            throws IOException {\n        return dir._createDirectories();\n    }\n\n    public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)\n            throws IOException {\n        start._walkFileTree(visitor);\n        return start;\n    }\n\n    public static Path createTempFile(String prefix,\n                                      String suffix,\n                                      FileAttribute<?>... attrs) throws IOException {\n        File f = File.createTempFile(prefix, suffix);\n        return new FileSystemProvider.DefPath(f, null);\n    }\n\n    public static Path copy(Path source, Path target, CopyOption... options) throws IOException {\n        InputStream is = source._newInputStream();\n        OutputStream os = target._newOutputStream();\n        FileSystemProvider.copy(is, os);\n        is.close();\n        os.close();\n        return target;\n    }\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/LinkOption.java",
    "content": "package pxb.java.nio.file;\n\npublic interface LinkOption {\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/OpenOption.java",
    "content": "package pxb.java.nio.file;\n\npublic interface OpenOption {\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/Path.java",
    "content": "package pxb.java.nio.file;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\npublic interface Path {\n\n    Path resolve(String other);\n\n    Path getFileName();\n\n    Path getParent();\n\n    File toFile();\n\n    String toString();\n\n    byte[] _readAllBytes() throws IOException;\n\n    OutputStream _newOutputStream() throws IOException;\n\n    boolean _isDirectory();\n\n    Path _createDirectories() throws IOException;\n\n    boolean _deleteIfExists();\n\n    boolean _exists();\n\n    void _write(byte[] b) throws IOException;\n\n    void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException;\n\n    Path relativize(Path other);\n\n    InputStream _newInputStream() throws IOException;\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/SimpleFileVisitor.java",
    "content": "package pxb.java.nio.file;\n\nimport pxb.java.nio.file.attribute.BasicFileAttributes;\n\nimport java.io.IOException;\n\npublic class SimpleFileVisitor<T> implements FileVisitor<T> {\n    @Override\n    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)\n            throws IOException {\n        return FileVisitResult.CONTINUE;\n    }\n\n    @Override\n    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)\n            throws IOException {\n        return FileVisitResult.CONTINUE;\n    }\n\n    @Override\n    public FileVisitResult visitFileFailed(T file, IOException exc)\n            throws IOException {\n        throw exc;\n    }\n\n    @Override\n    public FileVisitResult postVisitDirectory(T dir, IOException exc)\n            throws IOException {\n        if (exc != null)\n            throw exc;\n        return FileVisitResult.CONTINUE;\n    }\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/attribute/BasicFileAttributes.java",
    "content": "package pxb.java.nio.file.attribute;\n\npublic interface BasicFileAttributes {\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/attribute/FileAttribute.java",
    "content": "package pxb.java.nio.file.attribute;\n\npublic interface FileAttribute<T> {\n}\n"
  },
  {
    "path": "d2j-j6/src/main/java/pxb/java/nio/file/spi/FileSystemProvider.java",
    "content": "package pxb.java.nio.file.spi;\n\nimport pxb.java.nio.file.FileSystem;\nimport pxb.java.nio.file.FileVisitor;\nimport pxb.java.nio.file.Path;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\npublic abstract class FileSystemProvider {\n    public static void copy(InputStream is, OutputStream os) throws IOException {\n        byte[] xml = new byte[10 * 1024];\n        for (int c = is.read(xml); c > 0; c = is.read(xml)) {\n            os.write(xml, 0, c);\n        }\n    }\n\n    public static byte[] readFile(File in) throws IOException {\n        InputStream is = new FileInputStream(in);\n        byte[] xml = new byte[is.available()];\n        is.read(xml);\n        is.close();\n        return xml;\n    }\n\n    public static byte[] readIs(InputStream is) throws IOException {\n        ByteArrayOutputStream os = new ByteArrayOutputStream();\n        copy(is, os);\n        return os.toByteArray();\n    }\n\n    public static void writeFile(byte[] data, File out) throws IOException {\n        FileOutputStream fos = new FileOutputStream(out);\n        fos.write(data);\n        fos.close();\n    }\n\n    public static FileSystemProvider ZIP = new ZipFSP();\n    public static FileSystemProvider DEF = new DirFSP();\n\n    public static List<FileSystemProvider> installedProviders() {\n        return Arrays.asList(ZIP, DEF);\n    }\n\n    public abstract String getScheme();\n\n    public abstract FileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException;\n\n\n    static class CreatZipFS extends FileSystem {\n        ZipOutputStream zos;\n\n        class CreateZipPath implements Path {\n            String path;\n            String displayName;\n\n            public CreateZipPath(String s, String displayName) {\n                this.path = s;\n                this.displayName = displayName;\n            }\n\n            @Override\n            public Path resolve(String other) {\n                if (path.endsWith(\"/\")) {\n                    return new CreateZipPath(path + other, null);\n                }\n                return new CreateZipPath(path + \"/\" + other, null);\n            }\n\n            @Override\n            public Path getFileName() {\n                int t = path.length() - 1;\n                if (path.endsWith(\"/\")) {\n                    t--;\n                }\n                int i = path.lastIndexOf('/', t);\n                if (i > 0) {\n                    return new CreateZipPath(path, path.substring(i + 1, t + 1));\n                } else {\n                    return this;\n                }\n            }\n\n            @Override\n            public String toString() {\n                return displayName != null ? displayName : path;\n            }\n\n            @Override\n            public Path getParent() {\n                int i = path.lastIndexOf('/', path.length() - 2);\n                if (i > 0) {\n                    return new CreateZipPath(path.substring(0, i), null);\n                }\n                return null;\n            }\n\n            @Override\n            public File toFile() {\n                return null;\n            }\n\n            @Override\n            public byte[] _readAllBytes() {\n                throw new RuntimeException();\n            }\n\n            @Override\n            public OutputStream _newOutputStream() throws IOException {\n                ZipEntry e = new ZipEntry(path.substring(1));\n                zos.putNextEntry(e);\n                return new FilterOutputStream(zos) {\n                    @Override\n                    public void close() throws IOException {\n                        zos.closeEntry();\n                    }\n                };\n            }\n\n            @Override\n            public boolean _isDirectory() {\n                return path.endsWith(\"/\");\n            }\n\n            @Override\n            public Path _createDirectories() throws IOException {\n                createDir0(path);\n                return this;\n            }\n\n            @Override\n            public boolean _deleteIfExists() {\n                throw new RuntimeException();\n            }\n\n            @Override\n            public boolean _exists() {\n                return exists(path);\n            }\n\n            @Override\n            public void _write(byte[] b) throws IOException {\n                OutputStream os = _newOutputStream();\n                os.write(b);\n                os.close();\n            }\n\n            @Override\n            public void _walkFileTree(FileVisitor<? super Path> visitor) {\n                throw new RuntimeException();\n            }\n\n            @Override\n            public Path relativize(Path other) {\n                CreateZipPath p0 = (CreateZipPath) other;\n                String display = path.substring(p0.path.length());\n                return new CreateZipPath(p0.path, display);\n            }\n\n            @Override\n            public InputStream _newInputStream() throws IOException {\n                throw new RuntimeException();\n            }\n        }\n\n        private boolean createDir0(String path) throws IOException {\n            int x = path.lastIndexOf('/', path.length() - 2);\n            if (x > 0) {\n                String n = path.substring(0, x + 1);\n                createDir0(n);\n            }\n            if (!path.contains(path)) {\n                files.add(path);\n                ZipEntry zipEntry = new ZipEntry(path);\n                zos.putNextEntry(zipEntry);\n                zos.closeEntry();\n                return true;\n            }\n            return false;\n        }\n\n        private Set<String> files = new HashSet<>();\n\n        private boolean exists(String path) {\n            return files.contains(path);\n        }\n\n        public CreatZipFS(ZipOutputStream zipFile) {\n            this.zos = zipFile;\n        }\n\n        @Override\n        public void close() throws IOException {\n            zos.close();\n        }\n\n        @Override\n        public Path getPath(String first, String... more) {\n            return new CreateZipPath(first, null);\n        }\n    }\n\n    static class ReadZipPath implements Path {\n        ZipFile zipFile;\n        String path;\n        String displayName;\n\n        public ReadZipPath(ZipFile zipFile, String path) {\n            this(zipFile, path, null);\n        }\n\n        public ReadZipPath(ZipFile zipFile, String path, String substring) {\n            this.zipFile = zipFile;\n            this.path = path;\n            this.displayName = substring;\n        }\n\n        @Override\n        public Path resolve(String other) {\n            if (path.endsWith(\"/\")) {\n                return new ReadZipPath(zipFile, path + other);\n            } else {\n                return new ReadZipPath(zipFile, path + \"/\" + other);\n            }\n        }\n\n        @Override\n        public Path getFileName() {\n            int t = path.length() - 1;\n            if (path.endsWith(\"/\")) {\n                t--;\n            }\n            int i = path.lastIndexOf('/', t);\n            if (i > 0) {\n                return new ReadZipPath(zipFile, path, path.substring(i + 1, t + 1));\n            } else {\n                return this;\n            }\n        }\n\n        @Override\n        public Path getParent() {\n            int t = path.length() - 1;\n            if (path.endsWith(\"/\")) {\n                t--;\n            }\n            int i = path.lastIndexOf('/', t);\n            return i > 0 ? new ReadZipPath(zipFile, path.substring(0, i + 1), null) : null;\n        }\n\n        @Override\n        public File toFile() {\n            return null;\n        }\n\n        @Override\n        public String toString() {\n            return displayName != null ? displayName : path;\n        }\n\n        @Override\n        public byte[] _readAllBytes() throws IOException {\n            ZipEntry e = zipFile.getEntry(path);\n            return e != null ? readIs(zipFile.getInputStream(e)) : null;\n        }\n\n        @Override\n        public OutputStream _newOutputStream() throws FileNotFoundException {\n            throw new RuntimeException();\n        }\n\n        @Override\n        public boolean _isDirectory() {\n            ZipEntry e = zipFile.getEntry(path);\n            return e != null && e.isDirectory();\n        }\n\n        @Override\n        public Path _createDirectories() {\n            throw new RuntimeException();\n        }\n\n        @Override\n        public boolean _deleteIfExists() {\n            throw new RuntimeException();\n        }\n\n        @Override\n        public boolean _exists() {\n            ZipEntry e = zipFile.getEntry(path);\n            return e != null;\n        }\n\n        @Override\n        public void _write(byte[] b) throws IOException {\n            throw new RuntimeException();\n        }\n\n        @Override\n        public void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException {\n            for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {\n                ZipEntry zipEntry = e.nextElement();\n                ReadZipPath readZipPath = new ReadZipPath(zipFile, zipEntry.getName());\n                if (zipEntry.isDirectory()) {\n                    visitor.preVisitDirectory(readZipPath, null);\n                    visitor.postVisitDirectory(readZipPath, null);\n                } else {\n                    visitor.visitFile(readZipPath, null);\n                }\n            }\n        }\n\n        @Override\n        public Path relativize(Path other) {\n            ReadZipPath p0 = (ReadZipPath) other;\n            String display = path.substring(p0.path.length());\n            return new ReadZipPath(zipFile, p0.path, display);\n        }\n\n        @Override\n        public InputStream _newInputStream() throws IOException {\n            ZipEntry e = zipFile.getEntry(path);\n            return e != null ? zipFile.getInputStream(e) : null;\n        }\n    }\n\n    static class ReadZipFS extends FileSystem {\n        ZipFile zipFile;\n\n        public ReadZipFS(ZipFile zipFile) {\n            this.zipFile = zipFile;\n        }\n\n        @Override\n        public void close() throws IOException {\n            zipFile.close();\n        }\n\n        @Override\n        public Path getPath(String first, String... more) {\n            return new ReadZipPath(zipFile, first);\n        }\n    }\n\n    static class ZipFSP extends FileSystemProvider {\n\n        @Override\n        public String getScheme() {\n            return \"zip\";\n        }\n\n        @Override\n        public FileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException {\n            if (env != null && \"true\".equals(env.get(\"create\"))) {\n                return new CreatZipFS(new ZipOutputStream(path._newOutputStream()));\n            } else {\n                return new ReadZipFS(new ZipFile(((DefPath) path).file));\n            }\n        }\n    }\n\n    public static class DefPath implements Path {\n        File file;\n        String displayName;\n\n        public DefPath(File file) {\n            this.file = file;\n        }\n\n        public DefPath(File file, String name) {\n            this.file = file;\n            this.displayName = name;\n        }\n\n        @Override\n        public String toString() {\n            return displayName != null ? displayName : file.toString();\n        }\n\n        @Override\n        public Path resolve(String other) {\n            return new DefPath(new File(file, other));\n        }\n\n        @Override\n        public Path getFileName() {\n            return new DefPath(file, file.getName());\n        }\n\n        @Override\n        public Path getParent() {\n            return new DefPath(file.getParentFile());\n        }\n\n        @Override\n        public File toFile() {\n            return file;\n        }\n\n        @Override\n        public byte[] _readAllBytes() throws IOException {\n            return readFile(file);\n        }\n\n        @Override\n        public OutputStream _newOutputStream() throws FileNotFoundException {\n            return new BufferedOutputStream(new FileOutputStream(file));\n        }\n\n        @Override\n        public boolean _isDirectory() {\n            return file.isDirectory();\n        }\n\n        @Override\n        public Path _createDirectories() {\n            file.mkdirs();\n            return this;\n        }\n\n        @Override\n        public boolean _deleteIfExists() {\n            return file.exists() && file.delete();\n        }\n\n        @Override\n        public boolean _exists() {\n            return file.exists();\n        }\n\n        @Override\n        public void _write(byte[] b) throws IOException {\n            OutputStream os = _newOutputStream();\n            os.write(b);\n            os.close();\n        }\n\n        @Override\n        public void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException {\n            walk0(this, visitor);\n        }\n\n        public static void walk0(DefPath dir, FileVisitor<? super Path> visitor) throws IOException {\n            visitor.preVisitDirectory(dir, null);\n            File[] fs = dir.file.listFiles();\n            if (fs != null) {\n                for (File f : fs) {\n                    if (f.isDirectory()) {\n                        walk0(new DefPath(f, null), visitor);\n                    } else {\n                        visitor.visitFile(new DefPath(f, null), null);\n                    }\n                }\n            }\n            visitor.postVisitDirectory(dir, null);\n        }\n\n        @Override\n        public Path relativize(Path other) {\n            DefPath p0 = (DefPath) other;\n            String display = file.getAbsolutePath().substring(p0.file.getAbsolutePath().length());\n            return new DefPath(p0.file, display);\n        }\n\n        @Override\n        public InputStream _newInputStream() throws FileNotFoundException {\n            return new BufferedInputStream(new FileInputStream(file));\n        }\n    }\n\n    static class DirFSP extends FileSystemProvider {\n\n        @Override\n        public String getScheme() {\n            return \"default\";\n        }\n\n        @Override\n        public FileSystem newFileSystem(Path path, Map<String, ?> env) {\n            throw new RuntimeException();\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-jasmin/build.gradle",
    "content": "apply plugin: 'antlr'\n\ndependencies {\n  compile(group: 'org.antlr', name: 'antlr-runtime', version:'3.5.2') {\n        exclude(module: 'stringtemplate')\n  }\n  compile \"org.ow2.asm:asm-debug-all:5.0.3\"\n  compile project(':d2j-base-cmd')\n  antlr \"org.antlr:antlr:3.5.2\"\n}\n\nsourceSets.main.antlr.srcDirs = ['src/main/antlr3']\n"
  },
  {
    "path": "d2j-jasmin/src/main/antlr3/com/googlecode/d2j/jasmin/Jasmin.g",
    "content": "grammar Jasmin;\r\n\r\n@header {\r\npackage com.googlecode.d2j.jasmin;\r\nimport java.util.List;\r\nimport java.util.ArrayList;\r\nimport java.math.BigInteger;\r\nimport org.objectweb.asm.*;\r\nimport org.objectweb.asm.tree.*;\r\nimport static org.objectweb.asm.Opcodes.*;\r\n}\r\n@lexer::header {\r\npackage com.googlecode.d2j.jasmin;\r\n}\r\n@members{\r\n    private static int versions[] = { 0, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, 52 // V1_8 ?\r\n            , 53 // V1_9 ?\r\n    };\r\n    private ClassNode cn;\r\n    private FieldNode fn;\r\n    private MethodNode mn;\r\n    private String tmp;\r\n    private int tmpInt;\r\n    private String tmp2;\r\n    public boolean rebuildLine=false;\r\n    private java.util.Map<String, Label> labelMap = new java.util.HashMap<>();\r\n    private void reset0() {\r\n        cn = new ClassNode(ASM4);\r\n        fn = null;\r\n        mn = null;\r\n    }\r\n\r\n    static private int parseInt(String str, int start, int end) {\r\n        int sof = start;\r\n        int x = 1;\r\n        if (str.charAt(sof) == '+') {\r\n            sof++;\r\n        } else if (str.charAt(sof) == '-') {\r\n            sof++;\r\n            x = -1;\r\n        }\r\n        long v;\r\n        if (str.charAt(sof) == '0') {\r\n            sof++;\r\n            if (sof >= end) {\r\n                return 0;\r\n            }\r\n            char c = str.charAt(sof);\r\n            if (c == 'x' || c == 'X') {// hex\r\n                sof++;\r\n                v = Long.parseLong(str.substring(sof, end), 16);\r\n            } else {// oct\r\n                v = Long.parseLong(str.substring(sof, end), 8);\r\n            }\r\n        } else {\r\n            v = Long.parseLong(str.substring(sof, end), 10);\r\n        }\r\n        return (int) (v * x);\r\n    }\r\n\r\n    static private int parseInt(String str) {\r\n        return parseInt(str, 0, str.length());\r\n    }\r\n\r\n    static private Long parseLong(String str) {\r\n        int sof = 0;\r\n        int end = str.length() - 1;\r\n        int x = 1;\r\n        if (str.charAt(sof) == '+') {\r\n            sof++;\r\n        } else if (str.charAt(sof) == '-') {\r\n            sof++;\r\n            x = -1;\r\n        }\r\n        BigInteger v;\r\n        if (str.charAt(sof) == '0') {\r\n            sof++;\r\n            if (sof >= end) {\r\n                return 0L;\r\n            }\r\n            char c = str.charAt(sof);\r\n            if (c == 'x' || c == 'X') {// hex\r\n                sof++;\r\n                v = new BigInteger(str.substring(sof, end), 16);\r\n            } else {// oct\r\n                v = new BigInteger(str.substring(sof, end), 8);\r\n            }\r\n        } else {\r\n            v = new BigInteger(str.substring(sof, end), 10);\r\n        }\r\n        if (x == -1) {\r\n            return v.negate().longValue();\r\n        } else {\r\n            return v.longValue();\r\n        }\r\n    }\r\n\r\n    static private float parseFloat(String str) {\r\n        str = str.toLowerCase();\r\n        int s = 0;\r\n        float x = 1f;\r\n        if (str.charAt(s) == '+') {\r\n            s++;\r\n        } else if (str.charAt(s) == '-') {\r\n            s++;\r\n            x = -1;\r\n        }\r\n        int e = str.length() - 1;\r\n        if (str.charAt(e) == 'f') {\r\n            e--;\r\n        }\r\n        str = str.substring(s, e + 1);\r\n        if (str.equals(\"floatnan\")) {\r\n            return Float.NaN;\r\n        }\r\n        if (str.equals(\"floatinfinity\")) {\r\n            return x < 0 ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;\r\n        }\r\n        return (float) x * Float.parseFloat(str);\r\n    }\r\n\r\n    static private double parseDouble(String str) {\r\n        str = str.toLowerCase();\r\n        int s = 0;\r\n        double x = 1;\r\n        if (str.charAt(s) == '+') {\r\n            s++;\r\n        } else if (str.charAt(s) == '-') {\r\n            s++;\r\n            x = -1;\r\n        }\r\n        int e = str.length() - 1;\r\n        if (str.charAt(e) == 'd') {\r\n            e--;\r\n        }\r\n        str = str.substring(s, e + 1);\r\n        if (str.equals(\"doublenan\")) {\r\n            return Double.NaN;\r\n        }\r\n        if (str.equals(\"doubleinfinity\")) {\r\n            return x < 0 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;\r\n        }\r\n        return x * Double.parseDouble(str);\r\n    }\r\n\r\n    private void line(int ln){\r\n         if(rebuildLine) {\r\n            Label label=new Label();\r\n            mn.visitLabel(label);\r\n            mn.visitLineNumber(ln, label);\r\n         }\r\n    }\r\n    private static String unEscapeString(String str) {\r\n        return unEscape0(str, 1, str.length() - 1);\r\n    }\r\n    private static String unEscape(String str) {\r\n            return unEscape0(str, 0, str.length());\r\n    }\r\n\r\n    private static String unEscape0(String str, int start, int end) {\r\n\r\n        StringBuilder sb = new StringBuilder();\r\n        for (int i = start; i < end;) {\r\n            char c = str.charAt(i);\r\n            if (c == '\\\\') {\r\n                char d = str.charAt(i + 1);\r\n                switch (d) {\r\n                // ('b'|'t'|'n'|'f'|'r'|'\\\"'|'\\''|'\\\\')\r\n                case 'b':\r\n                    sb.append('\\b');\r\n                    i += 2;\r\n                    break;\r\n                case 't':\r\n                    sb.append('\\t');\r\n                    i += 2;\r\n                    break;\r\n                case 'n':\r\n                    sb.append('\\n');\r\n                    i += 2;\r\n                    break;\r\n                case 'f':\r\n                    sb.append('\\f');\r\n                    i += 2;\r\n                    break;\r\n                case 'r':\r\n                    sb.append('\\r');\r\n                    i += 2;\r\n                    break;\r\n                case '\\\"':\r\n                    sb.append('\\\"');\r\n                    i += 2;\r\n                    break;\r\n                case '\\'':\r\n                    sb.append('\\'');\r\n                    i += 2;\r\n                    break;\r\n                case '\\\\':\r\n                    sb.append('\\\\');\r\n                    i += 2;\r\n                    break;\r\n                case 'u':\r\n                    String sub = str.substring(i + 2, i + 6);\r\n                    sb.append((char) Integer.parseInt(sub, 16));\r\n                    i += 6;\r\n                    break;\r\n                default:\r\n                    int x = 0;\r\n                    while (x < 3) {\r\n                        char e = str.charAt(i + 1 + x);\r\n                        if (e >= '0' && e <= '7') {\r\n                            x++;\r\n                        } else {\r\n                            break;\r\n                        }\r\n                    }\r\n                    if (x == 0) {\r\n                        throw new RuntimeException(\"can't pase string\");\r\n                    }\r\n                    sb.append((char) Integer.parseInt(str.substring(i + 1, i + 1 + x), 8));\r\n                    i += 1 + x;\r\n                }\r\n\r\n            } else {\r\n                sb.append(c);\r\n                i++;\r\n            }\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    private static int getAcc(String name) {\r\n        if (name.equals(\"public\")) {\r\n            return ACC_PUBLIC;\r\n        } else if (name.equals(\"private\")) {\r\n            return ACC_PRIVATE;\r\n        } else if (name.equals(\"protected\")) {\r\n            return ACC_PROTECTED;\r\n        } else if (name.equals(\"static\")) {\r\n            return ACC_STATIC;\r\n        } else if (name.equals(\"final\")) {\r\n            return ACC_FINAL;\r\n        } else if (name.equals(\"synchronized\")) {\r\n            return ACC_SYNCHRONIZED;\r\n        } else if (name.equals(\"volatile\")) {\r\n            return ACC_VOLATILE;\r\n        } else if (name.equals(\"bridge\")) {\r\n            return ACC_BRIDGE;\r\n        } else if (name.equals(\"varargs\")) {\r\n            return ACC_VARARGS;\r\n        } else if (name.equals(\"transient\")) {\r\n            return ACC_TRANSIENT;\r\n        } else if (name.equals(\"native\")) {\r\n            return ACC_NATIVE;\r\n        } else if (name.equals(\"interface\")) {\r\n            return ACC_INTERFACE;\r\n        } else if (name.equals(\"abstract\")) {\r\n            return ACC_ABSTRACT;\r\n        } else if (name.equals(\"strict\")) {\r\n            return ACC_STRICT;\r\n        } else if (name.equals(\"strictfp\")) {\r\n            return ACC_STRICT;\r\n        } else if (name.equals(\"synthetic\")) {\r\n            return ACC_SYNTHETIC;\r\n        } else if (name.equals(\"annotation\")) {\r\n            return ACC_ANNOTATION;\r\n        } else if (name.equals(\"enum\")) {\r\n            return ACC_ENUM;\r\n        } else if (name.equals(\"super\")) {\r\n            return ACC_SUPER;\r\n        }\r\n        throw new RuntimeException(\"not support access flags \" + name);\r\n    }\r\n    private static int getOp(String str) {\r\n            switch (str) {\r\n            case \"nop\":\r\n                return Opcodes.NOP;\r\n            case \"aconst_null\":\r\n                return Opcodes.ACONST_NULL;\r\n            case \"iconst_m1\":\r\n                return Opcodes.ICONST_M1;\r\n            case \"iconst_0\":\r\n                return Opcodes.ICONST_0;\r\n            case \"iconst_1\":\r\n                return Opcodes.ICONST_1;\r\n            case \"iconst_2\":\r\n                return Opcodes.ICONST_2;\r\n            case \"iconst_3\":\r\n                return Opcodes.ICONST_3;\r\n            case \"iconst_4\":\r\n                return Opcodes.ICONST_4;\r\n            case \"iconst_5\":\r\n                return Opcodes.ICONST_5;\r\n            case \"lconst_0\":\r\n                return Opcodes.LCONST_0;\r\n            case \"lconst_1\":\r\n                return Opcodes.LCONST_1;\r\n            case \"fconst_0\":\r\n                return Opcodes.FCONST_0;\r\n            case \"fconst_1\":\r\n                return Opcodes.FCONST_1;\r\n            case \"fconst_2\":\r\n                return Opcodes.FCONST_2;\r\n            case \"dconst_0\":\r\n                return Opcodes.DCONST_0;\r\n            case \"dconst_1\":\r\n                return Opcodes.DCONST_1;\r\n            case \"bipush\":\r\n                return Opcodes.BIPUSH;\r\n            case \"sipush\":\r\n                return Opcodes.SIPUSH;\r\n            case \"ldc_w\":\r\n            case \"ldc2_w\":\r\n            case \"ldc\":\r\n                return Opcodes.LDC;\r\n            case \"iload\":\r\n                return Opcodes.ILOAD;\r\n            case \"lload\":\r\n                return Opcodes.LLOAD;\r\n            case \"fload\":\r\n                return Opcodes.FLOAD;\r\n            case \"dload\":\r\n                return Opcodes.DLOAD;\r\n            case \"aload\":\r\n                return Opcodes.ALOAD;\r\n            case \"iaload\":\r\n                return Opcodes.IALOAD;\r\n            case \"laload\":\r\n                return Opcodes.LALOAD;\r\n            case \"faload\":\r\n                return Opcodes.FALOAD;\r\n            case \"daload\":\r\n                return Opcodes.DALOAD;\r\n            case \"aaload\":\r\n                return Opcodes.AALOAD;\r\n            case \"baload\":\r\n                return Opcodes.BALOAD;\r\n            case \"caload\":\r\n                return Opcodes.CALOAD;\r\n            case \"saload\":\r\n                return Opcodes.SALOAD;\r\n            case \"istore\":\r\n                return Opcodes.ISTORE;\r\n            case \"lstore\":\r\n                return Opcodes.LSTORE;\r\n            case \"fstore\":\r\n                return Opcodes.FSTORE;\r\n            case \"dstore\":\r\n                return Opcodes.DSTORE;\r\n            case \"astore\":\r\n                return Opcodes.ASTORE;\r\n            case \"iastore\":\r\n                return Opcodes.IASTORE;\r\n            case \"lastore\":\r\n                return Opcodes.LASTORE;\r\n            case \"fastore\":\r\n                return Opcodes.FASTORE;\r\n            case \"dastore\":\r\n                return Opcodes.DASTORE;\r\n            case \"aastore\":\r\n                return Opcodes.AASTORE;\r\n            case \"bastore\":\r\n                return Opcodes.BASTORE;\r\n            case \"castore\":\r\n                return Opcodes.CASTORE;\r\n            case \"sastore\":\r\n                return Opcodes.SASTORE;\r\n            case \"pop\":\r\n                return Opcodes.POP;\r\n            case \"pop2\":\r\n                return Opcodes.POP2;\r\n            case \"dup\":\r\n                return Opcodes.DUP;\r\n            case \"dup_x1\":\r\n                return Opcodes.DUP_X1;\r\n            case \"dup_x2\":\r\n                return Opcodes.DUP_X2;\r\n            case \"dup2\":\r\n                return Opcodes.DUP2;\r\n            case \"dup2_x1\":\r\n                return Opcodes.DUP2_X1;\r\n            case \"dup2_x2\":\r\n                return Opcodes.DUP2_X2;\r\n            case \"swap\":\r\n                return Opcodes.SWAP;\r\n            case \"iadd\":\r\n                return Opcodes.IADD;\r\n            case \"ladd\":\r\n                return Opcodes.LADD;\r\n            case \"fadd\":\r\n                return Opcodes.FADD;\r\n            case \"dadd\":\r\n                return Opcodes.DADD;\r\n            case \"isub\":\r\n                return Opcodes.ISUB;\r\n            case \"lsub\":\r\n                return Opcodes.LSUB;\r\n            case \"fsub\":\r\n                return Opcodes.FSUB;\r\n            case \"dsub\":\r\n                return Opcodes.DSUB;\r\n            case \"imul\":\r\n                return Opcodes.IMUL;\r\n            case \"lmul\":\r\n                return Opcodes.LMUL;\r\n            case \"fmul\":\r\n                return Opcodes.FMUL;\r\n            case \"dmul\":\r\n                return Opcodes.DMUL;\r\n            case \"idiv\":\r\n                return Opcodes.IDIV;\r\n            case \"ldiv\":\r\n                return Opcodes.LDIV;\r\n            case \"fdiv\":\r\n                return Opcodes.FDIV;\r\n            case \"ddiv\":\r\n                return Opcodes.DDIV;\r\n            case \"irem\":\r\n                return Opcodes.IREM;\r\n            case \"lrem\":\r\n                return Opcodes.LREM;\r\n            case \"frem\":\r\n                return Opcodes.FREM;\r\n            case \"drem\":\r\n                return Opcodes.DREM;\r\n            case \"ineg\":\r\n                return Opcodes.INEG;\r\n            case \"lneg\":\r\n                return Opcodes.LNEG;\r\n            case \"fneg\":\r\n                return Opcodes.FNEG;\r\n            case \"dneg\":\r\n                return Opcodes.DNEG;\r\n            case \"ishl\":\r\n                return Opcodes.ISHL;\r\n            case \"lshl\":\r\n                return Opcodes.LSHL;\r\n            case \"ishr\":\r\n                return Opcodes.ISHR;\r\n            case \"lshr\":\r\n                return Opcodes.LSHR;\r\n            case \"iushr\":\r\n                return Opcodes.IUSHR;\r\n            case \"lushr\":\r\n                return Opcodes.LUSHR;\r\n            case \"iand\":\r\n                return Opcodes.IAND;\r\n            case \"land\":\r\n                return Opcodes.LAND;\r\n            case \"ior\":\r\n                return Opcodes.IOR;\r\n            case \"lor\":\r\n                return Opcodes.LOR;\r\n            case \"ixor\":\r\n                return Opcodes.IXOR;\r\n            case \"lxor\":\r\n                return Opcodes.LXOR;\r\n            case \"iinc\":\r\n                return Opcodes.IINC;\r\n            case \"i2l\":\r\n                return Opcodes.I2L;\r\n            case \"i2f\":\r\n                return Opcodes.I2F;\r\n            case \"i2d\":\r\n                return Opcodes.I2D;\r\n            case \"l2i\":\r\n                return Opcodes.L2I;\r\n            case \"l2f\":\r\n                return Opcodes.L2F;\r\n            case \"l2d\":\r\n                return Opcodes.L2D;\r\n            case \"f2i\":\r\n                return Opcodes.F2I;\r\n            case \"f2l\":\r\n                return Opcodes.F2L;\r\n            case \"f2d\":\r\n                return Opcodes.F2D;\r\n            case \"d2i\":\r\n                return Opcodes.D2I;\r\n            case \"d2l\":\r\n                return Opcodes.D2L;\r\n            case \"d2f\":\r\n                return Opcodes.D2F;\r\n            case \"i2b\":\r\n                return Opcodes.I2B;\r\n            case \"i2c\":\r\n                return Opcodes.I2C;\r\n            case \"i2s\":\r\n                return Opcodes.I2S;\r\n            case \"lcmp\":\r\n                return Opcodes.LCMP;\r\n            case \"fcmpl\":\r\n                return Opcodes.FCMPL;\r\n            case \"fcmpg\":\r\n                return Opcodes.FCMPG;\r\n            case \"dcmpl\":\r\n                return Opcodes.DCMPL;\r\n            case \"dcmpg\":\r\n                return Opcodes.DCMPG;\r\n            case \"ifeq\":\r\n                return Opcodes.IFEQ;\r\n            case \"ifne\":\r\n                return Opcodes.IFNE;\r\n            case \"iflt\":\r\n                return Opcodes.IFLT;\r\n            case \"ifge\":\r\n                return Opcodes.IFGE;\r\n            case \"ifgt\":\r\n                return Opcodes.IFGT;\r\n            case \"ifle\":\r\n                return Opcodes.IFLE;\r\n            case \"if_icmpeq\":\r\n                return Opcodes.IF_ICMPEQ;\r\n            case \"if_icmpne\":\r\n                return Opcodes.IF_ICMPNE;\r\n            case \"if_icmplt\":\r\n                return Opcodes.IF_ICMPLT;\r\n            case \"if_icmpge\":\r\n                return Opcodes.IF_ICMPGE;\r\n            case \"if_icmpgt\":\r\n                return Opcodes.IF_ICMPGT;\r\n            case \"if_icmple\":\r\n                return Opcodes.IF_ICMPLE;\r\n            case \"if_acmpeq\":\r\n                return Opcodes.IF_ACMPEQ;\r\n            case \"if_acmpne\":\r\n                return Opcodes.IF_ACMPNE;\r\n            case \"goto\":\r\n                return Opcodes.GOTO;\r\n            case \"jsr\":\r\n                return Opcodes.JSR;\r\n            case \"ret\":\r\n                return Opcodes.RET;\r\n            case \"tableswitch\":\r\n                return Opcodes.TABLESWITCH;\r\n            case \"lookupswitch\":\r\n                return Opcodes.LOOKUPSWITCH;\r\n            case \"ireturn\":\r\n                return Opcodes.IRETURN;\r\n            case \"lreturn\":\r\n                return Opcodes.LRETURN;\r\n            case \"freturn\":\r\n                return Opcodes.FRETURN;\r\n            case \"dreturn\":\r\n                return Opcodes.DRETURN;\r\n            case \"areturn\":\r\n                return Opcodes.ARETURN;\r\n            case \"return\":\r\n                return Opcodes.RETURN;\r\n            case \"getstatic\":\r\n                return Opcodes.GETSTATIC;\r\n            case \"putstatic\":\r\n                return Opcodes.PUTSTATIC;\r\n            case \"getfield\":\r\n                return Opcodes.GETFIELD;\r\n            case \"putfield\":\r\n                return Opcodes.PUTFIELD;\r\n            case \"invokevirtual\":\r\n                return Opcodes.INVOKEVIRTUAL;\r\n            case \"invokespecial\":\r\n                return Opcodes.INVOKESPECIAL;\r\n            case \"invokestatic\":\r\n                return Opcodes.INVOKESTATIC;\r\n            case \"invokeinterface\":\r\n                return Opcodes.INVOKEINTERFACE;\r\n            case \"invokedynamic\":\r\n                return Opcodes.INVOKEDYNAMIC;\r\n            case \"new\":\r\n                return Opcodes.NEW;\r\n            case \"newarray\":\r\n                return Opcodes.NEWARRAY;\r\n            case \"anewarray\":\r\n                return Opcodes.ANEWARRAY;\r\n            case \"arraylength\":\r\n                return Opcodes.ARRAYLENGTH;\r\n            case \"athrow\":\r\n                return Opcodes.ATHROW;\r\n            case \"checkcast\":\r\n                return Opcodes.CHECKCAST;\r\n            case \"instanceof\":\r\n                return Opcodes.INSTANCEOF;\r\n            case \"monitorenter\":\r\n                return Opcodes.MONITORENTER;\r\n            case \"monitorexit\":\r\n                return Opcodes.MONITOREXIT;\r\n            case \"multianewarray\":\r\n                return Opcodes.MULTIANEWARRAY;\r\n            case \"ifnull\":\r\n                return Opcodes.IFNULL;\r\n            case \"ifnonnull\":\r\n                return Opcodes.IFNONNULL;\r\n            case \"iload_0\":\r\n                return 26;\r\n            case \"iload_1\":\r\n                return 27;\r\n            case \"iload_2\":\r\n                return 28;\r\n            case \"iload_3\":\r\n                return 29;\r\n            case \"lload_0\":\r\n                return 30;\r\n            case \"lload_1\":\r\n                return 31;\r\n            case \"lload_2\":\r\n                return 32;\r\n            case \"lload_3\":\r\n                return 33;\r\n            case \"fload_0\":\r\n                return 34;\r\n            case \"fload_1\":\r\n                return 35;\r\n            case \"fload_2\":\r\n                return 36;\r\n            case \"fload_3\":\r\n                return 37;\r\n            case \"dload_0\":\r\n                return 38;\r\n            case \"dload_1\":\r\n                return 39;\r\n            case \"dload_2\":\r\n                return 40;\r\n            case \"dload_3\":\r\n                return 41;\r\n            case \"aload_0\":\r\n                return 42;\r\n            case \"aload_1\":\r\n                return 43;\r\n            case \"aload_2\":\r\n                return 44;\r\n            case \"aload_3\":\r\n                return 45;\r\n            case \"istore_0\":\r\n                return 59;\r\n            case \"istore_1\":\r\n                return 60;\r\n            case \"istore_2\":\r\n                return 61;\r\n            case \"istore_3\":\r\n                return 62;\r\n            case \"lstore_0\":\r\n                return 63;\r\n            case \"lstore_1\":\r\n                return 64;\r\n            case \"lstore_2\":\r\n                return 65;\r\n            case \"lstore_3\":\r\n                return 66;\r\n            case \"fstore_0\":\r\n                return 67;\r\n            case \"fstore_1\":\r\n                return 68;\r\n            case \"fstore_2\":\r\n                return 69;\r\n            case \"fstore_3\":\r\n                return 70;\r\n            case \"dstore_0\":\r\n                return 71;\r\n            case \"dstore_1\":\r\n                return 72;\r\n            case \"dstore_2\":\r\n                return 73;\r\n            case \"dstore_3\":\r\n                return 74;\r\n            case \"astore_0\":\r\n                return 75;\r\n            case \"astore_1\":\r\n                return 76;\r\n            case \"astore_2\":\r\n                return 77;\r\n            case \"astore_3\":\r\n                return 78;\r\n            }\r\n            return 0;\r\n        }\r\n\r\n    private String[] parseOwnerAndName(String str) {\r\n        int x=str.lastIndexOf('/');\r\n        if(x>0){\r\n        return new String[]{ unEscape0(str,0,x), unEscape0(str,x+1,str.length()) };\r\n        }\r\n        throw new RuntimeException(\"can't get owner and type from '\"+str+\"'\");\r\n    }\r\n\r\n    public Object parseValue(String desc, Object v) {\r\n        switch(desc) {\r\n        case \"Z\": return ((Number)v).intValue()!=0;\r\n        case \"B\": return ((Number)v).byteValue();\r\n        case \"S\": return ((Number)v).shortValue();\r\n        case \"I\": return ((Number)v).intValue();\r\n        case \"F\": return ((Number)v).floatValue();\r\n        case \"D\": return ((Number)v).doubleValue();\r\n        case \"J\": return ((Number)v).longValue();\r\n        case \"C\": return (char)((Number)v).intValue();\r\n        }\r\n        return v;\r\n    }\r\n\r\n    static class AV {\r\n        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {\r\n            return null;\r\n        };\r\n\r\n        public AnnotationNode visitParameterAnnotation(final int parameter, final String desc, final boolean visible) {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    AV cnv = new AV() {\r\n        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {\r\n            return (AnnotationNode) cn.visitAnnotation(desc, visible);\r\n        }\r\n    };\r\n    AV fnv = new AV() {\r\n        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {\r\n            return (AnnotationNode) fn.visitAnnotation(desc, visible);\r\n        }\r\n    };\r\n    AV mnv = new AV() {\r\n        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {\r\n            return (AnnotationNode) mn.visitAnnotation(desc, visible);\r\n        }\r\n\r\n        public AnnotationNode visitParameterAnnotation(final int parameter, final String desc, final boolean visible) {\r\n            return (AnnotationNode) mn.visitParameterAnnotation(parameter, desc, visible);\r\n        }\r\n    };\r\n    private void visitOP0(int op){\r\n    if(op>=26&&op<=45){    // xload_y\r\n            int x=op-26;\r\n            mn.visitVarInsn(ILOAD+x/4,x\\%4);\r\n            }else if(op>=59&&op<=78){    // xstore_y\r\n                     int x=op-26;\r\n                     mn.visitVarInsn(ISTORE+x/4,x\\%4);\r\n            }else{\r\n        mn.visitInsn(op);\r\n        }\r\n    }\r\n    private void visitIOP(int op, int a){\r\n         // xstore\r\n         // xload\r\n         if(op>=21&&op<=58){\r\n         mn.visitVarInsn(op,a);\r\n         }  else {\r\n         // xipush\r\n         mn.visitIntInsn(op,a);\r\n         }\r\n    }\r\n    private void visitJOP(int op, Label label){\r\n        mn.visitJumpInsn(op,label);\r\n    }\r\n    private void visitIIOP(int op, int a, int b){\r\n        mn.visitIincInsn(a,b);\r\n    }\r\n    private Label getLabel(String name){\r\n    Label label=labelMap.get(name);\r\n    if(label==null){\r\n    label= new Label();\r\n    labelMap.put(name,label);\r\n    }\r\n        return  label;\r\n    }\r\n    public void accept(ClassVisitor cv) throws RecognitionException{\r\n        sFile();\r\n        cn.accept(cv);\r\n    }\r\n    public ClassNode parse() throws RecognitionException {\r\n        sFile();\r\n        ClassNode cn=this.cn;\r\n        reset0();\r\n        return cn;\r\n    }\r\n    AV currentAv;\r\n    AnnotationNode currentAnnotationVisitor;\r\n}\r\n\r\n\r\n\r\nfragment\r\nINT_NENT: ('+'|'-')? (\r\n               '0' \r\n            | ('1'..'9') ('0'..'9')* \r\n            | '0' ('0'..'7')+ \r\n            | ('0x'|'0X') HEX_DIGIT+\r\n         );\r\nfragment\r\nFLOAT_NENT\r\n    : ('+'|'-')?( ('0'..'9')+ '.' ('0'..'9')* EXPONENT?\r\n    |   '.' ('0'..'9')+ EXPONENT?\r\n    |   ('0'..'9')+ EXPONENT)\r\n    ;\r\nfragment\r\nF_FLOAT\t:\t('f'|'F') ('l'|'L')('o'|'O')('a'|'A')('t'|'T');\r\nfragment\r\nF_DOUBLE\t:('d'|'D')('o'|'O')('u'|'U')('b'|'B')('l'|'L')('e'|'E');\r\nfragment\r\nF_NAN : ('N'|'n') ('A'|'a') ('N'|'n');\r\nfragment\r\nF_INFINITY: ('I'|'i') ('N'|'n') ('F'|'f') ('I'|'i') ('N'|'n') ('I'|'i') ('T'|'t') ('Y'|'y') ;\r\n\r\nFLOAT\t:\t((('0'..'9')+|FLOAT_NENT) ('f'|'F')) \r\n\t\t| ('+'|'-')F_FLOAT F_INFINITY\r\n\t\t| '+' F_FLOAT F_NAN\r\n\t\t;\r\nDOUBLE\t:\tFLOAT_NENT ('d'|'D')? \r\n\t\t| ('0'..'9')+ ('d'|'D') \r\n\t\t| ('+'|'-') F_DOUBLE F_INFINITY\r\n\t\t| '+' F_DOUBLE F_NAN\r\n\t\t;\r\nLONG\t:\tINT_NENT ('L'|'l');\r\nINT\t:\tINT_NENT;\r\n\r\nCOMMENT\r\n    :   ';' ~('\\n'|'\\r')* '\\r'? '\\n' {$channel=HIDDEN;}\r\n    ;\r\n\r\nWS  :   ( ' '\r\n        | '\\t'\r\n        | '\\r'\r\n        | '\\n'\r\n        ) {$channel=HIDDEN;}\r\n    ;\r\n\r\nSTRING\r\n    :  '\"' ( ESC_SEQ | ~('\\\\'|'\"') )* '\"'\r\n    ;\r\nDSTRING\r\n    :  '\\'' ( ESC_SEQ | ~('\\\\'|'\\'') )* '\\''\r\n    ;\r\n\t\r\nfragment\r\nEXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;\r\n\r\nfragment\r\nHEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;\r\n\r\nfragment\r\nESC_SEQ\r\n    :   '\\\\' ('b'|'t'|'n'|'f'|'r'|'\\''|'\\\"'|'\\\\')\r\n    |   '\\\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT\r\n    |   '\\\\' ('0'..'3') ('0'..'7') ('0'..'7')\r\n    |   '\\\\' ('0'..'7') ('0'..'7')\r\n    |   '\\\\' ('0'..'7')\r\n    ;\r\n\r\nVOID_TYPE:'V';\r\nfragment\r\nFRAGMENT_PRIMITIVE_TYPE:'B'|'Z'|'S'|'C'|'I'|'F'|'J'|'D';\r\nfragment\r\nFRAGMENT_OBJECT_TYPE: 'L' (ESC_SEQ |~(';'|':'|'\\\\'|' '|'\\n'|'\\t'|'\\r'|'('|')'))+ ';' ;\r\n\r\nMETHOD_DESC_WITHOUT_RET: '(' ('['*(FRAGMENT_PRIMITIVE_TYPE|FRAGMENT_OBJECT_TYPE))* ')';\r\nOBJECT_TYPE: 'L' (ESC_SEQ |~(';'|':'|'\\\\'|' '|'\\n'|'\\t'|'\\r'|'('|')'))+ ';' ;\r\nACC:\t'public' | 'private' | 'protected' | 'static' | 'final' | 'synchronized' | 'bridge' | 'varargs' | 'native' |\r\n    'abstract' | 'strictfp' | 'synthetic' | 'constructor' | 'interface' | 'enum' |\r\n    'annotation' | 'volatile' | 'transient' | 'declared-synchronized' | 'super' | 'strict';\r\nANNOTATION_VISIBLITY: 'visible' | 'invisible' ;\r\nMETHOD_ANNOTATION_VISIBLITY: 'visibleparam' | 'invisibleparam';\r\nINNER\t:\t'inner';\r\nOUTTER\t:\t'outer';\r\nOP0\t:\t'nop'|'monitorenter'|'monitorexit'|'pop2'|'pop'\r\n\t|\t'iconst_m1'\r\n\t|('a'|'i')'const_' ('0'..'5')\r\n\t|('d'|'l')'const_' ('0'..'1')\r\n\t|'fconst_' ('0'..'2')\r\n\t|'aconst_null'\r\n\t|('a'|'d'|'f'|'i'|'l')? 'return'\r\n\t|('a'|'d'|'f'|'i'|'l') ('store'|'load') '_' ('0'..'3')\r\n\t|('a'|'b'|'c'|'d'|'f'|'i'|'l') ('astore'|'aload')\r\n\t|'dcmpg'|'dcmpl' | 'lcmp' |'fcmpg'|'fcmpl'\r\n\t|'athrow'\r\n\t|('i'|'f'|'d'|'l')('add'|'div'|'sub'|'mul'|'rem'|'shl'|'shr'|'ushr'|'and'|'or'|'xor'|'neg')\r\n\t|'arraylength'\r\n\t|'dup'|'dup2'|'dup_x2'|'dup2_x2'|'dup2_x1'\r\n\t|'swap'\r\n\t|'i2b' | 'i2c' |'i2d' | 'i2f' | 'i2s' | 'i2l'\r\n\t| 'f2d' | 'f2i' | 'f2l'\r\n\t| 'd2f' | 'd2i' | 'd2l'\r\n\t| 'l2d' | 'l2f' | 'l2i'\r\n\t;\r\nIOP\t:\t('a'|'d'|'f'|'i'|'l') 'load'\r\n\t|\t('a'|'d'|'f'|'i'|'l') 'store'\r\n\t|'bipush'|'sipush'\r\n\t;\r\nIIOP\t:\t'iinc'\r\n\t;\r\nJOP\t:\t'goto'\r\n\t|\t'jsr'\r\n\t|\t'if' ('null'|'nonnull'|'eq'|'ne'|'gt'|'ge'|'lt'|'le')\r\n\t|       'if_' ('a'|'i') 'cmp' ('eq'|'ne'|'gt'|'ge'|'lt'|'le')\r\n\t;\r\nLDC\t:\t'ldc'|'ldc_w'|'ldc2_w'\r\n\t;\r\nXFIELD\t:\t'getstatic'|'putstatic'|'getfield'|'putfield';\r\nXNEWARRAY: 'newarray' ;\r\nXTYPE\t:\t'checkcast'|'instanceof'|'new'|'anewarray'\r\n\t;\r\nMULTIANEWARRAY\r\n\t:\t'multianewarray'\r\n\t;\r\nLOOKUPSWITCH:\t'lookupswitch';\r\nTABLESWITCH:\t'tableswitch';\r\nXINVOKE\t:\t'invokestatic'\r\n\t|\t'invokevirtual'\r\n\t|       'invokespecial'\r\n\t;\r\nINVOKEINTERFACE  :\r\n\t       'invokeinterface'\r\n\t;\r\nINVOKEDYNAMIC\r\n\t:\t'invokedynamic';\r\nHIGH\t:\t'high';\r\nDEFAULT\t:\t'default';\r\nFROM\t:\t'from';\r\nTO\t:\t'to';\r\nUSING\t:\t'using';\r\nSTACK\t:\t'stack';\r\nLOCALS\t:\t'locals';\r\nWBOOLEAN: 'boolean';\r\nWBYTE: 'byte';\r\nWSHORT: 'short';\r\nWCHAR: 'char';\r\nWINTEGER: 'int';\r\nWFLOAT: 'float';\r\nWLONG: 'long';\r\nWDOUBLE: 'double';\r\n\r\nfragment\r\nF_ID_FOLLOWS: ESC_SEQ| ~('\\\\'|'\\r'|'\\n'|'\\t'|' '|':'|'-'|'='|','|'{'|'}'|'('|')');\r\nID  :    FRAGMENT_PRIMITIVE_TYPE F_ID_FOLLOWS+\r\n    |    ESC_SEQ F_ID_FOLLOWS*\r\n    |    ~(FRAGMENT_PRIMITIVE_TYPE| '0'..'9'| '\\\\' | '\\r' | '\\n' | '\\t' | '\\'' | '\\\"' | ' ' | ':' | '-' | '=' | '.' | ',' | '&' | '@' | '/' | '{'|'['|']'|'}'|'('|')') F_ID_FOLLOWS*\r\n    ;\r\nPARRAY_TYPE\r\n\t:\t'['+ FRAGMENT_OBJECT_TYPE\r\n\t|\t'[' '['+ FRAGMENT_PRIMITIVE_TYPE\r\n\t;\r\nAT\t:\t'@';\r\nAND\t:\t'&';\r\nUP_Z\t:\t'Z';\r\nUP_B\t:\t'B';\r\nUP_S\t:\t'S';\r\nUP_C\t:\t'C';\r\nUP_I\t:\t'I';\r\nUP_F\t:\t'F';\r\nUP_D\t:\t'D';\r\nUP_J\t:\t'J';\r\nARRAY_Z\t:\t'[Z';\r\nARRAY_B\t:\t'[B';\r\nARRAY_S\t:\t'[S';\r\nARRAY_C\t:\t'[C';\r\nARRAY_I\t:\t'[I';\r\nARRAY_F\t:\t'[F';\r\nARRAY_D\t:\t'[D';\r\nARRAY_J\t:\t'[J';\r\nARRAY_LOW_E\t:\t'[e';\r\nARRAY_LOW_S\t:\t'[s';\r\nARRAY_LOW_C\t:\t'[c';\r\nARRAY_AT\t:\t'[@';\r\nARRAY_AND\t:\t'[&';\r\nLEFT_PAREN: '(';\r\nRIGHT_PAREN: ')';\r\n\r\nsFile\t: { reset0(); currentAv=cnv; }\r\nsHead+ (sAnnotation|sVisibiltyAnnotation)* (sField|sMethod)*\r\n\t;\r\nsHead   :  '.bytecode' ( a=INT { int v=parseInt($a.text); cn.version=versions[v>=45?v-45:v];}\r\n                        |a=DOUBLE {double v=parseDouble($a.text); cn.version=versions[(int)(v<2.0?(v*10)\\%10:(v-44))]; }\r\n                       )\r\n        |  '.source' aa4=sAnyIdOrString  { cn.sourceFile=$aa4.str; }\r\n\t\t|  '.class' i=sAccList {cn.access|=$i.acc; if ((cn.access & Opcodes.ACC_INTERFACE) == 0) {cn.access |= Opcodes.ACC_SUPER;} else { cn.access &= ~Opcodes.ACC_SUPER; } } a1=sInternalNameOrDesc { cn.name=Type.getType($a1.desc).getInternalName(); }\r\n\t\t|  '.interface' i=sAccList {cn.access|=ACC_INTERFACE|$i.acc;} a1=sInternalNameOrDesc { cn.name=Type.getType($a1.desc).getInternalName(); }\r\n\t\t|  '.super' a1=sInternalNameOrDescACC  {  cn.superName=Type.getType($a1.desc).getInternalName(); }\r\n\t\t|  '.implements' a1=sInternalNameOrDescACC { if(cn.interfaces==null){cn.interfaces=new ArrayList<>();}  cn.interfaces.add(Type.getType($a1.desc).getInternalName()); }\r\n\t\t|  '.enclosing method' ownerAndName=sOwnerAndName {tmp=null;} (b=sMethodDesc{tmp=$b.text;})? {cn.visitOuterClass($ownerAndName.ownerInternalName,$ownerAndName.memberName,tmp);}\r\n\t\t|  sDeprecateAttr  { cn.access|=ACC_DEPRECATED; }\r\n\t\t|  '.debug' a=STRING  { cn.sourceDebug=unEscapeString($a.text); }\r\n\t\t|  '.attribute' sId STRING     { System.err.println(\"ignore .attribute\"); }\r\n\t\t|  '.inner class' (i=sAccList sId{tmpInt=$i.acc;})? {tmp=null;tmp2=null;} ('inner' a3=sId{tmp=$a3.text;})? ('outer' a4=sId{tmp2=$a4.text;})?   { cn.visitInnerClass(null,tmp2,tmp,tmpInt); }\r\n\t\t|  '.no_super' {cn.superName=null;}\r\n\t\t|  '.class_attribute' sId STRING    { System.err.println(\"ignore .class_attribute\"); }\r\n\t\t|  '.enclosing_method_attr' a=STRING b1=STRING c=STRING   {cn.visitOuterClass($a.text,$b1.text,$c.text);}\r\n\t\t|  '.inner_class_attr' ('.inner_class_spec_attr' a=STRING b2=STRING i=sAccList '.end' '.inner_class_spec_attr' { cn.visitInnerClass(null,unEscape($a.text),unEscape($b2.text),i); } )* '.end' '.inner_class_attr'\r\n\t\t|  s=sSigAttr  { cn.signature=$s.sig; }\r\n\t\t|  sSynthetic   {cn.access|=ACC_SYNTHETIC;}\r\n\t\t;\r\nsSigAttr returns[String sig]:\t('.signature_attr' | '.signature') a=STRING{ $sig=unEscapeString($a.text); };\r\nsDeprecateAttr:\t'.deprecated';\r\nsSynthetic\r\n\t:\t'.synthetic'\r\n\t;\r\nsArrayType\r\n\t:\tPARRAY_TYPE|ARRAY_Z|ARRAY_B|ARRAY_S|ARRAY_C|ARRAY_I|ARRAY_F|ARRAY_D|ARRAY_J\r\n\t;\r\nsClassDesc\r\n\t:\tsArrayType|OBJECT_TYPE|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_J|UP_D|UP_F\r\n\t;\r\nsId\t:\tID|AT|AND|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_F|UP_D|UP_J|ANNOTATION_VISIBLITY|METHOD_ANNOTATION_VISIBLITY|INNER|OUTTER\r\n\t|\tIIOP|IOP|JOP|OP0|LDC|XFIELD|XTYPE|XINVOKE|INVOKEINTERFACE|MULTIANEWARRAY|LOOKUPSWITCH|TABLESWITCH|DEFAULT|FROM|TO|USING|STACK|LOCALS|HIGH|INVOKEDYNAMIC|VOID_TYPE\r\n\t| WBOOLEAN| WBYTE | WSHORT|WCHAR|WINTEGER|WLONG|WFLOAT|WDOUBLE |XNEWARRAY\r\n\t;\r\nsWord : sId ;\r\nsAnnotation\r\n\t: '.annotation' (b=ANNOTATION_VISIBLITY aInternalOrDesc=sInternalNameOrDescACC { currentAnnotationVisitor= currentAv.visitAnnotation($aInternalOrDesc.desc,!$b.text.contains(\"invisible\")); } |\r\n\t                  b=METHOD_ANNOTATION_VISIBLITY c=INT a=sId {currentAnnotationVisitor=currentAv.visitParameterAnnotation(parseInt($c.text),$a.text,!$b.text.contains(\"invisible\"));}\r\n\t                )\r\n\t    (sAnnotationElement* '.end annotation')?\r\n\t;\r\nsVisibiltyAnnotation\r\n\t: {boolean visible=false;} ('.runtime_visible_annotation' {visible=true;}|'.runtime_invisible_annotation'{visible=false;}) a=STRING      { currentAnnotationVisitor= currentAv.visitAnnotation(unEscape($a.text),visible); }\r\n\tsAnnotationSoot*\r\n\t '.end' '.annotation_attr'\r\n\t;\r\nsAnnotationSoot\r\n\t: '.annotation' \r\n\t(t=sAnnotationElementSoot {currentAnnotationVisitor.visit($t.nn,$t.v);} )*\r\n\t'.end' '.annotation'\r\n\t;\r\nsAnnotationElementSoot returns[String nn,Object v]\r\n\t:'.elem' ('.bool_kind' a=STRING b=INT          {$nn=unEscapeString($a.text); $v=0!=parseInt($b.text);}\r\n              \t    | '.short_kind' a=STRING b=INT        {$nn=unEscapeString($a.text); $v=(short)parseInt($b.text);}\r\n              \t    | '.byte_kind' a=STRING b=INT         {$nn=unEscapeString($a.text); $v=(byte)parseInt($b.text);}\r\n              \t    | '.char_kind' a=STRING b=INT         {$nn=unEscapeString($a.text); $v=(char)parseInt($b.text);}\r\n              \t    | '.int_kind' a=STRING b=INT          {$nn=unEscapeString($a.text); $v=parseInt($b.text);}\r\n              \t    | '.long_kind' a=STRING b=(INT|LONG)  {$nn=unEscapeString($a.text); $v=parseLong($b.text);}\r\n              \t    | '.float_kind' a=STRING b=INT        {$nn=unEscapeString($a.text); $v=parseFloat($b.text);}\r\n              \t    | '.doub_kind' a=STRING b=(INT|LONG)  {$nn=unEscapeString($a.text); $v=parseDouble($b.text);}\r\n              \t    | '.str_kind' a=STRING b=STRING       {$nn=unEscapeString($a.text); $v=unEscapeString($b.text);}\r\n              \t    | '.enum_kind' a=STRING b=STRING      {$nn=unEscapeString($a.text); String on[]=parseOwnerAndName($b.text);$v=new String[]{on[0],on[1]};}\r\n              \t    | '.cls_kind' a=STRING b=STRING       {$nn=unEscapeString($a.text); $v=Type.getType(unEscapeString($b.text));}\r\n              \t    | '.arr_kind' a=STRING {List<Object> array=new ArrayList<>();} (t=sAnnotationElementSoot{array.add($t.v);})* '.end'  '.arr_elem'   {$nn=unEscapeString($a.text); $v=array;}\r\n              \t    | '.ann_kind' a=STRING q=sSubannotationSoot '.end' '.annot_elem'     {$nn=unEscapeString($a.text); $v=$q.v;})\r\n\t;\r\n\r\nsSubannotationSoot  returns[AnnotationNode v]\r\n\t:\t'.annotation' a=STRING   { $v=new AnnotationNode(unEscapeString($a.text)); }\r\n\t     (t=sAnnotationElementSoot {$v.visit($t.nn,$t.v);} )*\r\n\t    '.end' '.annotation'\r\n\t;\r\nsAnnotationElement @init{List<Object> array = new ArrayList<Object>(); AnnotationNode _t= currentAnnotationVisitor;}\r\n    :   a=sId (\r\n             xid=ID { if(!\"e\".contains($xid.text)){ throw new RecognitionException(input);} }  c=OBJECT_TYPE '=' b=sWord {  _t.visit($a.text,new String[]{$c.text,$b.text}); }\r\n           | AT b2=OBJECT_TYPE '=' {  currentAnnotationVisitor=new AnnotationNode($b2.text);} sSubannotation  { _t.visit($a.text,currentAnnotationVisitor); }\r\n           | xid=ID { if(!\"c\".contains($xid.text)){ throw new RecognitionException(input);} } '=' b1=sClassDesc { currentAnnotationVisitor.visit($a.text,Type.getType($b1.text)); }\r\n           | xid=ID { if(!\"s\".contains($xid.text)){ throw new RecognitionException(input);} } '=' b3=STRING      { currentAnnotationVisitor.visit($a.text,unEscapeString($b3.text)); }\r\n           | UP_B  '=' b4=INT  { currentAnnotationVisitor.visit($a.text,(byte)parseInt($b4.text)); }\r\n           | UP_Z  '=' b5=INT  { currentAnnotationVisitor.visit($a.text,0!=parseInt($b5.text)); }\r\n           | UP_S  '=' b6=INT   { currentAnnotationVisitor.visit($a.text,(short)parseInt($b6.text)); }\r\n           | UP_C  '=' b7=INT   { currentAnnotationVisitor.visit($a.text,(char)parseInt($b7.text)); }\r\n           | UP_I  '=' b8=INT   { currentAnnotationVisitor.visit($a.text,parseInt($b8.text)); }\r\n           | UP_J  '=' b9=(INT|LONG)  { currentAnnotationVisitor.visit($a.text,parseLong($b9.text)); }\r\n           | UP_F  '=' b10=(INT|FLOAT|DOUBLE)  { currentAnnotationVisitor.visit($a.text,parseFloat($b10.text)); }\r\n           | UP_D  '=' b11=(INT|FLOAT|DOUBLE)   { currentAnnotationVisitor.visit($a.text,parseDouble($b11.text)); }\r\n           | ARRAY_B '='  (b12=INT {array.add((byte)parseInt($b12.text));} )+    { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_Z '='  (b13=INT {array.add(0!=parseInt($b13.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_S '='  (b14=INT {array.add((short)parseInt($b14.text));} )+   { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_C '='  (b15=INT {array.add((char)parseInt($b15.text));} )+    { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_I '='  (b16=INT {array.add(parseInt($b16.text));} )+          { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_J '='  (b17=(INT|LONG) {array.add(parseLong($b17.text));} )+  { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_F '='  (b18=(INT|FLOAT|DOUBLE) {array.add(parseFloat($b18.text));} )+  { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_D '='  (b19=(INT|DOUBLE) {array.add(parseDouble($b19.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_LOW_E c=OBJECT_TYPE '='  ((b1=sWord{  array.add(new String[]{$c.text,unEscape($b1.text)}); }|b2=STRING{  array.add(new String[]{$c.text,unEscapeString($b2.text)}); }|b3=DSTRING{  array.add(new String[]{$c.text,unEscapeString($b3.text)}); })  )+  { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_AND b20=OBJECT_TYPE '=' ARRAY_AT '='  ({currentAnnotationVisitor=new AnnotationNode($b20.text);} sSubannotation{ array.add(currentAnnotationVisitor); })+ { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_LOW_C '='  (b=sClassDesc {array.add(Type.getType($b.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }\r\n           | ARRAY_LOW_S '='  (b21=STRING {array.add(unEscapeString($b21.text));})+   { currentAnnotationVisitor.visit($a.text,array); }\r\n\t\t)\r\n\t{ currentAnnotationVisitor=_t; }\r\n;\r\nsSubannotation\r\n\t:\t'.annotation' \r\n\t     sAnnotationElement*\r\n\t    '.end annotation'\r\n\t;\r\nsAccList returns[int acc]: {$acc=0;} ( a=ACC {$acc|=getAcc($a.text);})*  ;\r\nsMemberName returns[String name]: a=sId {$name=unEscape($a.text);} | b=STRING {$name=unEscapeString($b.text);}| c=DSTRING {$name=unEscapeString($c.text);};\r\nsField\t@init {\r\n                    if(cn.fields==null){\r\n                        cn.fields=new ArrayList<>();\r\n                    }\r\n                    currentAv=fnv;\r\n                    fn=new FieldNode(0,null,null,null,null);\r\n                    cn.fields.add(fn);\r\n              }\r\n    :\t'.field' i=sAccList n=sMemberName t=sClassDesc { fn.access|=i;fn.name=$n.name;fn.desc=unEscape($t.text); }\r\n        ( '=' (a=STRING {fn.value=parseValue(fn.desc,unEscapeString($a.text));}\r\n              |a1=INT      {fn.value=parseValue(fn.desc,parseInt($a1.text));}\r\n              |a2=LONG     {fn.value=parseValue(fn.desc,parseLong($a2.text));}\r\n              |a3=FLOAT    {fn.value=parseValue(fn.desc,parseFloat($a3.text));}\r\n              |a4=DOUBLE   {fn.value=parseValue(fn.desc,parseDouble($a4.text));}\r\n              |a5=sClassDesc {fn.value=parseValue(fn.desc,Type.getType(unEscape($a5.text)));}\r\n              )\r\n        )?\r\n            (\r\n            s=sSigAttr{fn.signature=$s.sig;}\r\n            |sDeprecateAttr{ fn.access|=ACC_DEPRECATED; }\r\n            |sSynthetic {cn.access|=ACC_SYNTHETIC;}\r\n            |sVisibiltyAnnotation\r\n            |sAnnotation\r\n            )*\r\n    ('.end field'| '.end' '.field')?\r\n\t('.field_attribute' sId STRING {System.err.println(\"ignore .field_attribute\");})*\r\n\t;\r\nsMethod\t@init{\r\n    if(cn.methods==null){\r\n        cn.methods=new ArrayList<>();\r\n    }\r\n    currentAv=mnv;\r\n    mn=new MethodNode(ASM4);\r\n    cn.methods.add(mn);\r\n    labelMap.clear();\r\n    if(mn.exceptions==null){\r\n        mn.exceptions=new ArrayList<>();\r\n    }\r\n    if(mn.tryCatchBlocks==null){\r\n            mn.tryCatchBlocks=new ArrayList<>();\r\n        }\r\n}\r\n    :\t'.method' i=sAccList n=sMemberName t=sMethodDesc {mn.access|=i;mn.name=$n.name;mn.desc=unEscape($t.text);}\r\n            (s=sSigAttr{mn.signature=$s.sig;}\r\n                |sDeprecateAttr{ cn.access|=ACC_DEPRECATED; }\r\n                |sSynthetic {cn.access|=ACC_SYNTHETIC;}\r\n                |sVisibiltyAnnotation\r\n                |sAnnotation\r\n                |'.throws' at=sInternalNameOrDesc {  mn.exceptions.add(Type.getType($at.desc).getInternalName()); }\r\n                |'.annotation_default' (t=sAnnotationElementSoot {currentAnnotationVisitor=(AnnotationNode)mn.visitAnnotationDefault();} )? '.end' '.annotation_default'\r\n                |'.param' ('.runtime_invisible_annotation'|'.runtime_visible_annotation') {int index=0;}\r\n                    ({boolean visible=false;} ('.runtime_visible_annotation' {visible=true;}|'.runtime_invisible_annotation'{visible=false;}) a1=STRING\r\n                    { currentAnnotationVisitor= currentAv.visitParameterAnnotation(index,unEscapeString($a1.text),visible); }\r\n                        sAnnotationSoot*\r\n                       '.end' '.annotation_attr' {index++;}\r\n                    )*\r\n                 '.end' '.param'\r\n                | code\r\n            )*\r\n        '.end method'\r\n\t('.method_attribute' sId STRING {System.err.println(\"ignore method_attribute\");})*\r\n\t;\r\n\r\nsLabel\t:\tACC|ID|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_F|UP_D|UP_J|ANNOTATION_VISIBLITY|METHOD_ANNOTATION_VISIBLITY|INNER|OUTTER\r\n\t;\r\ncode\r\n    :\ta=OP0 { line($a.line); visitOP0(getOp($a.text)); }\r\n\t|\ta=IOP b=INT { line($a.line); visitIOP(getOp($a.text),parseInt($b.text)); }\r\n\t|\ta=IIOP b=INT c=INT   { line($a.line); visitIIOP(getOp($a.text),parseInt($b.text),parseInt($c.text)); }\r\n\t| \ta=LDC  {line($a.line);  } ( c=INT        {mn.visitLdcInsn(parseInt($c.text));}\r\n\t                               |c=LONG       {mn.visitLdcInsn(parseLong($c.text));}\r\n\t                               |c=FLOAT      {mn.visitLdcInsn(parseFloat($c.text));}\r\n\t                               |c=DOUBLE     {mn.visitLdcInsn(parseDouble($c.text));}\r\n\t                               |c=STRING     {mn.visitLdcInsn(unEscapeString($c.text));}\r\n\t                               |eTV=sInternalNameOrDescNoString {mn.visitLdcInsn(Type.getType($eTV.desc));}\r\n\t                              )\r\n\t|\ta=XFIELD efo=sFieldObject {  line($a.line);  mn.visitFieldInsn(getOp($a.text),$efo.ownerInternalName,$efo.memberName,$efo.type);   }\r\n\t|   a=XNEWARRAY {line($a.line); }  (\r\n\t               WBOOLEAN{mn.visitIntInsn(NEWARRAY,T_BOOLEAN);}\r\n\t               |WBYTE{mn.visitIntInsn(NEWARRAY,T_BYTE);}\r\n\t               |WSHORT{mn.visitIntInsn(NEWARRAY,T_SHORT);}\r\n\t               |WCHAR{mn.visitIntInsn(NEWARRAY,T_CHAR);}\r\n\t               |WINTEGER{mn.visitIntInsn(NEWARRAY,T_INT);}\r\n\t               |WLONG{mn.visitIntInsn(NEWARRAY,T_LONG);}\r\n\t               |WFLOAT{mn.visitIntInsn(NEWARRAY,T_FLOAT);}\r\n\t               |WDOUBLE{mn.visitIntInsn(NEWARRAY,T_DOUBLE);})\r\n\t|\ta=XTYPE ffTV=sInternalNameOrDescACC {\r\n\t                       line($a.line);\r\n\t                          mn.visitTypeInsn(getOp($a.text),Type.getType($ffTV.desc).getInternalName());\r\n\t            }\r\n\t|\ta=JOP z=sLabel  { line($a.line); visitJOP(getOp($a.text),getLabel($z.text)); }\r\n\t|\ta=XINVOKE e1=sMethodObject   {line($a.line);\r\n\t                    mn.visitMethodInsn(getOp($a.text),$e1.ownerInternalName,$e1.memberName,$e1.desc);\r\n\t                  }\r\n\t|\ta=INVOKEINTERFACE e2=sMethodObject INT?  {line($a.line);\r\n\t                    mn.visitMethodInsn(getOp($a.text),$e2.ownerInternalName,$e2.memberName,$e2.desc);\r\n\t                  }\r\n\t|\ta=INVOKEDYNAMIC e3=sMethodObject sId sMethodDesc '(' sInvokeDynamicE (',' sInvokeDynamicE)* ')'  {line($a.line); if(1==1) throw new RuntimeException(\"not support Yet!\");}\r\n\t|\ta=MULTIANEWARRAY ff=sClassDesc c=INT   {line($a.line); mn.visitMultiANewArrayInsn(unEscape($ff.text),parseInt($c.text)); }\r\n\t|   z=sLabel ':' { Label label=getLabel($z.text); mn.visitLabel(label); if(rebuildLine) {mn.visitLineNumber($z.start.getLine(),label);}\r\n\t }\r\n\t|\t'.catch' e=sId 'from' z1=sLabel 'to' z2=sLabel 'using' z3=sLabel { String type=\"all\".equals($e.text)?null:unEscape($e.text); mn.visitTryCatchBlock(getLabel($z1.text),getLabel($z2.text),getLabel($z3.text),type); }\r\n\t|\t'.limit' 'stack' ('?' { mn.maxStack=-1; } | i1=INT { mn.maxStack=parseInt($i1.text); })\r\n\t|\t'.limit' 'locals' ('?' {mn.maxLocals=-1;}| i1=INT { mn.maxLocals=parseInt($i1.text);})\r\n\t|\t'.code_attribute' sId STRING   { System.err.println(\"ignore .code_attribute\"); }\r\n\t|\t'.line' b=INT  { if(!rebuildLine) { Label label=new Label(); mn.visitLabel(label); mn.visitLineNumber(parseInt($b.text),label); } }\r\n\t|   '.var' var=INT 'is' mber=sMemberName desc=sClassDesc ('signature' sig=STRING)? 'from' z1=sLabel 'to' z2=sLabel  { mn.visitLocalVariable($mber.name,unEscape($desc.text),unEscapeString($sig.text),getLabel($z1.text),getLabel($z2.text),parseInt($var.text)); }\r\n    |   sSwitch\r\n\t;\r\nsInvokeDynamicE\r\n\t:\tMETHOD_DESC_WITHOUT_RET (INT|LONG|FLOAT|DOUBLE|STRING)\r\n\t;\r\nsMethodDesc\r\n\t:\tMETHOD_DESC_WITHOUT_RET (sClassDesc|VOID_TYPE)\r\n\t;\r\nsSwitch @init {List<Integer> keys=null;List<Label> labels=null;Label defaultLabel=null;}\r\n\t:\ta=LOOKUPSWITCH { keys=new ArrayList<>(); labels=new ArrayList<>();  } (c=INT ':' z=sLabel { keys.add(parseInt($c.text)); labels.add(getLabel($z.text)); })* (DEFAULT ':' z=sLabel { defaultLabel=getLabel($z.text); })   {\r\n\t        line($a.line);\r\n\t        int ts[]=new int[keys.size()];\r\n\t        for(int i=0;i<keys.size();i++){\r\n\t            ts[i]=keys.get(i);\r\n\t        }\r\n\t        mn.visitLookupSwitchInsn(defaultLabel, ts, labels.toArray(new Label[labels.size()]));\r\n\t        }\r\n\t|\ta=TABLESWITCH { labels=new ArrayList<>();  } c=INT ';' 'high' '=' d=INT (z=sLabel  {labels.add(getLabel($z.text));} )* (DEFAULT ':' z=sLabel {defaultLabel=getLabel($z.text);})    {\r\n\t        line($a.line); mn.visitTableSwitchInsn(parseInt($c.text),parseInt($c.text)+labels.size()-1,defaultLabel,labels.toArray(new Label[labels.size()]));\r\n\t        }\r\n\t|   a=TABLESWITCH { labels=new ArrayList<>();  } c=INT (z=sLabel  {labels.add(getLabel($z.text));} )* (DEFAULT ':' z=sLabel {defaultLabel=getLabel($z.text);})    {\r\n        \t        line($a.line); mn.visitTableSwitchInsn(parseInt($c.text),parseInt($c.text)+labels.size()-1,defaultLabel,labels.toArray(new Label[labels.size()]));\r\n        \t        }\r\n    ;\r\nsInternalNameOrDesc returns[String desc]\r\n    : (a=sArrayType { $desc=unEscape($a.text); }|b=OBJECT_TYPE { $desc=unEscape($b.text); })\r\n    | c=sId {  $desc= \"L\"+unEscape($c.text)+\";\"; }\r\n    | DSTRING {  $desc= \"L\"+unEscapeString($DSTRING.text)+\";\"; }\r\n    | STRING {  $desc= \"L\"+unEscapeString($STRING.text)+\";\"; }\r\n    ;\r\nsInternalNameOrDescACC returns[String desc]\r\n        : (a=sArrayType { $desc=unEscape($a.text); }|b=OBJECT_TYPE { $desc=unEscape($b.text); })\r\n        | c=sAnyId {  $desc= \"L\"+unEscape($c.text)+\";\"; }\r\n        | DSTRING {  $desc= \"L\"+unEscapeString($DSTRING.text)+\";\"; }\r\n        | STRING {  $desc= \"L\"+unEscapeString($STRING.text)+\";\"; }\r\n        ;\r\nsInternalNameOrDescNoString returns[String desc]\r\n    : (a=sArrayType { $desc=unEscape($a.text); }|b=OBJECT_TYPE { $desc=unEscape($b.text); })\r\n    | c=sAnyId {  $desc= \"L\"+unEscape($c.text)+\";\"; }\r\n    ;\r\nsAnyId\r\n    : ACC | sId\r\n    ;\r\nsAnyIdOrString returns[String str]\r\n    : sAnyId { $str=unEscape($sAnyId.text);}\r\n    | STRING { $str=unEscapeString($STRING.text); }\r\n    | DSTRING { $str=unEscapeString($DSTRING.text); }\r\n    ;\r\nsOwnerAndName returns[String ownerInternalName, String memberName]\r\n    :    a=sArrayType '/' x=sAnyId { if($x.text.contains(\"/\")){ throw new RecognitionException(input);}  $ownerInternalName=unEscape($a.text); $memberName=unEscape($x.text); }\r\n    | b=sClassDesc '->' x=sAnyId { if($x.text.contains(\"/\")){ throw new RecognitionException(input);} $ownerInternalName=Type.getType(unEscape($b.text)).getInternalName(); $memberName=unEscape($x.text);  }\r\n    | c=sId { String cstr=$c.text; int idx=cstr.lastIndexOf('/'); if(idx<=0) { throw new RecognitionException(input); } $ownerInternalName=unEscape(cstr.substring(0,idx)); $memberName=unEscape(cstr.substring(idx+1)); }\r\n    ;\r\nsMethodObject returns[String ownerInternalName, String memberName, String desc]\r\n    :   ( a=sArrayType '/' x=sAnyId { if($x.text.contains(\"/\")){ throw new RecognitionException(input);}  $ownerInternalName=unEscape($a.text); $memberName=unEscape($x.text); }\r\n        | b=sClassDesc '->' x=sAnyId { if($x.text.contains(\"/\")){ throw new RecognitionException(input);} $ownerInternalName=Type.getType(unEscape($b.text)).getInternalName(); $memberName=unEscape($x.text);  }\r\n        | c=sId { String cstr=$c.text; int idx=cstr.lastIndexOf('/'); if(idx<=0) { throw new RecognitionException(input); } $ownerInternalName=unEscape(cstr.substring(0,idx)); $memberName=unEscape(cstr.substring(idx+1)); }\r\n        )\r\n      d=sMethodDesc { $desc=unEscape($d.text);  }\r\n    ;\r\nsFieldObject returns[String ownerInternalName, String memberName, String type]\r\n    :   ( a=sArrayType '/' x=sAnyId { if($x.text.contains(\"/\")){ throw new RecognitionException(input);}  $ownerInternalName=unEscape($a.text); $memberName=unEscape($x.text); }\r\n        | b=sClassDesc '->' x=sAnyId ':' { if($x.text.contains(\"/\")){ throw new RecognitionException(input);} $ownerInternalName=Type.getType(unEscape($b.text)).getInternalName(); $memberName=unEscape($x.text);  }\r\n        | c=sId { String cstr=$c.text; int idx=cstr.lastIndexOf('/'); if(idx<=0) { throw new RecognitionException(input); } $ownerInternalName=unEscape(cstr.substring(0,idx)); $memberName=unEscape(cstr.substring(idx+1)); }\r\n        )\r\n      b=sClassDesc { $type=unEscape($b.text);  }\r\n    ;\r\n"
  },
  {
    "path": "d2j-jasmin/src/main/java/com/googlecode/d2j/jasmin/Jar2JasminCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.jasmin;\n\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.tree.ClassNode;\n\nimport java.io.*;\nimport java.net.URISyntaxException;\nimport java.nio.charset.Charset;\nimport java.nio.file.FileSystem;\nimport java.nio.file.*;\nimport java.nio.file.attribute.BasicFileAttributes;\n\n@Syntax(cmd = \"d2j-jar2jasmin\", syntax = \"[options] <jar>\", desc = \"Disassemble .class in jar file to jasmin file\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/Jasmin\")\npublic class Jar2JasminCmd extends BaseCmd {\n    @Opt(opt = \"d\", longOpt = \"debug\", hasArg = false, description = \"disassemble debug info\")\n    private boolean debugInfo = false;\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output dir of .j files, default is $current_dir/[jar-name]-jar2jasmin/\", argName = \"out-dir\")\n    private Path output;\n    @Opt(opt = \"e\", longOpt = \"encoding\", description = \"encoding for .j files, default is UTF-8\", argName = \"enc\")\n    private String encoding = \"UTF-8\";\n\n    public static void main(String... args) {\n        new Jar2JasminCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length != 1) {\n            usage();\n            return;\n        }\n\n        Path jar = new File(remainingArgs[0]).toPath().toAbsolutePath();\n        if (!Files.exists(jar)) {\n            System.err.println(jar + \" is not exists\");\n            usage();\n            return;\n        }\n\n        if (output == null) {\n            output = new File(getBaseName(jar) + \"-jar2jasmin/\").toPath();\n        }\n\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            usage();\n            return;\n        }\n\n        System.out.println(\"disassemble \" + jar + \" -> \" + output);\n\n        if (!output.toString().endsWith(\".jar\") && !output.toString().endsWith(\".apk\")) {\n            disassemble0(jar, output);\n        } else {\n            try (FileSystem fs = createZip(output)) {\n                disassemble0(jar, fs.getPath(\"/\"));\n            }\n        }\n    }\n\n    private void disassemble0(Path in, final Path output) throws IOException, URISyntaxException {\n        if (Files.isDirectory(in)) { // a dir\n            travelFileTree(in, output);\n        } else if (in.toString().endsWith(\".class\")) {\n            disassemble1(in, output);\n        } else {\n            try (FileSystem fs = openZip(in)) {\n                travelFileTree(fs.getPath(\"/\"), output);\n            }\n        }\n    }\n\n    private void travelFileTree(Path in, final Path output) throws IOException {\n        Files.walkFileTree(in, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                if (file.getFileName().toString().endsWith(\".class\")) {\n                    disassemble1(file, output);\n                }\n                return super.visitFile(file, attrs);\n            }\n        });\n    }\n\n    private void disassemble1(Path file, Path output) throws IOException {\n        ClassReader r = new ClassReader(Files.readAllBytes(file));\n        Path jFile = output.resolve(r.getClassName().replace('.', '/') + \".j\");\n        createParentDirectories(jFile);\n        try (BufferedWriter out = Files.newBufferedWriter(jFile, Charset.forName(encoding))) {\n            PrintWriter pw = new PrintWriter(out);\n            ClassNode node = new ClassNode();\n            r.accept(node, (debugInfo ? 0 : ClassReader.SKIP_DEBUG) | ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);\n            new JasminDumper(pw).dump(node);\n            pw.flush();\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-jasmin/src/main/java/com/googlecode/d2j/jasmin/Jasmin2JarCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.jasmin;\n\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport org.antlr.runtime.ANTLRReaderStream;\nimport org.antlr.runtime.ANTLRStringStream;\nimport org.antlr.runtime.CommonTokenStream;\nimport org.antlr.runtime.RecognitionException;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.tree.ClassNode;\n\nimport java.io.*;\nimport java.net.URISyntaxException;\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.*;\nimport java.nio.file.attribute.BasicFileAttributes;\n\n@BaseCmd.Syntax(cmd = \"d2j-jasmin2jar\", syntax = \"[options] <jar>\", desc = \"Assemble .j files to .class file\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/Jasmin\")\npublic class Jasmin2JarCmd extends BaseCmd implements Opcodes {\n    private static int versions[] = { 0, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, 52 // V1_8 ?\n            , 53 // V1_9 ?\n    };\n    @Opt(opt = \"g\", longOpt = \"autogenerate-linenumbers\", hasArg = false, description = \"autogenerate-linenumbers\")\n    boolean autogenLines = false;\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .jar file, default is $current_dir/[jar-name]-jasmin2jar.jar\", argName = \"out-jar-file\")\n    private Path output;\n    @Opt(opt = \"e\", longOpt = \"encoding\", description = \"encoding for .j files, default is UTF-8\", argName = \"enc\")\n    private String encoding = \"UTF-8\";\n\n    @Opt(opt = \"d\", longOpt = \"dump\", description = \"dump to stdout\", hasArg = false)\n    private boolean dump;\n\n    @Opt( longOpt = \"no-compute-max\", description = \"\", hasArg = false)\n    private boolean noComputeMax;\n\n    @Opt(opt = \"cv\", longOpt = \"class-version\", description = \"default .class version, [1~9], default 6 for JAVA6\")\n    private int classVersion = 6;\n\n    public static void main(String... args) throws ClassNotFoundException, SecurityException {\n        new Jasmin2JarCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length != 1) {\n            usage();\n            return;\n        }\n        if (classVersion < 1 || classVersion > 9) {\n            throw new HelpException(\"-cv,--class-version out of range, 1-9 is supported.\");\n        }\n\n        Path jar = new File(remainingArgs[0]).toPath().toAbsolutePath();\n        if (!Files.exists(jar)) {\n            System.err.println(jar + \" is not exists\");\n            usage();\n            return;\n        }\n\n        if (output == null) {\n            output = new File(getBaseName(jar) + \"-jasmin2jar/\").toPath();\n        }\n\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            usage();\n            return;\n        }\n\n        System.out.println(\"assemble \" + jar + \" -> \" + output);\n\n        if (!output.toString().endsWith(\".jar\") && !output.toString().endsWith(\".zip\")) {\n            assemble0(jar, output);\n        } else {\n            try (FileSystem fs = createZip(output)) {\n                assemble0(jar, fs.getPath(\"/\"));\n            }\n        }\n    }\n\n    private void assemble0(Path in, Path output) throws IOException, URISyntaxException {\n        if (Files.isDirectory(in)) { // a dir\n            travelFileTree(in, output);\n        } else if (in.toString().endsWith(\".j\")) {\n            assemble1(in, output);\n        } else {\n            try (FileSystem fs = openZip(in)) {\n                travelFileTree(fs.getPath(\"/\"), output);\n            }\n        }\n    }\n\n    private void travelFileTree(Path in, final Path output) throws IOException {\n        Files.walkFileTree(in, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                if (file.getFileName().toString().endsWith(\".j\")) {\n                    assemble1(file, output);\n                }\n                return super.visitFile(file, attrs);\n            }\n        });\n    }\n\n    private void assemble1(Path file, Path output) throws IOException {\n        try (BufferedReader bufferedReader = Files.newBufferedReader(file, Charset.forName(encoding))) {\n            ANTLRStringStream is = new ANTLRReaderStream(bufferedReader);\n            is.name = file.toString();\n            JasminLexer lexer = new JasminLexer(is);\n            CommonTokenStream ts = new CommonTokenStream(lexer);\n            JasminParser parser = new JasminParser(ts);\n            parser.rebuildLine = autogenLines;\n            ClassWriter cw = new ClassWriter(noComputeMax?0:ClassWriter.COMPUTE_MAXS);\n            ClassNode cn = parser.parse();\n            if (cn.version == 0) {\n                cn.version = versions[classVersion];\n            }\n            if (dump) {\n                new JasminDumper(new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8), true)).dump(cn);\n            }\n            cn.accept(cw);\n            Path clzFile = output.resolve(cn.name.replace('.', '/') + \".class\");\n            createParentDirectories(clzFile);\n            Files.write(clzFile, cw.toByteArray());\n        } catch (RecognitionException e) {\n            System.err.println(\"Fail to assemble \" + file);\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-jasmin/src/main/java/com/googlecode/d2j/jasmin/JasminDumper.java",
    "content": "/***\r\n * ASM: a very small and fast Java bytecode manipulation framework\r\n * Copyright (c) 2000-2005 INRIA, France Telecom\r\n * All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without\r\n * modification, are permitted provided that the following conditions\r\n * are met:\r\n * 1. Redistributions of source code must retain the above copyright\r\n *    notice, this list of conditions and the following disclaimer.\r\n * 2. Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimer in the\r\n *    documentation and/or other materials provided with the distribution.\r\n * 3. Neither the name of the copyright holders nor the names of its\r\n *    contributors may be used to endorse or promote products derived from\r\n *    this software without specific prior written permission.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\r\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n */\r\npackage com.googlecode.d2j.jasmin;\r\n\r\nimport org.objectweb.asm.Label;\r\nimport org.objectweb.asm.MethodVisitor;\r\nimport org.objectweb.asm.Opcodes;\r\nimport org.objectweb.asm.Type;\r\nimport org.objectweb.asm.tree.*;\r\nimport org.objectweb.asm.util.Printer;\r\n\r\nimport java.io.PrintWriter;\r\nimport java.util.*;\r\n\r\n/**\r\n * <b>get from asm example</b>\r\n * <p>\r\n * Disassembled view of the classes in Jasmin assembler format.\r\n * <p>\r\n * The trace printed when visiting the <tt>Hello</tt> class is the following:\r\n * <p>\r\n * <blockquote>\r\n * \r\n * <pre>\r\n * .bytecode 45.3\r\n * .class public Hello\r\n * .super java/lang/Object\r\n * \r\n * .method public <init>()V\r\n * aload 0\r\n * invokespecial java/lang/Object/<init>()V\r\n * return\r\n * .limit locals 1\r\n * .limit stack 1\r\n * .end method\r\n * \r\n * .method public static main([Ljava/lang/String;)V\r\n * getstatic java/lang/System/out Ljava/io/PrintStream;\r\n * ldc \"hello\"\r\n * invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V\r\n * return\r\n * .limit locals 2\r\n * .limit stack 2\r\n * .end method\r\n * </pre>\r\n * \r\n * </blockquote> where <tt>Hello</tt> is defined by:\r\n * <p>\r\n * <blockquote>\r\n * \r\n * <pre>\r\n * public class Hello {\r\n * \r\n *     public static void main(String[] args) {\r\n *         System.out.println(&quot;hello&quot;);\r\n *     }\r\n * }\r\n * </pre>\r\n * \r\n * </blockquote>\r\n * \r\n * @author Eric Bruneton\r\n */\r\npublic class JasminDumper implements Opcodes {\r\n    private static Set<String> ACCESS_KWS = new HashSet<String>(Arrays\r\n            .asList(\"abstract\", \"private\", \"protected\", \"public\", \"enum\", \"final\", \"interface\", \"static\", \"strictfp\", \"native\", \"super\"));\r\n\r\n    public JasminDumper(PrintWriter pw) {\r\n        this.pw = pw;\r\n    }\r\n\r\n    /**\r\n     * The print writer to be used to print the class.\r\n     */\r\n    protected PrintWriter pw;\r\n\r\n    /**\r\n     * The label names. This map associate String values to Label keys.\r\n     */\r\n    protected final Map<Label, String> labelNames = new HashMap<>();\r\n\r\n    static void printIdAfterAccess(PrintWriter out, String id) {\r\n        if (ACCESS_KWS.contains(id)) {\r\n            out.print(\"\\\"\");\r\n            out.print(id);\r\n            out.print(\"\\\"\");\r\n        } else {\r\n            out.print(id);\r\n        }\r\n    }\r\n\r\n    public void dump(ClassNode cn) {\r\n        labelNames.clear();\r\n        pw.print(\".bytecode \");\r\n        pw.print(cn.version & 0xFFFF);\r\n        pw.print('.');\r\n        pw.println(cn.version >>> 16);\r\n        println(\".source \", cn.sourceFile);\r\n        pw.print(\".class\");\r\n        pw.print(access_clz(cn.access));\r\n        pw.print(' ');\r\n        printIdAfterAccess(pw, cn.name);\r\n        pw.println();\r\n        if (cn.superName != null) {\r\n            pw.print(\".super \");\r\n            printIdAfterAccess(pw, cn.superName);\r\n            pw.println();\r\n        }\r\n        for (String itf : cn.interfaces) {\r\n            pw.print(\".implements \");\r\n            printIdAfterAccess(pw, itf);\r\n            pw.println();\r\n        }\r\n        if (cn.signature != null) {\r\n            println(\".signature \", '\"' + cn.signature + '\"');\r\n        }\r\n        if (cn.outerClass != null) {\r\n            pw.print(\".enclosing method \");\r\n            pw.print(cn.outerClass);\r\n            if (cn.outerMethod != null) {\r\n                pw.print('/');\r\n                pw.print(cn.outerMethod);\r\n                pw.println(cn.outerMethodDesc);\r\n            } else {\r\n                pw.println();\r\n            }\r\n        }\r\n        if ((cn.access & Opcodes.ACC_DEPRECATED) != 0) {\r\n            pw.println(\".deprecated\");\r\n        }\r\n        if (cn.visibleAnnotations != null) {\r\n            for (AnnotationNode an : cn.visibleAnnotations) {\r\n                printAnnotation(an, 1, -1);\r\n            }\r\n        }\r\n        if (cn.invisibleAnnotations != null) {\r\n            for (AnnotationNode an : cn.invisibleAnnotations) {\r\n                printAnnotation(an, 2, -1);\r\n            }\r\n        }\r\n\r\n        println(\".debug \", cn.sourceDebug == null ? null : '\"' + cn.sourceDebug + '\"');\r\n\r\n        for (InnerClassNode in : cn.innerClasses) {\r\n            pw.print(\".inner class\");\r\n            pw.print(access_clz(in.access & (~Opcodes.ACC_SUPER)));\r\n            if (in.innerName != null) {\r\n                pw.print(' ');\r\n                printIdAfterAccess(pw, in.innerName);\r\n            }\r\n            if (in.name != null) {\r\n                pw.print(\" inner \");\r\n                pw.print(in.name);\r\n            }\r\n            if (in.outerName != null) {\r\n                pw.print(\" outer \");\r\n                pw.print(in.outerName);\r\n            }\r\n            pw.println();\r\n        }\r\n\r\n        for (FieldNode fn : cn.fields) {\r\n            boolean annotations = false;\r\n            if (fn.visibleAnnotations != null && fn.visibleAnnotations.size() > 0) {\r\n                annotations = true;\r\n            }\r\n            if (fn.invisibleAnnotations != null && fn.invisibleAnnotations.size() > 0) {\r\n                annotations = true;\r\n            }\r\n            boolean deprecated = (fn.access & Opcodes.ACC_DEPRECATED) != 0;\r\n            pw.print(\"\\n.field\");\r\n            pw.print(access_fld(fn.access));\r\n            pw.print(' ');\r\n            printIdAfterAccess(pw,fn.name);\r\n            pw.print(' ');\r\n            pw.print(fn.desc);\r\n            if (fn.value instanceof String) {\r\n                StringBuffer buf = new StringBuffer();\r\n                Printer.appendString(buf, (String) fn.value);\r\n                pw.print(\" = \");\r\n                pw.print(buf.toString());\r\n            } else if (fn.value != null) {\r\n                pw.print(\" = \");\r\n                print(fn.value);\r\n            }\r\n            pw.println();\r\n            if (fn.signature != null) {\r\n                pw.print(\".signature \\\"\");\r\n                pw.print(fn.signature);\r\n                pw.println(\"\\\"\");\r\n            }\r\n            if (deprecated) {\r\n                pw.println(\".deprecated\");\r\n            }\r\n            if (fn.visibleAnnotations != null) {\r\n                for (AnnotationNode an : fn.visibleAnnotations) {\r\n                    printAnnotation(an, 1, -1);\r\n                }\r\n            }\r\n            if (fn.invisibleAnnotations != null) {\r\n                for (AnnotationNode an : fn.invisibleAnnotations) {\r\n                    printAnnotation(an, 2, -1);\r\n                }\r\n            }\r\n            if (fn.signature != null || deprecated || annotations) {\r\n                pw.println(\".end field\");\r\n            }\r\n        }\r\n\r\n        for (MethodNode mn : cn.methods) {\r\n            pw.print(\"\\n.method\");\r\n            pw.print(access_mtd(mn.access));\r\n            pw.print(' ');\r\n            printIdAfterAccess(pw, mn.name);\r\n            pw.println(mn.desc);\r\n            if (mn.signature != null) {\r\n                pw.print(\".signature \\\"\");\r\n                pw.print(mn.signature);\r\n                pw.println(\"\\\"\");\r\n            }\r\n            if (mn.annotationDefault != null) {\r\n                pw.println(\".annotation default\");\r\n                printAnnotationValue(mn.annotationDefault);\r\n                pw.println(\".end annotation\");\r\n            }\r\n            if (mn.visibleAnnotations != null) {\r\n                for (AnnotationNode an : mn.visibleAnnotations) {\r\n                    printAnnotation(an, 1, -1);\r\n                }\r\n            }\r\n            if (mn.invisibleAnnotations != null) {\r\n                for (AnnotationNode an : mn.invisibleAnnotations) {\r\n                    printAnnotation(an, 2, -1);\r\n                }\r\n            }\r\n            if (mn.visibleParameterAnnotations != null) {\r\n                for (int j = 0; j < mn.visibleParameterAnnotations.length; ++j) {\r\n                    List<AnnotationNode> pas = mn.visibleParameterAnnotations[j];\r\n                    if (pas != null) {\r\n                        for (AnnotationNode an : pas) {\r\n                            printAnnotation(an, 1, j + 1);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            if (mn.invisibleParameterAnnotations != null) {\r\n                for (int j = 0; j < mn.invisibleParameterAnnotations.length; ++j) {\r\n                    List<AnnotationNode> pas = mn.invisibleParameterAnnotations[j];\r\n                    if (pas != null) {\r\n                        for (AnnotationNode an : pas) {\r\n                            printAnnotation(an, 2, j + 1);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            for (String ex : mn.exceptions) {\r\n                println(\".throws \", ex);\r\n            }\r\n            if ((mn.access & Opcodes.ACC_DEPRECATED) != 0) {\r\n                pw.println(\".deprecated\");\r\n            }\r\n            if (mn.instructions != null && mn.instructions.size() > 0) {\r\n                labelNames.clear();\r\n                if (mn.tryCatchBlocks != null) {\r\n                    for (TryCatchBlockNode tcb : mn.tryCatchBlocks) {\r\n                        pw.print(\".catch \");\r\n                        pw.print(tcb.type == null ? \"all\" : \"all\".equals(tcb.type) ? \"\\\\u0097ll\" : tcb.type);\r\n                        pw.print(\" from \");\r\n                        print(tcb.start);\r\n                        pw.print(\" to \");\r\n                        print(tcb.end);\r\n                        pw.print(\" using \");\r\n                        print(tcb.handler);\r\n                        pw.println();\r\n                    }\r\n                }\r\n                for (int j = 0; j < mn.instructions.size(); ++j) {\r\n                    AbstractInsnNode in = mn.instructions.get(j);\r\n                    if (in.getType() != AbstractInsnNode.LINE && in.getType() != AbstractInsnNode.FRAME) {\r\n                       if(in.getType()==AbstractInsnNode.LABEL){\r\n                           pw.print(\"  \");\r\n                       }else {\r\n                           pw.print(\"    \");\r\n                       }\r\n                    }\r\n                    in.accept(new MethodVisitor(ASM4) {\r\n\r\n                        @Override\r\n                        public void visitInsn(int opcode) {\r\n                            print(opcode);\r\n                            pw.println();\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitIntInsn(int opcode, int operand) {\r\n                            print(opcode);\r\n                            if (opcode == Opcodes.NEWARRAY) {\r\n                                switch (operand) {\r\n                                case Opcodes.T_BOOLEAN:\r\n                                    pw.println(\" boolean\");\r\n                                    break;\r\n                                case Opcodes.T_CHAR:\r\n                                    pw.println(\" char\");\r\n                                    break;\r\n                                case Opcodes.T_FLOAT:\r\n                                    pw.println(\" float\");\r\n                                    break;\r\n                                case Opcodes.T_DOUBLE:\r\n                                    pw.println(\" double\");\r\n                                    break;\r\n                                case Opcodes.T_BYTE:\r\n                                    pw.println(\" byte\");\r\n                                    break;\r\n                                case Opcodes.T_SHORT:\r\n                                    pw.println(\" short\");\r\n                                    break;\r\n                                case Opcodes.T_INT:\r\n                                    pw.println(\" int\");\r\n                                    break;\r\n                                case Opcodes.T_LONG:\r\n                                default:\r\n                                    pw.println(\" long\");\r\n                                    break;\r\n                                }\r\n                            } else {\r\n                                pw.print(' ');\r\n                                pw.println(operand);\r\n                            }\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitVarInsn(int opcode, int var) {\r\n                            print(opcode);\r\n                            pw.print(' ');\r\n                            pw.println(var);\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitTypeInsn(int opcode, String type) {\r\n                            print(opcode);\r\n                            pw.print(' ');\r\n                            pw.println(type);\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitFieldInsn(int opcode, String owner, String name, String desc) {\r\n                            print(opcode);\r\n                            pw.print(' ');\r\n                            pw.print(owner);\r\n                            pw.print('/');\r\n                            pw.print(name);\r\n                            pw.print(' ');\r\n                            pw.println(desc);\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitMethodInsn(int opcode, String owner, String name, String desc) {\r\n                            print(opcode);\r\n                            pw.print(' ');\r\n                            pw.print(owner);\r\n                            pw.print('/');\r\n                            pw.print(name);\r\n                            pw.print(desc);\r\n                            if (opcode == Opcodes.INVOKEINTERFACE) {\r\n                                pw.print(' ');\r\n                                pw.print((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);\r\n                            }\r\n                            pw.println();\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitJumpInsn(int opcode, Label label) {\r\n                            print(opcode);\r\n                            pw.print(' ');\r\n                            print(label);\r\n                            pw.println();\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitLabel(Label label) {\r\n                            print(label);\r\n                            pw.println(':');\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitLdcInsn(Object cst) {\r\n\r\n                            if (cst instanceof Integer || cst instanceof Float) {\r\n                                pw.print(\"ldc_w \");\r\n                                print(cst);\r\n                            } else if (cst instanceof Long || cst instanceof Double) {\r\n                                pw.print(\"ldc2_w \");\r\n                                print(cst);\r\n                            } else {\r\n                                pw.print(\"ldc \");\r\n                                if (cst instanceof Type) {\r\n                                    pw.print(((Type) cst).getInternalName());\r\n                                } else {\r\n                                    print(cst);\r\n                                }\r\n                            }\r\n                            pw.println();\r\n\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitIincInsn(int var, int increment) {\r\n                            pw.print(\"iinc \");\r\n                            pw.print(var);\r\n                            pw.print(' ');\r\n                            pw.println(increment);\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {\r\n                            pw.print(\"tableswitch \");\r\n                            pw.println(min);\r\n                            for (Label label : labels) {\r\n                                pw.print(\"      \");\r\n                                print(label);\r\n                                pw.println();\r\n                            }\r\n                            pw.print(\"      default : \");\r\n                            print(dflt);\r\n                            pw.println();\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {\r\n                            pw.println(\"lookupswitch\");\r\n                            for (int i = 0; i < keys.length; ++i) {\r\n                                pw.print(\"      \");\r\n                                pw.print(keys[i]);\r\n                                pw.print(\" : \");\r\n                                print(labels[i]);\r\n                                pw.println();\r\n                            }\r\n                            pw.print(\"      default : \");\r\n                            print(dflt);\r\n                            pw.println();\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitMultiANewArrayInsn(String desc, int dims) {\r\n                            pw.print(\"multianewarray \");\r\n                            pw.print(desc);\r\n                            pw.print(' ');\r\n                            pw.println(dims);\r\n                        }\r\n\r\n                        @Override\r\n                        public void visitLineNumber(int line, Label start) {\r\n                            pw.print(\".line \");\r\n                            pw.println(line);\r\n                        }\r\n                    });\r\n                }\r\n                if (mn.localVariables != null) {\r\n                    for (LocalVariableNode lv : mn.localVariables) {\r\n                        pw.print(\"  .var \");\r\n                        pw.print(lv.index);\r\n                        pw.print(\" is '\");\r\n                        pw.print(lv.name);\r\n                        pw.print(\"' \");\r\n                        pw.print(lv.desc);\r\n                        if (lv.signature != null) {\r\n                            pw.print(\" signature \\\"\");\r\n                            pw.print(lv.signature);\r\n                            pw.print(\"\\\"\");\r\n                        }\r\n                        pw.print(\" from \");\r\n                        print(lv.start);\r\n                        pw.print(\" to \");\r\n                        print(lv.end);\r\n                        pw.println();\r\n                    }\r\n                }\r\n                println(\"  .limit locals \", Integer.toString(mn.maxLocals));\r\n                println(\"  .limit stack \", Integer.toString(mn.maxStack));\r\n            }\r\n            pw.println(\".end method\");\r\n        }\r\n    }\r\n\r\n    protected void println(final String directive, final String arg) {\r\n        if (arg != null) {\r\n            pw.print(directive);\r\n            pw.println(arg);\r\n        }\r\n    }\r\n    protected String access_clz(final int access) {\r\n        StringBuilder b = new StringBuilder();\r\n        if ((access & Opcodes.ACC_PUBLIC) != 0) {\r\n            b.append(\" public\");\r\n        }\r\n        if ((access & Opcodes.ACC_PRIVATE) != 0) {\r\n            b.append(\" private\");\r\n        }\r\n        if ((access & Opcodes.ACC_PROTECTED) != 0) {\r\n            b.append(\" protected\");\r\n        }\r\n        if ((access & Opcodes.ACC_FINAL) != 0) {\r\n            b.append(\" final\");\r\n        }\r\n        if ((access & Opcodes.ACC_SUPER) != 0) {\r\n            b.append(\" super\");\r\n        }\r\n        if ((access & Opcodes.ACC_ABSTRACT) != 0) {\r\n            b.append(\" abstract\");\r\n        }\r\n        if ((access & Opcodes.ACC_INTERFACE) != 0) {\r\n            b.append(\" interface\");\r\n        }\r\n        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {\r\n            b.append(\" synthetic\");\r\n        }\r\n        if ((access & Opcodes.ACC_ANNOTATION) != 0) {\r\n            b.append(\" annotation\");\r\n        }\r\n        if ((access & Opcodes.ACC_ENUM) != 0) {\r\n            b.append(\" enum\");\r\n        }\r\n        return b.toString();\r\n    }\r\n    protected String access_fld(final int access) {\r\n        StringBuilder b = new StringBuilder();\r\n        if ((access & Opcodes.ACC_PUBLIC) != 0) {\r\n            b.append(\" public\");\r\n        }\r\n        if ((access & Opcodes.ACC_PRIVATE) != 0) {\r\n            b.append(\" private\");\r\n        }\r\n        if ((access & Opcodes.ACC_PROTECTED) != 0) {\r\n            b.append(\" protected\");\r\n        }\r\n        if ((access & Opcodes.ACC_STATIC) != 0) {\r\n            b.append(\" static\");\r\n        }\r\n        if ((access & Opcodes.ACC_FINAL) != 0) {\r\n            b.append(\" final\");\r\n        }\r\n        if ((access & Opcodes.ACC_VOLATILE) != 0) {\r\n            b.append(\" volatile\");\r\n        }\r\n        if ((access & Opcodes.ACC_TRANSIENT) != 0) {\r\n            b.append(\" transient\");\r\n        }\r\n        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {\r\n            b.append(\" synthetic\");\r\n        }\r\n        if ((access & Opcodes.ACC_ENUM) != 0) {\r\n            b.append(\" enum\");\r\n        }\r\n        return b.toString();\r\n    }\r\n    protected String access_mtd(final int access) {\r\n        StringBuilder b = new StringBuilder();\r\n        if ((access & Opcodes.ACC_PUBLIC) != 0) {\r\n            b.append(\" public\");\r\n        }\r\n        if ((access & Opcodes.ACC_PRIVATE) != 0) {\r\n            b.append(\" private\");\r\n        }\r\n        if ((access & Opcodes.ACC_PROTECTED) != 0) {\r\n            b.append(\" protected\");\r\n        }\r\n        if ((access & Opcodes.ACC_STATIC) != 0) {\r\n            b.append(\" static\");\r\n        }\r\n        if ((access & Opcodes.ACC_FINAL) != 0) {\r\n            b.append(\" final\");\r\n        }\r\n        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {\r\n            b.append(\" synchronized\");\r\n        }\r\n        if ((access & Opcodes.ACC_BRIDGE) != 0) {\r\n            b.append(\" bridge\");\r\n        }\r\n        if ((access & Opcodes.ACC_VARARGS) != 0) {\r\n            b.append(\" varargs\");\r\n        }\r\n        if ((access & Opcodes.ACC_NATIVE) != 0) {\r\n            b.append(\" native\");\r\n        }\r\n        if ((access & Opcodes.ACC_ABSTRACT) != 0) {\r\n            b.append(\" abstract\");\r\n        }\r\n        if ((access & Opcodes.ACC_STRICT) != 0) {\r\n            b.append(\" strict\");\r\n        }\r\n        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {\r\n            b.append(\" synthetic\");\r\n        }\r\n        return b.toString();\r\n    }\r\n\r\n    protected void print(final int opcode) {\r\n        pw.print(Printer.OPCODES[opcode].toLowerCase());\r\n    }\r\n\r\n    protected void print(final Object cst) {\r\n        if (cst instanceof String) {\r\n            StringBuffer buf = new StringBuffer();\r\n            Printer.appendString(buf, (String) cst);\r\n            pw.print(buf.toString());\r\n        } else if (cst instanceof Float) {\r\n            Float f = (Float) cst;\r\n            if (!f.isNaN() && !f.isInfinite()) {\r\n                pw.print(cst + \"F\");\r\n            } else if (f.isNaN()) {\r\n                pw.print(\"floatnan\");\r\n            } else {\r\n                double v = f;\r\n                if ((v == Float.POSITIVE_INFINITY)) {\r\n                    pw.print(\"+floatinfinity\");\r\n                } else {\r\n                    pw.print(\"-floatinfinity\");\r\n                }\r\n            }\r\n        } else if (cst instanceof Double) {\r\n            Double d = (Double) cst;\r\n\r\n            if (!d.isNaN() && !d.isInfinite()) {\r\n                pw.print(cst + \"D\");\r\n            } else if (d.isNaN()) {\r\n                pw.print(\"doublenan\");\r\n            } else {\r\n                double v = d;\r\n                if ((v == Double.POSITIVE_INFINITY)) {\r\n                    pw.print(\"+doubleinfinity\");\r\n                } else {\r\n                    pw.print(\"-doubleinfinity\");\r\n                }\r\n            }\r\n        } else if (cst instanceof Long) {\r\n            pw.print(cst + \"L\");\r\n        } else {\r\n            pw.print(cst);\r\n        }\r\n    }\r\n\r\n    protected void print(final Label l) {\r\n        String name = labelNames.get(l);\r\n        if (name == null) {\r\n            name = \"L\" + labelNames.size();\r\n            labelNames.put(l, name);\r\n        }\r\n        pw.print(name);\r\n    }\r\n\r\n    protected void print(final LabelNode l) {\r\n        print(l.getLabel());\r\n    }\r\n\r\n    protected void printAnnotation(final AnnotationNode n, final int visible, final int param) {\r\n        pw.print(\".annotation \");\r\n        if (visible > 0) {\r\n            if (param == -1) {\r\n                pw.print(visible == 1 ? \"visible \" : \"invisible \");\r\n            } else {\r\n                pw.print(visible == 1 ? \"visibleparam \" : \"invisibleparam \");\r\n                pw.print(param);\r\n                pw.print(' ');\r\n            }\r\n            pw.print(n.desc);\r\n        }\r\n        pw.println();\r\n        if (n.values != null) {\r\n            for (int i = 0; i < n.values.size(); i += 2) {\r\n                pw.print(n.values.get(i));\r\n                pw.print(' ');\r\n                printAnnotationValue(n.values.get(i + 1));\r\n            }\r\n        }\r\n        pw.println(\".end annotation\");\r\n    }\r\n\r\n    protected void printAnnotationValue(final Object value) {\r\n        if (value instanceof String[]) {\r\n            pw.print(\"e \");\r\n            pw.print(((String[]) value)[0]);\r\n            pw.print(\" = \");\r\n            pw.print(((String[]) value)[1]);\r\n            pw.println();\r\n        } else if (value instanceof AnnotationNode) {\r\n            pw.print(\"@ \");\r\n            pw.print(((AnnotationNode) value).desc);\r\n            pw.print(\" = \");\r\n            printAnnotation((AnnotationNode) value, 0, -1);\r\n        } else if (value instanceof byte[]) {\r\n            pw.print(\"[B = \");\r\n            byte[] v = (byte[]) value;\r\n            for (byte element : v) {\r\n                pw.print(element);\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof boolean[]) {\r\n            pw.print(\"[Z = \");\r\n            boolean[] v = (boolean[]) value;\r\n            for (boolean element : v) {\r\n                pw.print(element ? '1' : '0');\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof short[]) {\r\n            pw.print(\"[S = \");\r\n            short[] v = (short[]) value;\r\n            for (short element : v) {\r\n                pw.print(element);\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof char[]) {\r\n            pw.print(\"[C = \");\r\n            char[] v = (char[]) value;\r\n            for (char element : v) {\r\n                pw.print(new Integer(element));\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof int[]) {\r\n            pw.print(\"[I = \");\r\n            int[] v = (int[]) value;\r\n            for (int element : v) {\r\n                pw.print(element);\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof long[]) {\r\n            pw.print(\"[J = \");\r\n            long[] v = (long[]) value;\r\n            for (long element : v) {\r\n                pw.print(element);\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof float[]) {\r\n            pw.print(\"[F = \");\r\n            float[] v = (float[]) value;\r\n            for (float element : v) {\r\n                print(new Float(element));\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof double[]) {\r\n            pw.print(\"[D = \");\r\n            double[] v = (double[]) value;\r\n            for (double element : v) {\r\n                print(new Double(element));\r\n                pw.print(' ');\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof List) {\r\n            List l = (List) value;\r\n            if (l.size() > 0) {\r\n                Object o = l.get(0);\r\n                if (o instanceof String[]) {\r\n                    pw.print(\"[e \");\r\n                    pw.print(((String[]) o)[0]);\r\n                    pw.print(\" = \");\r\n                } else if (o instanceof AnnotationNode) {\r\n                    pw.print(\"[& \");\r\n                    pw.print(((AnnotationNode) o).desc);\r\n                    pw.print(\" = \");\r\n                    pw.print(\"[@ = \");\r\n                } else if (o instanceof String) {\r\n                    pw.print(\"[s = \");\r\n                } else if (o instanceof Byte) {\r\n                    pw.print(\"[B = \");\r\n                } else if (o instanceof Boolean) {\r\n                    pw.print(\"[Z = \");\r\n                } else if (o instanceof Character) {\r\n                    pw.print(\"[C = \");\r\n                } else if (o instanceof Short) {\r\n                    pw.print(\"[S = \");\r\n                } else if (o instanceof Type) {\r\n                    pw.print(\"[c = \");\r\n                } else if (o instanceof Integer) {\r\n                    pw.print(\"[I = \");\r\n                } else if (o instanceof Float) {\r\n                    pw.print(\"[F = \");\r\n                } else if (o instanceof Long) {\r\n                    pw.print(\"[J = \");\r\n                } else if (o instanceof Double) {\r\n                    pw.print(\"[D = \");\r\n                }\r\n                for (Object aL : l) {\r\n                    printAnnotationArrayValue(aL);\r\n                    pw.print(' ');\r\n                }\r\n            } else {\r\n                pw.print(\"; empty array annotation value\");\r\n            }\r\n            pw.println();\r\n        } else if (value instanceof String) {\r\n            pw.print(\"s = \");\r\n            print(value);\r\n            pw.println();\r\n        } else if (value instanceof Byte) {\r\n            pw.print(\"B = \");\r\n            pw.println(((Byte) value).intValue());\r\n        } else if (value instanceof Boolean) {\r\n            pw.print(\"Z = \");\r\n            pw.println(((Boolean) value).booleanValue() ? 1 : 0);\r\n        } else if (value instanceof Character) {\r\n            pw.print(\"C = \");\r\n            pw.println(new Integer(((Character) value).charValue()));\r\n        } else if (value instanceof Short) {\r\n            pw.print(\"S = \");\r\n            pw.println(((Short) value).intValue());\r\n        } else if (value instanceof Type) {\r\n            pw.print(\"c = \");\r\n            pw.println(((Type) value).getDescriptor());\r\n        } else if (value instanceof Integer) {\r\n            pw.print(\"I = \");\r\n            print(value);\r\n            pw.println();\r\n        } else if (value instanceof Float) {\r\n            pw.print(\"F = \");\r\n            print(value);\r\n            pw.println();\r\n        } else if (value instanceof Long) {\r\n            pw.print(\"J = \");\r\n            print(value);\r\n            pw.println();\r\n        } else if (value instanceof Double) {\r\n            pw.print(\"D = \");\r\n            print(value);\r\n            pw.println();\r\n        } else {\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    protected void printAnnotationArrayValue(final Object value) {\r\n        if (value instanceof String[]) {\r\n            print(((String[]) value)[1]);\r\n        } else if (value instanceof AnnotationNode) {\r\n            printAnnotation((AnnotationNode) value, 0, -1);\r\n        } else if (value instanceof String) {\r\n            print(value);\r\n        } else if (value instanceof Byte) {\r\n            pw.print(((Byte) value).intValue());\r\n        } else if (value instanceof Boolean) {\r\n            pw.print(((Boolean) value).booleanValue() ? 1 : 0);\r\n        } else if (value instanceof Character) {\r\n            pw.print(new Integer(((Character) value).charValue()));\r\n        } else if (value instanceof Short) {\r\n            pw.print(((Short) value).intValue());\r\n        } else if (value instanceof Type) {\r\n            pw.print(((Type) value).getDescriptor());\r\n        } else {\r\n            print(value);\r\n        }\r\n    }\r\n\r\n    protected void printFrameType(final Object type) {\r\n        if (type == Opcodes.TOP) {\r\n            pw.print(\"Top\");\r\n        } else if (type == Opcodes.INTEGER) {\r\n            pw.print(\"Integer\");\r\n        } else if (type == Opcodes.FLOAT) {\r\n            pw.print(\"Float\");\r\n        } else if (type == Opcodes.LONG) {\r\n            pw.print(\"Long\");\r\n        } else if (type == Opcodes.DOUBLE) {\r\n            pw.print(\"Double\");\r\n        } else if (type == Opcodes.NULL) {\r\n            pw.print(\"Null\");\r\n        } else if (type == Opcodes.UNINITIALIZED_THIS) {\r\n            pw.print(\"UninitializedThis\");\r\n        } else if (type instanceof Label) {\r\n            pw.print(\"Uninitialized \");\r\n            print((Label) type);\r\n        } else {\r\n            pw.print(\"Object \");\r\n            pw.print(type);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-jasmin/src/main/java/com/googlecode/d2j/jasmin/Jasmins.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.jasmin;\r\n\r\nimport org.antlr.runtime.ANTLRReaderStream;\r\nimport org.antlr.runtime.ANTLRStringStream;\r\nimport org.antlr.runtime.CommonTokenStream;\r\nimport org.antlr.runtime.RecognitionException;\r\nimport org.objectweb.asm.tree.ClassNode;\r\n\r\nimport java.io.*;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\n\r\npublic class Jasmins {\r\n    public static ClassNode parse(Path file) throws IOException {\r\n        try (BufferedReader bufferedReader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {\r\n            return parse(file.toString(), bufferedReader);\r\n        } catch (RecognitionException e) {\r\n            throw new RuntimeException(\"Fail to assemble \" + file, e);\r\n        }\r\n    }\r\n\r\n    public static ClassNode parse(String fileName, Reader bufferedReader) throws IOException, RecognitionException {\r\n        ANTLRStringStream is = new ANTLRReaderStream(bufferedReader);\r\n        is.name = fileName;\r\n        JasminLexer lexer = new JasminLexer(is);\r\n        CommonTokenStream ts = new CommonTokenStream(lexer);\r\n        JasminParser parser = new JasminParser(ts);\r\n        return parser.parse();\r\n    }\r\n\r\n    public static ClassNode parse(String fileName, InputStream is) throws IOException, RecognitionException {\r\n        return parse(fileName, new InputStreamReader(is, \"UTF-8\"));\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-jasmin/src/test/java/com/googlecode/d2j/tools/jar/test/Jasmin2jTest.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2015 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.tools.jar.test;\n\nimport com.googlecode.d2j.jasmin.JasminDumper;\nimport com.googlecode.d2j.jasmin.Jasmins;\nimport org.junit.Assert;\nimport org.junit.runner.Description;\nimport org.junit.runner.RunWith;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.ParentRunner;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\nimport org.objectweb.asm.tree.ClassNode;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.net.URL;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@RunWith(Jasmin2jTest.S.class)\npublic class Jasmin2jTest {\n\n    public static class S extends ParentRunner<Path> {\n\n        public S(Class<?> klass) throws InitializationError {\n            super(klass);\n            init(klass);\n        }\n\n        Path basePath;\n        List<Path> runners = new ArrayList<>();\n\n        public void init(final Class<?> testClass) throws InitializationError {\n            URL url = testClass.getResource(\"/jasmins/type.j\");\n            Assert.assertNotNull(url);\n\n            final String file = url.getFile();\n            Assert.assertNotNull(file);\n\n            basePath = new File(file).toPath().getParent();\n\n            System.out.println(\"jasmins dir is \" + basePath);\n\n            try {\n                Files.walkFileTree(basePath, new SimpleFileVisitor<Path>() {\n                    @Override\n                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                        if (file.getFileName().toString().endsWith(\".j\")) {\n                            runners.add(basePath.relativize(file));\n                        }\n                        return super.visitFile(file, attrs);\n                    }\n                });\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n        }\n\n        @Override\n        protected List<Path> getChildren() {\n            return runners;\n        }\n\n        @Override\n        protected Description describeChild(Path child) {\n            return Description.createTestDescription(getTestClass().getJavaClass(), child.toString());\n        }\n\n        @Override\n        protected void runChild(final Path child, RunNotifier notifier) {\n            runLeaf(new Statement() {\n                @Override\n                public void evaluate() throws Throwable {\n                    ClassNode cn= Jasmins.parse(basePath.resolve(child));\n                    JasminDumper dumper=new JasminDumper(new PrintWriter(System.out,true));\n                    dumper.dump(cn);\n                }\n            }, describeChild(child), notifier);\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-jasmin/src/test/resources/jasmins/type.j",
    "content": ".class public 'public'\n.implements A\n.implements interface\n.implements public\n\n.annotation visible Ljava/lang/A;\n.annotation visible java/lang/B\n.end annotation\n\n.annotation visible Ljava/lang/annotation/Retention;\nvalue e Ljava/lang/annotation/RetentionPolicy; = CLASS\nvalue [e LR; = CLASS 'CLASS2' \"CLASS3\"\n.end annotation\n\n.method public ldc()V\nldc 0\nldc 1L\nldc \"abc\"\nldc I                ;;;;;;; equals to LI;\nldc Ljava/lang/Object;\nldc [I\nldc [[Ljava/lang/Object;\n.end method\n\n.method public checkcast()V\ninvokeinterface android/content/DialogInterface/dismiss()V 0\ncheckcast Ljava/lang/Object;\ncheckcast [I\ncheckcast [[Ljava/lang/Object;\ncheckcast I\ninvokestatic LB;->clone()V\ninvokestatic B/clone()V\ninvokestatic [B->clone()V\ninvokestatic [B/clone()V\ngetstatic LB;->a:I\ngetstatic B/a I\ngetstatic [B->a:I\ngetstatic [B/a I\n\n\ngetstatic B/public I\n\n.end method\n.method public \"public\"()V\n.end method\n.method public 'static'()V\n.end method\n"
  },
  {
    "path": "d2j-smali/build.gradle",
    "content": "apply plugin: 'antlr'\n\ndependencies {\n  compile 'org.antlr:antlr4-runtime:4.5'\n  compile project(':dex-reader')\n  antlr 'org.antlr:antlr4:4.5'\n  compile project(':d2j-base-cmd')\n  compile project(':dex-writer')\n  testCompile 'org.smali:baksmali:2.0.6'\n}\n\ngenerateGrammarSource {\n    arguments += ['-no-listener', '-visitor','-package','com.googlecode.d2j.smali.antlr4']\n}\n\nsourceSets {\n    test.output.resourcesDir = \"build/classes/test\"\n    main.antlr.srcDirs = ['src/main/antlr4']\n}\n"
  },
  {
    "path": "d2j-smali/src/main/antlr4/com/googlecode/d2j/smali/antlr4/Smali.g4",
    "content": "grammar Smali;\n\nfragment\nINT_NENT: ('+'|'-')? (\n               '0'\n            | ('1'..'9') ('0'..'9')*\n            | '0' ('0'..'7')+\n            | ('0x'|'0X') HEX_DIGIT+\n         );\nfragment\nFLOAT_NENT\n    : (('+'|'-')?( ('0'..'9')+ '.' ('0'..'9')* EXPONENT?\n    |   '.' ('0'..'9')+ EXPONENT?\n    |   ('0'..'9')+ EXPONENT)| ( ('+'|'-') F_INFINITY) )\n    ;\nfragment\nF_NAN : ('N'|'n') ('A'|'a') ('N'|'n');\n\nCOMMENT\n    :   ('//' ~('\\n'|'\\r')* '\\r'? '\\n'\n    |   '#' ~('\\n'|'\\r')* '\\r'? '\\n'\n    |   '/*' .*? '*/' ) -> skip\n    ;\n\nWS  :   [ \\t\\r\\n]+ -> skip\n    ;\n\nfragment\nEXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;\n\nfragment\nHEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;\n\nfragment\nESC_SEQ\n    :   '\\\\' ('b'|'t'|'n'|'f'|'r'|'\\''|'\\\"'|'\\\\')\n    |   UNICODE_ESC\n    |   OCTAL_ESC\n    ;\n\nfragment\nOCTAL_ESC\n    :   '\\\\' ('0'..'3') ('0'..'7') ('0'..'7')\n    |   '\\\\' ('0'..'7') ('0'..'7')\n    |   '\\\\' ('0'..'7')\n    ;\n\nfragment\nUNICODE_ESC\n    :   '\\\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT\n    ;\nVOID_TYPE:'V';\nfragment\nFRAGMENT_PRIMITIVE_TYPE:'B'|'Z'|'S'|'C'|'I'|'F'|'J'|'D';\nfragment\nFRAGMENT_OBJECT_TYPE: 'L' (ESC_SEQ |~(';'|':'|'\\\\'|' '|'\\n'|'\\t'|'\\r'|'('|')'))+ ';' ;\nfragment\nFRAGMENT_ARRAY_TYPE: ('[')+ (FRAGMENT_PRIMITIVE_TYPE|FRAGMENT_OBJECT_TYPE);\n\nfragment\nFRAGMENT_ID: (ESC_SEQ| ~('\\\\'|'\\r'|'\\n'|'\\t'|' '|':'|'-'|'='|','|'{'|'}'|'('|')'|'+'|'\\\"'|'\\''|'#'|'/'|'.'|';'))+;\nfragment\nFRAGMENT_METHOD_PROTO: '(' (FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE|FRAGMENT_PRIMITIVE_TYPE)* ')' ('V' | FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE|FRAGMENT_PRIMITIVE_TYPE)\n;\nfragment\nFRAGMENT_FIELD_PART:\n FRAGMENT_ID\n ':' (FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE|FRAGMENT_PRIMITIVE_TYPE)\n;\n\n\nMETHOD_FULL: (FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE) '->' FRAGMENT_ID FRAGMENT_METHOD_PROTO;\nMETHOD_PART: FRAGMENT_ID FRAGMENT_METHOD_PROTO;\nMETHOD_PROTO: FRAGMENT_METHOD_PROTO;\n\nFIELD_FULL: (FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE) '->' FRAGMENT_FIELD_PART;\nFIELD_PART: FRAGMENT_FIELD_PART;\nLABEL: ':' FRAGMENT_ID;\n\nSMALI_V2_LOCAL_NAME_TYPE : '\"' ( ESC_SEQ | ~('\\\\'|'\"') )* '\"' ':' (FRAGMENT_OBJECT_TYPE|FRAGMENT_ARRAY_TYPE|FRAGMENT_PRIMITIVE_TYPE)\n                         ;\n\nF_INFINITY: ('I'|'i') ('N'|'n') ('F'|'f') ('I'|'i') ('N'|'n') ('I'|'i') ('T'|'t') ('Y'|'y') ;\nFLOAT_NAN : F_NAN ('f'|'F');\nDOUBLE_NAN: F_NAN ('d'|'D')?;\nFLOAT_INFINITY: F_INFINITY ('f'|'F');\nDOUBLE_INFINITY: F_INFINITY ('d'|'D')?;\nBASE_FLOAT\t:\t(('0'..'9')+|FLOAT_NENT) ('f'|'F');\nBASE_DOUBLE\t:\tFLOAT_NENT ('d'|'D')? | ('0'..'9')+ ('d'|'D') ;\nCHAR\t:\t'\\''  ( ESC_SEQ | ~('\\\\'|'\\'') ) '\\'';\nLONG\t:\tINT_NENT ('L'|'l');\nSHORT\t:\tINT_NENT ('S'|'s');\nBYTE\t:\tINT_NENT ('T'|'t');\nINT\t:\tINT_NENT;\nBOOLEAN\t:\t'true'|'false';\n\n\nSTRING\n    :  '\"' ( ESC_SEQ | ~('\\\\'|'\"') )* '\"'\n    ;\n\nOBJECT_TYPE: FRAGMENT_OBJECT_TYPE;\nARRAY_TYPE: FRAGMENT_ARRAY_TYPE;\nPRIMITIVE_TYPE: FRAGMENT_PRIMITIVE_TYPE;\n\nACC:\t'public' | 'private' | 'protected' | 'static' | 'final' | 'synchronized' | 'bridge' | 'varargs' | 'native' |\n    'abstract' | 'strictfp' | 'synthetic' | 'constructor' | 'interface' | 'enum' |\n    'annotation' | 'volatile' | 'transient' | 'declared-synchronized' ;\nANN_VISIBLE\n\t:\t'build' | 'runtime' | 'system';\nREGISTER:\t('v'|'V'|'p'|'P') '0'..'9'+;\nNOP\t:\t'nop';\nMOVE\t:\t'move';\nRETURN\t:\t'return';\nCONST\t:\t'const';\nTHROW\t:\t'throw';\nGOTO\t:\t'goto';\nAGET\t:\t'aget';\nAPUT\t:\t'aput';\nIGET\t:\t'iget';\nIPUT\t:\t'iput';\nSGET\t:\t'sget';\nSPUT\t:\t'sput';\nNULL    :   'null';\nID  :\tFRAGMENT_ID\n    ;\nDPARAMETER:'.parameter';\nDENUM:'.enum';\nDPARAM: '.param';\nDLINENUMBER: '.line';\nDLOCAL:'.local';\nDENDLOCAL:'.end local';\nDRESTARTLOCAL:'.restart local';\nDPROLOGUE:'.prologue';\nDEPIOGUE:'.epiogue';\n\nsFiles: sFile+;\nsFile\t:\t'.class' sAccList className=OBJECT_TYPE\n    ( sSuper | sInterface|sSource|sMethod|sField|sAnnotation)*\n             '.end class'?\n    \t;\nsSource :\t'.source' src=STRING;\nsSuper\t:\t'.super' name=OBJECT_TYPE;\nsInterface:\t'.implements' name=OBJECT_TYPE;\nsMethod\n\t:\t'.method' sAccList methodObj=(METHOD_FULL|METHOD_PART)\n\t\t(  sAnnotation\n\t\t  | sParameter\n\t\t  | sInstruction\n\t\t )*\n\t\t'.end method';\nsField\t: '.field' sAccList fieldObj=(FIELD_FULL|FIELD_PART) ('=' sBaseValue)?\n\t\t(sAnnotation*\n\t\t'.end field')?\n\t;\nsAccList: ACC*;\nsAnnotation\n\t: \t'.annotation' visibility=ANN_VISIBLE type=OBJECT_TYPE\n\t\t(sAnnotationKeyName '=' sAnnotationValue)*\n\t\t '.end annotation'\n\t;\nsSubannotation\n\t:\t'.subannotation' type=OBJECT_TYPE (sAnnotationKeyName '=' sAnnotationValue )* '.end subannotation'\n\t;\nsParameter\n\t:\tparameter=DPARAMETER (name=STRING)?  ( (sAnnotation)* '.end parameter')?\n\t\t| param=DPARAM r=REGISTER (',' name=STRING )? (sAnnotation* '.end param')?\n\t;\nsAnnotationKeyName\n\t:\tPRIMITIVE_TYPE |VOID_TYPE\n        \t|ANN_VISIBLE|REGISTER|BOOLEAN|ID | NULL\n        \t|FLOAT_INFINITY|DOUBLE_INFINITY|FLOAT_NAN|DOUBLE_NAN\n        \t|NOP|MOVE|RETURN|CONST|THROW|GOTO|AGET|APUT|IGET|IPUT|SGET|SPUT|ACC;\nsAnnotationValue\n\t:sSubannotation\n\t|sBaseValue\n\t|sArrayValue\n\t| ( '.iget' | '.iput' | '.sget' | '.sput' ) FIELD_FULL\n\t| ( '.invoke-instance' | '.invoke-static' ) METHOD_FULL\n\t;// field,method,array,subannotation\nsBaseValue\n\t:STRING\n\t|BOOLEAN|BYTE|SHORT|CHAR|INT|LONG\n\t|BASE_FLOAT| FLOAT_INFINITY | FLOAT_NAN\n\t|BASE_DOUBLE|DOUBLE_INFINITY|DOUBLE_NAN\n\t|METHOD_FULL\n\t|METHOD_PROTO\n\t|OBJECT_TYPE\n\t|ARRAY_TYPE\n\t|PRIMITIVE_TYPE\n\t|VOID_TYPE\n\t|NULL\n\t|DENUM FIELD_FULL\n\t;\nsArrayValue: '{' sAnnotationValue? (',' sAnnotationValue)* '}';\n\n\nsInstruction\n    :fline\n    |flocal\n    |fend\n    |frestart\n    |fprologue\n    |fepiogue\n    |fregisters\n\t|flocals\n\t|fcache\n\t|fcacheall\n\t|f0x\n\t|f0t\n\t|f1t\n\t|f2t\n\t|f1x\n\t|fconst\n\t|ft2c\n\t|ff1c\n\t|ff2c\n\t|f2x\n\t|f3x\n\t|ft5c\n\t|fm5c\n\t|fmrc\n\t|fm45cc\n\t|fm4rcc\n\t|fmcustomc\n\t|fmcustomrc\n\t|ftrc\n\t|sLabel\n\t|f2sb\n\t|f31t\n\t|fpackageswitch\n\t|fspareswitch\n\t|farraydata\n\t;\nfline:'.line' line=INT;\nflocal:'.local' r=REGISTER ','\n            (\n                    (name1=sAnnotationKeyName |  name2=STRING) ':' type=(OBJECT_TYPE | PRIMITIVE_TYPE | ARRAY_TYPE) // normal case\n                |   v1=FIELD_PART // smali 1.x\n                |   v2=SMALI_V2_LOCAL_NAME_TYPE // smali 2.x\n            )\n         (',' sig=STRING)?\n        ;\nfend:'.end local' r=REGISTER;\nfrestart:'.restart local'  r=REGISTER;\nfprologue:'.prologue';\nfepiogue:'.epiogue';\nfregisters:'.registers' xregisters=INT;\nflocals: '.locals' xlocals=INT;\nfcache:'.catch' type=OBJECT_TYPE '{' start=LABEL '..' end=LABEL  '}' handle=LABEL;\nfcacheall:'.catchall' '{' start=LABEL '..' end=LABEL  '}' handle=LABEL;\nsLabel: label=LABEL;\nfpackageswitch:'.packed-switch' start=INT LABEL+ '.end packed-switch';\nfspareswitch:'.sparse-switch' (INT '->' LABEL)* '.end sparse-switch';\nfarraydata:'.array-data' size=INT (sBaseValue)+ '.end array-data';\nf0x\t:\top=(NOP\n\t|\t'return-void')\n\t;\nf0t\t:\top=(GOTO|'goto/16'|'goto/32') target=LABEL\n\t;\nf1x\t:\top=('move-result'|'move-result-wide'|'move-result-object'\n\t|\t'move-exception'\n\t|\tRETURN|'return-wide'|'return-object'\n\t|\tTHROW\n\t|\t'monitor-enter' | 'monitor-exit' ) r1=REGISTER\n\t;\nfconst\n    : op=('const/4'|'const/16'|CONST|'const/high16'|'const-wide/16'|'const-wide/32'|'const-wide/high16'|'const-wide')\n                                                      r1=REGISTER ',' cst=(INT|LONG)\n\t| op=('const-string'|'const-string/jumbo')        r1=REGISTER ','  cst=STRING\n    | op=('const-class'|'check-cast'|'new-instance')  r1=REGISTER ','  cst=(OBJECT_TYPE|ARRAY_TYPE)\n\t;\nff1c\t:\top=(SGET\n\t|'sget-wide'\n\t|'sget-object'\n\t|'sget-boolean'\n\t|'sget-byte'\n\t|'sget-char'\n\t|'sget-short'\n\t|SPUT\n\t|'sput-wide'\n\t|'sput-object'\n\t|'sput-boolean'\n\t|'sput-byte'\n\t|'sput-char'\n\t|'sput-short' ) r1=REGISTER ',' fld=FIELD_FULL\n\t;\nft2c\t:\top=('instance-of'|'new-array') r1=REGISTER ',' r2=REGISTER ',' type=(OBJECT_TYPE|ARRAY_TYPE);\nff2c\t:\top=(IGET\n\t|'iget-wide'\n\t|'iget-object'\n\t|'iget-boolean'\n\t|'iget-byte'\n\t|'iget-char'\n\t|'iget-short'\n\t|\tIPUT\n\t|'iput-wide'\n\t|'iput-object'\n\t|'iput-boolean'\n\t|'iput-byte'\n\t|'iput-char'\n\t|'iput-short' ) r1=REGISTER ',' r2=REGISTER ',' fld=FIELD_FULL\n\t;\nf2x\t:\top=(MOVE|'move/from16'|'move/16'\n\t|\t'move-wide'|'move-wide/from16'|'move-wide/16'\n\t|\t'move-object'|'move-object/from16'|'move-object/16'\n\t|\t'array-length'\n\t|'neg-int'\n|'not-int'\n|'neg-long'\n|'not-long'\n|'neg-float'\n|'neg-double'\n|'int-to-long'\n|'int-to-float'\n|'int-to-double'\n|'long-to-int'\n|'long-to-float'\n|'long-to-double'\n|'float-to-int'\n|'float-to-long'\n|'float-to-double'\n|'double-to-int'\n|'double-to-long'\n|'double-to-float'\n|'int-to-byte'\n|'int-to-char'\n|'int-to-short'\n|'add-int/2addr'\n|'sub-int/2addr'\n|'mul-int/2addr'\n|'div-int/2addr'\n|'rem-int/2addr'\n|'and-int/2addr'\n|'or-int/2addr'\n|'xor-int/2addr'\n|'shl-int/2addr'\n|'shr-int/2addr'\n|'ushr-int/2addr'\n|'add-long/2addr'\n|'sub-long/2addr'\n|'mul-long/2addr'\n|'div-long/2addr'\n|'rem-long/2addr'\n|'and-long/2addr'\n|'or-long/2addr'\n|'xor-long/2addr'\n|'shl-long/2addr'\n|'shr-long/2addr'\n|'ushr-long/2addr'\n|'add-float/2addr'\n|'sub-float/2addr'\n|'mul-float/2addr'\n|'div-float/2addr'\n|'rem-float/2addr'\n|'add-double/2addr'\n|'sub-double/2addr'\n|'mul-double/2addr'\n|'div-double/2addr'\n|'rem-double/2addr') r1=REGISTER ',' r2=REGISTER\n\t;\nf3x\t:\top=('cmpl-float'|'cmpg-float'|'cmpl-double'|'cmpg-double'|'cmp-long'\n\t|\tAGET|'aget-wide'|'aget-object'|'aget-boolean'|'aget-byte'|'aget-char'|'aget-short'\n\t|\tAPUT|'aput-wide'|'aput-object'|'aput-boolean'|'aput-byte'|'aput-char'|'aput-short'\n\t|'add-int'\n|'sub-int'\n|'mul-int'\n|'div-int'\n|'rem-int'\n|'and-int'\n|'or-int'\n|'xor-int'\n|'shl-int'\n|'shr-int'\n|'ushr-int'\n|'add-long'\n|'sub-long'\n|'mul-long'\n|'div-long'\n|'rem-long'\n|'and-long'\n|'or-long'\n|'xor-long'\n|'shl-long'\n|'shr-long'\n|'ushr-long'\n|'add-float'\n|'sub-float'\n|'mul-float'\n|'div-float'\n|'rem-float'\n|'add-double'\n|'sub-double'\n|'mul-double'\n|'div-double'\n|'rem-double') r1=REGISTER ',' r2=REGISTER ',' r3=REGISTER\n\t;\nft5c\t:\top='filled-new-array' '{' (REGISTER (',' REGISTER)* )? '}' ',' type=ARRAY_TYPE;\nfm5c\t:\top=('invoke-virtual'|'invoke-super'|'invoke-direct'\n              |'invoke-static'|'invoke-interface'\n            )  '{' (REGISTER (',' REGISTER)* )? '}' ',' method=METHOD_FULL\n\t;\nfmrc\t:\top=('invoke-virtual/range'|'invoke-super/range'\n              |'invoke-direct/range'|'invoke-static/range'\n              |'invoke-interface/range'\n            )  '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' method=METHOD_FULL\n\t;\nfm45cc\t:\top='invoke-polymorphic'  '{' (REGISTER (',' REGISTER)* )? '}' ',' method=METHOD_FULL ',' proto=METHOD_PROTO\n\t;\nfm4rcc\t:\top='invoke-polymorphic/range'  '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' method=METHOD_FULL ',' proto=METHOD_PROTO\n\t;\nfmcustomc\t:\top='invoke-custom'  '{' (REGISTER (',' REGISTER)* )? '}' ',' sArrayValue\n\t;\nfmcustomrc\t:\top='invoke-custom/range'  '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' sArrayValue\n\t;\nftrc\t:\top='filled-new-array/range' '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' type=(OBJECT_TYPE|ARRAY_TYPE);\nf31t: op=('fill-array-data'|'packed-switch'|'sparse-switch') r1=REGISTER ',' label=LABEL;\nf1t\t:op=('if-eqz'|'if-nez'|'if-ltz'|'if-gez'|'if-gtz'|'if-lez')  r1=REGISTER ',' label=LABEL\n\t;\nf2t\t:op=('if-eq'|'if-ne'|'if-lt'|'if-ge'|'if-gt'|'if-le') r1=REGISTER ',' r2=REGISTER ',' label=LABEL\n\t;\nf2sb\t:op=('add-int/lit16'|'rsub-int'|'mul-int/lit16'|'div-int/lit16'|'rem-int/lit16'|'and-int/lit16'\n             |'or-int/lit16'|'xor-int/lit16'|'add-int/lit8'|'rsub-int/lit8'|'mul-int/lit8'\n             |'div-int/lit8'|'rem-int/lit8'|'and-int/lit8'|'or-int/lit8'|'xor-int/lit8'|'shl-int/lit8'|'shr-int/lit8'\n             |'ushr-int/lit8'\n          ) r1=REGISTER ',' r2=REGISTER ',' lit=INT\n\t;"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/AntlrSmaliUtil.java",
    "content": "package com.googlecode.d2j.smali;\n\nimport com.googlecode.d2j.*;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.smali.antlr4.SmaliBaseVisitor;\nimport com.googlecode.d2j.smali.antlr4.SmaliLexer;\nimport com.googlecode.d2j.smali.antlr4.SmaliParser;\nimport com.googlecode.d2j.visitors.*;\nimport org.antlr.v4.runtime.ParserRuleContext;\nimport org.antlr.v4.runtime.Token;\nimport org.antlr.v4.runtime.tree.TerminalNode;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static com.googlecode.d2j.smali.Utils.*;\n\npublic class AntlrSmaliUtil {\n    public static void acceptFile(SmaliParser.SFileContext ctx, DexFileVisitor dexFileVisitor) {\n        DexClassVisitor dexClassVisitor;\n        String className = Utils.unEscapeId(ctx.className.getText());\n        int access = collectAccess(ctx.sAccList());\n        List<SmaliParser.SSuperContext> superContexts = ctx.sSuper();\n        String superClass = null;\n        if (superContexts.size() > 0) {\n            superClass = Utils.unEscapeId(superContexts.get(superContexts.size() - 1).name.getText());\n        }\n        List<SmaliParser.SInterfaceContext> itfs = ctx.sInterface();\n        String[] interfaceNames = null;\n        if (itfs.size() > 0) {\n            interfaceNames = new String[itfs.size()];\n            for (int i = 0; i < itfs.size(); i++) {\n                interfaceNames[i] = Utils.unEscapeId(itfs.get(i).name.getText());\n            }\n        }\n\n        dexClassVisitor = dexFileVisitor.visit(access, className, superClass, interfaceNames);\n\n        List<SmaliParser.SSourceContext> sources = ctx.sSource();\n        if (sources.size() > 0) {\n            dexClassVisitor.visitSource(\n                    Utils.unescapeStr(sources.get(sources.size() - 1).src.getText())\n            );\n        }\n        acceptAnnotations(ctx.sAnnotation(), dexClassVisitor);\n        acceptField(ctx.sField(), className, dexClassVisitor);\n        acceptMethod(ctx.sMethod(), className, dexClassVisitor);\n\n        dexClassVisitor.visitEnd();\n    }\n\n    private static void acceptMethod(List<SmaliParser.SMethodContext> sMethodContexts, String className, DexClassVisitor dexClassVisitor) {\n        if (dexClassVisitor == null || sMethodContexts == null || sMethodContexts.size() == 0) {\n            return;\n        }\n        for (SmaliParser.SMethodContext ctx : sMethodContexts) {\n            acceptMethod(ctx, className, dexClassVisitor);\n        }\n    }\n\n    public static void acceptMethod(SmaliParser.SMethodContext ctx, String className, DexClassVisitor dexClassVisitor) {\n        Method method;\n        Token methodObj = ctx.methodObj;\n        if (methodObj.getType() == SmaliLexer.METHOD_FULL) {\n            method = Utils.parseMethodAndUnescape(methodObj.getText());\n        } else {// PART\n            method = Utils.parseMethodAndUnescape(className, methodObj.getText());\n        }\n        int access = collectAccess(ctx.sAccList());\n        boolean isStatic = 0 != (access & DexConstants.ACC_STATIC);\n        DexMethodVisitor dexMethodVisitor = dexClassVisitor.visitMethod(access, method);\n        if (dexMethodVisitor != null) {\n            acceptAnnotations(ctx.sAnnotation(), dexMethodVisitor);\n            int ins = Utils.methodIns(method, isStatic);\n            int totalRegisters = findTotalRegisters(ctx, ins);\n            if (totalRegisters < 0) {\n                totalRegisters = ins;\n            }\n            M m = new M(method, totalRegisters, ins, isStatic);\n            acceptParameter(ctx.sParameter(), m, dexMethodVisitor);\n            acceptCode(ctx, m, dexMethodVisitor);\n            dexMethodVisitor.visitEnd();\n        }\n    }\n\n    private static class M {\n        int locals;\n        String[] paramNames;\n        int map[];\n        public int total;\n\n        void setNameByIdx(int index, String name) {\n            if (index >= 0 && index < paramNames.length) {\n                paramNames[index] = name;\n            }\n        }\n\n        int regToParamIdx(int reg) {\n            int x = reg - locals;\n            if (x >= 0 && x < map.length) {\n                return map[x];\n            }\n            return 0;\n        }\n\n        int pareReg(String str) {\n            char f = Character.toLowerCase(str.charAt(0));\n            if (f == 'p') {\n                return parseInt(str.substring(1)) + locals;\n            } else {\n                return parseInt(str.substring(1));\n            }\n        }\n\n        M(Method method, int totals, int ins, boolean isStatic) {\n            this.locals = totals - ins;\n            this.total = totals;\n            String paramTypes[] = method.getParameterTypes();\n            paramNames = new String[paramTypes.length];\n            map = new int[ins];\n            int start = 0;\n            if (!isStatic) {\n                map[start] = -1;\n                start++;\n            }\n\n            for (int i = 0; i < paramTypes.length; i++) {\n                char t = paramTypes[i].charAt(0);\n                map[start++] = i;\n                if (t == 'J' || t == 'D') {\n                    map[start++] = i;\n                }\n            }\n        }\n    }\n\n    private static void acceptCode(SmaliParser.SMethodContext ctx, final M m, DexMethodVisitor dexMethodVisitor) {\n        if (ctx == null || dexMethodVisitor == null) {\n            return;\n        }\n        final DexCodeVisitor dexCodeVisitor = dexMethodVisitor.visitCode();\n        if (dexCodeVisitor == null) {\n            return;\n        }\n        final SmaliCodeVisitor scv = new SmaliCodeVisitor(dexCodeVisitor);\n        final DexDebugVisitor dexDebugVisitor = scv.visitDebug();\n        final List<SmaliParser.SInstructionContext> instructionContexts = ctx.sInstruction();\n        final SmaliBaseVisitor v = new SmaliBaseVisitor() {\n            @Override\n            public Object visitFregisters(SmaliParser.FregistersContext ctx) {\n                return null;\n            }\n\n            @Override\n            public Object visitFlocals(SmaliParser.FlocalsContext ctx) {\n                return null;\n            }\n\n            @Override\n            public Object visitFline(SmaliParser.FlineContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    dexDebugVisitor.visitLineNumber(Utils.parseInt(ctx.line.getText()), dexLabel);\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFend(SmaliParser.FendContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    int reg = m.pareReg(ctx.r.getText());\n                    dexDebugVisitor.visitEndLocal(reg, dexLabel);\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFlocal(SmaliParser.FlocalContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    int reg = m.pareReg(ctx.r.getText());\n                    String name;\n                    String type;\n                    if (ctx.v1 != null) {\n                        Field fld = parseFieldAndUnescape(\"Lt;\", ctx.v1.getText());\n                        name = fld.getName();\n                        type = fld.getType();\n                    } else if (ctx.v2 != null) {\n                        String txt = ctx.v2.getText();\n                        int i = findString(txt, 1, txt.length(), '\\\"');\n                        name = unescapeStr(txt.substring(0, i + 1));\n                        type = unEscapeId(txt.substring(i + 2));\n                    } else {\n                        if (ctx.name2 != null) {\n                            name = unescapeStr(ctx.name2.getText());\n                        } else {\n                            name = unEscapeId(ctx.name1.getText());\n                        }\n                        type = unEscapeId(ctx.type.getText());\n                    }\n                    String sig = ctx.sig == null ? null : unescapeStr(ctx.sig.getText());\n                    dexDebugVisitor.visitStartLocal(reg, dexLabel, name, type, sig);\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFrestart(SmaliParser.FrestartContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    int reg = m.pareReg(ctx.r.getText());\n                    dexDebugVisitor.visitRestartLocal(reg, dexLabel);\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFprologue(SmaliParser.FprologueContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    dexDebugVisitor.visitPrologue(dexLabel);\n                }\n                return null;\n            }\n\n            Map<String, DexLabel> labelMap = new HashMap<>();\n\n            @Override\n            public Object visitSLabel(SmaliParser.SLabelContext ctx) {\n                scv.visitLabel(getLabel(ctx.label.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFspareswitch(SmaliParser.FspareswitchContext ctx) {\n                List<TerminalNode> ints = ctx.INT();\n                List<TerminalNode> ts = ctx.LABEL();\n                int cases[] = new int[ts.size()];\n                DexLabel labels[] = new DexLabel[ts.size()];\n                for (int i = 0; i < ts.size(); i++) {\n                    cases[i] = parseInt(ints.get(i).getSymbol().getText());\n                    labels[i] = getLabel(ts.get(i).getSymbol().getText());\n                }\n                scv.dSparseSwitch(cases, labels);\n                return null;\n            }\n\n            @Override\n            public Object visitFarraydata(SmaliParser.FarraydataContext ctx) {\n                int size = parseInt(ctx.size.getText());\n                List<SmaliParser.SBaseValueContext> ts = ctx.sBaseValue();\n                byte[] ps = new byte[ts.size()];\n                for (int i = 0; i < ts.size(); i++) {\n                    ps[i] = ((Number) parseBaseValue(ts.get(i))).byteValue();\n                }\n                scv.dArrayData(size, ps);\n                return null;\n            }\n\n            Op getOp(Token t) {\n                return Utils.getOp(t.getText());\n            }\n\n            @Override\n            public Object visitF0x(SmaliParser.F0xContext ctx) {\n                scv.visitStmt0R(getOp(ctx.op));\n                return null;\n            }\n\n            @Override\n            public Object visitF0t(SmaliParser.F0tContext ctx) {\n                scv.visitJumpStmt(getOp(ctx.op), 0, 0, getLabel(ctx.target.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitF1x(SmaliParser.F1xContext ctx) {\n                scv.visitStmt1R(getOp(ctx.op), m.pareReg(ctx.r1.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFconst(SmaliParser.FconstContext ctx) {\n                Op op = getOp(ctx.op);\n                int r = m.pareReg(ctx.r1.getText());\n                Token cst = ctx.cst;\n\n                switch (op) {\n                    case CONST_STRING:\n                    case CONST_STRING_JUMBO:\n                        scv.visitConstStmt(op, r, unescapeStr(cst.getText()));\n                        break;\n                    case CONST_CLASS:\n                        scv.visitConstStmt(op, r, new DexType(unEscapeId(cst.getText())));\n                        break;\n                    case CHECK_CAST:\n                    case NEW_INSTANCE:\n                        scv.visitTypeStmt(op, r, 0, unEscapeId(cst.getText()));\n                        break;\n                    case CONST_WIDE:\n                        scv.visitConstStmt(op, r, cst.getType() == SmaliLexer.INT ? ((long) parseInt(cst.getText())) : parseLong(cst.getText()));\n                        break;\n                    case CONST_WIDE_16: {\n                        long v;\n                        if (cst.getType() == SmaliLexer.LONG) {\n                            v = parseLong(cst.getText());\n                        } else {\n\n                            v = (short) parseInt(cst.getText());\n                        }\n                        scv.visitConstStmt(op, r, v);\n                    }\n                    break;\n                    case CONST_WIDE_32: {\n                        long v;\n                        if (cst.getType() == SmaliLexer.LONG) {\n                            v = parseLong(cst.getText());\n                        } else {\n                            v = parseInt(cst.getText());\n                        }\n                        scv.visitConstStmt(op, r, v);\n                    }\n                    break;\n                    case CONST_WIDE_HIGH16: {\n                        long v;\n                        if (cst.getType() == SmaliLexer.LONG) {\n                            v = parseLong(cst.getText());\n                        } else {\n                            v = (short) parseInt(cst.getText());\n                            v <<= 48;\n                        }\n                        scv.visitConstStmt(op, r, v);\n                    }\n                    break;\n                    case CONST:\n                    case CONST_4:\n                    case CONST_16: {\n                        int v = parseInt(cst.getText());\n                        scv.visitConstStmt(op, r, v);\n                    }\n                    break;\n                    case CONST_HIGH16: {\n                        int v = parseInt(cst.getText());\n                        v <<= 16;\n                        scv.visitConstStmt(op, r, v);\n                    }\n                    break;\n                    default:\n                        throw new RuntimeException();\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFf1c(SmaliParser.Ff1cContext ctx) {\n                int r = m.pareReg(ctx.r1.getText());\n                Field field = parseFieldAndUnescape(ctx.fld.getText());\n                scv.visitFieldStmt(getOp(ctx.op), r, 0, field);\n                return null;\n            }\n\n            @Override\n            public Object visitFt2c(SmaliParser.Ft2cContext ctx) {\n                int r1 = m.pareReg(ctx.r1.getText());\n                int r2 = m.pareReg(ctx.r2.getText());\n                scv.visitTypeStmt(getOp(ctx.op), r1, r2, unEscapeId(ctx.type.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFf2c(SmaliParser.Ff2cContext ctx) {\n                int r1 = m.pareReg(ctx.r1.getText());\n                int r2 = m.pareReg(ctx.r2.getText());\n                scv.visitFieldStmt(getOp(ctx.op), r1, r2, parseFieldAndUnescape(ctx.fld.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitF2x(SmaliParser.F2xContext ctx) {\n                int r1 = m.pareReg(ctx.r1.getText());\n                int r2 = m.pareReg(ctx.r2.getText());\n                scv.visitStmt2R(getOp(ctx.op), r1, r2);\n                return null;\n            }\n\n            @Override\n            public Object visitF3x(SmaliParser.F3xContext ctx) {\n                int r1 = m.pareReg(ctx.r1.getText());\n                int r2 = m.pareReg(ctx.r2.getText());\n                int r3 = m.pareReg(ctx.r3.getText());\n                scv.visitStmt3R(getOp(ctx.op), r1, r2, r3);\n                return null;\n            }\n\n            @Override\n            public Object visitFt5c(SmaliParser.Ft5cContext ctx) {\n                Op op = getOp(ctx.op);\n\n                List<TerminalNode> ts = ctx.REGISTER();\n                int rs[] = new int[ts.size()];\n                for (int i = 0; i < ts.size(); i++) {\n                    rs[i] = m.pareReg(ts.get(i).getSymbol().getText());\n                }\n                scv.visitFilledNewArrayStmt(op, rs, unEscapeId(ctx.type.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFm5c(SmaliParser.Fm5cContext ctx) {\n                Op op = getOp(ctx.op);\n\n                List<TerminalNode> ts = ctx.REGISTER();\n                int rs[] = new int[ts.size()];\n                for (int i = 0; i < ts.size(); i++) {\n                    rs[i] = m.pareReg(ts.get(i).getSymbol().getText());\n                }\n                scv.visitMethodStmt(op, rs, parseMethodAndUnescape(ctx.method.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFmrc(SmaliParser.FmrcContext ctx) {\n                if (ctx.rstart != null) {\n                    int start = m.pareReg(ctx.rstart.getText());\n                    int end = m.pareReg(ctx.rend.getText());\n                    int size = end - start + 1;\n                    int rs[] = new int[size];\n                    for (int i = 0; i < size; i++) {\n                        rs[i] = start + i;\n                    }\n                    scv.visitMethodStmt(getOp(ctx.op), rs, parseMethodAndUnescape(ctx.method.getText()));\n                } else {\n                    scv.visitMethodStmt(getOp(ctx.op), new int[0], parseMethodAndUnescape(ctx.method.getText()));\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitFtrc(SmaliParser.FtrcContext ctx) {\n                if (ctx.rstart != null) {\n                    int start = m.pareReg(ctx.rstart.getText());\n                    int end = m.pareReg(ctx.rend.getText());\n                    int size = end - start + 1;\n                    int rs[] = new int[size];\n                    for (int i = 0; i < size; i++) {\n                        rs[i] = start + i;\n                    }\n                    scv.visitFilledNewArrayStmt(getOp(ctx.op), rs, unEscapeId(ctx.type.getText()));\n                } else {\n                    scv.visitFilledNewArrayStmt(getOp(ctx.op), new int[0], unEscapeId(ctx.type.getText()));\n                }\n                return null;\n            }\n\n            @Override\n            public Object visitF31t(SmaliParser.F31tContext ctx) {\n                scv.visitF31tStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), getLabel(ctx.label.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitF1t(SmaliParser.F1tContext ctx) {\n                scv.visitJumpStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), 0, getLabel(ctx.label.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitF2t(SmaliParser.F2tContext ctx) {\n                scv.visitJumpStmt(getOp(ctx.op), m.pareReg(ctx.r1.getText()), m.pareReg(ctx.r2.getText()), getLabel(ctx.label.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitF2sb(SmaliParser.F2sbContext ctx) {\n                scv.visitStmt2R1N(getOp(ctx.op), m.pareReg(ctx.r1.getText()), m.pareReg(ctx.r2.getText()), parseInt(ctx.lit.getText()));\n                return null;\n            }\n\n            @Override\n            public Object visitFpackageswitch(SmaliParser.FpackageswitchContext ctx) {\n                int start = parseInt(ctx.start.getText());\n                List<TerminalNode> ts = ctx.LABEL();\n                DexLabel labels[] = new DexLabel[ts.size()];\n                for (int i = 0; i < ts.size(); i++) {\n                    labels[i] = getLabel(ts.get(i).getSymbol().getText());\n                }\n                scv.dPackedSwitch(start, labels);\n                return null;\n            }\n\n            @Override\n            public Object visitFcache(SmaliParser.FcacheContext ctx) {\n                scv.visitTryCatch(getLabel(ctx.start.getText()), getLabel(ctx.end.getText()),\n                        new DexLabel[]{getLabel(ctx.handle.getText())},\n                        new String[]{unEscapeId(ctx.type.getText())}\n                );\n                return null;\n            }\n\n            @Override\n            public Object visitFcacheall(SmaliParser.FcacheallContext ctx) {\n                scv.visitTryCatch(getLabel(ctx.start.getText()), getLabel(ctx.end.getText()),\n                        new DexLabel[]{getLabel(ctx.handle.getText())},\n                        new String[]{null}\n                );\n                return null;\n            }\n\n            DexLabel getLabel(String name) {\n                DexLabel dexLabel = labelMap.get(name);\n                if (dexLabel == null) {\n                    dexLabel = new DexLabel();\n                    labelMap.put(name, dexLabel);\n                }\n                return dexLabel;\n            }\n\n            @Override\n            public Object visitFepiogue(SmaliParser.FepiogueContext ctx) {\n                if (dexDebugVisitor != null) {\n                    DexLabel dexLabel = new DexLabel();\n                    scv.visitLabel(dexLabel);\n                    dexDebugVisitor.visitEpiogue(dexLabel);\n                }\n                return null;\n            }\n        };\n        scv.visitRegister(m.total);\n        if (dexDebugVisitor != null) {\n            for (int i = 0; i < m.paramNames.length; i++) {\n                String name = m.paramNames[i];\n                if (name != null) {\n                    dexDebugVisitor.visitParameterName(i, name);\n                }\n            }\n        }\n        for (SmaliParser.SInstructionContext instructionContext : instructionContexts) {\n            ParserRuleContext parserRuleContext = (ParserRuleContext) instructionContext.getChild(0);\n            parserRuleContext.accept(v);\n        }\n        scv.visitEnd();\n    }\n\n    private static int findTotalRegisters(SmaliParser.SMethodContext ctx, int ins) {\n        int totalRegisters = -1;\n        List<SmaliParser.SInstructionContext> instructionContexts = ctx.sInstruction();\n        for (SmaliParser.SInstructionContext instructionContext : instructionContexts) {\n            ParserRuleContext parserRuleContext = (ParserRuleContext) instructionContext.getChild(0);\n            if (parserRuleContext != null) {\n                int ruleIndex = parserRuleContext.getRuleIndex();\n                if (ruleIndex == SmaliParser.RULE_fregisters) {\n                    totalRegisters = parseInt(((SmaliParser.FregistersContext) parserRuleContext).xregisters.getText());\n                    break;\n                } else if (ruleIndex == SmaliParser.RULE_flocals) {\n                    totalRegisters = ins + parseInt(((SmaliParser.FlocalsContext) parserRuleContext).xlocals.getText());\n                    break;\n                }\n            }\n        }\n        return totalRegisters;\n    }\n\n    private static void acceptParameter(List<SmaliParser.SParameterContext> sParameterContexts, M m, DexMethodVisitor dexMethodVisitor) {\n        if (sParameterContexts == null || sParameterContexts.size() == 0 || dexMethodVisitor == null) {\n            return;\n        }\n        boolean hasParam = false;\n        boolean hasParamter = false;\n        for (SmaliParser.SParameterContext ctx : sParameterContexts) {\n            if (ctx.param != null) {\n                hasParam = true;\n            }\n            if (ctx.parameter != null) {\n                hasParamter = true;\n            }\n        }\n        if (hasParam && hasParamter) {\n            throw new RuntimeException(\"cant mix use .param and .parameter on method\");\n        }\n        for (int i = 0; i < sParameterContexts.size(); i++) {\n            SmaliParser.SParameterContext ctx = sParameterContexts.get(i);\n            int index;\n            if (ctx.param != null) {\n                index = m.regToParamIdx(m.pareReg(ctx.r.getText()));\n            } else {\n                index = i;\n            }\n            if (ctx.name != null) {\n                m.setNameByIdx(index, unescapeStr(ctx.name.getText()));\n            }\n            List<SmaliParser.SAnnotationContext> annotationContexts = ctx.sAnnotation();\n            if (annotationContexts.size() > 0) {\n                acceptAnnotations(annotationContexts, dexMethodVisitor.visitParameterAnnotation(index));\n            }\n        }\n\n\n    }\n\n    private static void acceptField(List<SmaliParser.SFieldContext> sFieldContexts, String className, DexClassVisitor dexClassVisitor) {\n        if (sFieldContexts == null || sFieldContexts.size() == 0 || dexClassVisitor == null) {\n            return;\n        }\n        for (SmaliParser.SFieldContext ctx : sFieldContexts) {\n            acceptField(ctx, className, dexClassVisitor);\n        }\n    }\n\n    public static void acceptField(SmaliParser.SFieldContext ctx, String className, DexClassVisitor dexClassVisitor) {\n        Field field;\n        Token fieldObj = ctx.fieldObj;\n        if (fieldObj.getType() == SmaliLexer.FIELD_FULL) {\n            field = Utils.parseFieldAndUnescape(fieldObj.getText());\n        } else {\n            field = Utils.parseFieldAndUnescape(className, fieldObj.getText());\n        }\n        int access = collectAccess(ctx.sAccList());\n        Object value = null;\n        SmaliParser.SBaseValueContext vctx = ctx.sBaseValue();\n        if (vctx != null) {\n            value = parseBaseValue(vctx);\n        }\n        DexFieldVisitor dexFieldVisitor = dexClassVisitor.visitField(access, field, value);\n        if (dexFieldVisitor != null) {\n            acceptAnnotations(ctx.sAnnotation(), dexFieldVisitor);\n            dexFieldVisitor.visitEnd();\n        }\n    }\n\n    private static Object parseBaseValue(SmaliParser.SBaseValueContext ctx) {\n        Token value;\n        if (ctx.getChildCount() == 1) {\n            TerminalNode tn = (TerminalNode) ctx.getChild(0);\n            value = tn.getSymbol();\n        } else {\n            TerminalNode tn = (TerminalNode) ctx.getChild(1);\n            value = tn.getSymbol();\n        }\n        switch (value.getType()) {\n            case SmaliLexer.STRING:\n                return unescapeStr(value.getText());\n            case SmaliLexer.BOOLEAN:\n                return \"true\".equals(value.getText());\n            case SmaliLexer.BYTE:\n                return parseByte(value.getText());\n            case SmaliLexer.SHORT:\n                return parseShort(value.getText());\n            case SmaliLexer.CHAR:\n                return unescapeChar(value.getText());\n            case SmaliLexer.INT:\n                return parseInt(value.getText());\n            case SmaliLexer.LONG:\n                return parseLong(value.getText());\n\n            case SmaliLexer.BASE_FLOAT:\n            case SmaliLexer.FLOAT_INFINITY:\n            case SmaliLexer.FLOAT_NAN:\n                return parseFloat(value.getText());\n            case SmaliLexer.BASE_DOUBLE:\n            case SmaliLexer.DOUBLE_INFINITY:\n            case SmaliLexer.DOUBLE_NAN:\n                return parseDouble(value.getText());\n\n            case SmaliLexer.METHOD_FULL:\n                return parseMethodAndUnescape(value.getText());\n            case SmaliLexer.OBJECT_TYPE:\n                return new DexType(unEscapeId(value.getText()));\n            case SmaliLexer.NULL:\n                return null;\n            case SmaliLexer.FIELD_FULL:\n                return parseFieldAndUnescape(value.getText());\n        }\n        return null;\n    }\n\n    private static void acceptAnnotations(List<SmaliParser.SAnnotationContext> sAnnotationContexts, DexAnnotationAble dexAnnotationAble) {\n        if (dexAnnotationAble == null) {\n            return;\n        }\n        if (sAnnotationContexts.size() > 0) {\n            for (SmaliParser.SAnnotationContext ctx : sAnnotationContexts) {\n                Visibility visibility = Utils.getAnnVisibility(ctx.visibility.getText());\n                String type = Utils.unEscapeId(ctx.type.getText());\n                DexAnnotationVisitor dexAnnotationVisitor = dexAnnotationAble.visitAnnotation(type, visibility);\n                if (dexAnnotationVisitor != null) {\n                    List<SmaliParser.SAnnotationKeyNameContext> keys = ctx.sAnnotationKeyName();\n                    if (keys.size() > 0) {\n                        List<SmaliParser.SAnnotationValueContext> values = ctx.sAnnotationValue();\n                        for (int i = 0; i < keys.size(); i++) {\n                            acceptAnnotation(dexAnnotationVisitor, Utils.unEscapeId(keys.get(i).getText()), values.get(i));\n                        }\n                    }\n                    dexAnnotationVisitor.visitEnd();\n                }\n            }\n        }\n    }\n\n    private static void acceptAnnotation(DexAnnotationVisitor dexAnnotationVisitor, String name, SmaliParser.SAnnotationValueContext ctx) {\n        ParserRuleContext t = (ParserRuleContext) ctx.getChild(0);\n        switch (t.getRuleIndex()) {\n            case SmaliParser.RULE_sSubannotation: {\n                SmaliParser.SSubannotationContext subannotationContext = (SmaliParser.SSubannotationContext) t;\n                DexAnnotationVisitor annotationVisitor = dexAnnotationVisitor.visitAnnotation(name, Utils\n                        .unEscapeId(subannotationContext.type.getText()));\n                if (annotationVisitor != null) {\n                    List<SmaliParser.SAnnotationKeyNameContext> keys = subannotationContext.sAnnotationKeyName();\n                    if (keys.size() > 0) {\n                        List<SmaliParser.SAnnotationValueContext> values = subannotationContext.sAnnotationValue();\n                        for (int i = 0; i < keys.size(); i++) {\n                            acceptAnnotation(annotationVisitor, Utils.unEscapeId(keys.get(i).getText()), values.get(i));\n                        }\n                    }\n                    annotationVisitor.visitEnd();\n                }\n                break;\n            }\n            case SmaliParser.RULE_sArrayValue: {\n                SmaliParser.SArrayValueContext arrayValueContext = (SmaliParser.SArrayValueContext) t;\n                DexAnnotationVisitor annotationVisitor = dexAnnotationVisitor.visitArray(name);\n                if (annotationVisitor != null) {\n                    for (SmaliParser.SAnnotationValueContext annotationValueContext : arrayValueContext\n                            .sAnnotationValue()) {\n                        acceptAnnotation(annotationVisitor, null, annotationValueContext);\n                    }\n                    annotationVisitor.visitEnd();\n                }\n                break;\n            }\n            case SmaliParser.RULE_sBaseValue:\n                SmaliParser.SBaseValueContext baseValueContext = (SmaliParser.SBaseValueContext) t;\n                Object value = parseBaseValue(baseValueContext);\n                dexAnnotationVisitor.visit(name, value);\n                break;\n        }\n    }\n\n\n    static private int collectAccess(SmaliParser.SAccListContext ctx) {\n        int access = 0;\n        for (TerminalNode acc : ctx.ACC()) {\n            access |= Utils.getAcc(acc.getSymbol().getText());\n        }\n        return access;\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/Baksmali.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.smali;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.file.Path;\n\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\n\npublic class Baksmali {\n    private Baksmali() {\n    }\n\n    public static Baksmali from(byte[] in) throws IOException {\n        return from(new DexFileReader(in));\n    }\n\n    public static Baksmali from(ByteBuffer in) throws IOException {\n        return from(new DexFileReader(in));\n    }\n\n    public static Baksmali from(DexFileReader reader) {\n        return new Baksmali(reader);\n    }\n\n    public static Baksmali from(File in) throws IOException {\n        return from(ZipUtil.readDex(in));\n    }\n\n    public static Baksmali from(Path in) throws IOException {\n        return from(ZipUtil.readDex(in));\n    }\n\n    public static Baksmali from(InputStream in) throws IOException {\n        return from(ZipUtil.readDex(in));\n    }\n\n    public static Baksmali from(String in) throws IOException {\n        return from(new File(in));\n    }\n\n    boolean noDebug = false;\n    boolean parameterRegisters = true;\n    DexFileReader reader;\n    boolean useLocals = false;\n\n    private Baksmali(DexFileReader reader) {\n        this.reader = reader;\n    }\n\n    /**\n     * <pre>\n     * -b,--no-debug-info don't write out debug info (.local, .param, .line, etc.)\n     * </pre>\n     * \n     * @return\n     */\n    public Baksmali noDebug() {\n        this.noDebug = true;\n        return this;\n    }\n\n    /**\n     * <pre>\n     *  -p,--no-parameter-registers use the v<n> syntax instead of the p<n> syntax for registers mapped to method parameters\n     * </pre>\n     * \n     * @return\n     */\n    public Baksmali noParameterRegisters() {\n        this.parameterRegisters = false;\n        return this;\n    }\n\n    public void to(final File dir) {\n        to(dir.toPath());\n    }\n\n    public void to(final Path base) {\n        final BaksmaliDumper bs = new BaksmaliDumper(parameterRegisters, useLocals);\n        reader.accept(new BaksmaliDexFileVisitor(base, bs), this.noDebug ? DexFileReader.SKIP_CODE : 0);\n    }\n\n    /**\n     * <pre>\n     *  -l,--use-locals output the .locals directive with the number of non-parameter registers, rather than the .register\n     * </pre>\n     * \n     * @return\n     */\n    public Baksmali useLocals() {\n        this.useLocals = true;\n        return this;\n    }\n\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/BaksmaliCmd.java",
    "content": "package com.googlecode.d2j.smali;\n\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\n\n@Syntax(cmd = \"d2j-baksmali\", syntax = \"[options] <dex>\", desc = \"disassembles and/or dumps a dex file\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/Smali\")\npublic class BaksmaliCmd extends BaseCmd {\n    @Opt(opt = \"b\", longOpt = \"no-debug-info\", hasArg = false, description = \"[not impl] don't write out debug info (.local, .param, .line, etc.)\")\n    private boolean noDebug;\n    @Opt(opt = \"p\", longOpt = \"no-parameter-registers\", hasArg = false, description = \"use the v<n> syntax instead of the p<n> syntax for registers mapped to method parameters\")\n    private boolean noParameterRegisters;\n    @Opt(opt = \"l\", longOpt = \"use-locals\", hasArg = false, description = \"output the .locals directive with the number of non-parameter registers, rather than the .register\")\n    private boolean useLocals;\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output dir of .smali files, default is $current_dir/[jar-name]-out/\", argName = \"out\")\n    private Path output;\n\n    public static void main(String[] args) {\n        new BaksmaliCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length < 1) {\n            System.err.println(\"ERRPR: no file to process\");\n            return;\n        } else if (remainingArgs.length > 1) {\n            System.err.println(\"ERRPR: too many files to process\");\n            return;\n        }\n\n        File dex = new File(remainingArgs[0]);\n        if (!dex.exists()) {\n            System.err.println(\"ERROR: \" + dex + \" is not exists\");\n            return;\n        }\n        if (output == null) {\n            output = new File(getBaseName(dex.getName()) + \"-out\").toPath();\n        }\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            return;\n        }\n        Baksmali b = Baksmali.from(dex);\n        if (noDebug) {\n            b.noDebug();\n        }\n        if (noParameterRegisters) {\n            b.noParameterRegisters();\n        }\n        if (useLocals) {\n            b.useLocals();\n        }\n        System.err.println(\"baksmali \" + dex + \" -> \" + output);\n        b.to(output);\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/BaksmaliCodeDumper.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.smali;\r\n\r\nimport com.googlecode.d2j.*;\r\nimport com.googlecode.d2j.node.DexDebugNode;\r\nimport com.googlecode.d2j.reader.InstructionFormat;\r\nimport com.googlecode.d2j.reader.Op;\r\nimport com.googlecode.d2j.util.Out;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\r\n\r\nimport java.util.*;\r\n\r\n/*package*/class BaksmaliCodeDumper extends DexCodeVisitor {\r\n    private boolean useParameterRegisters;\r\n    private boolean useLocals;\r\n    private int nextLabelNumber;\r\n    private Out out;\r\n    final int startParamR;\r\n    final Set<DexLabel> usedLabel;\r\n    final Map<DexLabel, List<DexDebugNode.DexDebugOpNode>> debugLabelMap;\r\n\r\n    public BaksmaliCodeDumper(Out out, boolean useParameterRegisters, boolean useLocals, int nextLabelNumber,\r\n            int startParamR, Set<DexLabel> usedLabel, Map<DexLabel, List<DexDebugNode.DexDebugOpNode>> debugLabelMap) {\r\n        super();\r\n        this.out = out;\r\n        this.useParameterRegisters = useParameterRegisters;\r\n        this.useLocals = useLocals;\r\n        this.nextLabelNumber = nextLabelNumber;\r\n        this.startParamR = startParamR;\r\n        this.usedLabel = usedLabel;\r\n        this.debugLabelMap = debugLabelMap;\r\n    }\r\n\r\n    class PackedSwitchStmt {\r\n        int first_case;\r\n\r\n        DexLabel[] labels;\r\n\r\n        public PackedSwitchStmt(int first_case, DexLabel[] labels) {\r\n            super();\r\n            this.first_case = first_case;\r\n            this.labels = labels;\r\n        }\r\n    }\r\n\r\n    class SparseSwitchStmt {\r\n        int[] cases;\r\n\r\n        DexLabel[] labels;\r\n\r\n        public SparseSwitchStmt(int[] cases, DexLabel[] labels) {\r\n            super();\r\n            this.cases = cases;\r\n            this.labels = labels;\r\n        }\r\n    }\r\n\r\n    List<Map.Entry<DexLabel, Object>> appendLast = new ArrayList<>();\r\n\r\n    String reg(int rdx) {\r\n        if (useParameterRegisters && rdx >= this.startParamR) {\r\n            return \"p\" + (rdx - this.startParamR);\r\n        }\r\n        return \"v\" + rdx;\r\n    }\r\n\r\n    @Override\r\n    public void visitFillArrayDataStmt(Op op, int ra, Object array) {\r\n        DexLabel dx = new DexLabel();\r\n        dx.displayName = \"L\" + nextLabelNumber++;\r\n        usedLabel.add(dx);\r\n        out.s(\"%s %s, %s\", op.displayName, reg(ra), xLabel(dx));\r\n        appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, array));\r\n    }\r\n\r\n    @SuppressWarnings(\"incomplete-switch\")\r\n    @Override\r\n    public void visitConstStmt(Op op, int ra, Object value) {\r\n        switch (op) {\r\n        case CONST_WIDE_16: {\r\n            Long v = (Long) value;\r\n            value = (int) v.shortValue();\r\n            break;\r\n        }\r\n        case CONST_WIDE_HIGH16: {\r\n            Long v = (Long) value;\r\n            value = (int) ((short) (v >> 48));\r\n            break;\r\n        }\r\n        case CONST_WIDE_32: {\r\n            Long v = (Long) value;\r\n            value = (int) v.intValue();\r\n            break;\r\n        }\r\n        case CONST_HIGH16: {\r\n            Integer v = (Integer) value;\r\n            value = (int) v.intValue() >> 16;\r\n            break;\r\n        }\r\n        }\r\n        out.s(\"%s %s, %s\", op.displayName, reg(ra), BaksmaliDumper.escapeValue(value));\r\n        super.visitConstStmt(op, ra, value);\r\n    }\r\n\r\n    @Override\r\n    public void visitEnd() {\r\n        for (Map.Entry<DexLabel, Object> e : this.appendLast) {\r\n            visitLabel(e.getKey());\r\n            Object v = e.getValue();\r\n            if (v instanceof SparseSwitchStmt) {\r\n                SparseSwitchStmt ss = (SparseSwitchStmt) v;\r\n                out.s(\".sparse-switch\");\r\n                out.push();\r\n                for (int i = 0; i < ss.cases.length; i++) {\r\n                    out.s(\"%d -> %s\", ss.cases[i], xLabel(ss.labels[i]));\r\n                }\r\n                out.pop();\r\n                out.s(\".end sparse-switch\");\r\n            } else if (v instanceof PackedSwitchStmt) {\r\n                PackedSwitchStmt ps = (PackedSwitchStmt) v;\r\n                out.s(\".packed-switch %d\", ps.first_case);\r\n                out.push();\r\n                for (DexLabel label : ps.labels) {\r\n                    out.s(xLabel(label));\r\n                }\r\n                out.pop();\r\n                out.s(\".end packed-switch\");\r\n            } else {\r\n                Object array = e.getValue();\r\n                if (array instanceof byte[]) {\r\n                    out.s(\".array-data 1\");\r\n                    out.push();\r\n                    byte[] vs = (byte[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        out.s(BaksmaliDumper.escapeValue(vs[i]));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                } else if (array instanceof short[]) {\r\n                    out.s(\".array-data 2\");\r\n                    out.push();\r\n                    short[] vs = (short[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        short a = vs[i];\r\n                        out.s(\"%s %s\", BaksmaliDumper.escapeValue((byte) (a & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 8))));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                } else if (array instanceof int[]) {\r\n                    out.s(\".array-data 4\");\r\n                    out.push();\r\n                    int[] vs = (int[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        int a = vs[i];\r\n                        out.s(\"%s %s %s %s\", BaksmaliDumper.escapeValue((byte) (a & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 24))));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                } else if (array instanceof float[]) {\r\n                    out.s(\".array-data 4\");\r\n                    out.push();\r\n                    float[] vs = (float[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        int a = Float.floatToIntBits(vs[i]);\r\n                        out.s(\"%s %s %s %s\", BaksmaliDumper.escapeValue((byte) (a & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 24))));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                } else if (array instanceof long[]) {\r\n                    out.s(\".array-data 8\");\r\n                    out.push();\r\n                    long[] vs = (long[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        long ttt = vs[i];\r\n                        int a = (int) ttt;\r\n                        int b = (int) (ttt >>> 32);\r\n                        out.s(\"%s %s %s %s %s %s %s %s\", BaksmaliDumper.escapeValue((byte) (a & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 24))),\r\n                                BaksmaliDumper.escapeValue((byte) (b & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 24))));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                } else if (array instanceof double[]) {\r\n                    out.s(\".array-data 8\");\r\n                    out.push();\r\n                    double[] vs = (double[]) array;\r\n                    for (int i = 0; i < vs.length; i++) {\r\n                        long ttt = Double.doubleToLongBits(vs[i]);\r\n                        int a = (int) ttt;\r\n                        int b = (int) (ttt >>> 32);\r\n                        out.s(\"%s %s %s %s %s %s %s %s\", BaksmaliDumper.escapeValue((byte) (a & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (a >> 24))),\r\n                                BaksmaliDumper.escapeValue((byte) (b & 0xFF)),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 8))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 16))),\r\n                                BaksmaliDumper.escapeValue((byte) (0xFF & (b >> 24))));\r\n                    }\r\n                    out.pop();\r\n                    out.s(\".end array-data\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitFieldStmt(Op op, int a, int b, Field field) {\r\n        if (op.format == InstructionFormat.kFmt22c) {// iget,iput\r\n            out.s(\"%s %s, %s, %s\", op.displayName, reg(a), reg(b), BaksmaliDumper.escapeField(field));\r\n        } else {\r\n            out.s(\"%s %s, %s\", op.displayName, reg(a), BaksmaliDumper.escapeField(field));\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitFilledNewArrayStmt(Op op, int[] args, String type) {\r\n        if (args.length > 0) {\r\n            if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range\r\n                out.s(\"%s { %d .. %d }, %s\", op.displayName, reg(args[0]), reg(args[args.length - 1]),\r\n                        BaksmaliDumper.escapeType(type));\r\n            } else {\r\n                StringBuilder buff = new StringBuilder();\r\n                boolean first = true;\r\n                for (int i : args) {\r\n                    if (first) {\r\n                        first = false;\r\n                    } else {\r\n                        buff.append(\", \");\r\n                    }\r\n                    buff.append(reg(i));\r\n                }\r\n                out.s(\"%s { %s }, %s\", op.displayName, buff, BaksmaliDumper.escapeType(type));\r\n            }\r\n        } else {\r\n            out.s(\"%s { }, %s\", op.displayName, BaksmaliDumper.escapeType(type));\r\n        }\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\r\n        if (op.format == InstructionFormat.kFmt21t || op.format == InstructionFormat.kFmt31t) {\r\n            out.s(op.displayName + \" \" + reg(a) + \", \" + xLabel(label));\r\n        } else if (op.format == InstructionFormat.kFmt22t) {\r\n            out.s(op.displayName + \" \" + reg(a) + \", \" + reg(b) + \", \" + xLabel(label));\r\n        } else {\r\n            out.s(op.displayName + \" \" + xLabel(label));\r\n        }\r\n    }\r\n\r\n    DexDebugVisitor debugDumper = new DexDebugVisitor() {\r\n        @Override\r\n        public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) {\r\n            super.visitStartLocal(reg, label, name, type, signature);\r\n            if (signature == null) {\r\n                out.s(\".local %s, %s:%s\", reg(reg), BaksmaliDumper.escapeValue(name), type);\r\n            } else {\r\n                out.s(\".local %s, %s:%s, %s\", reg(reg), BaksmaliDumper.escapeValue(name), type, BaksmaliDumper.escapeValue(signature));\r\n            }\r\n        }\r\n\r\n        @Override\r\n        public void visitPrologue(DexLabel dexLabel) {\r\n            out.s(\".prologue\");\r\n        }\r\n\r\n        @Override\r\n        public void visitEpiogue(DexLabel dexLabel) {\r\n            out.s(\".epiogue\");\r\n        }\r\n\r\n        @Override\r\n        public void visitLineNumber(int line, DexLabel label) {\r\n            out.s(\".line %d\", line);\r\n        }\r\n\r\n        @Override\r\n        public void visitEndLocal(int reg, DexLabel label) {\r\n            out.s(\".end local %s\", reg(reg));\r\n        }\r\n\r\n        @Override\r\n        public void visitRestartLocal(int reg, DexLabel label) {\r\n            out.s(\".restart local %s\", reg(reg));\r\n        }\r\n    };\r\n\r\n    @Override\r\n    public void visitLabel(DexLabel label) {\r\n        if (usedLabel.contains(label)) {\r\n            out.s(xLabel(label));\r\n        }\r\n        List<DexDebugNode.DexDebugOpNode> dOps = debugLabelMap.get(label);\r\n        if (dOps != null) {\r\n            for (DexDebugNode.DexDebugOpNode dOp : dOps) {\r\n                dOp.accept(debugDumper);\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    final public DexDebugVisitor visitDebug() {\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, Method method) {\r\n\r\n        if (args.length > 0) {\r\n            if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range\r\n                out.s(\"%s { %s .. %s }, %s\", op.displayName, reg(args[0]), reg(args[args.length - 1]),\r\n                        BaksmaliDumper.escapeMethod(method));\r\n            } else {\r\n                boolean first = true;\r\n                StringBuilder buff = new StringBuilder();\r\n                for (int i : args) {\r\n                    if (first) {\r\n                        first = false;\r\n                    } else {\r\n                        buff.append(\", \");\r\n                    }\r\n                    buff.append(reg(i));\r\n                }\r\n                out.s(\"%s { %s }, %s\", op.displayName, buff, BaksmaliDumper.escapeMethod(method));\r\n            }\r\n        } else {\r\n            out.s(\"%s { }, %s\", op.displayName, BaksmaliDumper.escapeMethod(method));\r\n        }\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, Method method, Proto proto) {\r\n        if (args.length > 0) {\r\n            if (op.format == InstructionFormat.kFmt4rcc) { // invoke-x/range\r\n                out.s(\"%s { %s .. %s }, %s, %s\", op.displayName, reg(args[0]), reg(args[args.length - 1]),\r\n                        BaksmaliDumper.escapeMethod(method), BaksmaliDumper.escapeMethodDesc(proto));\r\n            } else {\r\n                boolean first = true;\r\n                StringBuilder buff = new StringBuilder();\r\n                for (int i : args) {\r\n                    if (first) {\r\n                        first = false;\r\n                    } else {\r\n                        buff.append(\", \");\r\n                    }\r\n                    buff.append(reg(i));\r\n                }\r\n                out.s(\"%s { %s }, %s, %s\", op.displayName, buff, BaksmaliDumper.escapeMethod(method),\r\n                        BaksmaliDumper.escapeMethodDesc(proto));\r\n            }\r\n        } else {\r\n            out.s(\"%s { }, %s, %s\", op.displayName, BaksmaliDumper.escapeMethod(method),\r\n                    BaksmaliDumper.escapeMethodDesc(proto));\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) {\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(\"{ \").append( BaksmaliDumper.escapeValue(bsm)).append(\", \").append(BaksmaliDumper.escapeValue(name)).append(\", \").append(BaksmaliDumper.escapeMethodDesc(proto));\r\n        for(Object o: bsmArgs) {\r\n            sb.append(\", \").append(BaksmaliDumper.escapeValue(o));\r\n        }\r\n        sb.append(\"}\");\r\n\r\n\r\n        if (args.length > 0) {\r\n            if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range\r\n                out.s(\"%s { %s .. %s }, %s\", op.displayName, reg(args[0]), reg(args[args.length - 1]),\r\n                        sb);\r\n            } else {\r\n                boolean first = true;\r\n                StringBuilder buff = new StringBuilder();\r\n                for (int i : args) {\r\n                    if (first) {\r\n                        first = false;\r\n                    } else {\r\n                        buff.append(\", \");\r\n                    }\r\n                    buff.append(reg(i));\r\n                }\r\n                out.s(\"%s { %s }, %s\", op.displayName, buff, sb);\r\n            }\r\n        } else {\r\n            out.s(\"%s { }, %s\", op.displayName, sb);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitPackedSwitchStmt(Op op, int ra, int first_case, DexLabel[] labels) {\r\n        DexLabel dx = new DexLabel();\r\n        dx.displayName = \"L\" + nextLabelNumber++;\r\n        usedLabel.add(dx);\r\n        out.s(op.displayName + \" \" + reg(ra) + \", \" + xLabel(dx));\r\n        appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new PackedSwitchStmt(first_case, labels)));\r\n    }\r\n\r\n    @Override\r\n    public void visitRegister(int total) {\r\n        if (useLocals) {\r\n            out.s(\".locals %d\", startParamR);\r\n        } else {\r\n            out.s(\".registers %d\", total);\r\n        }\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {\r\n        DexLabel dx = new DexLabel();\r\n        dx.displayName = \"L\" + nextLabelNumber++;\r\n        usedLabel.add(dx);\r\n        out.s(op.displayName + \" \" + reg(ra) + \", \" + xLabel(dx));\r\n        appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new SparseSwitchStmt(cases, labels)));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt0R(Op op) {\r\n        if (op == Op.BAD_OP) {\r\n            out.s(\"%s # bad op\", Op.NOP.displayName);\r\n        } else {\r\n            out.s(op.displayName);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt1R(Op op, int a) {\r\n        out.s(op.displayName + \" \" + reg(a));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R(Op op, int a, int b) {\r\n        out.s(op.displayName + \" \" + reg(a) + \", \" + reg(b));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R1N(Op op, int a, int b, int content) {\r\n        out.s(\"%s %s, %s, %s\", op.displayName, reg(a), reg(b), content);\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt3R(Op op, int a, int b, int c) {\r\n        out.s(\"%s %s, %s, %s\", op.displayName, reg(a), reg(b), reg(c));\r\n    }\r\n\r\n    @Override\r\n    public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) {\r\n        for (int i = 0; i < type.length; i++) {\r\n            String t = type[i];\r\n            if (t == null) {\r\n                out.s(\".catchall { %s .. %s } %s\", xLabel(start), xLabel(end), xLabel(handler[i]));\r\n            } else {\r\n                out.s(\".catch %s { %s .. %s } %s\", t, xLabel(start), xLabel(end), xLabel(handler[i]));\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitTypeStmt(Op op, int a, int b, String type) {\r\n        if (op.format == InstructionFormat.kFmt21c) {\r\n            out.s(\"%s %s, %s\", op.displayName, reg(a), BaksmaliDumper.escapeType(type));\r\n        } else {\r\n            out.s(\"%s %s, %s, %s\", op.displayName, reg(a), reg(b), BaksmaliDumper.escapeType(type));\r\n        }\r\n    }\r\n\r\n    String xLabel(DexLabel d) {\r\n        return \":\" + d.displayName;\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/BaksmaliDexFileVisitor.java",
    "content": "package com.googlecode.d2j.smali;\r\n\r\nimport com.googlecode.d2j.node.DexClassNode;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexFileVisitor;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.IOException;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.util.HashSet;\r\nimport java.util.Set;\r\n\r\npublic class BaksmaliDexFileVisitor extends DexFileVisitor {\r\n    private final Path dir;\r\n    private final BaksmaliDumper bs;\r\n    private Set<String> hases;\r\n    private int i;\r\n\r\n    public BaksmaliDexFileVisitor(Path dir, BaksmaliDumper bs) {\r\n        this.dir = dir;\r\n        this.bs = bs;\r\n        hases = new HashSet<String>();\r\n        i = 1;\r\n    }\r\n\r\n    protected String rebuildFileName(String s) {\r\n        s = BaksmaliDumper.escapeId(s);\r\n        s = s.replace('\\\\', '-');\r\n        String low = s.toLowerCase();\r\n        if (hases.contains(low)) {\r\n            return s + \"_d2j\" + i++;\r\n        } else {\r\n            hases.add(low);\r\n        }\r\n        return s;\r\n    }\r\n\r\n    @Override\r\n    public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\r\n        return new DexClassNode(access_flags, className, superClass, interfaceNames) {\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                super.visitEnd();\r\n\r\n                Path smaliFile = dir\r\n                        .resolve(rebuildFileName(className.substring(1, className.length() - 1)) + \".smali\");\r\n\r\n                try {\r\n                    Path parent = smaliFile.getParent();\r\n                    if (parent != null && !Files.exists(parent)) {\r\n                        Files.createDirectories(parent);\r\n                    }\r\n                } catch (IOException e) {\r\n                    throw new RuntimeException(e);\r\n                }\r\n\r\n                try (BufferedWriter writer = Files.newBufferedWriter(smaliFile, StandardCharsets.UTF_8)) {\r\n                    BaksmaliDumpOut out = new BaksmaliDumpOut(writer);\r\n                    bs.baksmaliClass(this, out);\r\n                    writer.flush();\r\n                } catch (IOException e) {\r\n                    throw new RuntimeException(e);\r\n                }\r\n\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/BaksmaliDumpOut.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.smali;\r\n\r\nimport com.googlecode.d2j.util.Out;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.IOException;\r\n\r\npublic class BaksmaliDumpOut implements Out {\r\n    private final BufferedWriter writer;\r\n    int i;\r\n    final String indent;\r\n\r\n    public BaksmaliDumpOut(BufferedWriter writer) {\r\n        this(\"  \", writer);\r\n    }\r\n\r\n    public BaksmaliDumpOut(String indent, BufferedWriter writer) {\r\n        this.writer = writer;\r\n        i = 0;\r\n        this.indent = indent;\r\n    }\r\n\r\n    @Override\r\n    public void pop() {\r\n        i--;\r\n    }\r\n\r\n    @Override\r\n    public void push() {\r\n        i++;\r\n    }\r\n\r\n    @Override\r\n    public void s(String s) {\r\n        try {\r\n            for (int i = 0; i < this.i; i++) {\r\n                writer.append(indent);\r\n            }\r\n            writer.append(s);\r\n            writer.newLine();\r\n        } catch (IOException ex) {\r\n            throw new RuntimeException(ex);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void s(String format, Object... arg) {\r\n        try {\r\n            for (int i = 0; i < this.i; i++) {\r\n                writer.append(indent);\r\n            }\r\n            writer.append(String.format(format, arg));\r\n            writer.newLine();\r\n        } catch (IOException ex) {\r\n            throw new RuntimeException(ex);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/BaksmaliDumper.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.smali;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.util.*;\r\n\r\nimport com.googlecode.d2j.*;\r\nimport com.googlecode.d2j.node.*;\r\nimport com.googlecode.d2j.node.DexAnnotationNode.Item;\r\nimport com.googlecode.d2j.node.insn.DexLabelStmtNode;\r\nimport com.googlecode.d2j.node.insn.DexStmtNode;\r\nimport com.googlecode.d2j.reader.Op;\r\nimport com.googlecode.d2j.util.Out;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\r\n\r\npublic class BaksmaliDumper implements DexConstants {\r\n    private static final int ACCESS_FIELD = 1 << 31;\r\n    private final static String[] accessWords = new String[]{\"public\", \"private\", \"protected\", \"static\", \"final\",\r\n            \"synchronized\", \"bridge\", \"varargs\", \"native\", \"abstract\", \"strictfp\", \"synthetic\", \"constructor\",\r\n            \"interface\", \"enum\", \"annotation\", \"volatile\", \"transient\"};\r\n\r\n    static {\r\n        Arrays.sort(accessWords);\r\n    }\r\n\r\n    private final StringBuilder buff = new StringBuilder();\r\n    private boolean useParameterRegisters = true;\r\n    private boolean useLocals = false;\r\n\r\n    public BaksmaliDumper() {\r\n    }\r\n\r\n    public BaksmaliDumper(boolean useParameterRegisters, boolean useLocals) {\r\n        this.useParameterRegisters = useParameterRegisters;\r\n        this.useLocals = useLocals;\r\n    }\r\n\r\n    private static boolean isAccessWords(String name) {\r\n        return Arrays.binarySearch(accessWords, name) >= 0;\r\n    }\r\n\r\n    static void escape0(final StringBuilder buf, char c) {\r\n        if (c == '\\n') {\r\n            buf.append(\"\\\\n\");\r\n        } else if (c == '\\r') {\r\n            buf.append(\"\\\\r\");\r\n        } else if (c == '\\t') {\r\n            buf.append(\"\\\\t\");\r\n        } else if (c == '\\\\') {\r\n            buf.append(\"\\\\\\\\\");\r\n        } else if (c == '\"') {\r\n            buf.append(\"\\\\\\\"\");\r\n        } else if (c < 0x20 || c > 0x7f) {\r\n            buf.append(\"\\\\u\");\r\n            if (c < 0x10) {\r\n                buf.append(\"000\");\r\n            } else if (c < 0x100) {\r\n                buf.append(\"00\");\r\n            } else if (c < 0x1000) {\r\n                buf.append('0');\r\n            }\r\n            buf.append(Integer.toString(c, 16));\r\n        } else {\r\n            buf.append(c);\r\n        }\r\n    }\r\n\r\n    static String escapeType(String id) {\r\n        StringBuilder escapeBuff = new StringBuilder();\r\n        escapeType0(escapeBuff, id);\r\n        return escapeBuff.toString();\r\n    }\r\n\r\n    static void escapeId0(StringBuilder sb, String id) {\r\n        for (int i = 0; i < id.length(); ++i) {\r\n            char c = id.charAt(i);\r\n            escape1(sb, c);\r\n        }\r\n    }\r\n\r\n    static String escapeId(String id) {\r\n        StringBuilder escapeBuff = new StringBuilder();\r\n        escapeId0(escapeBuff, id);\r\n        return escapeBuff.toString();\r\n    }\r\n\r\n    static void escape1(final StringBuilder buf, char c) {\r\n        if (c == ' ' || c == '-' || c == ':' | c == '=' || c == ',' || c == '{' || c == '}' || c == '(' || c == ')') {\r\n            buf.append(String.format(\"\\\\u%04x\", (int) c));\r\n        } else {\r\n            escape0(buf, c);\r\n        }\r\n    }\r\n\r\n    static void escapeType0(StringBuilder sb, String id) {\r\n        for (int i = 0; i < id.length(); ++i) {\r\n            char c = id.charAt(i);\r\n            if (c == '-') {\r\n                sb.append(c);\r\n            } else {\r\n                escape1(sb, c);\r\n            }\r\n        }\r\n    }\r\n\r\n    static String escapeMethod(Method method) {\r\n        return BaksmaliDumper.escapeType(method.getOwner()) + \"->\" + BaksmaliDumper.escapeId(method.getName()) + BaksmaliDumper.escapeMethodDesc(method);\r\n    }\r\n    static String escapeMethodDesc(Method m) {\r\n        return escapeMethodDesc(m.getProto());\r\n    }\r\n    static String escapeMethodDesc(Proto m) {\r\n        StringBuilder escapeBuff = new StringBuilder();\r\n        escapeBuff.append(\"(\");\r\n        for (String t : m.getParameterTypes()) {\r\n            escapeType0(escapeBuff, t);\r\n        }\r\n        escapeBuff.append(\")\");\r\n        escapeType0(escapeBuff, m.getReturnType());\r\n        return escapeBuff.toString();\r\n    }\r\n\r\n    static void appendAccess(final int access, final StringBuilder sb) {\r\n        if ((access & ACC_PUBLIC) != 0) {\r\n            sb.append(\"public \");\r\n        }\r\n        if ((access & ACC_PRIVATE) != 0) {\r\n            sb.append(\"private \");\r\n        }\r\n        if ((access & ACC_PROTECTED) != 0) {\r\n            sb.append(\"protected \");\r\n        }\r\n        if ((access & ACC_FINAL) != 0) {\r\n            sb.append(\"final \");\r\n        }\r\n        if ((access & ACC_STATIC) != 0) {\r\n            sb.append(\"static \");\r\n        }\r\n        if ((access & ACC_VOLATILE) != 0) {\r\n            if ((access & ACCESS_FIELD) == 0) {\r\n                sb.append(\"bridge \");\r\n            } else {\r\n                sb.append(\"volatile \");\r\n            }\r\n        }\r\n        if ((access & ACC_TRANSIENT) != 0) {\r\n            if ((access & ACCESS_FIELD) == 0) {\r\n                sb.append(\"varargs \");\r\n            } else {\r\n                sb.append(\"transient \");\r\n            }\r\n        }\r\n        if ((access & ACC_NATIVE) != 0) {\r\n            sb.append(\"native \");\r\n        }\r\n        if ((access & ACC_STRICT) != 0) {\r\n            sb.append(\"strict \");\r\n        }\r\n        if ((access & ACC_INTERFACE) != 0) {\r\n            sb.append(\"interface \");\r\n        }\r\n        if ((access & ACC_ABSTRACT) != 0) {\r\n            sb.append(\"abstract \");\r\n        }\r\n        if ((access & ACC_SYNTHETIC) != 0) {\r\n            sb.append(\"synthetic \");\r\n        }\r\n        if ((access & ACC_ANNOTATION) != 0) {\r\n            sb.append(\"annotation \");\r\n        }\r\n        if ((access & ACC_ENUM) != 0) {\r\n            sb.append(\"enum \");\r\n        }\r\n        if ((access & ACC_DECLARED_SYNCHRONIZED) != 0) {\r\n            sb.append(\"declared-synchronized \");\r\n        }\r\n        if ((access & ACC_CONSTRUCTOR) != 0) {\r\n            sb.append(\"constructor \");\r\n        }\r\n    }\r\n\r\n    static void escape(final StringBuilder buf, final String s) {\r\n        buf.append(\"\\\"\");\r\n        for (int i = 0; i < s.length(); ++i) {\r\n            escape0(buf, s.charAt(i));\r\n        }\r\n        buf.append(\"\\\"\");\r\n    }\r\n\r\n    static String escapeValue(Object obj) {\r\n        if (obj == null) {\r\n            return \"null\";\r\n        }\r\n\r\n        if (obj instanceof String) {\r\n            StringBuilder buf = new StringBuilder();\r\n            escape(buf, (String) obj);\r\n            return buf.toString();\r\n        }\r\n\r\n        if (obj instanceof DexType) {\r\n            return escapeType(((DexType) obj).desc);\r\n        }\r\n        if(obj instanceof Proto) {\r\n            return escapeMethodDesc((Proto) obj);\r\n        }\r\n        if(obj instanceof MethodHandle) {\r\n            return escapeMethodHandle((MethodHandle) obj);\r\n        }\r\n        if (obj instanceof Field) {\r\n            Field f = ((Field) obj);\r\n            String owner = f.getOwner();\r\n            if (owner == null) {\r\n                owner = f.getType();\r\n            }\r\n            return \".enum \" + escapeType(owner) + \"->\" + f.getName() + \":\" + escapeType(f.getType());\r\n        }\r\n\r\n        if (obj instanceof Integer) {\r\n            int i = ((Integer) obj);\r\n            if (i == Integer.MIN_VALUE) {\r\n                return \"0x\" + Integer.toHexString(i);\r\n            }\r\n            return obj.toString();\r\n        }\r\n        if (obj instanceof Long) {\r\n            Long v = ((Long) obj);\r\n            if (v == Long.MIN_VALUE) {\r\n                return \"0x\" + Long.toHexString(v) + \"L\";\r\n            } else {\r\n                return ((Long) obj).toString() + \"L\";\r\n            }\r\n        }\r\n        if (obj instanceof Float) {\r\n            return ((Float) obj).toString() + \"F\";\r\n        }\r\n        if (obj instanceof Double) {\r\n            return ((Double) obj).toString() + \"D\";\r\n        }\r\n        if (obj instanceof Short) {\r\n            return ((Short) obj).toString() + \"S\";\r\n        }\r\n        if (obj instanceof Byte) {\r\n            return ((Byte) obj).toString() + 't';\r\n        }\r\n        if (obj instanceof Character) {\r\n            StringBuilder buf = new StringBuilder();\r\n            buf.append(\"\\'\");\r\n            escape0(buf, ((Character) obj).charValue());\r\n            buf.append(\"\\'\");\r\n            return buf.toString();\r\n        }\r\n        if (obj instanceof Boolean) {\r\n            return ((Boolean) obj).toString();\r\n        }\r\n        if (obj instanceof Method) {\r\n            return escapeMethod((Method) obj);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private static String escapeMethodHandle(MethodHandle obj) {\r\n        switch (obj.getType()) {\r\n        case MethodHandle.INSTANCE_GET:\r\n            return \".iget \" + escapeField(obj.getField());\r\n        case MethodHandle.INSTANCE_PUT:\r\n            return \".iput \" + escapeField(obj.getField());\r\n        case MethodHandle.STATIC_GET:\r\n            return \".sget \" + escapeField(obj.getField());\r\n        case MethodHandle.STATIC_PUT:\r\n            return \".sput \" + escapeField(obj.getField());\r\n\r\n        case MethodHandle.INVOKE_INSTANCE:\r\n            return \".invoke-instance \" + escapeMethod(obj.getMethod());\r\n        case MethodHandle.INVOKE_STATIC:\r\n            return \".invoke-static \" + escapeMethod(obj.getMethod());\r\n        case MethodHandle.INVOKE_CONSTRUCTOR:\r\n            return \".invoke-constructor \" + escapeMethod(obj.getMethod());\r\n        case MethodHandle.INVOKE_DIRECT:\r\n            return \".invoke-direct \" + escapeMethod(obj.getMethod());\r\n        case MethodHandle.INVOKE_INTERFACE:\r\n            return \".invoke-interface \" + escapeMethod(obj.getMethod());\r\n        default:\r\n        }\r\n        return \"?\";\r\n    }\r\n\r\n    public static String escapeField(Field f) {\r\n        String owner = f.getOwner();\r\n        if (owner == null) {\r\n            owner = f.getType();\r\n        }\r\n        return escapeType(owner) + \"->\" + f.getName() + \":\" + escapeType(f.getType());\r\n    }\r\n\r\n    private static void dumpAnns(List<DexAnnotationNode> anns, Out out) {\r\n        for (DexAnnotationNode ann : anns) {\r\n            dumpAnn(ann, out);\r\n        }\r\n    }\r\n\r\n    private static void dumpItem(String name, Object o, Out out, boolean array) {\r\n\r\n        if (o instanceof Object[]) {\r\n            Object[] vs = (Object[]) o;\r\n            if (name != null) {\r\n                out.s(escapeId(name) + \" = {\");\r\n            } else {\r\n                out.s(\"{\");\r\n            }\r\n            out.push();\r\n            for (int i = 0; i < vs.length; i++) {\r\n                Object v = vs[i];\r\n                dumpItem(null, v, out, i != vs.length - 1);\r\n            }\r\n            out.pop();\r\n            if (array) {\r\n                out.s(\"},\");\r\n            } else {\r\n                out.s(\"}\");\r\n            }\r\n        } else if (o instanceof DexAnnotationNode) {\r\n            DexAnnotationNode dexAnnotationNode = (DexAnnotationNode) o;\r\n            if (name != null) {\r\n                out.s(escapeId(name) + \" = .subannotation \" + escapeType(dexAnnotationNode.type));\r\n            } else {\r\n                out.s(\".subannotation \" + escapeType(dexAnnotationNode.type));\r\n            }\r\n            out.push();\r\n            for (Item item : dexAnnotationNode.items) {\r\n                dumpItem(item.name, item.value, out, false);\r\n            }\r\n            out.pop();\r\n            if (array) {\r\n                out.s(\".end subannotation,\");\r\n            } else {\r\n                out.s(\".end subannotation\");\r\n            }\r\n        } else {\r\n            StringBuilder sb = new StringBuilder();\r\n            if (name != null) {\r\n                sb.append(escapeId(name)).append(\" = \");\r\n            }\r\n            sb.append(escapeValue(o));\r\n            if (array) {\r\n                sb.append(\",\");\r\n            }\r\n            out.s(sb.toString());\r\n        }\r\n    }\r\n\r\n    private static void dumpAnn(DexAnnotationNode ann, Out out) {\r\n        out.s(\".annotation %s %s\", ann.visibility.displayName(), escapeType(ann.type));\r\n        out.push();\r\n        for (Item item : ann.items) {\r\n            dumpItem(item.name, item.value, out, false);\r\n        }\r\n        out.pop();\r\n        out.s(\".end annotation\");\r\n    }\r\n\r\n    public void baksmaliClass(DexClassNode n, BufferedWriter writer) {\r\n        baksmaliClass(n, new BaksmaliDumpOut(writer));\r\n    }\r\n\r\n    public void baksmaliClass(DexClassNode n, Out out) {\r\n\r\n        buff.setLength(0);\r\n        buff.append(\".class \");\r\n        appendAccess(n.access, buff);\r\n        buff.append(escapeType(n.className));\r\n        out.s(buff.toString());\r\n        if (n.superClass != null) {\r\n            out.s(\".super %s\", escapeType(n.superClass));\r\n        }\r\n        if (n.interfaceNames != null && n.interfaceNames.length > 0) {\r\n            for (String itf : n.interfaceNames) {\r\n                out.s(\".implements %s\", escapeType(itf));\r\n            }\r\n        }\r\n        if (n.source != null) {\r\n            out.s(\".source \" + escapeValue(n.source));\r\n        }\r\n        if (n.anns != null) {\r\n            out.s(\"\");\r\n            dumpAnns(n.anns, out);\r\n        }\r\n        if (n.fields != null) {\r\n            for (DexFieldNode f : n.fields) {\r\n                out.s(\"\");\r\n                buff.setLength(0);\r\n                buff.append(\".field \");\r\n                appendAccess(f.access | ACCESS_FIELD, buff);\r\n                Field field = f.field;\r\n                buff.append(escapeId(f.field.getName())).append(\":\").append(escapeType(field.getType()));\r\n                if (f.cst != null) {\r\n                    buff.append(\" = \");\r\n                    buff.append(escapeValue(f.cst));\r\n                }\r\n                out.s(buff.toString());\r\n\r\n                if (f.anns != null) {\r\n                    out.push();\r\n                    dumpAnns(f.anns, out);\r\n                    out.pop();\r\n                    out.s(\".end field\");\r\n                }\r\n            }\r\n        }\r\n        if (n.methods != null) {\r\n            for (DexMethodNode m : n.methods) {\r\n                baksmaliMethod(m, out);\r\n            }\r\n        }\r\n    }\r\n\r\n    public void baksmaliMethod(DexMethodNode m, BufferedWriter writer) {\r\n        baksmaliMethod(m, new BaksmaliDumpOut(writer));\r\n    }\r\n\r\n    public void baksmaliMethod(DexMethodNode m, Out out) {\r\n        out.s(\"\");\r\n        buff.setLength(0);\r\n        buff.append(\".method \");\r\n        Method method = m.method;\r\n        appendAccess(m.access, buff);\r\n        buff.append(escapeId(method.getName())).append(escapeMethodDesc(method));\r\n        out.s(buff.toString());\r\n        out.push();\r\n        if (m.anns != null) {\r\n            dumpAnns(m.anns, out);\r\n        }\r\n\r\n        int paramMax = 0;\r\n        List<String> parameterNames = null;\r\n        if (m.codeNode != null && m.codeNode.debugNode != null) {\r\n            parameterNames = m.codeNode.debugNode.parameterNames;\r\n            if (parameterNames != null) {\r\n                paramMax = parameterNames.size();\r\n            }\r\n        }\r\n        int annoMax = 0;\r\n        if (m.parameterAnns != null) {\r\n            for (int i = 0; i < m.parameterAnns.length; i++) {\r\n                List<DexAnnotationNode> ps = m.parameterAnns[i];\r\n                if (ps != null && ps.size() > 0) {\r\n                    annoMax = i + 1;\r\n                }\r\n            }\r\n        }\r\n\r\n        int max = Math.max(paramMax, annoMax);\r\n        for (int i = 0; i < max; i++) {\r\n            String type = method.getParameterTypes()[i];\r\n            String debugName = parameterNames == null ? null : i < parameterNames.size() ? parameterNames.get(i) : null;\r\n            if (debugName != null) {\r\n                out.s(\".parameter \\\"\" + escapeId(debugName) + \"\\\" # \" + type);\r\n            } else {\r\n                out.s(\".parameter # \" + type);\r\n            }\r\n            List<DexAnnotationNode> ps = m.parameterAnns == null ? null : m.parameterAnns[i];\r\n            if (ps != null && ps.size() != 0) {\r\n                out.push();\r\n                dumpAnns(ps, out);\r\n                out.pop();\r\n                out.s(\".end parameter\");\r\n            }\r\n            // FIXME support '.param' REGISTER, STRING\r\n        }\r\n\r\n        if (m.codeNode != null) {\r\n            baksmaliCode(m, m.codeNode, out);\r\n        }\r\n\r\n        out.pop();\r\n        out.s(\".end method\");\r\n    }\r\n\r\n    public void baksmaliCode(DexMethodNode methodNode, DexCodeNode codeNode, Out out) {\r\n\r\n        final List<DexLabel> allLabel = new ArrayList<>();\r\n        final Set<DexLabel> usedLabel = new HashSet<>();\r\n        codeNode.accept(new DexCodeVisitor() {\r\n            @Override\r\n            public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\r\n                usedLabel.add(label);\r\n            }\r\n\r\n            @Override\r\n            public void visitPackedSwitchStmt(Op op, int aA, int first_case, DexLabel[] labels) {\r\n                usedLabel.addAll(Arrays.asList(labels));\r\n            }\r\n\r\n            @Override\r\n            public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) {\r\n                usedLabel.add(start);\r\n                usedLabel.add(end);\r\n                usedLabel.addAll(Arrays.asList(handler));\r\n            }\r\n\r\n            @Override\r\n            public void visitLabel(DexLabel label) {\r\n                allLabel.add(label);\r\n            }\r\n\r\n            @Override\r\n            public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {\r\n                usedLabel.addAll(Arrays.asList(labels));\r\n            }\r\n        });\r\n        Map<DexLabel, List<DexDebugNode.DexDebugOpNode>> debugLabelMap = new HashMap<>();\r\n        if (codeNode.debugNode != null) {\r\n            DexDebugNode debugNode = codeNode.debugNode;\r\n            for (DexDebugNode.DexDebugOpNode opNode : debugNode.debugNodes) {\r\n                List<DexDebugNode.DexDebugOpNode> list = debugLabelMap.get(opNode.label);\r\n                if (list == null) {\r\n                    list = new ArrayList<>(3);\r\n                    debugLabelMap.put(opNode.label, list);\r\n                }\r\n                list.add(opNode);\r\n            }\r\n        }\r\n        int nextLabelNumber = 0;\r\n        for (DexLabel label : allLabel) {\r\n            if (usedLabel.contains(label)) {\r\n                label.displayName = \"L\" + nextLabelNumber++;\r\n            }\r\n        }\r\n\r\n        int inRegs = Utils.methodIns(methodNode.method, (methodNode.access & ACC_STATIC) != 0);\r\n\r\n        DexCodeVisitor dexCodeVisitor = new BaksmaliCodeDumper(out, useParameterRegisters, useLocals, nextLabelNumber,\r\n                codeNode.totalRegister - inRegs, usedLabel, debugLabelMap);\r\n        accept(out, codeNode, dexCodeVisitor);\r\n        dexCodeVisitor.visitEnd();\r\n    }\r\n\r\n    void accept(Out out, DexCodeNode code, DexCodeVisitor v) {\r\n        if (code.tryStmts != null) {\r\n            for (TryCatchNode n : code.tryStmts) {\r\n                n.accept(v);\r\n            }\r\n        }\r\n        if (code.debugNode != null) {\r\n            DexDebugVisitor ddv = v.visitDebug();\r\n            if (ddv != null) {\r\n                code.debugNode.accept(ddv);\r\n                ddv.visitEnd();\r\n            }\r\n        }\r\n        if (code.totalRegister >= 0 && code.stmts.size() > 0) {\r\n            v.visitRegister(code.totalRegister);\r\n        }\r\n        for (DexStmtNode n : code.stmts) {\r\n            if (n instanceof DexLabelStmtNode) {\r\n                n.accept(v);\r\n            } else {\r\n                out.push();\r\n                n.accept(v);\r\n                out.pop();\r\n            }\r\n\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/Smali.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.smali;\n\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.smali.antlr4.SmaliLexer;\nimport com.googlecode.d2j.smali.antlr4.SmaliParser;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\nimport org.antlr.v4.runtime.*;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.attribute.BasicFileAttributes;\n\npublic class Smali {\n    public static void smaliFile(Path path, DexFileVisitor dcv) throws IOException {\n        try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {\n            ANTLRInputStream is = new ANTLRInputStream(reader);\n            is.name = path.toString();\n            smali0(dcv, is);\n        }\n    }\n\n    public static void smaliFile(String name, String buff, DexFileVisitor dcv) throws IOException {\n        ANTLRInputStream is = new ANTLRInputStream(buff);\n        is.name = name;\n        smali0(dcv, is);\n    }\n\n    public static void smaliFile(String name, InputStream in, DexFileVisitor dcv) throws IOException {\n        try (InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {\n            ANTLRInputStream is = new ANTLRInputStream(reader);\n            is.name = name;\n            smali0(dcv, is);\n        }\n    }\n\n    public static DexClassNode smaliFile2Node(String name, InputStream in) throws IOException {\n        DexFileNode dfn = new DexFileNode();\n        smaliFile(name, in, dfn);\n        return dfn.clzs.size() > 0 ? dfn.clzs.get(0) : null;\n    }\n\n    public static DexClassNode smaliFile2Node(String name, String buff) throws IOException {\n        DexFileNode dfn = new DexFileNode();\n        smaliFile(name, buff, dfn);\n        return dfn.clzs.size() > 0 ? dfn.clzs.get(0) : null;\n    }\n\n    private static void smali0(DexFileVisitor dcv, CharStream is) throws IOException {\n        SmaliLexer lexer = new SmaliLexer(is);\n        CommonTokenStream ts = new CommonTokenStream(lexer);\n        SmaliParser parser = new SmaliParser(ts);\n\n        for (SmaliParser.SFileContext ctx : parser.sFiles().sFile()) {\n            AntlrSmaliUtil.acceptFile(ctx, dcv);\n        }\n    }\n\n    public static void smaliFile(String fileName, char[] data, DexFileVisitor dcv) throws IOException {\n        // System.err.println(\"parsing \" + f.getAbsoluteFile());\n        ANTLRInputStream is = new ANTLRInputStream(data, data.length);\n        is.name = fileName;\n        smali0(dcv, is);\n    }\n\n    public static void smali(Path base, final DexFileVisitor dfv) throws IOException {\n        if (Files.isDirectory(base)) {\n            Files.walkFileTree(base, new SimpleFileVisitor<Path>() {\n                @Override\n                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\n                    Path fn = dir.getFileName();\n                    if (fn != null && fn.toString().startsWith(\".\")) {\n                        return FileVisitResult.SKIP_SUBTREE;\n                    }\n                    return super.preVisitDirectory(dir, attrs);\n                }\n\n                @Override\n                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                    smaliFile(file, dfv);\n                    return super.visitFile(file, attrs);\n                }\n            });\n        } else if (Files.isRegularFile(base)) {\n            smaliFile(base, dfv);\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/SmaliCmd.java",
    "content": "package com.googlecode.d2j.smali;\n\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\nimport com.googlecode.d2j.dex.writer.DexFileWriter;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\n\n@Syntax(cmd = \"d2j-smali\", syntax = \"[options] [--] [<smali-file>|folder]*\", desc = \"assembles a set of smali files into a dex file\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/Smali\")\npublic class SmaliCmd extends BaseCmd {\n    @Opt(opt = \"x\", longOpt = \"allow-odex-instructions\", hasArg = false, description = \"[not impl] allow odex instructions to be compiled into the dex file. Only a few instructions are supported - the ones that can exist in a dead code path and not cause dalvik to reject the class\")\n    private boolean allowOdexInstructions;\n    @Opt(opt = \"a\", longOpt = \"api-level\", description = \"[not impl] The numeric api-level of the file to generate, e.g. 14 for ICS. If not specified, it defaults to 14 (ICS).\", argName = \"API_LEVEL\")\n    private int apiLevel = 14;\n    @Opt(opt = \"v\", longOpt = \"version\", hasArg = false, description = \"prints the version then exits\")\n    private boolean showVersionThenExits;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"the name of the dex file that will be written. The default is out.dex\", argName = \"FILE\")\n    private Path output;\n    @Opt(opt = \"-\", hasArg = false, description = \"read smali from stdin\")\n    private boolean readSmaliFromStdin;\n\n    public static void main(String[] args) {\n        new SmaliCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n\n        if (showVersionThenExits) {\n            System.out.println(\"smali 1.4.2p (https://sourceforge.net/p/dex2jar)\");\n            System.out.println(\"Copyright (c) 2009-2013 Panxiaobo (pxb1988@gmail.com)\");\n            System.out.println(\"Apache license (http://www.apache.org/licenses/LICENSE-2.0)\");\n            return;\n        }\n\n        if (!readSmaliFromStdin && remainingArgs.length < 1) {\n            System.err.println(\"ERRPR: no file to process\");\n            return;\n        }\n\n        if (output == null) {\n            output = new File(\"out.dex\").toPath();\n        }\n\n        Smali smali = new Smali();\n        DexFileWriter fw = new DexFileWriter();\n\n        DexFileVisitor fv = new DexFileVisitor(fw) {\n            @Override\n            public void visitEnd() {// intercept the call to super\n            }\n        };\n\n        if (readSmaliFromStdin) {\n            smali.smaliFile(\"<stdin>\", System.in, fv);\n            System.err.println(\"smali <stdin> -> \" + output);\n        }\n\n        for (String s : remainingArgs) {\n            Path file = new File(s).toPath();\n            if (!Files.exists(file)) {\n                System.err.println(\"skip \" + file + \", it is not a dir or a file\");\n            } else {\n                System.err.println(\"smali \" + s + \" -> \" + output);\n                smali.smali(file, fv);\n            }\n        }\n\n        fw.visitEnd();\n        byte[] data = fw.toByteArray();\n        Files.write(output, data);\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/SmaliCodeVisitor.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.smali;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.node.DexCodeNode;\nimport com.googlecode.d2j.node.insn.DexLabelStmtNode;\nimport com.googlecode.d2j.node.insn.DexStmtNode;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class SmaliCodeVisitor extends DexCodeNode {\n\n    public SmaliCodeVisitor(DexCodeVisitor visitor) {\n        super(visitor);\n    }\n\n    @Override\n    public void visitConstStmt(Op op, int ra, Object value) {\n        switch (op) {\n        case CONST_WIDE_16: {\n            if(value instanceof Integer) {\n                short v = ((Number) value).shortValue();\n                super.visitConstStmt(op, ra, (long) v);\n            } else {\n                super.visitConstStmt(op, ra, value);\n            }\n        }\n            break;\n        case CONST_WIDE_HIGH16: {\n            if(value instanceof Integer) {\n                short v = ((Number) value).shortValue();\n                super.visitConstStmt(op, ra, ((long) v) << 48);\n            } else {\n                super.visitConstStmt(op, ra, value);\n            }\n        }\n            break;\n        case CONST_WIDE_32: {\n            if(value instanceof Integer) {\n                int v = ((Number) value).intValue();\n                super.visitConstStmt(op, ra, (long) v);\n            } else {\n                super.visitConstStmt(op, ra, value);\n            }\n        }\n            break;\n        case CONST_HIGH16: {\n            int v = ((Number) value).intValue();\n            if(0 != (v & 0xFFff0000)){\n                super.visitConstStmt(op, ra, v);\n            } else {\n                super.visitConstStmt(op, ra, v << 16);\n            }\n        }\n            break;\n        default:\n            super.visitConstStmt(op, ra, value);\n            break;\n        }\n    }\n\n    public static class ArrayDataStmt extends DexStmtNode {\n        int length;\n        byte[] objs;\n\n        public ArrayDataStmt(int length, byte[] obj) {\n            super(null);\n            this.length = length;\n            this.objs = obj;\n        }\n\n        @Override\n        public void accept(DexCodeVisitor cv) {\n        }\n\n    }\n\n    public static class PackedSwitchStmt extends DexStmtNode {\n        int firstCase;\n        DexLabel[] labels;\n\n        public PackedSwitchStmt(int reg, DexLabel[] labels) {\n            super(null);\n            this.firstCase = reg;\n            this.labels = labels;\n        }\n\n        @Override\n        public void accept(DexCodeVisitor cv) {\n        }\n    }\n\n    public static class SparseSwitchStmt extends DexStmtNode {\n        int[] cases;\n        DexLabel labels[];\n\n        public SparseSwitchStmt(int[] cases, DexLabel[] labels) {\n            super(null);\n            this.cases = cases;\n            this.labels = labels;\n        }\n\n        @Override\n        public void accept(DexCodeVisitor cv) {\n        }\n    }\n\n    private List<DexStmtNode> needCareStmts = new ArrayList<DexStmtNode>();\n\n    @Override\n    public void visitEnd() {\n        if (super.visitor != null) {\n            super.accept(super.visitor);\n        }\n        needCareStmts = null;\n        stmts = null;\n        tryStmts = null;\n        super.visitEnd();\n    }\n\n    private void addCare(DexStmtNode stmt) {\n        needCareStmts.add(stmt);\n        super.add(stmt);\n    }\n\n    /* package */void dArrayData(int length, byte[] obj) {\n        addCare(new ArrayDataStmt(length, obj));\n    }\n\n    void dPackedSwitch(int first, DexLabel[] labels) {\n        addCare(new PackedSwitchStmt(first, labels));\n    }\n\n    /* package */void dSparseSwitch(int[] cases, DexLabel[] labels) {\n        addCare(new SparseSwitchStmt(cases, labels));\n    }\n\n    int findLabelIndex(DexLabel label) {\n        int labelIndex = -1;\n        for (int i = 0; i < needCareStmts.size(); i++) {\n            DexStmtNode s = needCareStmts.get(i);\n            if (s instanceof DexLabelStmtNode) {\n                DexLabelStmtNode ss = (DexLabelStmtNode) s;\n                if (ss.label == label) {\n                    labelIndex = i;\n                }\n            }\n        }\n        return labelIndex;\n    }\n\n    /* package */void visitF31tStmt(final Op op, final int reg, final DexLabel label) {\n        add(new DexStmtNode(op) {\n\n            @Override\n            public void accept(DexCodeVisitor cv) {\n                int labelIndex = findLabelIndex(label);\n                if (labelIndex < 0 || labelIndex >= needCareStmts.size()) {\n                    throw new RuntimeException(\"can't find label for \" + op + \" \" + label);\n                }\n\n                switch (op) {\n                case PACKED_SWITCH:\n                    PackedSwitchStmt packedSwitchStmt = (PackedSwitchStmt) needCareStmts.get(labelIndex + 1);\n                    cv.visitPackedSwitchStmt(op, reg, packedSwitchStmt.firstCase, packedSwitchStmt.labels);\n                    break;\n                case SPARSE_SWITCH:\n                    SparseSwitchStmt sparseSwitchStmt = (SparseSwitchStmt) needCareStmts.get(labelIndex + 1);\n                    cv.visitSparseSwitchStmt(op, reg, sparseSwitchStmt.cases, sparseSwitchStmt.labels);\n                    break;\n                case FILL_ARRAY_DATA:\n                    ArrayDataStmt arrayDataStmt = (ArrayDataStmt) needCareStmts.get(labelIndex + 1);\n                    Object v;\n                    byte[] vs = arrayDataStmt.objs;\n                    switch (arrayDataStmt.length) {\n                    case 1: {\n                        v = vs;\n                    }\n                        break;\n                    case 2: {\n                        short[] vs1 = new short[vs.length / 2];\n                        for (int i = 0; i < vs1.length; i++) {\n                            vs1[i] = (short) ((vs[i * 2] & 0xFF) | ((vs[i * 2 + 1] & 0xFF) << 8));\n                        }\n                        v = vs1;\n                    }\n                        break;\n                    case 4: {\n                        int[] vs1 = new int[vs.length / 4];\n                        for (int i = 0; i < vs1.length; i++) {\n                            int base = i * 4;\n                            vs1[i] = (vs[base + 0] & 0xFF) | ((vs[base + 1] & 0xFF) << 8)\n                                    | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);\n                        }\n                        v = vs1;\n                    }\n                        break;\n                    case 8: {\n                        long[] vs1 = new long[vs.length / 8];\n                        for (int i = 0; i < vs1.length; i++) {\n                            int base = i * 8;\n                            int a = ((vs[base + 0] & 0xFF) << 0) | ((vs[base + 1] & 0xFF) << 8)\n                                    | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);\n                            int b = ((vs[base + 4] & 0xFF) << 0) | ((vs[base + 5] & 0xFF) << 8)\n                                    | ((vs[base + 6] & 0xFF) << 16) | ((vs[base + 7] & 0xFF) << 24);\n                            vs1[i] = (((long) b) << 32) | a;\n                        }\n                        v = vs1;\n                    }\n                        break;\n                    default:\n                        throw new RuntimeException();\n                    }\n                    cv.visitFillArrayDataStmt(Op.FILL_ARRAY_DATA, reg, v);\n                    break;\n                default:\n                    throw new RuntimeException();\n                }\n            }\n        });\n    }\n\n    @Override\n    public void visitLabel(final DexLabel label) {\n        addCare(new DexLabelStmtNode(label));\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/main/java/com/googlecode/d2j/smali/Utils.java",
    "content": "package com.googlecode.d2j.smali;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\n\nimport java.math.BigInteger;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Utils implements DexConstants {\n\n    public static void doAccept(DexAnnotationVisitor dexAnnotationVisitor, String k, Object value) {\n        if (value instanceof ArrayList) {\n            DexAnnotationVisitor a = dexAnnotationVisitor.visitArray(k);\n            for (Object o : (ArrayList) value) {\n                doAccept(a, null, o);\n            }\n            a.visitEnd();\n        } else if (value instanceof Ann) {\n            Ann ann = (Ann) value;\n            DexAnnotationVisitor a = dexAnnotationVisitor.visitAnnotation(k, ann.name);\n            for (Map.Entry<String, Object> e : ann.elements) {\n                doAccept(a, e.getKey(), e.getValue());\n            }\n            a.visitEnd();\n        } else if (value instanceof Field) {\n            Field f = (Field) value;\n            dexAnnotationVisitor.visitEnum(k, f.getOwner(), f.getName());\n        } else {\n            dexAnnotationVisitor.visit(k, value);\n        }\n    }\n\n    public static int getAcc(String name) {\n        if (name.equals(\"public\")) {\n            return ACC_PUBLIC;\n        } else if (name.equals(\"private\")) {\n            return ACC_PRIVATE;\n        } else if (name.equals(\"protected\")) {\n            return ACC_PROTECTED;\n        } else if (name.equals(\"static\")) {\n            return ACC_STATIC;\n        } else if (name.equals(\"final\")) {\n            return ACC_FINAL;\n        } else if (name.equals(\"synchronized\")) {\n            return ACC_SYNCHRONIZED;\n        } else if (name.equals(\"volatile\")) {\n            return ACC_VOLATILE;\n        } else if (name.equals(\"bridge\")) {\n            return ACC_BRIDGE;\n        } else if (name.equals(\"varargs\")) {\n            return ACC_VARARGS;\n        } else if (name.equals(\"transient\")) {\n            return ACC_TRANSIENT;\n        } else if (name.equals(\"native\")) {\n            return ACC_NATIVE;\n        } else if (name.equals(\"interface\")) {\n            return ACC_INTERFACE;\n        } else if (name.equals(\"abstract\")) {\n            return ACC_ABSTRACT;\n        } else if (name.equals(\"strict\")) {\n            return ACC_STRICT;\n        } else if (name.equals(\"synthetic\")) {\n            return ACC_SYNTHETIC;\n        } else if (name.equals(\"annotation\")) {\n            return ACC_ANNOTATION;\n        } else if (name.equals(\"enum\")) {\n            return ACC_ENUM;\n        } else if (name.equals(\"constructor\")) {\n            return ACC_CONSTRUCTOR;\n        } else if (name.equals(\"declared-synchronized\")) {\n            return ACC_DECLARED_SYNCHRONIZED;\n        }\n        return 0;\n    }\n\n    public static List<String> listDesc(String desc) {\n        List<String> list = new ArrayList(5);\n        if (desc == null) {\n            return list;\n        }\n        char[] chars = desc.toCharArray();\n        int i = 0;\n        while (i < chars.length) {\n            switch (chars[i]) {\n                case 'V':\n                case 'Z':\n                case 'C':\n                case 'B':\n                case 'S':\n                case 'I':\n                case 'F':\n                case 'J':\n                case 'D':\n                    list.add(Character.toString(chars[i]));\n                    i++;\n                    break;\n                case '[': {\n                    int count = 1;\n                    while (chars[i + count] == '[') {\n                        count++;\n                    }\n                    if (chars[i + count] == 'L') {\n                        count++;\n                        while (chars[i + count] != ';') {\n                            count++;\n                        }\n                    }\n                    count++;\n                    list.add(new String(chars, i, count));\n                    i += count;\n                    break;\n                }\n                case 'L': {\n                    int count = 1;\n                    while (chars[i + count] != ';') {\n                        ++count;\n                    }\n                    count++;\n                    list.add(new String(chars, i, count));\n                    i += count;\n                    break;\n                }\n                default:\n                    throw new RuntimeException(\"can't parse type list: \" + desc);\n            }\n        }\n        return list;\n    }\n\n    public static String[] toTypeList(String s) {\n        return listDesc(s).toArray(new String[0]);\n    }\n\n    static public Byte parseByte(String str) {\n        return Byte.valueOf((byte) parseInt(str.substring(0, str.length() - 1)));\n    }\n\n    static public Short parseShort(String str) {\n        return Short.valueOf((short) parseInt(str.substring(0, str.length() - 1)));\n    }\n\n    static public Long parseLong(String str) {\n        int sof = 0;\n        int end = str.length() - 1;\n        int x = 1;\n        if (str.charAt(sof) == '+') {\n            sof++;\n        } else if (str.charAt(sof) == '-') {\n            sof++;\n            x = -1;\n        }\n        BigInteger v;\n        if (str.charAt(sof) == '0') {\n            sof++;\n            if (sof >= end) {\n                return 0L;\n            }\n            char c = str.charAt(sof);\n            if (c == 'x' || c == 'X') {// hex\n                sof++;\n                v = new BigInteger(str.substring(sof, end), 16);\n            } else {// oct\n                v = new BigInteger(str.substring(sof, end), 8);\n            }\n        } else {\n            v = new BigInteger(str.substring(sof, end), 10);\n        }\n        if (x == -1) {\n            return v.negate().longValue();\n        } else {\n            return v.longValue();\n        }\n    }\n\n    static public float parseFloat(String str) {\n        str = str.toLowerCase();\n        int s = 0;\n        float x = 1f;\n        if (str.charAt(s) == '+') {\n            s++;\n        } else if (str.charAt(s) == '-') {\n            s++;\n            x = -1;\n        }\n        int e = str.length() - 1;\n        if (str.charAt(e) == 'f') {\n            e--;\n        }\n        str = str.substring(s, e + 1);\n        if (str.equals(\"nan\")) {\n            return Float.NaN;\n        }\n        if (str.equals(\"infinity\")) {\n            return x < 0 ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;\n        }\n        return (float) x * Float.parseFloat(str);\n    }\n\n    static public double parseDouble(String str) {\n        str = str.toLowerCase();\n        int s = 0;\n        double x = 1;\n        if (str.charAt(s) == '+') {\n            s++;\n        } else if (str.charAt(s) == '-') {\n            s++;\n            x = -1;\n        }\n        int e = str.length() - 1;\n        if (str.charAt(e) == 'd') {\n            e--;\n        }\n        str = str.substring(s, e + 1);\n        if (str.equals(\"nan\")) {\n            return Double.NaN;\n        }\n        if (str.equals(\"infinity\")) {\n            return x < 0 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;\n        }\n        return x * Double.parseDouble(str);\n    }\n\n    static public int parseInt(String str, int start, int end) {\n        int sof = start;\n        int x = 1;\n        if (str.charAt(sof) == '+') {\n            sof++;\n        } else if (str.charAt(sof) == '-') {\n            sof++;\n            x = -1;\n        }\n        long v;\n        if (str.charAt(sof) == '0') {\n            sof++;\n            if (sof >= end) {\n                return 0;\n            }\n            char c = str.charAt(sof);\n            if (c == 'x' || c == 'X') {// hex\n                sof++;\n                v = Long.parseLong(str.substring(sof, end), 16);\n            } else {// oct\n                v = Long.parseLong(str.substring(sof, end), 8);\n            }\n        } else {\n            v = Long.parseLong(str.substring(sof, end), 10);\n        }\n        return (int) (v * x);\n    }\n\n    static public int parseInt(String str) {\n        return parseInt(str, 0, str.length());\n    }\n\n    public static String unescapeStr(String str) {\n        return unEscape(str);\n    }\n\n    public static Character unescapeChar(String str) {\n        return unEscape(str).charAt(0);\n    }\n\n    public static int[] toIntArray(List<String> ss) {\n        int vs[] = new int[ss.size()];\n        for (int i = 0; i < ss.size(); i++) {\n            vs[i] = parseInt(ss.get(i));\n        }\n        return vs;\n    }\n\n    public static byte[] toByteArray(List<Object> ss) {\n        byte vs[] = new byte[ss.size()];\n        for (int i = 0; i < ss.size(); i++) {\n            vs[i] = ((Number) (ss.get(i))).byteValue();\n        }\n        return vs;\n    }\n\n    static Map<String, Op> ops = new HashMap();\n\n    static {\n        for (Op op : Op.values()) {\n            ops.put(op.displayName, op);\n        }\n    }\n\n    static public Op getOp(String name) {\n        return ops.get(name);\n    }\n\n    public static String unEscape(String str) {\n        return unEscape0(str, 1, str.length() - 1);\n    }\n\n    public static String unEscapeId(String str) {\n        return unEscape0(str, 0, str.length());\n    }\n\n    public static int findString(String str, int start, int end, char dEnd) {\n        for (int i = start; i < end; ) {\n            char c = str.charAt(i);\n            if (c == '\\\\') {\n                char d = str.charAt(i + 1);\n                switch (d) {\n                    // ('b'|'t'|'n'|'f'|'r'|'\\\"'|'\\''|'\\\\')\n                    case 'b':\n                    case 't':\n                    case 'n':\n                    case 'f':\n                    case 'r':\n                    case '\\\"':\n                    case '\\'':\n                    case '\\\\':\n                        i += 2;\n                        break;\n                    case 'u':\n                        String sub = str.substring(i + 2, i + 6);\n                        i += 6;\n                        break;\n                    default:\n                        int x = 0;\n                        while (x < 3) {\n                            char e = str.charAt(i + 1 + x);\n                            if (e >= '0' && e <= '7') {\n                                x++;\n                            } else {\n                                break;\n                            }\n                        }\n                        if (x == 0) {\n                            throw new RuntimeException(\"can't pase string\");\n                        }\n                        i += 1 + x;\n                }\n\n            } else {\n                if (c == dEnd) {\n                    return i;\n                }\n                i++;\n            }\n        }\n        return end;\n    }\n\n    public static String unEscape0(String str, int start, int end) {\n\n        StringBuilder sb = new StringBuilder();\n        for (int i = start; i < end; ) {\n            char c = str.charAt(i);\n            if (c == '\\\\') {\n                char d = str.charAt(i + 1);\n                switch (d) {\n                    // ('b'|'t'|'n'|'f'|'r'|'\\\"'|'\\''|'\\\\')\n                    case 'b':\n                        sb.append('\\b');\n                        i += 2;\n                        break;\n                    case 't':\n                        sb.append('\\t');\n                        i += 2;\n                        break;\n                    case 'n':\n                        sb.append('\\n');\n                        i += 2;\n                        break;\n                    case 'f':\n                        sb.append('\\f');\n                        i += 2;\n                        break;\n                    case 'r':\n                        sb.append('\\r');\n                        i += 2;\n                        break;\n                    case '\\\"':\n                        sb.append('\\\"');\n                        i += 2;\n                        break;\n                    case '\\'':\n                        sb.append('\\'');\n                        i += 2;\n                        break;\n                    case '\\\\':\n                        sb.append('\\\\');\n                        i += 2;\n                        break;\n                    case 'u':\n                        String sub = str.substring(i + 2, i + 6);\n                        sb.append((char) Integer.parseInt(sub, 16));\n                        i += 6;\n                        break;\n                    default:\n                        int x = 0;\n                        while (x < 3) {\n                            char e = str.charAt(i + 1 + x);\n                            if (e >= '0' && e <= '7') {\n                                x++;\n                            } else {\n                                break;\n                            }\n                        }\n                        if (x == 0) {\n                            throw new RuntimeException(\"can't pase string\");\n                        }\n                        sb.append((char) Integer.parseInt(str.substring(i + 1, i + 1 + x), 8));\n                        i += 1 + x;\n                }\n\n            } else {\n                sb.append(c);\n                i++;\n            }\n        }\n        return sb.toString();\n    }\n\n    public static class Ann {\n        public String name;\n        public List<Map.Entry<String, Object>> elements = new ArrayList();\n\n        public void put(String name, Object value) {\n            elements.add(new java.util.AbstractMap.SimpleEntry(name, value));\n        }\n    }\n\n    public static Visibility getAnnVisibility(String name) {\n        return Visibility.valueOf(name.toUpperCase());\n    }\n\n    public static int methodIns(Method m, boolean isStatic) {\n        int a = isStatic ? 0 : 1;\n        for (String t : m.getParameterTypes()) {\n            switch (t.charAt(0)) {\n                case 'J':\n                case 'D':\n                    a += 2;\n                    break;\n                default:\n                    a += 1;\n                    break;\n            }\n        }\n        return a;\n    }\n\n    public static int reg2ParamIdx(Method m, int reg, int locals, boolean isStatic) {\n        int x = reg - locals;\n        if (x < 0) {\n            return -1;\n        }\n        int a = isStatic ? 0 : 1;\n        String[] parameterTypes = m.getParameterTypes();\n        for (int i = 0, parameterTypesLength = parameterTypes.length; i < parameterTypesLength; i++) {\n\n            if (x == a) {\n                return i;\n            }\n\n            String t = parameterTypes[i];\n            switch (t.charAt(0)) {\n                case 'J':\n                case 'D':\n                    a += 2;\n                    break;\n                default:\n                    a += 1;\n                    break;\n            }\n        }\n        return -1;\n    }\n\n    public static Method parseMethodAndUnescape(String owner, String part) throws RuntimeException {\n        int x = part.indexOf('(');\n        if (x < 0) {\n            throw new RuntimeException();\n        }\n        int y = part.indexOf(')', x);\n        if (y < 0) {\n            throw new RuntimeException();\n        }\n\n        String methodName = unEscapeId(part.substring(0, x));\n        String[] params = toTypeList(part.substring(x + 1, y));\n        for (int i = 0; i < params.length; i++) {\n            params[i] = unEscapeId(params[i]);\n        }\n        String ret = unEscapeId(part.substring(y + 1));\n        return new Method(owner, methodName, params, ret);\n    }\n\n    public static Method parseMethodAndUnescape(String full) throws RuntimeException {\n\n        int x = full.indexOf(\"->\");\n        if (x <= 0) {\n            throw new RuntimeException();\n        }\n        return parseMethodAndUnescape(unEscapeId(full.substring(0, x)), full.substring(x + 2));\n    }\n\n    public static Field parseFieldAndUnescape(String owner, String part) throws RuntimeException {\n        int x = part.indexOf(':');\n        if (x < 0) {\n            throw new RuntimeException();\n        }\n        return new Field(owner, unEscapeId(part.substring(0, x)), unEscapeId(part.substring(x + 1)));\n    }\n\n    public static Field parseFieldAndUnescape(String full) throws RuntimeException {\n        int x = full.indexOf(\"->\");\n        if (x <= 0) {\n            throw new RuntimeException();\n        }\n        return parseFieldAndUnescape(unEscapeId(full.substring(0, x)), full.substring(x + 2));\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/test/java/a/BaksmaliTest.java",
    "content": "package a;\n\nimport com.googlecode.d2j.smali.Baksmali;\nimport com.googlecode.d2j.smali.BaksmaliDexFileVisitor;\nimport com.googlecode.d2j.smali.BaksmaliDumper;\nimport com.googlecode.d2j.smali.Smali;\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport org.junit.Test;\n\nimport java.io.File;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Path;\n\npublic class BaksmaliTest {\n\n\n    @Test\n    public void t() throws Exception {\n        File dir = new File(\"../dex-translator/src/test/resources/dexes\");\n        File[] fs = dir.listFiles();\n        if (fs != null) {\n            for (File f : fs) {\n                if (f.getName().endsWith(\".dex\") || f.getName().endsWith(\".apk\")) {\n                    dotest(f.toPath());\n                }\n            }\n        }\n    }\n\n    private void dotest(Path f) throws Exception {\n        Path smali0 = new File(\"target/\" + f.getFileName() + \"-smali0.zip\").toPath();\n        try (FileSystem fs0 = BaseCmd.createZip(smali0)) {\n            Baksmali.from(f).to(fs0.getPath(\"/\"));\n        }\n        Path smali1 = new File(\"target/\" + f.getFileName() + \"-smali1.zip\").toPath();\n        try (FileSystem fs0 = BaseCmd.openZip(smali0); FileSystem fs1 = BaseCmd.createZip(smali1)) {\n            BaksmaliDumper baksmaliDumper = new BaksmaliDumper();\n            BaksmaliDexFileVisitor v = new BaksmaliDexFileVisitor(fs1.getPath(\"/\"), baksmaliDumper);\n            Smali.smali(fs0.getPath(\"/\"), v);\n        }\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/test/java/a/SmaliTest.java",
    "content": "package a;\n\nimport com.googlecode.d2j.dex.writer.DexFileWriter;\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.d2j.smali.BaksmaliDumpOut;\nimport com.googlecode.d2j.smali.BaksmaliDumper;\nimport com.googlecode.d2j.smali.Smali;\nimport org.jf.baksmali.Adaptors.ClassDefinition;\nimport org.jf.baksmali.baksmaliOptions;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedDexFile;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.util.IndentingWriter;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.io.*;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class SmaliTest {\n    @Test\n    public void test() throws IOException {\n        DexFileNode dfn = new DexFileNode();\n        try (InputStream is = SmaliTest.class.getResourceAsStream(\"/a.smali\")) {\n            Smali.smaliFile(\"a.smali\", is, dfn);\n        }\n        for (DexClassNode dcn : dfn.clzs) {\n            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));\n            new BaksmaliDumper(true, true).baksmaliClass(dcn, new BaksmaliDumpOut(w));\n            w.flush();\n        }\n    }\n\n    Map<String, DexClassNode> readDex(File path) throws IOException {\n        DexFileReader dexFileReader = new DexFileReader(ZipUtil.readDex(path));\n        DexFileNode dexFileNode = new DexFileNode();\n        dexFileReader.accept(dexFileNode);\n        Map<String, DexClassNode> map = new HashMap<>();\n        for (DexClassNode c : dexFileNode.clzs) {\n            map.put(c.className, c);\n        }\n        return map;\n    }\n\n    @Test\n    public void test2() throws IOException {\n        File dir = new File(\"../dex-translator/src/test/resources/dexes\");\n        File[] fs = dir.listFiles();\n        if (fs != null) {\n            for (File f : fs) {\n                if (f.getName().endsWith(\".dex\") || f.getName().endsWith(\".apk\")) {\n                    System.out.println(f.getName());\n                    dotest(f);\n                }\n            }\n        }\n    }\n\n    private void dotest(File dexFile) throws IOException {\n        DexBackedDexFile dex;\n        try {\n            dex = DexFileFactory.loadDexFile(dexFile, 14, false);\n        } catch (DexBackedDexFile.NotADexFile ex) {\n            ex.printStackTrace();\n            return;\n        }\n        Map<String, DexClassNode> map = readDex(dexFile);\n\n        for (DexBackedClassDef def : dex.getClasses()) {\n            String type = def.getType();\n            System.out.println(type);\n            DexClassNode dexClassNode = map.get(type);\n            Assert.assertNotNull(dexClassNode);\n            String smali = baksmali(def); // original\n\n            Smali.smaliFile2Node(\"fake.smali\", smali);\n\n            {\n                byte[] data = toDex(dexClassNode);\n                DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();\n                String baksmali3 = baksmali(def2); // original\n                Assert.assertEquals(smali, baksmali3);\n            }\n\n            String psmali = pbaksmali(dexClassNode);\n            DexClassNode dexClassNode2 = Smali.smaliFile2Node(\"fake.smali\", psmali);\n            Assert.assertEquals(\"cmp smalip\", psmali, pbaksmali(dexClassNode2));\n\n            {\n                byte[] data = toDex(dexClassNode2);\n                DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();\n                String baksmali3 = baksmali(def2); // original\n                Assert.assertEquals(smali, baksmali3);\n            }\n        }\n    }\n\n    private byte[] toDex(DexClassNode dexClassNode2) {\n        DexFileWriter w = new DexFileWriter();\n        dexClassNode2.accept(w);\n        w.visitEnd();\n        return w.toByteArray();\n    }\n\n    private static String pbaksmali(DexClassNode dcn) throws IOException {\n        StringWriter bufWriter = new StringWriter();\n        BufferedWriter w = new BufferedWriter(bufWriter);\n        new BaksmaliDumper(true, true).baksmaliClass(dcn, new BaksmaliDumpOut(w));\n        w.flush();\n        bufWriter.flush();\n        return bufWriter.toString();\n    }\n\n    private static String baksmali(DexBackedClassDef def) throws IOException {\n        baksmaliOptions opts = new baksmaliOptions();\n        opts.outputDebugInfo = false;\n        opts.syntheticAccessorResolver = new SyntheticAccessorResolver(Collections.EMPTY_LIST);\n        ClassDefinition classDefinition = new ClassDefinition(opts, def);\n        StringWriter bufWriter = new StringWriter();\n        IndentingWriter writer = new IndentingWriter(bufWriter);\n        classDefinition.writeTo((IndentingWriter) writer);\n        writer.flush();\n        return bufWriter.toString();\n    }\n}\n"
  },
  {
    "path": "d2j-smali/src/test/resources/a.smali",
    "content": ".class public La;\n.super Ljava/lang/Object;\n.implements Lj; .implements Lq; \n.source \"aaa\"\n.source \"aa\\u1234a\"\n\n.field private a:Ljava/lang/String; = NAN\n.field private a:Ljava/lang/String; = NANf\n.field private a:Ljava/lang/String; = NANd\n.field private a:Ljava/lang/String; = nan\n.field private a:Ljava/lang/String; = -infinityF\n.field private a:Ljava/lang/String; = +infinityF\n.field private a:Ljava/lang/String; = -infinityD\n.field private a:Ljava/lang/String; = +infinityD\n.field private a:Ljava/lang/String; = -infinity\n.field private a:Ljava/lang/String; = +infinity\n.field private a:Ljava/lang/String; = nan\n.field private a:Ljava/lang/String; = nanf\n.field private a:Ljava/lang/String; = nand\n.field private a:Ljava/lang/String; = 0.2\n.field private a:Ljava/lang/String; = 0.2f\n.field private a:Ljava/lang/String; = 0x1\n.field private a:Ljava/lang/String; = +0x1\n.field private a:Ljava/lang/String; = -0x1\n.field private a:Ljava/lang/String; = 0\n.field private a:Ljava/lang/String; = 001\n.field private a:Ljava/lang/String; = 123\n.field private a:Ljava/lang/String; = 123t\n.field private a:Ljava/lang/String; = 123s\n.field private a:Ljava/lang/String; = 123f\n.field private a:Ljava/lang/String; = 123d\n.field private a:Ljava/lang/String; = .enum La;->d:I\n.field private a:Ljava/lang/String; = 't'\n.field private a:Ljava/lang/String; = '\\t'\n.field private a:Ljava/lang/String; = '\\u1234'\n.field private a:Ljava/lang/String; = true\n.field private a:Ljava/lang/String; = 0x7fffffff\n.annotation system La;\n.end annotation\n.end field\n.method public I(II)V\n.parameter \"AAAA\"\n.annotation system La;\n.end annotation\n.end parameter\n.parameter\n.registers 4\n.local v2, a : I\n.local v2, a:I\n.local v2, \"a\":I\n.end local v2\n.restart local v2\n.end method\n.method private Lggg;->static([Z)V\n.end method\n.method private static([Z)V\n.end method\n.method private Lg>gg;->static([Z)V\n.end method"
  },
  {
    "path": "dex-ir/build.gradle",
    "content": "description = 'Dex Translator'\n\ndependencies {\n  compile project(':dex-reader-api')\n}\n\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ET.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\n\r\n/**\r\n * The number of argument\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n * @see Stmt\r\n * @see Value\r\n */\r\npublic enum ET {\r\n\r\n    /**\r\n     * no argument\r\n     */\r\n    E0,\r\n    /**\r\n     * 1 argument\r\n     */\r\n    E1,\r\n    /**\r\n     * 2 argument\r\n     */\r\n    E2,\r\n    /**\r\n     * 3+ argument\r\n     */\r\n    En\r\n}"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/IrMethod.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\r\n\r\n/**\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class IrMethod {\r\n\r\n    public boolean isStatic;\r\n    public String[] args;\r\n    public List<Local> locals = new ArrayList<Local>();\r\n    public String name;\r\n\r\n    public String owner;\r\n\r\n    public String ret;\r\n\r\n    public StmtList stmts = new StmtList();\r\n\r\n    public List<Trap> traps = new ArrayList<Trap>();\r\n    public List<LocalVar> vars = new ArrayList<LocalVar>();\r\n    public List<LabelStmt> phiLabels;\r\n\r\n    public IrMethod clone() {\r\n        IrMethod n = new IrMethod();\r\n        LabelAndLocalMapper mapper = new LabelAndLocalMapper();\r\n        n.name = name;\r\n        n.args = args;\r\n        n.isStatic = isStatic;\r\n        n.owner = owner;\r\n        n.ret = ret;\r\n        n.stmts = stmts.clone(mapper);\r\n        for (Trap trap : traps) {\r\n            n.traps.add(trap.clone(mapper));\r\n        }\r\n        for (LocalVar var : vars) {\r\n            n.vars.add(var.clone(mapper));\r\n        }\r\n        if (phiLabels != null) {\r\n            List<LabelStmt> nPhiLabels = new ArrayList<>(phiLabels.size());\r\n            for (LabelStmt labelStmt : phiLabels) {\r\n                nPhiLabels.add(labelStmt.clone(mapper));\r\n            }\r\n            n.phiLabels = nPhiLabels;\r\n        }\r\n        for(Local local:locals){\r\n            n.locals.add((Local) local.clone(mapper));\r\n        }\r\n        return n;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(\"// \").append(this.owner).append(\"\\n\");\r\n        if (isStatic) {\r\n            sb.append(\" static \");\r\n        }\r\n        sb.append(ret == null ? null : Util.toShortClassName(ret)).append(' ').append(this.name).append('(');\r\n        if (args != null) {\r\n            boolean first = true;\r\n            for (String arg : args) {\r\n                if (first) {\r\n                    first = false;\r\n                } else {\r\n                    sb.append(',');\r\n                }\r\n                sb.append(Util.toShortClassName(arg));\r\n            }\r\n        }\r\n        sb.append(\") {\\n\\n\").append(stmts).append(\"\\n\");\r\n        if (traps.size() > 0 || vars.size() > 0) {\r\n            sb.append(\"=============\\n\");\r\n            for (Trap trap : traps) {\r\n                sb.append(trap).append('\\n');\r\n            }\r\n            for (LocalVar var : vars) {\r\n                sb.append(var).append('\\n');\r\n            }\r\n        }\r\n        sb.append(\"}\");\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/LabelAndLocalMapper.java",
    "content": "package com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\npublic class LabelAndLocalMapper {\r\n    Map<LabelStmt, LabelStmt> labels = new HashMap<>();\r\n    Map<Local, Local> locals = new HashMap<>();\r\n\r\n    public LabelStmt map(LabelStmt label) {\r\n        LabelStmt nTarget = labels.get(label);\r\n        if (nTarget == null) {\r\n            nTarget = Stmts.nLabel();\r\n            labels.put(label, nTarget);\r\n        }\r\n        return nTarget;\r\n    }\r\n\r\n    public Local map(Local local) {\r\n        Local nTarget = locals.get(local);\r\n        if (nTarget == null) {\r\n            nTarget = (Local) local.clone();\r\n            locals.put(local, nTarget);\r\n        }\r\n        return nTarget;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/LocalVar.java",
    "content": "package com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\n\r\npublic class LocalVar {\r\n\r\n    public LabelStmt start, end;\r\n    public String name, type, signature;\r\n    public Local reg;\r\n\r\n    public LocalVar(String name, String type, String signature, LabelStmt start, LabelStmt end, Local reg) {\r\n        this.name = name;\r\n        this.start = start;\r\n        this.end = end;\r\n        this.type = type;\r\n        this.signature = signature;\r\n        this.reg = reg;\r\n    }\r\n\r\n    public LocalVar clone(LabelAndLocalMapper map) {\r\n        return new LocalVar(name, type, signature, start.clone(map), end.clone(map), (Local) reg.clone());\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return String.format(\".var %s ~ %s %s -> %s //%s\", start.getDisplayName(), end.getDisplayName(), reg, name,\r\n                type);\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/StmtSearcher.java",
    "content": "package com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\r\n\r\npublic class StmtSearcher {\r\n    public void travel(StmtList stmts) {\r\n        for (Stmt stmt : stmts) {\r\n            travel(stmt);\r\n        }\r\n    }\r\n\r\n    public void travel(Stmt stmt) {\r\n        switch (stmt.et) {\r\n            case E0:\r\n                break;\r\n            case E1:\r\n               travel(stmt.getOp());\r\n                break;\r\n            case E2:\r\n                travel(stmt.getOp1());\r\n                travel(stmt.getOp2());\r\n                break;\r\n            case En:\r\n                Value[] ops = stmt.getOps();\r\n                for (Value op : ops) {\r\n                    travel(op);\r\n                }\r\n                break;\r\n        }\r\n    }\r\n\r\n    public void travel(Value op) {\r\n        switch (op.et) {\r\n            case E0:\r\n                break;\r\n            case E1:\r\n                travel(op.getOp());\r\n                break;\r\n            case E2:\r\n                travel(op.getOp1());\r\n                travel(op.getOp2());\r\n                break;\r\n            case En:\r\n                Value[] ops = op.getOps();\r\n                for (Value op1 : ops) {\r\n                    travel(op1);\r\n                }\r\n                break;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/StmtTraveler.java",
    "content": "package com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\r\n\r\nimport java.util.Iterator;\r\n\r\npublic class StmtTraveler {\r\n    public void travel(IrMethod method) {\r\n        travel(method.stmts);\r\n    }\r\n    public void travel(StmtList stmts) {\r\n        for (Iterator<Stmt> it = stmts.iterator(); it.hasNext(); ) {\r\n            Stmt stmt = it.next();\r\n            Stmt n = travel(stmt);\r\n            if (n != stmt) {\r\n                stmts.insertBefore(stmt, n);\r\n                it.remove();\r\n            }\r\n        }\r\n    }\r\n\r\n    public Stmt travel(Stmt stmt) {\r\n        switch (stmt.et) {\r\n            case E0:\r\n                break;\r\n            case E1:\r\n                stmt.setOp(travel(stmt.getOp()));\r\n                break;\r\n            case E2:\r\n                stmt.setOp1(travel(stmt.getOp1()));\r\n                stmt.setOp2(travel(stmt.getOp2()));\r\n                break;\r\n            case En:\r\n                Value[] ops = stmt.getOps();\r\n                for (int i = 0; i < ops.length; i++) {\r\n                    ops[i] = travel(ops[i]);\r\n                }\r\n                break;\r\n        }\r\n        return stmt;\r\n    }\r\n\r\n    public Value travel(Value op) {\r\n        switch (op.et) {\r\n            case E0:\r\n                break;\r\n            case E1:\r\n                op.setOp(travel(op.getOp()));\r\n                break;\r\n            case E2:\r\n                op.setOp1(travel(op.getOp1()));\r\n                op.setOp2(travel(op.getOp2()));\r\n                break;\r\n            case En:\r\n                Value[] ops = op.getOps();\r\n                for (int i = 0; i < ops.length; i++) {\r\n                    ops[i] = travel(ops[i]);\r\n                }\r\n                break;\r\n        }\r\n\r\n        return op;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/TransformerException.java",
    "content": "package com.googlecode.dex2jar.ir;\n\npublic class TransformerException extends RuntimeException {\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    public TransformerException() {\n        super();\n    }\n\n    public TransformerException(String arg0, Throwable arg1) {\n        super(arg0, arg1);\n    }\n\n    public TransformerException(String arg0) {\n        super(arg0);\n    }\n\n    public TransformerException(Throwable arg0) {\n        super(arg0);\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/Trap.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir;\r\n\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\n\r\n/**\r\n * TODO DOC\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Trap {\r\n    public LabelStmt start, end, handlers[];\r\n    public String types[];\r\n\r\n    public Trap() {\r\n        super();\r\n    }\r\n\r\n    public Trap(LabelStmt start, LabelStmt end, LabelStmt handlers[], String types[]) {\r\n        super();\r\n        this.start = start;\r\n        this.end = end;\r\n        this.handlers = handlers;\r\n        this.types = types;\r\n    }\r\n\r\n    public Trap clone(LabelAndLocalMapper mapper) {\r\n        int size = handlers.length;\r\n        LabelStmt[] cloneHandlers = new LabelStmt[size];\r\n        String[] cloneTypes = new String[size];\r\n        for (int i = 0; i < size; i++) {\r\n            cloneHandlers[i] = handlers[i].clone(mapper);\r\n            cloneTypes[i] = types[i];\r\n        }\r\n        return new Trap(start.clone(mapper), end.clone(mapper), cloneHandlers, cloneTypes);\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        StringBuilder sb = new StringBuilder(String.format(\".catch %s - %s : \", start.getDisplayName(),\r\n                end.getDisplayName()));\r\n        for (int i = 0; i < handlers.length; i++) {\r\n            sb.append(types[i] == null ? \"all\" : types[i]).append(\" > \").append(handlers[i].getDisplayName())\r\n                    .append(\",\");\r\n        }\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/TypeClass.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir;\n\npublic enum TypeClass {\n\n    BOOLEAN(\"Z\", true), //\n    INT(\"I\", true), //\n    FLOAT(\"F\", true), //\n    DOUBLE(\"D\", true), //\n    LONG(\"J\", true), //\n    OBJECT(\"L\", true), //\n    VOID(\"V\", true), //\n    UNKNOWN(\"?\"), //\n    ZIL(\"s\"), //\n    ZIFL(\"z\"), //\n    ZIF(\"m\"), //\n    ZI(\"n\"), //\n    IF(\"i\"), //\n    JD(\"w\"); //\n\n    public String name;\n    public boolean fixed;\n\n    TypeClass(String use, boolean fixed) {\n        this.name = use;\n        this.fixed = fixed;\n    }\n\n    TypeClass(String use) {\n        this.name = use;\n        this.fixed = false;\n    }\n\n    public static TypeClass clzOf(String desc) {\n        switch (desc.charAt(0)) {\n        case 'Z':\n            return BOOLEAN;\n        case 'B':\n        case 'C':\n        case 'S':\n        case 'I':\n            return INT;\n        case 'F':\n            return FLOAT;\n        case 'D':\n            return DOUBLE;\n        case 'J':\n            return LONG;\n        case 'L':\n        case '[':\n            return OBJECT;\n        case 'V':\n            return VOID;\n        case 'z':\n            return ZIFL;\n        case 's':\n            return ZIL;\n        case 'i':\n            return IF;\n        case 'm':\n            return ZIF;\n        case 'n':\n            return ZI;\n        case 'w':\n            return JD;\n        default:\n            return UNKNOWN;\n        }\n    }\n\n    public static TypeClass merge(TypeClass thizCls, TypeClass clz) {\n        if (thizCls == clz) {\n            return thizCls;\n        }\n        if (thizCls == TypeClass.UNKNOWN) {\n            return clz;\n        } else if (clz == TypeClass.UNKNOWN) {\n            // do nothing\n            return thizCls;\n        } else {\n            if (thizCls.fixed) {\n                if (clz.fixed) {\n                    // special case for merge I and Z\n                    // https://bitbucket.org/pxb1988/dex2jar/issues/1/javalangruntimeexception-can-not-merge-i\n                    // http://sourceforge.net/p/dex2jar/tickets/237/\n                    if ((thizCls == INT && clz == BOOLEAN) || (thizCls == BOOLEAN || clz == INT)) {\n                        return INT;\n                    }\n                    throw new RuntimeException(\"can not merge \" + thizCls + \" and \" + clz);\n                } else {\n                    return thizCls;\n                }\n            } else if (clz.fixed) {\n                return clz;\n            } else { // both not fixed\n                return merge0(thizCls, clz);\n            }\n        }\n    }\n\n    /**\n     * X     ZIL   ZIFL ZIF  ZI  IF\n     * ZIL   X     ZIL  ZI   ZI  I\n     * ZIFL  ZIL   X    ZIF  ZI  IF\n     * ZIF   ZI    ZIF  X    ZI  IF\n     * ZI    ZI    ZI   ZI   X   I\n     * IF    I     IF   IF   I   X\n     */\n    private static TypeClass merge0(TypeClass a, TypeClass b) {\n        if (a == JD || b == JD) {\n            throw new RuntimeException(\"can not merge \" + a + \" and \" + b);\n        }\n        switch (a) {\n            case ZIL:\n                switch (b) {\n                    case ZIFL:\n                        return ZIL;\n                    case IF:\n                        return INT;\n                    case ZIF:\n                    case ZI:\n                        return ZI;\n                    default:\n                }\n            case ZIFL:\n                return b;\n            case IF:\n                switch (b) {\n                    case ZIL:\n                    case ZI:\n                        return INT;\n                    case ZIFL:\n                    case ZIF:\n                        return IF;\n                    default:\n                }\n            case ZIF:\n                switch (b) {\n                    case IF:\n                        return IF;\n                    case ZIL:\n                    case ZI:\n                        return ZI;\n                    case ZIFL:\n                        return ZIF;\n                    default:\n                }\n            case ZI:\n                if (b == TypeClass.IF) {\n                    return INT;\n                } else {\n                    return ZI;\n                }\n            default:\n        }\n        throw new RuntimeException();\n    }\n\n    public String toString() {\n        return name;\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/Util.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Util {\r\n    public static List<String> listDesc(String desc) {\r\n        List<String> list = new ArrayList<String>(5);\r\n        char[] chars = desc.toCharArray();\r\n        int i = 0;\r\n        while (i < chars.length) {\r\n            switch (chars[i]) {\r\n            case 'V':\r\n            case 'Z':\r\n            case 'C':\r\n            case 'B':\r\n            case 'S':\r\n            case 'I':\r\n            case 'F':\r\n            case 'J':\r\n            case 'D':\r\n                list.add(Character.toString(chars[i]));\r\n                i++;\r\n                break;\r\n            case '[': {\r\n                int count = 1;\r\n                while (chars[i + count] == '[') {\r\n                    count++;\r\n                }\r\n                if (chars[i + count] == 'L') {\r\n                    count++;\r\n                    while (chars[i + count] != ';') {\r\n                        count++;\r\n                    }\r\n                }\r\n                count++;\r\n                list.add(new String(chars, i, count));\r\n                i += count + 1;\r\n                break;\r\n            }\r\n            case 'L': {\r\n                int count = 1;\r\n                while (chars[i + count] != ';') {\r\n                    ++count;\r\n                }\r\n                count++;\r\n                list.add(new String(chars, i, count));\r\n                i += count + 1;\r\n                break;\r\n            }\r\n            default:\r\n            }\r\n        }\r\n        return list;\r\n    }\r\n\r\n    /**\r\n     * Appends a quoted string to a given buffer.\r\n     * \r\n     * @param buf\r\n     *            the buffer where the string must be added.\r\n     * @param s\r\n     *            the string to be added.\r\n     */\r\n    public static void appendString(final StringBuffer buf, final String s) {\r\n        buf.append('\\\"');\r\n        for (int i = 0; i < s.length(); ++i) {\r\n            char c = s.charAt(i);\r\n            if (c == '\\n') {\r\n                buf.append(\"\\\\n\");\r\n            } else if (c == '\\r') {\r\n                buf.append(\"\\\\r\");\r\n            } else if (c == '\\\\') {\r\n                buf.append(\"\\\\\\\\\");\r\n            } else if (c == '\"') {\r\n                buf.append(\"\\\\\\\"\");\r\n            } else if (c < 0x20 || c > 0x7f) {\r\n                buf.append(\"\\\\u\");\r\n                if (c < 0x10) {\r\n                    buf.append(\"000\");\r\n                } else if (c < 0x100) {\r\n                    buf.append(\"00\");\r\n                } else if (c < 0x1000) {\r\n                    buf.append('0');\r\n                }\r\n                buf.append(Integer.toString(c, 16));\r\n            } else {\r\n                buf.append(c);\r\n            }\r\n        }\r\n        buf.append('\\\"');\r\n    }\r\n\r\n    public static String toShortClassName(String desc) {\r\n        switch (desc.charAt(0)) {\r\n        case 'Z':\r\n            return \"boolean\";\r\n        case 'B':\r\n            return \"byte\";\r\n        case 'C':\r\n            return \"char\";\r\n        case 'S':\r\n            return \"short\";\r\n        case 'I':\r\n            return \"int\";\r\n        case 'J':\r\n            return \"long\";\r\n        case 'F':\r\n            return \"float\";\r\n        case 'D':\r\n            return \"double\";\r\n        case 'V':\r\n            return \"void\";\r\n        case 'L': {\r\n            int i = desc.lastIndexOf('/');\r\n            return desc.substring(i < 0 ? 1 : i + 1, desc.length() - 1);\r\n        }\r\n        case '[':\r\n            int d = 1;\r\n            for (; d < desc.length(); d++) {\r\n                if (desc.charAt(d) != '[') {\r\n                    break;\r\n                }\r\n            }\r\n            StringBuilder sb = new StringBuilder().append(toShortClassName(desc.substring(d)));\r\n            for (int t = 0; t < d; t++) {\r\n                sb.append(\"[]\");\r\n            }\r\n            return sb.toString();\r\n        }\r\n        throw new UnsupportedOperationException();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/AbstractInvokeExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2017 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\n\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\r\n\r\npublic abstract class AbstractInvokeExpr extends EnExpr {\r\n    @Override\r\n    protected void releaseMemory() {\r\n        super.releaseMemory();\r\n    }\r\n\r\n    public abstract Proto getProto();\r\n\r\n    public AbstractInvokeExpr(VT type, Value[] args) {\r\n        super(type, args);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/ArrayExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E2Expr;\r\n\r\n/**\r\n * Represent an Array expression\r\n * \r\n * @see VT#ARRAY\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class ArrayExpr extends E2Expr {\r\n\r\n    public ArrayExpr() {\r\n        super(VT.ARRAY, null, null);\r\n    }\r\n\r\n    public String elementType;\r\n\r\n    public ArrayExpr(Value base, Value index, String elementType) {\r\n        super(VT.ARRAY, base, index);\r\n        this.elementType = elementType;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new ArrayExpr(op1.trim().clone(), op2.trim().clone(), this.elementType);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new ArrayExpr(op1.clone(mapper), op2.clone(mapper), this.elementType);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        return op1 + \"[\" + op2 + \"]\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/BinopExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E2Expr;\r\n\r\n/**\r\n * Represent a Binop expression, value = op1 vt op2\r\n * \r\n * @see VT#ADD\r\n * @see VT#AND\r\n * @see VT#LCMP\r\n * @see VT#FCMPG\r\n * @see VT#DCMPG\r\n * @see VT#FCMPL\r\n * @see VT#DCMPL\r\n * @see VT#DIV\r\n * @see VT#EQ\r\n * @see VT#GE\r\n * @see VT#GT\r\n * @see VT#LE\r\n * @see VT#LT\r\n * @see VT#MUL\r\n * @see VT#NE\r\n * @see VT#OR\r\n * @see VT#REM\r\n * @see VT#SHL\r\n * @see VT#SHR\r\n * @see VT#SUB\r\n * @see VT#USHR\r\n * @see VT#XOR\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class BinopExpr extends E2Expr {\r\n    public String type;\r\n\r\n    public BinopExpr(VT vt, Value op1, Value op2, String type) {\r\n        super(vt, op1, op2);\r\n        this.type = type;\r\n    }\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new BinopExpr(vt, op1.trim().clone(), op2.trim().clone(), type);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new BinopExpr(vt, op1.clone(mapper), op2.clone(mapper), type);\r\n    }\r\n    @Override\r\n    public String toString0() {\r\n        return \"(\" + op1 + \" \" + super.vt + \" \" + op2 + \")\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/CastExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\r\n\r\n/**\r\n * * @see VT#CAST\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class CastExpr extends E1Expr {\r\n    public String from;\r\n    public String to;\r\n\r\n    public CastExpr(Value value, String from, String to) {\r\n        super(VT.CAST, value);\r\n        this.from = from;\r\n        this.to = to;\r\n    }\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        from = to = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new CastExpr(op.trim().clone(), from, to);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new CastExpr(op.clone(mapper), from, to);\r\n    }\r\n    @Override\r\n    public String toString0() {\r\n        return \"((\" + Util.toShortClassName(to) + \")\" + op + \")\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/Constant.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.d2j.DexType;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E0Expr;\r\n\r\nimport java.lang.reflect.Array;\r\n\r\n/**\r\n * Represent a constant, number/string/type\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Constant extends E0Expr {\r\n\r\n    public static final Object Null = new Object();\r\n\r\n    public Object value;\r\n\r\n    public Constant(Object value) {\r\n        super(VT.CONSTANT);\r\n        this.value = value;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new Constant(value);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new Constant(value);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        if (Null == value) {\r\n            return \"null\";\r\n        } else if (value == null) {\r\n            return \"NULL\";\r\n        } else if (value instanceof Number) {\r\n            if (value instanceof Float) {\r\n                return value.toString() + \"F\";\r\n            }\r\n            if (value instanceof Long) {\r\n                return value.toString() + \"L\";\r\n            }\r\n            return value.toString();\r\n        } else if (value instanceof String) {\r\n            StringBuffer buf = new StringBuffer();\r\n            Util.appendString(buf, (String) value);\r\n            return buf.toString();\r\n        } else if (value instanceof DexType) {\r\n            return Util.toShortClassName(((DexType) value).desc) + \".class\";\r\n        } else if (value.getClass().isArray()) {\r\n            StringBuilder sb = new StringBuilder();\r\n            sb.append(\"[\");\r\n            int size = Array.getLength(value);\r\n            for (int i = 0; i < size; i++) {\r\n                sb.append(Array.get(value, i)).append(\",\");\r\n            }\r\n            if (size > 0) {\r\n                sb.setLength(sb.length() - 1);\r\n            }\r\n            sb.append(\"]\");\r\n            return sb.toString();\r\n        }\r\n        return \"\" + value;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/Exprs.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.d2j.DexType;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.MethodHandle;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\r\n\r\npublic final class Exprs {\r\n    public static Value[] copy(Value[] v) {\r\n        if (v == null) {\r\n            return new Value[0];\r\n        }\r\n        Value vb[] = new Value[v.length];\r\n        for (int i = 0; i < v.length; i++) {\r\n            vb[i] = v[i].trim();\r\n        }\r\n        return vb;\r\n    }\r\n\r\n    public static Constant nByte(byte i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nChar(char i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nType(String desc) {\r\n        return new Constant(new DexType(desc));\r\n    }\r\n    public static Constant nType(DexType t) {\r\n        return new Constant(t);\r\n    }\r\n\r\n    public static Constant nDouble(double i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nFloat(float i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nInt(int i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nLong(long i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nNull() {\r\n        return new Constant(Constant.Null);\r\n    }\r\n\r\n    public static Constant nShort(short i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static Constant nString(String i) {\r\n        return new Constant(i);\r\n    }\r\n\r\n    public static BinopExpr nAdd(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.ADD, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr niAdd(Value a, Value b) {\r\n        return new BinopExpr(VT.ADD, a, b, \"I\");\r\n    }\r\n\r\n    public static BinopExpr nAnd(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.AND, a, b, type);\r\n    }\r\n\r\n    public static ArrayExpr nArray(Value base, Value index, String elementType) {\r\n        return new ArrayExpr(base, index, elementType);\r\n    }\r\n\r\n    public static Constant nArrayValue(Object array) {\r\n        return new Constant(array);\r\n    }\r\n\r\n    public static CastExpr nCast(Value obj, String from, String to) {\r\n        return new CastExpr(obj, from, to);\r\n    }\r\n\r\n    public static TypeExpr nCheckCast(Value obj, String type) {\r\n        return new TypeExpr(VT.CHECK_CAST, obj, type);\r\n    }\r\n\r\n    public static BinopExpr nDCmpg(Value a, Value b) {\r\n        return new BinopExpr(VT.DCMPG, a, b, \"D\");\r\n    }\r\n\r\n    public static BinopExpr nDCmpl(Value a, Value b) {\r\n        return new BinopExpr(VT.DCMPL, a, b, \"D\");\r\n    }\r\n\r\n    public static BinopExpr nDiv(Value a, Value b, String type) {\r\n        switch (type){\r\n            case \"I\":\r\n                return new BinopExpr(VT.IDIV, a, b, type);\r\n            case \"J\":\r\n                return new BinopExpr(VT.LDIV, a, b, type);\r\n            case \"F\":\r\n                return new BinopExpr(VT.FDIV, a, b, type);\r\n            case \"D\":\r\n                return new BinopExpr(VT.DDIV, a, b, type);\r\n            default:\r\n                throw new RuntimeException(\"type must set to one of I/J/F/D\");\r\n        }\r\n    }\r\n\r\n    public static BinopExpr nEq(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.EQ, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr niEq(Value a, Value b) {\r\n        return nEq(a, b, \"I\");\r\n    }\r\n\r\n    public static RefExpr nExceptionRef(String type) {\r\n        return new RefExpr(VT.EXCEPTION_REF, type, -1);\r\n    }\r\n\r\n    public static BinopExpr nFCmpg(Value a, Value b) {\r\n        return new BinopExpr(VT.FCMPG, a, b, \"F\");\r\n    }\r\n\r\n    public static BinopExpr nFCmpl(Value a, Value b) {\r\n        return new BinopExpr(VT.FCMPL, a, b, \"F\");\r\n    }\r\n\r\n    public static FieldExpr nField(Value object, String ownerType, String fieldName, String fieldType) {\r\n        return new FieldExpr(object, ownerType, fieldName, fieldType);\r\n    }\r\n\r\n    public static BinopExpr nGe(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.GE, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nGt(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.GT, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr njGt(Value a, Value b) {\r\n        return new BinopExpr(VT.GT, a, b, \"J\");\r\n    }\r\n\r\n    public static BinopExpr niGt(Value a, Value b) {\r\n        return new BinopExpr(VT.GT, a, b, \"I\");\r\n    }\r\n\r\n    public static TypeExpr nInstanceOf(Value value, String type) {\r\n        return new TypeExpr(VT.INSTANCE_OF, value, type);\r\n    }\r\n\r\n    public static InvokeExpr nInvokeInterface(Value[] regs, String owner, String name, String[] argmentTypes,\r\n            String returnType) {\r\n        return new InvokeExpr(VT.INVOKE_INTERFACE, regs, owner, name, argmentTypes, returnType);\r\n    }\r\n\r\n    public static InvokeExpr nInvokeNew(Value[] regs, String[] argmentTypes, String owner) {\r\n        return new InvokeExpr(VT.INVOKE_NEW, regs, owner, \"<init>\", argmentTypes, owner);\r\n    }\r\n\r\n    public static InvokeExpr nInvokeSpecial(Value[] regs, String owner, String name, String[] argmentTypes,\r\n            String returnType) {\r\n        return new InvokeExpr(VT.INVOKE_SPECIAL, regs, owner, name, argmentTypes, returnType);\r\n    }\r\n\r\n    public static InvokeExpr nInvokeStatic(Value[] regs, String owner, String name, String[] argmentTypes,\r\n            String returnType) {\r\n        return new InvokeExpr(VT.INVOKE_STATIC, regs, owner, name, argmentTypes, returnType);\r\n    }\r\n\r\n    public static InvokeExpr nInvokeVirtual(Value[] regs, String owner, String name, String[] argmentTypes,\r\n            String returnType) {\r\n        return new InvokeExpr(VT.INVOKE_VIRTUAL, regs, owner, name, argmentTypes, returnType);\r\n    }\r\n\r\n    public static InvokeCustomExpr nInvokeCustom(Value[] regs, String name, Proto proto, MethodHandle handle, Object[] bsmArgs) {\r\n        return new InvokeCustomExpr(VT.INVOKE_CUSTOM, regs , name, proto, handle,  bsmArgs);\r\n    }\r\n\r\n    public static InvokePolymorphicExpr nInvokePolymorphic(Value[] regs, Proto proto, Method method) {\r\n        return new InvokePolymorphicExpr(VT.INVOKE_POLYMORPHIC, regs , proto, method);\r\n    }\r\n\r\n    public static BinopExpr nLCmp(Value a, Value b) {\r\n        return new BinopExpr(VT.LCMP, a, b, \"J\");\r\n    }\r\n\r\n    public static BinopExpr nLe(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.LE, a, b, type);\r\n    }\r\n\r\n    public static UnopExpr nLength(Value array) {\r\n        return new UnopExpr(VT.LENGTH, array, null);\r\n    }\r\n\r\n    public static Local nLocal(int index) {\r\n        return new Local(index);\r\n    }\r\n\r\n    public static Local nLocal(String debugName) {\r\n        return new Local(debugName);\r\n    }\r\n\r\n    public static Local nLocal(int index, String debugName) {\r\n        return new Local(index, debugName);\r\n    }\r\n\r\n    public static BinopExpr nLt(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.LT, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nMul(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.MUL, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nNe(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.NE, a, b, type);\r\n    }\r\n\r\n    public static UnopExpr nNeg(Value array, String type) {\r\n        return new UnopExpr(VT.NEG, array, type);\r\n    }\r\n\r\n    public static NewExpr nNew(String type) {\r\n        return new NewExpr(type);\r\n    }\r\n\r\n    public static TypeExpr nNewArray(String elementType, Value size) {\r\n        return new TypeExpr(VT.NEW_ARRAY, size, elementType);\r\n    }\r\n\r\n    public static TypeExpr nNewIntArray(Value size) {\r\n        return nNewArray(\"I\", size);\r\n    }\r\n\r\n    public static TypeExpr nNewLongArray(Value size) {\r\n        return nNewArray(\"J\", size);\r\n    }\r\n\r\n    public static FilledArrayExpr nFilledArray(String elementType, Value[] datas) {\r\n        return new FilledArrayExpr(datas, elementType);\r\n    }\r\n\r\n    public static NewMutiArrayExpr nNewMutiArray(String base, int dim, Value[] sizes) {\r\n        return new NewMutiArrayExpr(base, dim, sizes);\r\n    }\r\n\r\n    public static UnopExpr nNot(Value array, String type) {\r\n        return new UnopExpr(VT.NOT, array, type);\r\n    }\r\n\r\n    public static BinopExpr nOr(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.OR, a, b, type);\r\n    }\r\n\r\n    public static RefExpr nParameterRef(String type, int index) {\r\n        return new RefExpr(VT.PARAMETER_REF, type, index);\r\n    }\r\n\r\n    public static BinopExpr nRem(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.REM, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nShl(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.SHL, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nShr(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.SHR, a, b, type);\r\n    }\r\n\r\n    public static StaticFieldExpr nStaticField(String ownerType, String fieldName, String fieldType) {\r\n        return new StaticFieldExpr(ownerType, fieldName, fieldType);\r\n    }\r\n\r\n    public static BinopExpr nSub(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.SUB, a, b, type);\r\n    }\r\n\r\n    public static RefExpr nThisRef(String type) {\r\n        return new RefExpr(VT.THIS_REF, type, -1);\r\n    }\r\n\r\n    public static BinopExpr nUshr(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.USHR, a, b, type);\r\n    }\r\n\r\n    public static BinopExpr nXor(Value a, Value b, String type) {\r\n        return new BinopExpr(VT.XOR, a, b, type);\r\n    }\r\n\r\n    private Exprs() {\r\n    }\r\n\r\n    public static PhiExpr nPhi(Value... ops) {\r\n        return new PhiExpr(ops);\r\n    }\r\n\r\n    public static Constant nConstant(Object cst) {\r\n        return new Constant(cst);\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/FieldExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\r\n\r\n/**\r\n * Represent a non-static Field expression.\r\n * \r\n * @see VT#FIELD\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n */\r\npublic class FieldExpr extends E1Expr {\r\n\r\n    /**\r\n     * Field name\r\n     */\r\n    public String name;\r\n    /**\r\n     * Field owner type descriptor\r\n     */\r\n    public String owner;\r\n    /**\r\n     * Field type descriptor\r\n     */\r\n    public String type;\r\n\r\n    public FieldExpr(Value object, String ownerType, String fieldName, String fieldType) {\r\n        super(VT.FIELD, object);\r\n        this.type = fieldType;\r\n        this.name = fieldName;\r\n        this.owner = ownerType;\r\n    }\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        name = null;\r\n        owner = type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new FieldExpr(op.trim().clone(), owner, name, type);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new FieldExpr(op.clone(mapper), owner, name, type);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        return op + \".\" + name;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/FilledArrayExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\r\n\r\n/**\r\n * Represent a FILLED_ARRAY expression.\r\n *\r\n * @see VT#FILLED_ARRAY\r\n */\r\npublic class FilledArrayExpr extends EnExpr {\r\n\r\n    public String type;\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n    public FilledArrayExpr(Value[] datas, String type) {\r\n        super(VT.FILLED_ARRAY, datas);\r\n        this.type = type;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new FilledArrayExpr(cloneOps(), type);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new FilledArrayExpr(cloneOps(mapper), type);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        StringBuilder sb = new StringBuilder().append(\"new \").append(Util.toShortClassName(type)).append(\"[]{\");\r\n        for (int i = 0; i < ops.length; i++) {\r\n            sb.append(ops[i]).append(\", \");\r\n        }\r\n        if (ops.length > 0) {\r\n            sb.setLength(sb.length() - 2); // remove tail \", \"\r\n        }\r\n        sb.append('}');\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/InvokeCustomExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2017 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.d2j.MethodHandle;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\n\r\npublic class InvokeCustomExpr extends AbstractInvokeExpr {\r\n    public String name;\r\n    public Proto proto;\r\n    public MethodHandle handle;\r\n    public Object[] bsmArgs;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        name = null;\r\n        proto = null;\r\n        handle = null;\r\n        bsmArgs = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Proto getProto() {\r\n        return proto;\r\n    }\r\n\r\n    public InvokeCustomExpr(VT type, Value[] args, String methodName, Proto proto, MethodHandle handle, Object[] bsmArgs) {\r\n        super(type, args);\r\n        this.proto = proto;\r\n        this.name = methodName;\r\n        this.handle = handle;\r\n        this.bsmArgs = bsmArgs;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new InvokeCustomExpr(vt, cloneOps(), name, proto, handle, bsmArgs);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new InvokeCustomExpr(vt, cloneOps(mapper), name, proto, handle, bsmArgs);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        StringBuilder sb = new StringBuilder();\r\n\r\n        sb.append(\"InvokeCustomExpr(....)\");\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/InvokeExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\r\n\r\n/**\r\n * Represent a method invocation expression. To represent a {@link VT#INVOKE_INTERFACE},{@link VT#INVOKE_SPECIAL} or\r\n * {@link VT#INVOKE_VIRTUAL} the first element of ops is the owner object,To represent a {@link VT#INVOKE_NEW} or\r\n * {@link VT#INVOKE_STATIC} all ops are arguments. The return type of {@link VT#INVOKE_NEW} is owner instead of ret\r\n *\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n * @see VT#INVOKE_INTERFACE\r\n * @see VT#INVOKE_NEW\r\n * @see VT#INVOKE_SPECIAL\r\n * @see VT#INVOKE_STATIC\r\n * @see VT#INVOKE_VIRTUAL\r\n */\r\npublic class InvokeExpr extends AbstractInvokeExpr {\r\n\r\n    public Method method;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        method = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Proto getProto() {\r\n        return method.getProto();\r\n    }\r\n\r\n    public InvokeExpr(VT type, Value[] args, String ownerType, String methodName, String[] argmentTypes,\r\n                      String returnType) {\r\n        super(type, args);\r\n        this.method = new Method(ownerType, methodName, argmentTypes, returnType);\r\n    }\r\n\r\n    public InvokeExpr(VT type, Value[] args, Method method) {\r\n        super(type, args);\r\n        this.method = method;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new InvokeExpr(vt, cloneOps(), method);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new InvokeExpr(vt, cloneOps(mapper), method);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        StringBuilder sb = new StringBuilder();\r\n\r\n        int i = 0;\r\n        if (super.vt == VT.INVOKE_NEW) {\r\n            sb.append(\"new \").append(Util.toShortClassName(method.getOwner()));\r\n        } else if (super.vt == VT.INVOKE_STATIC) {\r\n            sb.append(Util.toShortClassName(method.getOwner())).append('.')\r\n                    .append(this.method.getName());\r\n        } else {\r\n            sb.append(ops[i++]).append('.').append(this.method.getName());\r\n        }\r\n        sb.append('(');\r\n        boolean first = true;\r\n        for (; i < ops.length; i++) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(',');\r\n            }\r\n            sb.append(ops[i]);\r\n        }\r\n        sb.append(')');\r\n        return sb.toString();\r\n    }\r\n\r\n    public String getOwner() {\r\n        return method.getOwner();\r\n    }\r\n\r\n    public String getRet() {\r\n        return method.getReturnType();\r\n    }\r\n\r\n    public String getName() {\r\n        return method.getName();\r\n    }\r\n\r\n    public String[] getArgs() {\r\n        return method.getParameterTypes();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/InvokePolymorphicExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2017 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\n\r\npublic class InvokePolymorphicExpr extends AbstractInvokeExpr {\r\n    public Proto proto;\r\n    public Method method;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        method = null;\r\n        proto = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Proto getProto() {\r\n        return proto;\r\n    }\r\n\r\n    public InvokePolymorphicExpr(VT type, Value[] args, Proto proto, Method method) {\r\n        super(type, args);\r\n        this.proto = proto;\r\n        this.method = method;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new InvokePolymorphicExpr(vt, cloneOps(), proto, method);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new InvokePolymorphicExpr(vt, cloneOps(mapper), proto, method);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        StringBuilder sb = new StringBuilder();\r\n        int i = 0;\r\n        sb.append(ops[i++]).append('.').append(this.method.getName());\r\n        String[] argTypes = getProto().getParameterTypes();\r\n        sb.append('(');\r\n        int j = 0;\r\n        boolean first = true;\r\n        for (; i < ops.length; i++) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(',');\r\n            }\r\n            sb.append(\"(\").append(Util.toShortClassName(argTypes[j++])).append(\")\").append(ops[i]);\r\n        }\r\n        sb.append(')');\r\n\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/Local.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E0Expr;\r\n\r\n/**\r\n * TODO DOC\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Local extends E0Expr {\r\n    public int _ls_index;\r\n    public String signature;\r\n    public String debugName;\r\n\r\n    public Local(String debugName) {\r\n        super(Value.VT.LOCAL);\r\n        this.debugName = debugName;\r\n    }\r\n\r\n    public Local(int index, String debugName) {\r\n        super(Value.VT.LOCAL);\r\n        this.debugName = debugName;\r\n        this._ls_index = index;\r\n    }\r\n\r\n    public Local() {\r\n        super(Value.VT.LOCAL);\r\n    }\r\n\r\n    public Local(int index) {\r\n        super(Value.VT.LOCAL);\r\n        this._ls_index = index;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        Local clone = new Local(_ls_index);\r\n        clone.debugName = debugName;\r\n        clone.signature = this.signature;\r\n        clone.valueType = this.valueType;\r\n        return clone;\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return mapper.map(this);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        if (debugName == null) {\r\n            return \"a\" + _ls_index;\r\n        } else {\r\n            return debugName + \"_\" + _ls_index;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/NewExpr.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E0Expr;\r\n\r\n/**\r\n * @author Panxiaobo\r\n */\r\npublic class NewExpr extends E0Expr {\r\n\r\n    public String type;\r\n\r\n    public NewExpr(String type) {\r\n        super(VT.NEW);\r\n        this.type = type;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new NewExpr(type);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new NewExpr(type);\r\n    }\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        return \"NEW \" + Util.toShortClassName(type);\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/NewMutiArrayExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\r\n\r\n/**\r\n * Represent a NEW_MUTI_ARRAY expression.\r\n *\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n * @see VT#NEW_MUTI_ARRAY\r\n */\r\npublic class NewMutiArrayExpr extends EnExpr {\r\n\r\n    /**\r\n     * the basic type, ZBSCIFDJL, no [\r\n     */\r\n    public String baseType;\r\n    /**\r\n     * the dimension of the array,\r\n     * <p/>\r\n     * for baseType: I, dimension 4, the result type is int[][][][];\r\n     * <p/>\r\n     * NOTICE, not all dimension are init in ops, so ops.length <= dimension\r\n     */\r\n    public int dimension;\r\n\r\n    public NewMutiArrayExpr(String base, int dimension, Value[] sizes) {\r\n        super(VT.NEW_MUTI_ARRAY, sizes);\r\n        this.baseType = base;\r\n        this.dimension = dimension;\r\n    }\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        baseType = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new NewMutiArrayExpr(baseType, dimension, cloneOps());\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new NewMutiArrayExpr(baseType, dimension, cloneOps(mapper));\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(\"new \").append(Util.toShortClassName(baseType));\r\n        for (Value op : ops) {\r\n            sb.append('[').append(op).append(']');\r\n        }\r\n        for (int i = ops.length; i < dimension; i++) {\r\n            sb.append(\"[]\");\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/PhiExpr.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.expr;\n\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\n\npublic class PhiExpr extends EnExpr {\n\n    public PhiExpr(Value[] ops) {\n        super(VT.PHI, ops);\n    }\n\n    @Override\n    public Value clone() {\n        return new PhiExpr(cloneOps());\n    }\n    @Override\n    public Value clone(LabelAndLocalMapper mapper) {\n        return new PhiExpr(cloneOps(mapper));\n    }\n    @Override\n    public String toString0() {\n        StringBuilder sb = new StringBuilder(\"φ(\");\n        boolean first = true;\n        for (Value vb : ops) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\", \");\n            }\n            sb.append(vb);\n        }\n        sb.append(\")\");\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/RefExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E0Expr;\r\n\r\n/**\r\n * Represent a Reference expression\r\n * \r\n * @see VT#THIS_REF\r\n * @see VT#PARAMETER_REF\r\n * @see VT#EXCEPTION_REF\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class RefExpr extends E0Expr {\r\n\r\n    public int parameterIndex;\r\n\r\n    public String type;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    public RefExpr(VT vt, String refType, int index) {\r\n        super(vt);\r\n        this.type = refType;\r\n        this.parameterIndex = index;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new RefExpr(vt, type, parameterIndex);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new RefExpr(vt, type, parameterIndex);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        switch (vt) {\r\n        case THIS_REF:\r\n            return \"@this\";\r\n        case PARAMETER_REF:\r\n            return \"@parameter_\" + parameterIndex;\r\n        case EXCEPTION_REF:\r\n            return \"@Exception\";\r\n        default:\r\n        }\r\n        return super.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/StaticFieldExpr.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E0Expr;\r\n\r\n/**\r\n * Represent a StaticField expression\r\n * \r\n * @see VT#STATIC_FIELD\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n */\r\npublic class StaticFieldExpr extends E0Expr {\r\n\r\n    /**\r\n     * Field name\r\n     */\r\n    public String name;\r\n    /**\r\n     * Field owner type\r\n     */\r\n    public String owner;\r\n    /**\r\n     * Field type\r\n     */\r\n    public String type;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        name = null;\r\n        owner = type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    public StaticFieldExpr(String ownerType, String fieldName, String fieldType) {\r\n        super(VT.STATIC_FIELD);\r\n        this.type = fieldType;\r\n        this.name = fieldName;\r\n        this.owner = ownerType;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new StaticFieldExpr(owner, name, type);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new StaticFieldExpr(owner, name, type);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        return Util.toShortClassName(owner) + \".\" + name;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/TypeExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Util;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\r\n\r\n/**\r\n * Represent a Type expression\r\n * \r\n * @see VT#CHECK_CAST\r\n * @see VT#INSTANCE_OF\r\n * @see VT#NEW_ARRAY\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class TypeExpr extends E1Expr {\r\n\r\n    public String type;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    public TypeExpr(VT vt, Value value, String desc) {\r\n        super(vt, value);\r\n        this.type = desc;\r\n\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new TypeExpr(vt, op.trim().clone(), type);\r\n    }\r\n\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new TypeExpr(vt, op.clone(mapper), type);\r\n    }\r\n\r\n\r\n    @Override\r\n    public String toString0() {\r\n        switch (super.vt) {\r\n        case CHECK_CAST:\r\n            return \"((\" + Util.toShortClassName(type) + \")\" + op + \")\";\r\n        case INSTANCE_OF:\r\n            return \"(\" + op + \" instanceof \" + Util.toShortClassName(type) + \")\";\r\n        case NEW_ARRAY:\r\n            if (type.charAt(0) == '[') {\r\n                int dimension = 1;\r\n                while (type.charAt(dimension) == '[') {\r\n                    dimension++;\r\n                }\r\n                StringBuilder sb = new StringBuilder(\"new \")\r\n                        .append(Util.toShortClassName(type.substring(dimension))).append(\"[\").append(op)\r\n                        .append(\"]\");\r\n                for (int i = 0; i < dimension; i++) {\r\n                    sb.append(\"[]\");\r\n                }\r\n                return sb.toString();\r\n            }\r\n            return \"new \" + Util.toShortClassName(type) + \"[\" + op + \"]\";\r\n        default:\r\n        }\r\n        return \"UNKNOW\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/UnopExpr.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\r\n\r\n/**\r\n * Represent a LENGTH,NEG expression\r\n * \r\n * @see VT#LENGTH\r\n * @see VT#NEG\r\n * @see VT#NOT\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class UnopExpr extends E1Expr {\r\n    public String type;\r\n\r\n    @Override\r\n    protected void releaseMemory() {\r\n        type = null;\r\n        super.releaseMemory();\r\n    }\r\n\r\n    /**\r\n     * @param vt\r\n     * @param value\r\n     * @param type\r\n     */\r\n    public UnopExpr(VT vt, Value value, String type) {\r\n        super(vt, value);\r\n        this.type = type;\r\n    }\r\n\r\n    @Override\r\n    public Value clone() {\r\n        return new UnopExpr(vt, op.trim().clone(), type);\r\n    }\r\n    @Override\r\n    public Value clone(LabelAndLocalMapper mapper) {\r\n        return new UnopExpr(vt, op.clone(mapper), type);\r\n    }\r\n\r\n    @Override\r\n    public String toString0() {\r\n        switch (vt) {\r\n        case LENGTH:\r\n            return op + \".length\";\r\n        case NEG:\r\n            return \"(-\" + op + \")\";\r\n        case NOT:\r\n            return \"(!\" + op + \")\";\r\n        default:\r\n        }\r\n        return super.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/Value.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.expr;\r\n\r\nimport com.googlecode.dex2jar.ir.ET;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\n\r\n/**\r\n * Represent a local/constant/expression\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic abstract class Value implements Cloneable {\r\n    public void setOp(Value op) {\r\n    }\r\n\r\n    public void setOp1(Value op) {\r\n    }\r\n\r\n    public void setOp2(Value op) {\r\n    }\r\n\r\n    public void setOps(Value[] op) {\r\n    }\r\n\r\n    /**\r\n     * Represent an expression with no argument\r\n     * \r\n     * @see ET#E0\r\n     */\r\n    public static abstract class E0Expr extends Value {\r\n\r\n        public E0Expr(VT vt) {\r\n            super(vt, ET.E0);\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * Represent an expression with 1 argument\r\n     * \r\n     * @see ET#E1\r\n     */\r\n    public static abstract class E1Expr extends Value {\r\n\r\n        public Value op;\r\n\r\n        public void setOp(Value op) {\r\n            this.op = op;\r\n        }\r\n\r\n        /**\r\n         * @param vt\r\n         * @param op\r\n         *            the value should be trimmed\r\n         */\r\n        public E1Expr(VT vt, Value op) {\r\n            super(vt, ET.E1);\r\n            this.op = op;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp() {\r\n            return op;\r\n        }\r\n\r\n        @Override\r\n        protected void releaseMemory() {\r\n            op = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Represent an expression with 2 arguments\r\n     * \r\n     * @see ET#E2\r\n     */\r\n    public static abstract class E2Expr extends Value {\r\n\r\n        public Value op1;\r\n        public Value op2;\r\n\r\n        public void setOp1(Value op1) {\r\n            this.op1 = op1;\r\n        }\r\n\r\n        public void setOp2(Value op2) {\r\n            this.op2 = op2;\r\n        }\r\n\r\n        public E2Expr(VT vt, Value op1, Value op2) {\r\n            super(vt, ET.E2);\r\n            this.op1 = op1;\r\n            this.op2 = op2;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp1() {\r\n            return op1;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp2() {\r\n            return op2;\r\n        }\r\n\r\n        @Override\r\n        protected void releaseMemory() {\r\n            op1 = op2 = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Represent an expression with 3+ arguments\r\n     * \r\n     * @see ET#En\r\n     */\r\n    public static abstract class EnExpr extends Value {\r\n\r\n        public Value[] ops;\r\n\r\n        public void setOps(Value[] ops) {\r\n            this.ops = ops;\r\n        }\r\n\r\n        public EnExpr(VT vt, Value[] ops) {\r\n            super(vt, ET.En);\r\n            this.ops = ops;\r\n        }\r\n\r\n        protected Value[] cloneOps() {\r\n            Value[] nOps = new Value[ops.length];\r\n            for (int i = 0; i < nOps.length; i++) {\r\n                nOps[i] = ops[i].trim().clone();\r\n            }\r\n            return nOps;\r\n        }\r\n        protected Value[] cloneOps(LabelAndLocalMapper mapper) {\r\n            Value[] nOps = new Value[ops.length];\r\n            for (int i = 0; i < nOps.length; i++) {\r\n                nOps[i] = ops[i].clone(mapper);\r\n            }\r\n            return nOps;\r\n        }\r\n\r\n        @Override\r\n        public Value[] getOps() {\r\n            return ops;\r\n        }\r\n\r\n        @Override\r\n        protected void releaseMemory() {\r\n            ops = null;\r\n        }\r\n    }\r\n    public static final int CAN_THROW = 1 << 3;\r\n    public static final int MAY_THROW=1<<4;\r\n\r\n    /**\r\n     * Value Type\r\n     */\r\n    public static enum VT {\r\n\r\n        ADD(\"+\", MAY_THROW), AND(\"&\", MAY_THROW), ARRAY(MAY_THROW), CAST(MAY_THROW), CHECK_CAST(CAN_THROW), CONSTANT(0), DCMPG(\r\n                MAY_THROW), DCMPL(MAY_THROW), IDIV(\"/\", CAN_THROW), LDIV(\"/\", CAN_THROW), FDIV(\"/\", MAY_THROW), DDIV(\"/\", MAY_THROW), EQ(\"==\", MAY_THROW), EXCEPTION_REF(0), FCMPG(\r\n                MAY_THROW), FCMPL(MAY_THROW), FIELD(CAN_THROW), FILLED_ARRAY(CAN_THROW), GE(\">=\", MAY_THROW), GT(\">\",\r\n                MAY_THROW), INSTANCE_OF(CAN_THROW), INVOKE_INTERFACE(CAN_THROW), //\r\n        INVOKE_NEW(CAN_THROW), INVOKE_SPECIAL(CAN_THROW), INVOKE_STATIC(CAN_THROW), INVOKE_VIRTUAL(CAN_THROW), INVOKE_CUSTOM(CAN_THROW), INVOKE_POLYMORPHIC(CAN_THROW), LCMP(\r\n                MAY_THROW), //\r\n        LE(\"<=\", MAY_THROW), LENGTH(CAN_THROW), LOCAL(0), LT(\"<\", MAY_THROW), MUL(\"*\", MAY_THROW), NE(\"!=\", MAY_THROW), NEG(\r\n                MAY_THROW), //\r\n        NEW(CAN_THROW), NEW_ARRAY(CAN_THROW), NEW_MUTI_ARRAY(CAN_THROW), NOT(MAY_THROW), OR(\"|\", MAY_THROW), PARAMETER_REF(\r\n                0), PHI(0), REM(\"%\", MAY_THROW), SHL(\"<<\", MAY_THROW), SHR(\">>\", MAY_THROW), STATIC_FIELD(CAN_THROW), SUB(\r\n                \"-\", MAY_THROW), THIS_REF(MAY_THROW), USHR(\">>>\", MAY_THROW), XOR(\"^\", MAY_THROW);\r\n        private String name;\r\n        private int flags;\r\n\r\n        VT(int flags) {\r\n            this(null, flags);\r\n        }\r\n\r\n        VT(String name, int flags) {\r\n            this.name = name;\r\n            this.flags = flags;\r\n        }\r\n\r\n        @Override\r\n        public String toString() {\r\n            return name == null ? super.toString() : name;\r\n        }\r\n\r\n        public boolean canThrow() {\r\n            return CAN_THROW == flags;\r\n        }\r\n\r\n        public boolean mayThrow() {\r\n            return MAY_THROW == flags;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The number of argument\r\n     */\r\n    final public ET et;\r\n\r\n    private Value next;\r\n\r\n    public String valueType;\r\n    public Object tag;\r\n    /**\r\n     * Value Type\r\n     */\r\n    final public VT vt;\r\n\r\n    /**\r\n     * \r\n     * @param vt\r\n     *            Value Type\r\n     * @param et\r\n     *            The number of argument\r\n     */\r\n    protected Value(VT vt, ET et) {\r\n        super();\r\n        this.vt = vt;\r\n        this.et = et;\r\n    }\r\n\r\n    @Override\r\n    public abstract Value clone();\r\n\r\n    public abstract Value clone(LabelAndLocalMapper mapper);\r\n\r\n    public Value getOp() {\r\n        return null;\r\n    }\r\n\r\n    public Value getOp1() {\r\n        return null;\r\n    }\r\n\r\n    public Value getOp2() {\r\n        return null;\r\n    }\r\n\r\n    public Value[] getOps() {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * clean resource used by this value,release memory\r\n     */\r\n    protected void releaseMemory() {\r\n    }\r\n\r\n    public final String toString() {\r\n        return trim().toString0();\r\n    }\r\n\r\n    protected abstract String toString0();\r\n\r\n    public Value trim() {\r\n        Value a = this;\r\n        while (a.next != null) {\r\n            Value b = a.next;\r\n            a.next = b;\r\n            a = b;\r\n        }\r\n        return a;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/AssignStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;\r\n\r\n/**\r\n * Represent an Assign statement\r\n * \r\n * @see ST#ASSIGN\r\n * @see ST#IDENTITY\r\n * @see ST#FILL_ARRAY_DATA\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 8da5a5faa6bd $\r\n */\r\npublic class AssignStmt extends E2Stmt {\r\n\r\n    public AssignStmt(ST type, Value left, Value right) {\r\n        super(type, left, right);\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        return new AssignStmt(st, op1.clone(mapper), op2.clone(mapper));\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        switch (st) {\r\n        case ASSIGN:\r\n            return op1 + \" = \" + op2;\r\n        case LOCAL_START:\r\n        case IDENTITY:\r\n            return op1 + \" := \" + op2;\r\n        case FILL_ARRAY_DATA:\r\n            return op1 + \" <- \" + op2;\r\n        default:\r\n        }\r\n        return super.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/BaseSwitchStmt.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.stmt;\n\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\n\n/**\n * Parent class of {@link LookupSwitchStmt} and {@link TableSwitchStmt}\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic abstract class BaseSwitchStmt extends E1Stmt {\n    public BaseSwitchStmt(ST type, Value op) {\n        super(type, op);\n    }\n\n    public LabelStmt[] targets;\n    public LabelStmt defaultTarget;\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/GotoStmt.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.stmt;\n\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;\n\n/**\n * Represent a GOTO statement\n * \n * @see ST#GOTO\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class GotoStmt extends E0Stmt implements JumpStmt {\n    public LabelStmt target;\n\n    public LabelStmt getTarget() {\n        return target;\n    }\n\n    public void setTarget(LabelStmt target) {\n        this.target = target;\n    }\n\n    public GotoStmt(LabelStmt target) {\n        super(ST.GOTO);\n        this.target = target;\n    }\n\n    @Override\n    public Stmt clone(LabelAndLocalMapper mapper) {\n        LabelStmt nTarget = mapper.map(target);\n        return new GotoStmt(nTarget);\n    }\n\n    @Override\n    public String toString() {\n        return \"GOTO \" + target.getDisplayName();\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/IfStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\r\n\r\n/**\r\n * Represent a IF statement\r\n * \r\n * @see ST#IF\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n */\r\npublic class IfStmt extends E1Stmt implements JumpStmt {\r\n\r\n    public LabelStmt target;\r\n\r\n    public LabelStmt getTarget() {\r\n        return target;\r\n    }\r\n\r\n    public void setTarget(LabelStmt target) {\r\n        this.target = target;\r\n    }\r\n\r\n    /**\r\n     * IF\r\n     * \r\n     * @param type\r\n     * @param condition\r\n     * @param target\r\n     */\r\n    public IfStmt(ST type, Value condition, LabelStmt target) {\r\n        super(type, condition);\r\n        this.target = target;\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        LabelStmt nTarget = mapper.map(target);\r\n        return new IfStmt(st, op.clone(mapper), nTarget);\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"if \" + op + \" GOTO \" + target.getDisplayName();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/JumpStmt.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.stmt;\n\npublic interface JumpStmt {\n\n    LabelStmt getTarget();\n\n    void setTarget(LabelStmt labelStmt);\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/LabelStmt.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.stmt;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;\n\n/**\n * Represent a Label statement\n * \n * @see ST#LABEL\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * @version $Rev$\n */\npublic class LabelStmt extends E0Stmt {\n\n    public String displayName;\n    public int lineNumber = -1;\n    public List<AssignStmt> phis;\n    public Object tag;\n\n    public LabelStmt() {\n        super(ST.LABEL);\n    }\n\n    @Override\n    public LabelStmt clone(LabelAndLocalMapper mapper) {\n        LabelStmt labelStmt = mapper.map(this);\n        if (phis != null && labelStmt.phis == null) {\n            labelStmt.phis = new ArrayList<>(phis.size());\n            for (AssignStmt phi : phis) {\n                labelStmt.phis.add((AssignStmt) phi.clone(mapper));\n            }\n        }\n        return labelStmt;\n    }\n\n    public String getDisplayName() {\n        if (displayName != null) {\n            return displayName;\n        }\n        int x = hashCode();\n        return String.format(\"L%08x\", x);\n    }\n\n    @Override\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n        sb.append(getDisplayName()).append(\":\");\n\n        if (phis != null && phis.size() > 0) {\n            sb.append(\" // \").append(phis);\n        }\n        if (lineNumber >= 0) {\n            sb.append(\" // line \").append(lineNumber);\n        }\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/LookupSwitchStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\n\r\n/**\r\n * Represent a LOOKUP_SWITCH statement\r\n * \r\n * @see ST#LOOKUP_SWITCH\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n */\r\npublic class LookupSwitchStmt extends BaseSwitchStmt {\r\n\r\n    public int[] lookupValues;\r\n\r\n    public LookupSwitchStmt(Value key, int[] lookupValues, LabelStmt[] targets, LabelStmt defaultTarget) {\r\n        super(ST.LOOKUP_SWITCH, key);\r\n        this.lookupValues = lookupValues;\r\n        this.targets = targets;\r\n        this.defaultTarget = defaultTarget;\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        LabelStmt[] nTargets = new LabelStmt[targets.length];\r\n        for (int i = 0; i < nTargets.length; i++) {\r\n            nTargets[i] = mapper.map(targets[i]);\r\n        }\r\n        int nLookupValues[] = new int[lookupValues.length];\r\n        System.arraycopy(lookupValues, 0, nLookupValues, 0, nLookupValues.length);\r\n\r\n        return new LookupSwitchStmt(op.clone(mapper), nLookupValues, nTargets, mapper.map(defaultTarget));\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        StringBuilder sb = new StringBuilder(\"switch(\").append(op).append(\") {\");\r\n\r\n        for (int i = 0; i < lookupValues.length; i++) {\r\n            sb.append(\"\\n case \").append(lookupValues[i]).append(\": GOTO \").append(targets[i].getDisplayName())\r\n                    .append(\";\");\r\n        }\r\n        sb.append(\"\\n default : GOTO \").append(defaultTarget.getDisplayName()).append(\";\");\r\n        sb.append(\"\\n}\");\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/NopStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;\r\n\r\n/**\r\n * Represent a NOP statement\r\n * \r\n * @see ST#NOP\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class NopStmt extends E0Stmt {\r\n\r\n    public NopStmt() {\r\n        super(ST.NOP);\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        return new NopStmt();\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"NOP\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/ReturnVoidStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;\r\n\r\n/**\r\n * Represent a RETURN_VOID statement\r\n * \r\n * @see ST#RETURN_VOID\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class ReturnVoidStmt extends E0Stmt {\r\n\r\n    public ReturnVoidStmt() {\r\n        super(ST.RETURN_VOID);\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        return new ReturnVoidStmt();\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"return\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/Stmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport java.util.Set;\r\nimport java.util.TreeSet;\r\n\r\nimport com.googlecode.dex2jar.ir.ET;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\n\r\n/**\r\n * Represent a statement\r\n * \r\n * @see ST\r\n * @see ET\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic abstract class Stmt {\r\n\r\n    /**\r\n     * Represent a statement with no argument\r\n     * \r\n     * @see ET#E0\r\n     */\r\n    public static abstract class E0Stmt extends Stmt {\r\n\r\n        public E0Stmt(ST type) {\r\n            super(type, ET.E0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Represent a statement with 1 argument\r\n     * \r\n     * @see ET#E1\r\n     */\r\n    public static abstract class E1Stmt extends Stmt {\r\n\r\n        public Value op;\r\n\r\n        public E1Stmt(ST type, Value op) {\r\n            super(type, ET.E1);\r\n            this.op = op;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp() {\r\n            return op;\r\n        }\r\n\r\n        public void setOp(Value op) {\r\n            this.op = op;\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * Represent a statement with 2 arguments\r\n     * \r\n     * @see ET#E2\r\n     */\r\n    public static abstract class E2Stmt extends Stmt {\r\n\r\n        public Value op1;\r\n        public Value op2;\r\n\r\n        public E2Stmt(ST type, Value op1, Value op2) {\r\n            super(type, ET.E2);\r\n            this.op1 = op1;\r\n            this.op2 = op2;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp1() {\r\n            return op1;\r\n        }\r\n\r\n        @Override\r\n        public Value getOp2() {\r\n            return op2;\r\n        }\r\n\r\n        public void setOp1(Value op1) {\r\n            this.op1 = op1;\r\n        }\r\n\r\n        public void setOp2(Value op2) {\r\n            this.op2 = op2;\r\n        }\r\n\r\n    }\r\n\r\n    public static final int CAN_CONTINUE = 1 << 0;\r\n    public static final int CAN_BRNANCH = 1 << 1;\r\n    public static final int CAN_SWITCH = 1 << 2;\r\n    public static final int CAN_THROW = 1 << 3;\r\n    public static final int MAY_THROW=1<<4;\r\n\r\n    /**\r\n     * Statement Type\r\n     * \r\n     */\r\n    public static enum ST {\r\n\r\n        LOCAL_START(CAN_CONTINUE), // same as ASSIGN but left must keep and must be local\r\n        LOCAL_END(CAN_CONTINUE), // must keep and op must be local\r\n        ASSIGN(CAN_CONTINUE | MAY_THROW), IDENTITY(CAN_CONTINUE), LABEL(CAN_CONTINUE), LOCK(CAN_CONTINUE | CAN_THROW), NOP(\r\n                CAN_CONTINUE), UNLOCK(CAN_CONTINUE | CAN_THROW), VOID_INVOKE(CAN_CONTINUE | CAN_THROW), FILL_ARRAY_DATA(\r\n                CAN_CONTINUE | CAN_THROW), //\r\n        RETURN(MAY_THROW), RETURN_VOID(0), THROW(CAN_THROW), //\r\n        GOTO(CAN_BRNANCH), IF(CAN_CONTINUE | CAN_BRNANCH | MAY_THROW), //\r\n        LOOKUP_SWITCH(CAN_SWITCH | MAY_THROW), TABLE_SWITCH(CAN_SWITCH | MAY_THROW), ;\r\n        private int config;\r\n\r\n        ST(int config) {\r\n            this.config = config;\r\n        }\r\n\r\n        public boolean canBranch() {\r\n            return 0 != (CAN_BRNANCH & config);\r\n        }\r\n\r\n        public boolean canContinue() {\r\n            return 0 != (CAN_CONTINUE & config);\r\n        }\r\n\r\n        public boolean canSwitch() {\r\n            return 0 != (CAN_SWITCH & config);\r\n        }\r\n\r\n        public boolean mayThrow() {\r\n            return 0 != (MAY_THROW & config);\r\n        }\r\n\r\n        public boolean canThrow() {\r\n            return 0 != (CAN_THROW & config);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Used in construct of a method CFG, Previous {@link Stmt} nodes\r\n     */\r\n    public Set<Stmt> _cfg_froms;\r\n\r\n    /**\r\n     * Used in construct of a method CFG, After {@link Stmt} nodes\r\n     */\r\n    public Set<LabelStmt> exceptionHandlers;\r\n\r\n    /**\r\n     * Used in visit the method CFG\r\n     */\r\n    public boolean visited;\r\n\r\n    /**\r\n     * Used in Local Split, forward frame of the {@link Stmt}\r\n     */\r\n    public Object frame;\r\n\r\n    public Stmt _ts_default_next;\r\n\r\n    /**\r\n     * The number of argument\r\n     */\r\n    public final ET et;\r\n    /**\r\n     * Used in ordering statements in a {@link TreeSet}, id of the {@link Stmt} in its {@link StmtList}\r\n     */\r\n    public int id;\r\n\r\n    /**\r\n     * Owner of the statement\r\n     */\r\n    /* default */\r\n    StmtList list;\r\n\r\n    /**\r\n     * Next statement in {@link StmtList}\r\n     */\r\n    /* default */\r\n    Stmt next;\r\n\r\n    /**\r\n     * Previous statement in {@link StmtList}\r\n     */\r\n    /* default */\r\n    Stmt pre;\r\n    /**\r\n     * Statement Type\r\n     */\r\n    public final ST st;\r\n\r\n    /**\r\n     * \r\n     * @param st\r\n     *            Statement Type\r\n     * @param et\r\n     *            The number of argument\r\n     */\r\n    protected Stmt(ST st, ET et) {\r\n        this.st = st;\r\n        this.et = et;\r\n    }\r\n\r\n    public abstract Stmt clone(LabelAndLocalMapper mapper);\r\n\r\n    /**\r\n     * \r\n     * @return Next statement in {@link StmtList}, null if it is the last statement in {@link StmtList}\r\n     */\r\n    public final Stmt getNext() {\r\n        return next;\r\n    }\r\n\r\n    public Value getOp() {\r\n        return null;\r\n    }\r\n\r\n    public Value getOp1() {\r\n        return null;\r\n    }\r\n\r\n    public Value getOp2() {\r\n        return null;\r\n    }\r\n\r\n    public Value[] getOps() {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * \r\n     * @return Previous statement in {@link StmtList}, null if it is the first statement in {@link StmtList}\r\n     */\r\n    public final Stmt getPre() {\r\n        return pre;\r\n    }\r\n\r\n    public void setOp(Value op) {\r\n    }\r\n\r\n    public void setOp1(Value op) {\r\n    }\r\n\r\n    public void setOp2(Value op) {\r\n    }\r\n\r\n    public void setOps(Value[] op) {\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/StmtList.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport java.util.Collection;\r\nimport java.util.Collections;\r\nimport java.util.Iterator;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\r\n\r\n/**\r\n * Represent a list of statement.\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class StmtList implements Iterable<Stmt>, java.util.Comparator<Stmt> {\r\n\r\n    private static class StmtListIterator implements Iterator<Stmt> {\r\n        private Stmt current, next;\r\n        private final StmtList list;\r\n\r\n        /**\r\n         * @param list\r\n         * @param next\r\n         */\r\n        public StmtListIterator(StmtList list, Stmt next) {\r\n            super();\r\n            this.list = list;\r\n            this.next = next;\r\n        }\r\n\r\n        @Override\r\n        public boolean hasNext() {\r\n            return next != null;\r\n        }\r\n\r\n        @Override\r\n        public Stmt next() {\r\n            Stmt x = current = next;\r\n            if (x != null) {\r\n                next = x.next;\r\n            } else {\r\n                next = null;\r\n            }\r\n            return x;\r\n        }\r\n\r\n        @Override\r\n        public void remove() {\r\n            if (current != null) {\r\n                list.remove(current);\r\n                current = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    private Stmt first, last;\r\n\r\n    private int index = 1;\r\n    private int size = 0;\r\n\r\n    public void add(Stmt stmt) {\r\n        insertLast(stmt);\r\n    }\r\n\r\n    public void addAll(Collection<Stmt> list) {\r\n        for (Stmt stmt : list) {\r\n            insertLast(stmt);\r\n        }\r\n    }\r\n\r\n    public StmtList clone(LabelAndLocalMapper mapper) {\r\n        StmtList nList = new StmtList();\r\n        for (Stmt stmt : this) {\r\n            nList.add(stmt.clone(mapper));\r\n        }\r\n        return nList;\r\n    }\r\n\r\n    @Override\r\n    public int compare(Stmt o1, Stmt o2) {\r\n        return o1.id - o2.id;\r\n    }\r\n\r\n    public boolean contains(Stmt stmt) {\r\n        return stmt.list == this;\r\n    }\r\n\r\n    public Stmt getFirst() {\r\n        return first;\r\n    }\r\n\r\n    public Stmt getLast() {\r\n        return last;\r\n    }\r\n\r\n    public int getSize() {\r\n        return size;\r\n    }\r\n\r\n    private void indexIt(Stmt stmt) {\r\n        if (stmt.id <= 0) {\r\n            stmt.id = this.index;\r\n            this.index++;\r\n        }\r\n    }\r\n\r\n    public void insertAfter(Stmt position, Stmt stmt) {\r\n        if (position.list == this) {\r\n            indexIt(stmt);\r\n            stmt.list = this;\r\n            size++;\r\n            stmt.next = position.next;\r\n            stmt.pre = position;\r\n            if (position.next == null) {\r\n                last = stmt;\r\n            } else {\r\n                position.next.pre = stmt;\r\n            }\r\n            position.next = stmt;\r\n        }\r\n    }\r\n\r\n    public void insertBefore(Stmt position, Stmt stmt) {\r\n        if (position.list == this) {\r\n            indexIt(stmt);\r\n            stmt.list = this;\r\n            size++;\r\n            stmt.pre = position.pre;\r\n            stmt.next = position;\r\n            if (position.pre == null) {\r\n                first = stmt;\r\n            } else {\r\n                position.pre.next = stmt;\r\n            }\r\n            position.pre = stmt;\r\n        }\r\n    }\r\n\r\n    public void insertFirst(Stmt stmt) {\r\n        indexIt(stmt);\r\n        stmt.list = this;\r\n        size++;\r\n        if (first == null) {// empty\r\n            first = last = stmt;\r\n            stmt.pre = stmt.next = null;\r\n        } else {\r\n            stmt.pre = null;\r\n            stmt.next = first;\r\n            first.pre = stmt;\r\n            first = stmt;\r\n        }\r\n    }\r\n\r\n    public void insertLast(Stmt stmt) {\r\n        indexIt(stmt);\r\n        stmt.list = this;\r\n        size++;\r\n        if (first == null) {// empty\r\n            first = last = stmt;\r\n            stmt.pre = stmt.next = null;\r\n        } else {\r\n            stmt.next = null;\r\n            stmt.pre = last;\r\n            last.next = stmt;\r\n            last = stmt;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public Iterator<Stmt> iterator() {\r\n        return new StmtListIterator(this, first);\r\n    };\r\n\r\n    public void remove(Stmt stmt) {\r\n        if (stmt.list == this) {\r\n            size--;\r\n            stmt.list = null;\r\n            if (stmt.pre == null) {\r\n                first = stmt.next;\r\n            } else {\r\n                stmt.pre.next = stmt.next;\r\n            }\r\n            if (stmt.next == null) {\r\n                last = stmt.pre;\r\n            } else {\r\n                stmt.next.pre = stmt.pre;\r\n            }\r\n            stmt.pre = null;\r\n            stmt.next = null;\r\n        }\r\n    }\r\n\r\n    public void replace(Stmt stmt, Stmt nas) {\r\n        if (stmt.list == this) {\r\n            indexIt(nas);\r\n            nas.list = this;\r\n            nas.next = stmt.next;\r\n            nas.pre = stmt.pre;\r\n            if (stmt.next != null) {\r\n                stmt.next.pre = nas;\r\n            } else {\r\n                this.last = nas;\r\n            }\r\n            if (stmt.pre != null) {\r\n                stmt.pre.next = nas;\r\n            } else {\r\n                this.first = nas;\r\n            }\r\n            stmt.next = null;\r\n            stmt.pre = null;\r\n            stmt.list = null;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        if (this.size == 0) {\r\n            return \"[Empty]\";\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        for (Stmt s : this) {\r\n            if (s.st == ST.LABEL) {\r\n                sb.append(\"\\n\");\r\n            }\r\n            sb.append(s).append(\"\\n\");\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public void move(Stmt start, Stmt end, Stmt dist) {\r\n        if (start.pre == null) {\r\n            this.first = end.next;\r\n        } else {\r\n            start.pre.next = end.next;\r\n        }\r\n        if (end.next == null) {\r\n            this.last = start.pre;\r\n        } else {\r\n            end.next.pre = start.pre;\r\n        }\r\n\r\n        if (dist.next == null) {\r\n            this.last = end;\r\n            end.next = null;\r\n        } else {\r\n            dist.next.pre = end;\r\n            end.next = dist.next;\r\n        }\r\n        dist.next = start;\r\n        start.pre = dist;\r\n    }\r\n\r\n    public void clear() {\r\n        size = 0;\r\n        first = null;\r\n        last = null;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/Stmts.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\r\n\r\npublic final class Stmts {\r\n\r\n    public static AssignStmt nAssign(Value left, Value right) {\r\n        return new AssignStmt(ST.ASSIGN, left, right);\r\n    }\r\n\r\n    public static AssignStmt nFillArrayData(Value left, Value arrayData) {\r\n        return new AssignStmt(ST.FILL_ARRAY_DATA, left, arrayData);\r\n    }\r\n\r\n    public static GotoStmt nGoto(LabelStmt target) {\r\n        return new GotoStmt(target);\r\n    }\r\n\r\n    public static AssignStmt nIdentity(Value local, Value identityRef) {\r\n        return new AssignStmt(ST.IDENTITY, local, identityRef);\r\n    }\r\n\r\n    public static IfStmt nIf(Value a, LabelStmt target) {\r\n        return new IfStmt(ST.IF, a, target);\r\n    }\r\n\r\n    public static LabelStmt nLabel() {\r\n        return new LabelStmt();\r\n    }\r\n\r\n    public static UnopStmt nLock(Value op) {\r\n        return new UnopStmt(ST.LOCK, op);\r\n    }\r\n\r\n    public static LookupSwitchStmt nLookupSwitch(Value key, int[] lookupValues, LabelStmt[] targets, LabelStmt target) {\r\n        return new LookupSwitchStmt(key, lookupValues, targets, target);\r\n    }\r\n\r\n    public static NopStmt nNop() {\r\n        return new NopStmt();\r\n    }\r\n\r\n    public static UnopStmt nReturn(Value op) {\r\n        return new UnopStmt(ST.RETURN, op);\r\n    }\r\n\r\n    public static ReturnVoidStmt nReturnVoid() {\r\n        return new ReturnVoidStmt();\r\n    }\r\n\r\n    public static TableSwitchStmt nTableSwitch(Value key, int lowIndex, LabelStmt[] targets,\r\n            LabelStmt target) {\r\n        return new TableSwitchStmt(key, lowIndex, targets, target);\r\n    }\r\n\r\n    public static UnopStmt nThrow(Value op) {\r\n        return new UnopStmt(ST.THROW, op);\r\n    }\r\n\r\n    public static UnopStmt nUnLock(Value op) {\r\n        return new UnopStmt(ST.UNLOCK, op);\r\n    }\r\n\r\n    public static VoidInvokeStmt nVoidInvoke(Value op) {\r\n        return new VoidInvokeStmt(op);\r\n    }\r\n\r\n    private Stmts() {\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/TableSwitchStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\n\r\n/**\r\n * Represent a TABLE_SWITCH statement\r\n * \r\n * @see ST#TABLE_SWITCH\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 9fd8005bbaa4 $\r\n */\r\npublic class TableSwitchStmt extends BaseSwitchStmt {\r\n\r\n    public int lowIndex;\r\n\r\n    public TableSwitchStmt() {\r\n        super(ST.TABLE_SWITCH, null);\r\n    }\r\n\r\n    public TableSwitchStmt(Value key, int lowIndex, LabelStmt[] targets, LabelStmt defaultTarget) {\r\n        super(ST.TABLE_SWITCH, key);\r\n        this.lowIndex = lowIndex;\r\n        this.targets = targets;\r\n        this.defaultTarget = defaultTarget;\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        LabelStmt[] nTargets = new LabelStmt[targets.length];\r\n        for (int i = 0; i < nTargets.length; i++) {\r\n            nTargets[i] = mapper.map(targets[i]);\r\n        }\r\n        return new TableSwitchStmt(op.clone(mapper), lowIndex, nTargets, mapper.map(defaultTarget));\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        StringBuilder sb = new StringBuilder(\"switch(\").append(op).append(\") {\");\r\n\r\n        for (int i = 0; i < targets.length; i++) {\r\n            sb.append(\"\\n case \").append(lowIndex + i).append(\": GOTO \").append(targets[i].getDisplayName())\r\n                    .append(\";\");\r\n        }\r\n        sb.append(\"\\n default : GOTO \").append(defaultTarget.getDisplayName()).append(\";\");\r\n        sb.append(\"\\n}\");\r\n        return sb.toString();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/UnopStmt.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\r\n\r\npublic class UnopStmt extends E1Stmt {\r\n\r\n    public UnopStmt(ST type, Value op) {\r\n        super(type, op);\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        return new UnopStmt(st, op.clone(mapper));\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        switch (super.st) {\r\n        case LOCK:\r\n            return \"lock \" + op;\r\n        case UNLOCK:\r\n            return \"unlock \" + op;\r\n        case THROW:\r\n            return \"throw \" + op;\r\n        case RETURN:\r\n            return \"return \" + op;\r\n        case LOCAL_END:\r\n            return op + \" ::END\";\r\n        default:\r\n        }\r\n        return super.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.stmt;\r\n\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\r\n\r\n/**\r\n * Represent a void-return Invoke\r\n * \r\n * @see ST#VOID_INVOKE\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev: 8da5a5faa6bd $\r\n */\r\npublic class VoidInvokeStmt extends E1Stmt {\r\n\r\n    public VoidInvokeStmt(Value op) {\r\n        super(ST.VOID_INVOKE, op);\r\n    }\r\n\r\n    @Override\r\n    public Stmt clone(LabelAndLocalMapper mapper) {\r\n        return new VoidInvokeStmt(op.clone(mapper));\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"void \" + op;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/AggTransformer.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.InvokeExpr;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\n\r\nimport java.util.*;\r\n\r\npublic class AggTransformer extends StatedTransformer {\r\n    @Override\r\n    public boolean transformReportChanged(IrMethod method) {\r\n        boolean changed = false;\r\n\r\n\r\n        Set<Stmt> locationSensitiveStmts = new HashSet<>();\r\n        // 1. merge location Insensitive stmts\r\n        changed = simpleMergeLocals(method, changed, locationSensitiveStmts);\r\n\r\n        if (locationSensitiveStmts.size() == 0) {\r\n            return changed;\r\n        }\r\n\r\n        ReplaceX replaceX = new ReplaceX();\r\n        Queue<Stmt> q = new UniqueQueue<>();\r\n        q.addAll(locationSensitiveStmts);\r\n\r\n        // 2. merge location sensitive stmts\r\n        while (!q.isEmpty()) {\r\n            Stmt stmt = q.poll();\r\n            Local local = (Local) stmt.getOp1();\r\n            Stmt next = stmt.getNext();\r\n\r\n            switch (next.st) {\r\n                case LABEL:\r\n                case GOTO:\r\n                case IDENTITY:\r\n                case FILL_ARRAY_DATA:\r\n                case NOP:\r\n                case RETURN_VOID:\r\n                    continue;\r\n                default:\r\n            }\r\n            try {\r\n                localCanExecFirst(local, next);\r\n                throw new RuntimeException(); // impossible here\r\n            } catch (MergeResult e) {\r\n                if (e == SUCCESS) {\r\n                    replaceX.local = local;\r\n                    replaceX.replaceWith = stmt.getOp2();\r\n                    method.locals.remove(local);\r\n                    method.stmts.remove(stmt);\r\n\r\n                    Cfg.travelMod(next, replaceX, false);\r\n\r\n                    Stmt pre = next.getPre();\r\n                    if (pre != null && locationSensitiveStmts.contains(pre)) {\r\n                        q.add(pre);\r\n                    }\r\n\r\n                }\r\n            }\r\n        }\r\n\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * dfs find find local and the first locationInsensitive Value\r\n     * // TODO if can not merge, try adjust the stmt to fit the local\r\n     */\r\n    private static void localCanExecFirst(Local local, Stmt target) throws MergeResult {\r\n\r\n        switch (target.et) {\r\n            case E0: // impossible\r\n            case En: // no EnStmt yet\r\n                throw FAIL;\r\n            case E1:\r\n                localCanExecFirst(local, target.getOp());\r\n                break;\r\n            case E2:\r\n                AssignStmt as = (AssignStmt) target;\r\n                Value op1 = as.getOp1();\r\n                Value op2 = as.getOp2();\r\n                switch (op1.vt) {\r\n                    case LOCAL:\r\n                        localCanExecFirst(local, op2);\r\n                        break;\r\n                    case FIELD:\r\n                        localCanExecFirst(local, op1.getOp());\r\n                        // pass through\r\n                    case STATIC_FIELD:\r\n                        localCanExecFirst(local, op2);\r\n                        break;\r\n                    case ARRAY:\r\n                        localCanExecFirst(local, op1.getOp1());\r\n                        localCanExecFirst(local, op1.getOp2());\r\n                        localCanExecFirst(local, op2);\r\n                        break;\r\n                    default:\r\n                }\r\n                break;\r\n        }\r\n        throw FAIL;\r\n    }\r\n\r\n    private static MergeResult FAIL = new MergeResult();\r\n    private static MergeResult SUCCESS = new MergeResult();\r\n\r\n    /**\r\n     * dfs searching, if local is appear before first location-insensitive value, throws SUCCESS, or throws FAIL\r\n     */\r\n    private static void localCanExecFirst(Local local, Value op) throws MergeResult {\r\n        switch (op.et) {\r\n            case E0:\r\n                if (local.vt == Value.VT.LOCAL) {\r\n                    if (op == local) {\r\n                        throw SUCCESS;\r\n                    }\r\n                }\r\n                break;\r\n            case E1:\r\n                localCanExecFirst(local, op.getOp());\r\n                break;\r\n            case E2:\r\n                localCanExecFirst(local, op.getOp1());\r\n                localCanExecFirst(local, op.getOp2());\r\n                break;\r\n            case En:\r\n                for (Value v : op.getOps()) {\r\n                    localCanExecFirst(local, v);\r\n                }\r\n        }\r\n\r\n        boolean shouldExclude = false;\r\n        if (op.vt == Value.VT.INVOKE_STATIC) {\r\n            InvokeExpr ie = (InvokeExpr) op;\r\n            if (ie.getName().equals(\"valueOf\") && ie.getOwner().startsWith(\"Ljava/lang/\") && ie.getArgs().length == 1 && ie.getArgs()[0].length() == 1) {\r\n                shouldExclude = true;\r\n            }\r\n        }\r\n\r\n        if (!isLocationInsensitive(op.vt) && !shouldExclude) {  // this is the first insensitive Value\r\n            throw FAIL;\r\n        }\r\n    }\r\n\r\n    static class MergeResult extends Throwable {\r\n\r\n    }\r\n\r\n    static class ReplaceX implements Cfg.TravelCallBack {\r\n        Local local;\r\n        Value replaceWith;\r\n\r\n        @Override\r\n        public Value onAssign(Local v, AssignStmt as) {\r\n            return v;\r\n        }\r\n\r\n        @Override\r\n        public Value onUse(Local v) {\r\n            if (v == local) {\r\n                return replaceWith;\r\n            }\r\n            return v;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * if a local is only used in one place, and the value is isLocationInsensitive,\r\n     * remove the local and replace it with its value\r\n     * <pre>\r\n     *     a=b+c\r\n     *     d=a+e\r\n     * </pre>\r\n     * to\r\n     * <pre>\r\n     *     d=(b+c)+e\r\n     * </pre>\r\n     */\r\n    private boolean simpleMergeLocals(IrMethod method, boolean changed, Set<Stmt> locationSensitiveStmts) {\r\n        if (method.locals.size() == 0) {\r\n            return false;\r\n        }\r\n        final int[] readCounts = Cfg.countLocalReads(method);\r\n        Set<Local> useInPhi = collectLocalUsedInPhi(method);\r\n        final Map<Local, Value> toReplace = new HashMap<>();\r\n        for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {\r\n            Stmt p = it.next();\r\n            if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) {\r\n                Local local = (Local) p.getOp1();\r\n                if (useInPhi.contains(local)) {\r\n                    continue;\r\n                }\r\n                if (readCounts[local._ls_index] < 2) {\r\n                    Value op2 = p.getOp2();\r\n                    if (isLocationInsensitive(op2)) {\r\n                        method.locals.remove(local);\r\n                        toReplace.put(local, op2);\r\n                        it.remove();\r\n                        changed = true;\r\n                    } else {\r\n                        locationSensitiveStmts.add(p);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        Cfg.TravelCallBack tcb = new Cfg.TravelCallBack() {\r\n            @Override\r\n            public Value onAssign(Local v, AssignStmt as) {\r\n                return v;\r\n            }\r\n\r\n            @Override\r\n            public Value onUse(Local v) {\r\n                Value v2 = toReplace.get(v);\r\n                if (v2 != null) {\r\n                    return v2;\r\n                }\r\n                return v;\r\n            }\r\n        };\r\n\r\n        modReplace(toReplace, tcb);\r\n\r\n        Cfg.travelMod(method.stmts, tcb, false);\r\n        return changed;\r\n    }\r\n\r\n    private Set<Local> collectLocalUsedInPhi(IrMethod method) {\r\n        Set<Local> useInPhi = new HashSet<>();\r\n        if (method.phiLabels != null) {\r\n            for (LabelStmt labelStmt : method.phiLabels) {\r\n                if (labelStmt.phis != null) {\r\n                    for (AssignStmt phi : labelStmt.phis) {\r\n                        useInPhi.add((Local) phi.getOp1());\r\n                        for (Value op : phi.getOp2().getOps()) {\r\n                            useInPhi.add((Local) op);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return useInPhi;\r\n    }\r\n\r\n    private void modReplace(Map<Local, Value> toReplace, Cfg.TravelCallBack tcb) {\r\n        for (Map.Entry<Local, Value> e : toReplace.entrySet()) {\r\n            Value v = e.getValue();\r\n            if (v.vt == Value.VT.LOCAL) {\r\n                while (true) {\r\n                    Value v2 = toReplace.get(v);\r\n                    if (v2 == null) {\r\n                        break;\r\n                    }\r\n                    v = v2;\r\n                    if (v.vt != Value.VT.LOCAL) {\r\n                        break;\r\n                    }\r\n                }\r\n                e.setValue(v);\r\n            } else {\r\n                Cfg.travelMod(v, tcb);\r\n            }\r\n        }\r\n    }\r\n\r\n    static boolean isLocationInsensitive(Value.VT vt) {\r\n        switch (vt) {\r\n            case LOCAL:\r\n            case CONSTANT:\r\n                // +-*/\r\n            case ADD:\r\n            case SUB:\r\n            case MUL:\r\n                // case DIV:   // div is not\r\n            case REM:\r\n                // logical\r\n            case AND:\r\n            case OR:\r\n            case XOR:\r\n\r\n            case SHL:\r\n            case SHR:\r\n            case USHR:\r\n                //cmp\r\n            case GE:\r\n            case GT:\r\n            case LE:\r\n            case LT:\r\n            case EQ:\r\n            case NE:\r\n            case DCMPG:\r\n            case DCMPL:\r\n            case LCMP:\r\n            case FCMPG:\r\n            case FCMPL:\r\n            case NOT:\r\n                return true;\r\n            default:\r\n        }\r\n        return false;\r\n    }\r\n\r\n    static boolean isLocationInsensitive(Value op) {\r\n        switch (op.et) {\r\n            case E0:\r\n                return isLocationInsensitive(op.vt);\r\n            case E1:\r\n                return isLocationInsensitive(op.vt) && isLocationInsensitive(op.getOp());\r\n            case E2:\r\n                return isLocationInsensitive(op.vt) && isLocationInsensitive(op.getOp1()) && isLocationInsensitive(op.getOp2());\r\n            case En:\r\n                if (op.vt == Value.VT.INVOKE_STATIC) {\r\n                    InvokeExpr ie = (InvokeExpr) op;\r\n                    if (ie.getName().equals(\"valueOf\") && ie.getOwner().startsWith(\"Ljava/lang/\") && ie.getArgs().length == 1 && ie.getArgs()[0].length() == 1) {\r\n                        for (Value v : op.getOps()) {\r\n                            if (!isLocationInsensitive(v)) {\r\n                                return false;\r\n                            }\r\n                        }\r\n                        return true;\r\n                    }\r\n                    return false;\r\n                }\r\n                if (isLocationInsensitive(op.vt)) {\r\n                    for (Value v : op.getOps()) {\r\n                        if (!isLocationInsensitive(v)) {\r\n                            return false;\r\n                        }\r\n                    }\r\n                    return true;\r\n                }\r\n                return false;\r\n        }\r\n        return false;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/Cfg.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport java.util.Collections;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.TreeSet;\n\nimport com.googlecode.dex2jar.ir.ET;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.*;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\n\n/**\n * TODO DOC\n *\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * @version $Rev$\n */\npublic class Cfg {\n\n    public static int[] countLocalReads(IrMethod method) {\n        int size = reIndexLocal(method);\n        final int readCounts[] = new int[size];\n        travel(method.stmts, new TravelCallBack() {\n            @Override\n            public Value onAssign(Local v, AssignStmt as) {\n                return v;\n            }\n\n            @Override\n            public Value onUse(Local v) {\n                readCounts[v._ls_index]++;\n                return v;\n            }\n        }, true);\n        return readCounts;\n    }\n\n    public static void reIndexLocalAndLabel(IrMethod irMethod) {\n        reIndexLocal(irMethod);\n        reIndexLabel(irMethod);\n    }\n\n    private static void reIndexLabel(IrMethod irMethod) {\n        int i = 0;\n        for (Stmt stmt : irMethod.stmts) {\n            if (stmt.st == ST.LABEL) {\n                ((LabelStmt) stmt).displayName = \"L\" + i++;\n            }\n        }\n    }\n\n    public interface FrameVisitor<T> {\n        T merge(T srcFrame, T distFrame, Stmt src, Stmt dist);\n\n        T initFirstFrame(Stmt first);\n\n        T exec(T frame, Stmt stmt);\n    }\n\n\n    public static boolean notThrow(Stmt s) {\n        return !isThrow(s);\n    }\n\n    public static boolean isThrow(Stmt s) {\n        ST st = s.st;\n        if (st.canThrow()) {\n            return true;\n        } else if (st.mayThrow()) {\n            ET et = s.et;\n            if (et == ET.E1) {\n                return isThrow(s.getOp());\n            } else if (et == ET.E2) {\n                return isThrow(s.getOp1()) || isThrow(s.getOp2());\n            } else {\n                throw new RuntimeException();\n            }\n        } else {\n            return false;\n        }\n    }\n\n    private static boolean isThrow(Value op) {\n        VT vt = op.vt;\n        if (vt.canThrow()) {\n            return true;\n        } else if (vt.mayThrow()) {\n            switch (op.et) {\n            case E1:\n                return isThrow(op.getOp());\n            case E2:\n                return isThrow(op.getOp1()) || isThrow(op.getOp2());\n            default:\n            case En:\n            case E0:\n                throw new RuntimeException();\n            }\n        } else {\n            return false;\n        }\n    }\n\n    public static void createCfgWithoutEx(IrMethod jm) {\n        for (Stmt st : jm.stmts) {\n            st.frame = null;\n            st.exceptionHandlers = null;\n            if (st._cfg_froms == null) {\n                st._cfg_froms = new TreeSet<>(jm.stmts);\n            } else {\n                st._cfg_froms.clear();\n            }\n        }\n\n        for (Stmt st : jm.stmts) {\n            if (st.st.canBranch()) {\n                link(st, ((JumpStmt) st).getTarget());\n            }\n            if (st.st.canContinue()) {\n                link(st, st.getNext());\n            }\n            if (st.st.canSwitch()) {\n                BaseSwitchStmt bss = (BaseSwitchStmt) st;\n                link(st, bss.defaultTarget);\n                for (Stmt target : bss.targets) {\n                    link(st, target);\n                }\n            }\n        }\n    }\n\n    public static void createCFG(IrMethod jm) {\n        createCfgWithoutEx(jm);\n        for (Trap t : jm.traps) {\n            for (Stmt s = t.start; s != t.end; s = s.getNext()) {\n                if (isThrow(s)) {\n                    Set<LabelStmt> hs = s.exceptionHandlers;\n                    if (hs == null) {\n                        hs = new TreeSet<>(jm.stmts);\n                        s.exceptionHandlers = hs;\n                    }\n                    for (LabelStmt handler : t.handlers) {\n                        link(s, handler);\n                        hs.add(handler);\n                    }\n                }\n            }\n        }\n\n    }\n\n    public static interface DfsVisitor {\n        void onVisit(Stmt p);\n    }\n\n    public static void dfsVisit(IrMethod method, DfsVisitor visitor) {\n        for (Stmt st : method.stmts) {\n            st.visited = false;\n        }\n        Stack<Stmt> stack = new Stack<>();\n        stack.add(method.stmts.getFirst());\n        while (!stack.isEmpty()) {\n            Stmt currentStmt = stack.pop();\n            if (currentStmt.visited) {\n                continue;\n            } else {\n                currentStmt.visited = true;\n            }\n            if (currentStmt.exceptionHandlers != null) {\n                for (LabelStmt labelStmt : currentStmt.exceptionHandlers) {\n                    stack.push(labelStmt);\n                }\n            }\n            if (visitor != null) {\n                visitor.onVisit(currentStmt);\n            }\n            if (currentStmt.st.canSwitch()) {\n                BaseSwitchStmt bs = (BaseSwitchStmt) currentStmt;\n                Collections.addAll(stack, bs.targets);\n                LabelStmt target = bs.defaultTarget;\n                stack.add(target);\n            }\n            if (currentStmt.st.canBranch()) {\n                Stmt target = ((JumpStmt) currentStmt).getTarget();\n                stack.add(target);\n            }\n            if (currentStmt.st.canContinue()) {\n                Stmt target = currentStmt.getNext();\n                stack.add(target);\n            }\n        }\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static <T> void dfs(StmtList stmts, FrameVisitor<T> sv) {\n        if (stmts.getSize() == 0) {\n            return;\n        }\n        // clean\n        for (Stmt st : stmts) {\n            st.visited = false;\n            st.frame = null;\n        }\n\n        Stack<Stmt> stack = new Stack<Stmt>();\n        Stmt first = stmts.getFirst();\n        Stmt nop = null;\n        if (first.st == ST.LABEL && first._cfg_froms.size() > 0) {\n            nop = Stmts.nNop();\n            // for\n            // L0:\n            // ...\n            // GOTO L0:\n            // make sure the first Label has one more super\n            first._cfg_froms.add(nop);\n        }\n        stack.add(first);\n        first.frame = sv.initFirstFrame(first);\n\n        while (!stack.isEmpty()) {\n            Stmt currentStmt = stack.pop();\n            if (currentStmt == null || currentStmt.visited) {\n                continue;\n            } else {\n                currentStmt.visited = true;\n            }\n\n            T beforeExecFrame = (T) currentStmt.frame;\n            \n            if (currentStmt.exceptionHandlers != null) {\n                for (LabelStmt labelStmt : currentStmt.exceptionHandlers) {\n                    labelStmt.frame = sv.merge(beforeExecFrame, (T) labelStmt.frame, currentStmt, labelStmt);\n                    stack.push(labelStmt);\n                }\n            }\n            \n            T afterExecFrame = sv.exec(beforeExecFrame, currentStmt);\n\n            if (currentStmt.st.canSwitch()) {\n                BaseSwitchStmt bs = (BaseSwitchStmt) currentStmt;\n                for (LabelStmt target : bs.targets) {\n                    target.frame = sv.merge(afterExecFrame, (T) target.frame, currentStmt, target);\n                    stack.push(target);\n                }\n                LabelStmt target = bs.defaultTarget;\n                target.frame = sv.merge(afterExecFrame, (T) target.frame, currentStmt, target);\n                stack.push(target);\n            }\n            if (currentStmt.st.canBranch()) {\n                Stmt target = ((JumpStmt) currentStmt).getTarget();\n                target.frame = sv.merge(afterExecFrame, (T) target.frame, currentStmt, target);\n                stack.push(target);\n            }\n            if (currentStmt.st.canContinue()) {\n                Stmt target = currentStmt.getNext();\n                target.frame = sv.merge(afterExecFrame, (T) target.frame, currentStmt, target);\n                stack.push(target);\n            }\n        }\n\n        if (nop != null) {\n            first._cfg_froms.remove(nop);\n        }      \n    }\n\n    private static void link(Stmt from, Stmt to) {\n        if (to == null) {// last stmt is a LabelStmt\n            return;\n        }\n        to._cfg_froms.add(from);\n    }\n\n    public interface OnUseCallBack {\n        Value onUse(Local v);\n    }\n\n    public interface OnAssignCallBack {\n        Value onAssign(Local v, AssignStmt as);\n    }\n\n    public interface TravelCallBack extends OnUseCallBack, OnAssignCallBack {\n\n    }\n\n    public static Value travelMod(Value value, OnUseCallBack callback) {\n        switch (value.et) {\n        case E0:\n            if (value.vt == VT.LOCAL) {\n                return callback.onUse((Local) value);\n            }\n            break;\n        case E1:\n            value.setOp(travelMod(value.getOp(), callback));\n            break;\n        case E2:\n            value.setOp1(travelMod(value.getOp1(), callback));\n            value.setOp2(travelMod(value.getOp2(), callback));\n            break;\n        case En:\n            Value ops[] = value.getOps();\n            for (int i = 0; i < ops.length; i++) {\n                ops[i] = travelMod(ops[i], callback);\n            }\n            break;\n        }\n        return value;\n    }\n\n    public static void travel(Value value, OnUseCallBack callback) {\n        switch (value.et) {\n        case E0:\n            if (value.vt == VT.LOCAL) {\n                callback.onUse((Local) value);\n            }\n            break;\n        case E1:\n            travel(value.getOp(), callback);\n            break;\n        case E2:\n            travel(value.getOp1(), callback);\n            travel(value.getOp2(), callback);\n            break;\n        case En:\n            Value ops[] = value.getOps();\n            for (int i = 0; i < ops.length; i++) {\n                travel(ops[i], callback);\n            }\n            break;\n        }\n    }\n\n    public static void travelMod(Stmt p, TravelCallBack callback, boolean travelPhi) {\n        switch (p.et) {\n        case E1:\n            p.setOp(travelMod(p.getOp(), callback));\n            break;\n        case E2:\n            Value e2op1 = p.getOp1();\n            if (e2op1.vt == VT.LOCAL && (p.st == ST.ASSIGN || p.st == ST.IDENTITY)) {\n                p.setOp2(travelMod(p.getOp2(), callback));\n                p.setOp1(callback.onAssign((Local) e2op1, (AssignStmt) p));\n            } else {\n                p.setOp1(travelMod(p.getOp1(), callback));\n                p.setOp2(travelMod(p.getOp2(), callback));\n            }\n            break;\n        case En:\n        case E0:\n            if (travelPhi && p.st == ST.LABEL) {\n                LabelStmt labelStmt = (LabelStmt) p;\n                if (labelStmt.phis != null) {\n                    for (AssignStmt phi : labelStmt.phis) {\n                        travelMod(phi, callback, false);\n                    }\n                }\n            }\n            break;\n        }\n    }\n\n    public static void travel(Stmt p, TravelCallBack callback, boolean travelPhi) {\n        switch (p.et) {\n        case E1:\n            travel(p.getOp(), callback);\n            break;\n        case E2:\n            Value e2op1 = p.getOp1();\n            if (e2op1.vt == VT.LOCAL && (p.st == ST.ASSIGN || p.st == ST.IDENTITY)) {\n                travel(p.getOp2(), callback);\n                callback.onAssign((Local) e2op1, (AssignStmt) p);\n            } else {\n                travel(p.getOp1(), callback);\n                travel(p.getOp2(), callback);\n            }\n            break;\n        case En:\n        case E0:\n            if (travelPhi && p.st == ST.LABEL) {\n                LabelStmt labelStmt = (LabelStmt) p;\n                if (labelStmt.phis != null) {\n                    for (AssignStmt phi : labelStmt.phis) {\n                        travel(phi, callback, false);\n                    }\n                }\n            }\n            break;\n        }\n    }\n\n    public static void travel(StmtList stmts, TravelCallBack callback, boolean travelPhi) {\n        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {\n            travel(p, callback, travelPhi);\n        }\n    }\n\n    public static void travelMod(StmtList stmts, TravelCallBack callback, boolean travelPhi) {\n        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {\n            travelMod(p, callback, travelPhi);\n        }\n    }\n\n    /**\n     * @param method\n     * @return size of locals\n     */\n    public static int reIndexLocal(IrMethod method) {\n        int i = 0;\n        for (Local local : method.locals) {\n            local._ls_index = i++;\n        }\n        return i;\n    }\n\n    public static void collectTos(Stmt stmt, Set<Stmt> tos) {\n        if (stmt.st.canBranch()) {\n            tos.add(((JumpStmt) stmt).getTarget());\n        }\n        if (stmt.st.canContinue()) {\n            tos.add(stmt.getNext());\n        }\n        if (stmt.st.canSwitch()) {\n            BaseSwitchStmt bss = (BaseSwitchStmt) stmt;\n            tos.add(bss.defaultTarget);\n\n            for (Stmt target : bss.targets) {\n                tos.add(target);\n            }\n        }\n        if (stmt.exceptionHandlers != null) {\n            tos.addAll(stmt.exceptionHandlers);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/CleanLabel.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.LocalVar;\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.stmt.*;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\n\n/**\n * Clean unused {@link LabelStmt}\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class CleanLabel implements Transformer {\n\n    @Override\n    public void transform(IrMethod irMethod) {\n        Set<LabelStmt> uselabels = new HashSet<LabelStmt>();\n        addTrap(irMethod.traps, uselabels);\n        addVars(irMethod.vars, uselabels);\n        addStmt(irMethod.stmts, uselabels);\n        if (irMethod.phiLabels != null) {\n            uselabels.addAll(irMethod.phiLabels);\n        }\n        rmUnused(irMethod.stmts, uselabels);\n    }\n\n    private void addVars(List<LocalVar> vars, Set<LabelStmt> uselabels) {\n        if (vars != null) {\n            for (LocalVar var : vars) {\n                uselabels.add(var.start);\n                uselabels.add(var.end);\n            }\n        }\n\n    }\n\n    private void rmUnused(StmtList stmts, Set<LabelStmt> uselabels) {\n        for (Stmt p = stmts.getFirst(); p != null;) {\n            if (p.st == ST.LABEL) {\n                if (!uselabels.contains(p)) {\n                    Stmt q = p.getNext();\n                    stmts.remove(p);\n                    p = q;\n                    continue;\n                }\n            }\n            p = p.getNext();\n        }\n    }\n\n    private void addStmt(StmtList stmts, Set<LabelStmt> labels) {\n        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {\n            if (p instanceof JumpStmt) {\n                labels.add(((JumpStmt) p).getTarget());\n            } else if (p instanceof BaseSwitchStmt) {\n                BaseSwitchStmt stmt = (BaseSwitchStmt) p;\n                labels.add(stmt.defaultTarget);\n                for (LabelStmt t : stmt.targets) {\n                    labels.add(t);\n                }\n            }\n        }\n    }\n\n    private void addTrap(List<Trap> traps, Set<LabelStmt> labels) {\n        if (traps != null) {\n            for (Trap trap : traps) {\n                labels.add(trap.start);\n                labels.add(trap.end);\n                for (LabelStmt h : trap.handlers) {\n                    labels.add(h);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/ConstTransformer.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.*;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack;\n\nimport java.util.HashSet;\nimport java.util.Queue;\nimport java.util.Set;\n\n/**\n * Replace must-be-constant local to constant\n * <p/>\n * Require a SSA form, usually run after {@link SSATransformer}\n *\n * @author Panxiaobo\n */\n@SuppressWarnings({\"unchecked\", \"rawtypes\"})\npublic class ConstTransformer implements Transformer {\n    @Override\n    public void transform(IrMethod m) {\n\n        // 1. init\n        init(m);\n\n        // 2. collect\n        collect(m);\n\n        // 3. mark constant\n        markConstant(m);\n        markReplacable(m);\n        // 4. replace\n        replace(m);\n\n        // 5. clean\n        clean(m);\n    }\n\n    private void clean(IrMethod m) {\n        for (Local local : m.locals) {\n            local.tag = null;\n        }\n    }\n\n    private void replace(IrMethod m) {\n        Cfg.travelMod(m.stmts, new TravelCallBack() {\n\n            @Override\n            public Value onUse(Local v) {\n                ConstAnalyzeValue cav = (ConstAnalyzeValue) v.tag;\n                if (cav.replacable) {\n                    return Exprs.nConstant(cav.cst);\n                }\n                return v;\n            }\n\n            @Override\n            public Value onAssign(Local v, AssignStmt as) {\n                ConstAnalyzeValue cav = (ConstAnalyzeValue) v.tag;\n                if (cav.replacable) {\n                    if (as.op2.trim().vt != VT.CONSTANT) {\n                        as.op2 = Exprs.nConstant(cav.cst);\n                    }\n                }\n                return v;\n            }\n\n        }, true);\n    }\n\n    private void markReplacable(IrMethod m) {\n        for (Local local : m.locals) {\n            ConstAnalyzeValue cav = (ConstAnalyzeValue) local.tag;\n            if (Boolean.TRUE.equals(cav.isConst)) {\n                boolean allTosAreCst = true;\n                for (ConstAnalyzeValue c : cav.assignTo) {\n                    if (!Boolean.TRUE.equals(c.isConst)) {\n                        allTosAreCst = false;\n                        break;\n                    }\n                }\n                if (allTosAreCst) {\n                    cav.replacable = true;\n                }\n            }\n        }\n    }\n\n    private void markConstant(IrMethod m) {\n        Queue<Local> queue = new UniqueQueue<>();\n        queue.addAll(m.locals);\n        while (!queue.isEmpty()) {\n            ConstAnalyzeValue cav = (ConstAnalyzeValue) queue.poll().tag;\n\n            Object cst = cav.cst;\n\n            if (cav.isConst == null) {\n                if (cst != null) {// we have a cst\n                    boolean allCstEquals = true;\n                    for (ConstAnalyzeValue p0 : cav.assignFrom) {\n                        if (!cst.equals(p0.cst)) {\n                            allCstEquals = false;\n                            break;\n                        }\n                    }\n                    if (allCstEquals) {\n                        cav.isConst = true;\n\n                    }\n                }\n            }\n\n            if (cst != null || Boolean.TRUE.equals(cav.isConst)) {\n                for (ConstAnalyzeValue p0 : cav.assignTo) {\n                    if (p0.isConst == null) {\n                        if (p0.cst == null) {\n                            p0.cst = cst;\n                        }\n                        queue.add(p0.local);\n                    }\n                }\n            }\n\n            if (Boolean.FALSE.equals(cav.isConst)) {\n                cav.cst = null;\n                for (ConstAnalyzeValue c : cav.assignTo) {\n                    if (!Boolean.FALSE.equals(c.isConst)) {\n                        c.cst = null;\n                        c.isConst = false;\n                        queue.add(c.local);\n                    }\n                }\n            }\n        }\n    }\n\n    private void collect(IrMethod m) {\n        for (Stmt p = m.stmts.getFirst(); p != null; p = p.getNext()) {\n            if (p.st == ST.ASSIGN || p.st == ST.IDENTITY) {\n                E2Stmt e2 = (E2Stmt) p;\n                Value op1 = e2.op1.trim();\n                Value op2 = e2.op2.trim();\n                if (op1.vt == VT.LOCAL) {\n                    ConstAnalyzeValue cav = (ConstAnalyzeValue) ((Local) op1).tag;\n                    if (op2.vt == VT.CONSTANT) {\n                        Constant c = (Constant) op2;\n                        cav.isConst = true;\n                        cav.cst = c.value;\n                    } else if (op2.vt == VT.LOCAL) {\n                        Local local2 = (Local) op2;\n                        ConstAnalyzeValue zaf2 = (ConstAnalyzeValue) local2.tag;\n                        cav.assignFrom.add(zaf2);\n                        zaf2.assignTo.add(cav);\n                    } else if (op2.vt == VT.PHI) {\n                        PhiExpr pe = (PhiExpr) op2;\n                        for (Value v : pe.ops) {\n                            ConstAnalyzeValue zaf2 = (ConstAnalyzeValue) ((Local) v.trim()).tag;\n                            cav.assignFrom.add(zaf2);\n                            zaf2.assignTo.add(cav);\n                        }\n                    } else {\n                        cav.isConst = Boolean.FALSE;\n                    }\n                }\n            }\n        }\n    }\n\n    private void init(IrMethod m) {\n        for (Local local : m.locals) {\n            local.tag = new ConstAnalyzeValue(local);\n        }\n    }\n\n    static class ConstAnalyzeValue {\n        private static final Integer ZERO = Integer.valueOf(0);\n        public final Local local;\n        public Boolean isConst = null;\n        public boolean replacable = false;\n        public Object cst;\n        public Set<ConstAnalyzeValue> assignFrom = new HashSet(3);\n        public Set<ConstAnalyzeValue> assignTo = new HashSet(3);\n\n        public ConstAnalyzeValue(Local local) {\n            super();\n            this.local = local;\n        }\n\n        public boolean isZero() {\n            if (isConst == null) {\n                return false;\n            }\n            return isConst && (ZERO.equals(cst));\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/DeadCodeTransformer.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.Trap;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.PhiExpr;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\n\r\nimport java.util.*;\r\n\r\npublic class DeadCodeTransformer implements Transformer {\r\n    @Override\r\n    public void transform(IrMethod method) {\r\n        Cfg.createCFG(method);\r\n        Cfg.dfsVisit(method, null);\r\n        if (method.traps != null) {\r\n            for (Iterator<Trap> it = method.traps.iterator(); it.hasNext();) {\r\n                Trap t = it.next();\r\n                boolean allNotThrow = true;\r\n                for (Stmt p = t.start; p != t.end; p = p.getNext()) {\r\n                    if (p.visited && Cfg.isThrow(p)) {\r\n                        allNotThrow = false;\r\n                        break;\r\n                    }\r\n                }\r\n                if (allNotThrow) {\r\n                    it.remove();\r\n                    continue;\r\n                }\r\n\r\n                boolean allNotVisited = true;\r\n                boolean allVisited = true;\r\n                for (LabelStmt labelStmt : t.handlers) {\r\n                    if (labelStmt.visited) {\r\n                        allNotVisited = false;\r\n                    } else {\r\n                        allVisited = false;\r\n                    }\r\n                }\r\n                if (allNotVisited) {\r\n                    it.remove();\r\n                } else {\r\n                    // keep start and end\r\n                    t.start.visited = true;\r\n                    t.end.visited = true;\r\n                    if (!allVisited) { // part visited\r\n                        List<String> types = new ArrayList<>(t.handlers.length);\r\n                        List<LabelStmt> labelStmts = new ArrayList<>(t.handlers.length);\r\n                        for (int i = 0; i < t.handlers.length; i++) {\r\n                            labelStmts.add(t.handlers[i]);\r\n                            types.add(t.types[i]);\r\n                        }\r\n                        t.handlers = labelStmts.toArray(new LabelStmt[labelStmts.size()]);\r\n                        t.types = types.toArray(new String[types.size()]);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        Set<Local> definedLocals = new HashSet<>();\r\n        for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext();) {\r\n            Stmt p = it.next();\r\n            if (!p.visited) {\r\n                it.remove();\r\n                continue;\r\n            }\r\n            if (p.st == Stmt.ST.ASSIGN || p.st == Stmt.ST.IDENTITY) {\r\n                if (p.getOp1().vt == Value.VT.LOCAL) {\r\n                    definedLocals.add((Local) p.getOp1());\r\n                }\r\n            }\r\n        }\r\n        if (method.phiLabels != null) {\r\n            for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext();) {\r\n                LabelStmt labelStmt = it.next();\r\n                if (!labelStmt.visited) {\r\n                    it.remove();\r\n                    continue;\r\n                }\r\n                if (labelStmt.phis != null) {\r\n                    for (AssignStmt phi : labelStmt.phis) {\r\n                        definedLocals.add((Local) phi.getOp1());\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        method.locals.clear();\r\n        method.locals.addAll(definedLocals);\r\n        Set<Value> tmp = new HashSet<>();\r\n        if (method.phiLabels != null) {\r\n            for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext();) {\r\n                LabelStmt labelStmt = it.next();\r\n                if (labelStmt.phis != null) {\r\n                    for (AssignStmt phi : labelStmt.phis) {\r\n                        PhiExpr phiExpr = (PhiExpr) phi.getOp2();\r\n                        boolean needRebuild = false;\r\n                        for (Value v : phiExpr.getOps()) {\r\n                            if (!definedLocals.contains(v)) {\r\n                                needRebuild = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (needRebuild) {\r\n                            for (Value v : phiExpr.getOps()) {\r\n                                if (definedLocals.contains(v)) {\r\n                                    tmp.add(v);\r\n                                }\r\n                            }\r\n                            phiExpr.setOps(tmp.toArray(new Value[tmp.size()]));\r\n                            tmp.clear();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/EndRemover.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\r\nimport com.googlecode.dex2jar.ir.Trap;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.stmt.*;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\r\n\r\nimport java.util.ArrayList;\r\n\r\n/**\r\n * Try to clean following between a {@link Trap}\r\n * <ol>\r\n * <li>Move {@link Stmt}s outside a {@link Trap} if {@link Stmt}s are not throw</li>\r\n * <li>Remove {@link Trap} if all {@link Stmt}s are not throw</li>\r\n * <li>...;GOTO L2; ... ; L2: ; return; => ...;return ; ... ; L2: ; return;</li>\r\n * </ol>\r\n * \r\n * @author bob\r\n * \r\n */\r\npublic class EndRemover implements Transformer {\r\n\r\n    private static final LabelAndLocalMapper keepLocal = new LabelAndLocalMapper() {\r\n        @Override\r\n        public Local map(Local local) {\r\n            return local;\r\n        }\r\n    };\r\n\r\n    @Override\r\n    public void transform(IrMethod irMethod) {\r\n        for (Trap trap : new ArrayList<Trap>(irMethod.traps)) {// copy the list and we can remove one from original list\r\n            LabelStmt start = null;\r\n            boolean removeTrap = true;\r\n            for (Stmt p = trap.start.getNext(); p != null && p != trap.end;) {\r\n                boolean notThrow = Cfg.notThrow(p);\r\n                if (!notThrow) {\r\n                    start = null;\r\n                    p = p.getNext();\r\n                    removeTrap = false;\r\n                    continue;\r\n                }\r\n                switch (p.st) {\r\n                case LABEL:\r\n                    if (start != null) {\r\n                        move4Label(irMethod.stmts, start, p.getPre(), (LabelStmt) p);\r\n                    }\r\n                    start = (LabelStmt) p;\r\n                    p = p.getNext();\r\n\r\n                    break;\r\n                case GOTO:\r\n                case RETURN:\r\n                case RETURN_VOID:\r\n                    if (start != null) {\r\n                        Stmt tmp = p.getNext();\r\n                        move4End(irMethod.stmts, start, p);\r\n                        start = null;\r\n                        p = tmp;\r\n                    } else {\r\n                        p = p.getNext();\r\n                    }\r\n                    break;\r\n                default:\r\n                    p = p.getNext();\r\n                }\r\n            }\r\n            if (removeTrap) {\r\n                irMethod.traps.remove(trap);\r\n            }\r\n        }\r\n        StmtList stmts = irMethod.stmts;\r\n        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {\r\n            if (p.st == ST.GOTO) {\r\n                LabelStmt target = ((GotoStmt) p).target;\r\n                Stmt next = target.getNext();\r\n                if (next != null && (next.st == ST.RETURN || next.st == ST.RETURN_VOID)) {\r\n                    Stmt nnext = next.clone(keepLocal);\r\n                    stmts.insertAfter(p, nnext);\r\n                    stmts.remove(p);\r\n                    p = nnext;\r\n                }\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n    private void move4Label(StmtList stmts, LabelStmt start, Stmt end, LabelStmt label) {\r\n        move4End(stmts, start, end);\r\n        stmts.insertAfter(end, Stmts.nGoto(label));\r\n    }\r\n\r\n    private void move4End(StmtList stmts, LabelStmt start, Stmt end) {\r\n        Stmt g1 = Stmts.nGoto(start);\r\n        stmts.insertBefore(start, g1);\r\n        Stmt last = stmts.getLast();\r\n        while (last.st == ST.GOTO && ((GotoStmt) last).target == start) {\r\n            stmts.remove(last);\r\n            last = stmts.getLast();\r\n        }\r\n        stmts.move(start, end, last);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/ExceptionHandlerTrim.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.LabelAndLocalMapper;\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Trim Exception handler.\n * \n * before:\n * \n * <pre>\n * L1\n * STMTs\n * throwableSTMTs\n * STMTs\n * throwableSTMTs\n * L2\n * ...\n * L3\n * ...\n * \n * L1 - L2 : all > L3\n * \n * </pre>\n * \n * after:\n * \n * <pre>\n * L1\n * STMTs\n * L4\n * throwableSTMTs\n * L5\n * STMTs\n * L6\n * throwableSTMTs\n * L2\n * ...\n * L3\n * ...\n * \n * L4 - L5 : all > L3\n * L6 - L2 : all > L3\n * </pre>\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class ExceptionHandlerTrim implements Transformer {\n\n    @SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n    @Override\n    public void transform(IrMethod irMethod) {\n        List<Trap> trips = irMethod.traps;\n        irMethod.traps = new ArrayList();\n        LabelAndLocalMapper map=new LabelAndLocalMapper(){\n            @Override\n            public LabelStmt map(LabelStmt label) {\n                return label;\n            }\n        };\n        for (Trap trap : trips) {\n            Trap ntrap = trap.clone(map);\n            int status = 0;\n            for (Stmt p = trap.start.getNext(); p != trap.end; p = p.getNext()) {\n                if (!Cfg.notThrow(p)) {\n                    if (status == 0) {\n                        Stmt pre = p.getPre();\n                        if (pre == null || pre.st != ST.LABEL) {\n                            pre = Stmts.nLabel();\n                            irMethod.stmts.insertBefore(p, pre);\n                        }\n                        ntrap.start = (LabelStmt) pre;\n                        status = 1;\n                    } else if (status == 1) {\n                        // continue;\n                    }\n\n                } else if (status == 1) {\n                    Stmt pre = p.getPre();\n                    if (pre == null || pre.st != ST.LABEL) {\n                        pre = Stmts.nLabel();\n                        irMethod.stmts.insertBefore(p, pre);\n                    }\n\n                    ntrap.end = (LabelStmt) pre;\n                    irMethod.traps.add(ntrap);\n                    status = 0;\n                    ntrap = trap.clone(map);\n                }\n            }\n            if (status == 1) {\n                ntrap.end = trap.end;\n                irMethod.traps.add(ntrap);\n                status = 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/FixVar.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.LocalVar;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\n\r\n/**\r\n * the {@link LocalVar#reg} in {@link LocalVar} may be replace to a constant value in {@link ConstTransformer}. This\r\n * class try to insert a new local before {@link LocalVar#start}.\r\n * \r\n * <p>\r\n * before:\r\n * </p>\r\n * \r\n * <pre>\r\n *   ...\r\n * L0:\r\n *   return a0\r\n * L1:\r\n * ======\r\n * .var L0 ~ L1 1 -> test // int\r\n * </pre>\r\n * <p>\r\n * after:\r\n * </p>\r\n * \r\n * <pre>\r\n *   ...\r\n *   d1 = 1\r\n * L0:\r\n *   return a0\r\n * L1:\r\n * ======\r\n * .var L0 ~ L1 d1 -> test // int\r\n * </pre>\r\n * \r\n * @author Panxiaobo\r\n * \r\n */\r\npublic class FixVar implements Transformer {\r\n\r\n    @Override\r\n    public void transform(IrMethod irMethod) {\r\n        int i = 0;\r\n        for (LocalVar var : irMethod.vars) {\r\n            if (var.reg.trim().vt != VT.LOCAL) {\r\n                if (var.reg.trim().vt == VT.CONSTANT) {\r\n                    Local n = new Local(i++);\r\n                    Value old = var.reg.trim();\r\n                    irMethod.stmts.insertBefore(var.start, Stmts.nAssign(n, old));\r\n                    var.reg = n;\r\n                    irMethod.locals.add(n);\r\n                } else {\r\n                    // throw new DexExcpeption(\"not support\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/Ir2JRegAssignTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport java.util.*;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.RefExpr;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.ts.an.SimpleLiveAnalyze;\nimport com.googlecode.dex2jar.ir.ts.an.SimpleLiveValue;\n\n/**\n * <ol>\n * <li>Share same reg between locals with same type.</li>\n * <li>@This always assign as 0, and not share with others.</li>\n * <li>long/double tasks two index</li>\n * </ol>\n *\n * @author bob\n */\npublic class Ir2JRegAssignTransformer implements Transformer {\n\n    public static class Reg {\n        public Set<Reg> excludes = new HashSet<>(4);\n        public Set<Reg> prefers = new HashSet<>(3);\n        int reg = -1;\n        public char type;\n    }\n\n    private static final Comparator<Reg> OrderRegAssignByPreferredSizeDesc = new Comparator<Reg>() {\n\n        @Override\n        public int compare(Reg o1, Reg o2) {\n            int x = o2.prefers.size() - o1.prefers.size();\n            if (x == 0) {\n                x = o2.excludes.size() - o1.excludes.size();\n            }\n            return x;\n        }\n    };\n\n    private Reg[] genGraph(IrMethod method, final Reg[] regs) {\n        Reg args[];\n        if (method.isStatic) {\n            args = new Reg[method.args.length];\n        } else {\n            args = new Reg[method.args.length + 1];\n        }\n\n        Set<Stmt> tos = new HashSet<>();\n        for (Stmt stmt : method.stmts) {\n            if (stmt.st == ST.ASSIGN || stmt.st == ST.IDENTITY) {\n                if (stmt.getOp1().vt == VT.LOCAL) {\n                    Local left = (Local) stmt.getOp1();\n                    Value op2 = stmt.getOp2();\n                    int idx = left._ls_index;\n                    Reg leftReg = regs[idx];\n\n                    // a new local can't effect next value live in next frame\n                    Cfg.collectTos(stmt, tos);\n                    for (Stmt next : tos) {\n                        SimpleLiveValue[] frame = (SimpleLiveValue[]) next.frame;\n                        if (frame == null) {\n                            continue;\n                        }\n                        for (int i = 0; i < frame.length; i++) {\n                            if (i == idx) {\n                                continue;\n                            }\n                            SimpleLiveValue v = frame[i];\n                            if (v != null && v.used) {\n                                Reg rightReg = regs[i];\n                                leftReg.excludes.add(rightReg);\n                                rightReg.excludes.add(leftReg);\n                            }\n                        }\n                    }\n                    tos.clear();\n\n                    // Preferred same reg can save load-store\n                    if (op2.vt == VT.LOCAL) {\n                        Reg rightReg = regs[((Local) op2)._ls_index];\n                        leftReg.prefers.add(rightReg);\n                        rightReg.prefers.add(leftReg);\n                    }\n\n                    // record @this @parameter_x\n                    if (op2.vt == VT.THIS_REF) {\n                        args[0] = leftReg;\n                    } else if (op2.vt == VT.PARAMETER_REF) {\n                        RefExpr refExpr = (RefExpr) op2;\n                        if (method.isStatic) {\n                            args[refExpr.parameterIndex] = leftReg;\n                        } else {\n                            args[refExpr.parameterIndex + 1] = leftReg;\n                        }\n                    }\n                }\n            }\n        }\n        // remove the link between itself\n        for (Reg reg : regs) {\n            reg.excludes.remove(reg);\n            reg.prefers.remove(reg);\n        }\n        return args;\n    }\n\n   Map<Character, List<Reg>> groupAndCleanUpByType(Reg[] regs) {\n        Map<Character, List<Reg>> groups = new HashMap<>();\n        for (Reg reg : regs) {\n            char simpleType = reg.type;\n            List<Reg> group = groups.get(simpleType);\n            if (group == null) {\n                group = new ArrayList<>();\n                groups.put(simpleType, group);\n            }\n            group.add(reg);\n\n            for (Iterator<Reg> it = reg.excludes.iterator(); it.hasNext(); ) {\n                Reg ex = it.next();\n                if (ex.type != reg.type) {\n                    it.remove();\n                }\n            }\n            for (Iterator<Reg> it = reg.prefers.iterator(); it.hasNext(); ) {\n                Reg ex = it.next();\n                if (ex.type != reg.type) {\n                    it.remove();\n                }\n            }\n        }\n        return groups;\n    }\n\n    private void initExcludeColor(BitSet excludeColor, Reg as) {\n        excludeColor.clear();\n        for (Reg ex : as.excludes) {\n            if (ex.reg >= 0) {\n                excludeColor.set(ex.reg);\n                if (ex.type == 'J' || ex.type == 'D') {\n                    excludeColor.set(ex.reg + 1);\n                }\n            }\n        }\n    }\n\n    private void initSuggestColor(BitSet suggestColor, Reg as) {\n        suggestColor.clear();\n        for (Reg ex : as.prefers) {\n            if (ex.reg >= 0) {\n                suggestColor.set(ex.reg);\n            }\n        }\n    }\n\n    @Override\n    public void transform(IrMethod method) {\n        if (method.locals.size() == 0) {\n            return;\n        }\n        SimpleLiveAnalyze sa = new SimpleLiveAnalyze(method, true);\n        sa.analyze();\n\n        // init regs\n        int maxLocalSize = sa.getLocalSize();\n        final Reg regs[] = new Reg[maxLocalSize];\n        for (Local local : method.locals) {\n            Reg reg = new Reg();\n            char type = local.valueType.charAt(0);\n            if (type == '[') {\n                type = 'L';\n            }\n            reg.type = type;\n            local.tag = reg;\n            regs[local._ls_index] = reg;\n        }\n\n        // gen graph\n        Reg[] args = genGraph(method, regs);\n\n        // fix up the graph, make sure @this is not share index with others\n        if (!method.isStatic) {\n            Reg atThis = args[0];\n            for (Reg reg : regs) {\n                if (reg == atThis) {\n                    continue;\n                }\n                reg.excludes.add(atThis);\n                atThis.excludes.add(reg);\n            }\n        }\n\n        { // assgin @this, @parameter_x from index 0\n            int i = 0;\n            int index = 0;\n            if (!method.isStatic) {\n                args[i++].reg = index++;\n            }\n            for (int j = 0; j < method.args.length; j++) {\n                Reg reg = args[i++];\n                String type = method.args[j];\n                if (reg == null) {\n                    index++;\n                } else {\n                    reg.reg = index++;\n                }\n                if (\"J\".equals(type) || \"D\".equals(type)) {\n                    index++;\n                }\n            }\n        }\n\n        Map<Character, List<Reg>> groups = groupAndCleanUpByType(regs);\n        // type each group\n        BitSet excludeColor = new BitSet();\n        BitSet suggestColor = new BitSet();\n        BitSet globalExcludes = new BitSet();\n        BitSet usedInOneType = new BitSet();\n        for (Map.Entry<Character, List<Reg>> e : groups.entrySet()) {\n            List<Reg> assigns = e.getValue();\n            Collections.sort(assigns, OrderRegAssignByPreferredSizeDesc);\n            char type = e.getKey();\n            boolean doubleOrLong = type == 'J' || type == 'D';\n            for (Reg as : assigns) {\n                if (as.reg < 0) {// need color\n\n                    initExcludeColor(excludeColor, as);\n                    excludeParameters(excludeColor, args, type);\n\n                    excludeColor.or(globalExcludes); // exclude index used by other types\n\n                    initSuggestColor(suggestColor, as);\n\n                    // first find a preferred color\n                    for (int i = suggestColor.nextSetBit(0); i >= 0; i = suggestColor.nextSetBit(i + 1)) {\n                        if (doubleOrLong) { // need 2\n                            if (!excludeColor.get(i) && !excludeColor.get(i + 1)) {\n                                as.reg = i;\n                                break;\n                            }\n                        } else {\n                            if (!excludeColor.get(i)) {\n                                as.reg = i;\n                                break;\n                            }\n                        }\n                    }\n                    if (as.reg < 0) {\n                        if (doubleOrLong) {\n                            int reg = -1;\n                            do {\n                                reg++;\n                                reg = excludeColor.nextClearBit(reg);\n                            } while (excludeColor.get(reg + 1));\n                            as.reg = reg;\n                        } else {\n                            int reg = excludeColor.nextClearBit(0);\n                            as.reg = reg;\n                        }\n                    }\n                }\n                usedInOneType.set(as.reg);\n                if (doubleOrLong) {\n                    usedInOneType.set(as.reg + 1);\n                }\n            }\n            globalExcludes.or(usedInOneType);\n            usedInOneType.clear();\n        }\n\n        for (Local local : method.locals) {\n            Reg as = (Reg) local.tag;\n            local._ls_index = as.reg;\n            local.tag = null;\n        }\n        for (Stmt stmt : method.stmts) {\n            stmt.frame = null;\n        }\n    }\n\n    private void excludeParameters(BitSet excludeColor, Reg[] args, char type) {\n        for (Reg arg : args) {\n            if (arg.type != type) {\n                excludeColor.set(arg.reg);\n                if (arg.type == 'J' || arg.type == 'D') {\n                    excludeColor.set(arg.reg + 1);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/JimpleTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Constant;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\n\n/**\n * transforme IR to simple 3-addr format\n * \n * a=b+c+d; => e=b+c; a=e+d;\n * \n * @author bob\n * \n */\npublic class JimpleTransformer implements Transformer {\n\n    static class N {\n        public List<Stmt> tmp;\n        int nextIdx;\n        private List<Local> locals;\n\n        public N(List<Stmt> tmp, List<Local> locals) {\n            super();\n            this.tmp = tmp;\n            this.locals = locals;\n            nextIdx = locals.size();\n        }\n\n        Value newAssign(Value x) {\n            Local loc = Exprs.nLocal(nextIdx++);\n            loc.valueType = x.valueType;\n            locals.add(loc);\n            tmp.add(Stmts.nAssign(loc, x));\n            return loc;\n        }\n\n    }\n\n    @Override\n    public void transform(IrMethod method) {\n        List<Stmt> tmp = new ArrayList<>();\n        N n = new N(tmp, method.locals);\n        for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\n            tmp.clear();\n            convertStmt(p, n);\n            for (Stmt t : tmp) {\n                method.stmts.insertBefore(p, t);\n            }\n\n        }\n    }\n\n    private Value convertExpr(Value x, boolean keep, N tmp) {\n        switch (x.et) {\n        case E0:\n            if (!keep) {\n                switch (x.vt) {\n                case CONSTANT:\n                    Constant cst = (Constant) x;\n                    if (cst.value instanceof String || cst.value instanceof DexType\n                            || cst.value.getClass().isArray()) {\n                        return tmp.newAssign(x);\n                    }\n                    break;\n                case NEW:\n                case STATIC_FIELD:\n                    return tmp.newAssign(x);\n                default:\n                }\n            }\n            break;\n        case E1:\n            x.setOp(convertExpr(x.getOp(), false, tmp));\n            if (!keep) {\n                return tmp.newAssign(x);\n            }\n            break;\n        case E2:\n            x.setOp1(convertExpr(x.getOp1(), false, tmp));\n            x.setOp2(convertExpr(x.getOp2(), false, tmp));\n            if (!keep) {\n                return tmp.newAssign(x);\n            }\n            break;\n        case En:\n            Value[] ops = x.getOps();\n            for (int i = 0; i < ops.length; i++) {\n                ops[i] = convertExpr(ops[i], false, tmp);\n            }\n            if (!keep) {\n                return tmp.newAssign(x);\n            }\n            break;\n        }\n\n        return x;\n    }\n\n    private void convertStmt(Stmt p, N tmp) {\n        switch (p.et) {\n        case E0:\n            return;\n        case E1:\n            boolean keep;\n            switch (p.st) {\n            case LOOKUP_SWITCH:\n            case TABLE_SWITCH:\n            case RETURN:\n            case THROW:\n                keep = false;\n                break;\n            default:\n                keep = true;\n                break;\n            }\n            p.setOp(convertExpr(p.getOp(), keep, tmp));\n            break;\n        case E2:\n            if (p.st == ST.IDENTITY) {\n                return;\n            } else if (p.st == ST.FILL_ARRAY_DATA) {\n                p.setOp1(convertExpr(p.getOp1(), false, tmp));\n                p.setOp2(convertExpr(p.getOp2(), true, tmp));\n            } else {\n                p.setOp1(convertExpr(p.getOp1(), true, tmp));\n                p.setOp2(convertExpr(p.getOp2(), p.getOp1().vt == VT.LOCAL, tmp));\n            }\n            break;\n        case En:\n            Value[] ops = p.getOps();\n            for (int i = 0; i < ops.length; i++) {\n                ops[i] = convertExpr(ops[i], true, tmp);\n            }\n            break;\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/MultiArrayTransformer.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.StmtTraveler;\nimport com.googlecode.dex2jar.ir.expr.*;\n\n/**\n * dex does have the instruction to create a multi-array. the implement is to\n * using the Array.newInstance().\n * transform\n * <pre>\n * ((String[][][])Array.newInstance(String.class,new int[]{4, 5, 6}))\n * </pre>\n * to\n * <pre>\n * new String[4][5][6]\n * </pre>\n */\npublic class MultiArrayTransformer extends StatedTransformer {\n    @Override\n    public boolean transformReportChanged(IrMethod method) {\n        final boolean changed[] = {false};\n        new StmtTraveler() {\n            @Override\n            public Value travel(Value op) {\n                if (op.vt == Value.VT.CHECK_CAST) {\n                    TypeExpr te = (TypeExpr) op;\n                    if (te.op.vt == Value.VT.CHECK_CAST) {\n                        TypeExpr te2 = (TypeExpr) te.op;\n                        if (te.type.equals(te2.type)) {\n                            op = te2;\n                        }\n                    }\n                }\n                op = super.travel(op);\n\n\n                if (op.vt == Value.VT.CHECK_CAST) {\n                    TypeExpr te = (TypeExpr) op;\n                    if (te.type.charAt(0) == '[') {\n                        Value from = te.getOp();\n                        if (from.vt == Value.VT.INVOKE_STATIC) {\n                            InvokeExpr invokeExpr = (InvokeExpr) from;\n                            if (invokeExpr.getName().equals(\"newInstance\")\n                                    && invokeExpr.getOwner().equals(\"Ljava/lang/reflect/Array;\")\n                                    && invokeExpr.getArgs().length == 2\n                                    && invokeExpr.getArgs()[0].equals(\"Ljava/lang/Class;\")) {\n                                Value arg0 = invokeExpr.getOps()[0];\n                                String elementType = null;\n                                if (arg0.vt == Value.VT.CONSTANT) {\n                                    elementType = ((DexType) ((Constant) invokeExpr.getOps()[0]).value).desc;\n                                } else {\n                                    if (arg0.vt == Value.VT.STATIC_FIELD) {\n                                        StaticFieldExpr sfe = (StaticFieldExpr) arg0;\n                                        if (sfe.owner.startsWith(\"Ljava/lang/\") && sfe.name.equals(\"TYPE\")) {\n                                            switch (sfe.owner) {\n                                                case \"Ljava/lang/Boolean;\":\n                                                    elementType = \"Z\";\n                                                    break;\n                                                case \"Ljava/lang/Byte;\":\n                                                    elementType = \"B\";\n                                                    break;\n                                                case \"Ljava/lang/Short;\":\n                                                    elementType = \"S\";\n                                                    break;\n                                                case \"Ljava/lang/Character;\":\n                                                    elementType = \"C\";\n                                                    break;\n                                                case \"Ljava/lang/Integer;\":\n                                                    elementType = \"I\";\n                                                    break;\n                                                case \"Ljava/lang/Long;\":\n                                                    elementType = \"J\";\n                                                    break;\n                                                case \"Ljava/lang/Float;\":\n                                                    elementType = \"F\";\n                                                    break;\n                                                case \"Ljava/lang/Double;\":\n                                                    elementType = \"D\";\n                                                    break;\n                                                case \"Ljava/lang/Void;\":\n                                                    elementType = \"V\";\n                                                    break;\n                                                default:\n                                            }\n                                        }\n                                    }\n                                }\n                                if (elementType != null) {\n                                    Value dt = invokeExpr.getOps()[1];\n                                    if (invokeExpr.getArgs()[1].equals(\"I\")) {\n                                        if (te.type.equals(\"[\" + elementType)) {\n                                            int d = 0;\n                                            while (elementType.charAt(d) == '[') {\n                                                d++;\n                                            }\n                                            changed[0] = true;\n                                            if (d > 0) {\n                                                return Exprs.nNewMutiArray(elementType.substring(d), d + 1, new Value[]{dt});\n                                            } else {\n                                                return Exprs.nNewArray(elementType, dt);\n                                            }\n                                        }\n                                    } else {// [I\n                                        if (dt.vt == Value.VT.FILLED_ARRAY) {\n                                            FilledArrayExpr filledArrayExpr = (FilledArrayExpr) dt;\n                                            int d = filledArrayExpr.getOps().length;\n                                            if (te.type.length() > d && te.type.substring(d).equals(elementType)) {\n                                                int d1 = 0;\n                                                while (elementType.charAt(d1) == '[') {\n                                                    d1++;\n                                                }\n                                                changed[0] = true;\n                                                return Exprs.nNewMutiArray(elementType.substring(d1), d1 + d, filledArrayExpr.getOps());\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                return op;\n            }\n        }.travel(method);\n\n        return changed[0];\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NewTransformer.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.ET;\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.StmtTraveler;\r\nimport com.googlecode.dex2jar.ir.expr.*;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\n\r\nimport java.util.*;\r\n\r\nimport static com.googlecode.dex2jar.ir.expr.Value.VT.*;\r\nimport static com.googlecode.dex2jar.ir.stmt.Stmt.ST.*;\r\n\r\n/**\r\n * simply merge\r\n * <p/>\r\n * <pre>\r\n *     a=NEW Labc;\r\n *     a.<init>();\r\n * </pre>\r\n * <p/>\r\n * to\r\n * <p/>\r\n * <pre>\r\n * a = new abc();\r\n * </pre>\r\n * <p/>\r\n * Run after [SSATransformer, RemoveLocalFromSSA]\r\n */\r\npublic class NewTransformer implements Transformer {\r\n\r\n    static Vx IGNORED = new Vx(null, true);\r\n\r\n    @Override\r\n    public void transform(IrMethod method) {\r\n\r\n        // 1. replace\r\n        // =========\r\n        // a=NEW Abc;\r\n        // b=a\r\n        // b.<init>()\r\n        // to ======\r\n        // a=new Abc();\r\n        // b=a;\r\n        // =========\r\n        replaceX(method);\r\n\r\n        // 2. replace NEW Abc;.<init>() -> new Abc();\r\n        replaceAST(method);\r\n\r\n    }\r\n\r\n    void replaceX(IrMethod method) {\r\n        final Map<Local, TObject> init = new HashMap<>();\r\n        for (Stmt p : method.stmts) {\r\n            if (p.st == ASSIGN && p.getOp1().vt == LOCAL && p.getOp2().vt == NEW) {\r\n                // the stmt is a new assign stmt\r\n                Local local = (Local) p.getOp1();\r\n                init.put(local, new TObject(local, (AssignStmt) p));\r\n            }\r\n        }\r\n\r\n        if (init.size() > 0) {\r\n            final int size = Cfg.reIndexLocal(method);\r\n            makeSureUsedBeforeConstructor(method, init, size);\r\n            if (init.size() > 0) {\r\n                replace0(method, init, size);\r\n            }\r\n            for (Stmt stmt : method.stmts) {\r\n                stmt.frame = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    void replaceAST(IrMethod method) {\r\n        for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {\r\n            Stmt p = it.next();\r\n\r\n            InvokeExpr ie = findInvokeExpr(p, null);\r\n\r\n            if (ie != null) {\r\n                if (\"<init>\".equals(ie.getName()) && \"V\".equals(ie.getRet())) {\r\n                    Value[] orgOps = ie.getOps();\r\n                    if (orgOps[0].vt == NEW) {\r\n                        NewExpr newExpr = (NewExpr) ie.getOps()[0];\r\n                        if (newExpr != null) {\r\n                            Value[] nOps = Arrays.copyOfRange(orgOps, 1, orgOps.length);\r\n                            InvokeExpr invokeNew = Exprs.nInvokeNew(nOps, ie.getArgs(), ie.getOwner());\r\n                            method.stmts.insertBefore(p, Stmts.nVoidInvoke(invokeNew));\r\n                            it.remove();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void replace0(IrMethod method, Map<Local, TObject> init, int size) {\r\n        Set<Local> toDelete = new HashSet<>();\r\n\r\n        Local locals[] = new Local[size];\r\n        for (Local local : method.locals) {\r\n            locals[local._ls_index] = local;\r\n        }\r\n\r\n        // find all locals to delete\r\n        for (TObject obj : init.values()) {\r\n            Vx[] frame = (Vx[]) obj.invokeStmt.frame;\r\n            for (int i = 0; i < frame.length; i++) {\r\n                Vx s = frame[i];\r\n                if (s != null && s.obj == obj) {\r\n                    toDelete.add(locals[i]);\r\n                }\r\n            }\r\n        }\r\n        // delete the locals\r\n        for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {\r\n            Stmt p = it.next();\r\n            if (p.st == ASSIGN && p.getOp1().vt == LOCAL) {\r\n                if (toDelete.contains((Local) p.getOp1())) {\r\n                    it.remove();\r\n                }\r\n            }\r\n        }\r\n        // add the locals back\r\n        for (TObject obj : init.values()) {\r\n            Vx[] frame = (Vx[]) obj.invokeStmt.frame;\r\n            for (int i = 0; i < frame.length; i++) {\r\n                Vx s = frame[i];\r\n                if (s != null && s.obj == obj) {\r\n                    Local b = locals[i];\r\n                    if (b != obj.local) {\r\n                        method.stmts.insertAfter(obj.invokeStmt, Stmts.nAssign(b, obj.local));\r\n                    }\r\n                }\r\n            }\r\n            InvokeExpr ie = findInvokeExpr(obj.invokeStmt, null);\r\n            Value[] orgOps = ie.getOps();\r\n            Value[] nOps = Arrays.copyOfRange(orgOps, 1, orgOps.length);\r\n            InvokeExpr invokeNew = Exprs.nInvokeNew(nOps, ie.getArgs(), ie.getOwner());\r\n            method.stmts.replace(obj.invokeStmt, Stmts.nAssign(obj.local, invokeNew));\r\n        }\r\n    }\r\n\r\n    void makeSureUsedBeforeConstructor(IrMethod method, final Map<Local, TObject> init, final int size) {\r\n        Cfg.createCFG(method);\r\n        Cfg.dfs(method.stmts, new Cfg.FrameVisitor<Vx[]>() {\r\n\r\n            boolean keepFrame = false;\r\n            Vx[] tmp = new Vx[size];\r\n            StmtTraveler stmtTraveler = new StmtTraveler() {\r\n                Stmt current;\r\n\r\n                @Override\r\n                public Stmt travel(Stmt stmt) {\r\n\r\n                    this.current = stmt;\r\n                    if (stmt.et == ET.E2) {\r\n                        if (stmt.getOp1().vt == LOCAL) {\r\n                            Local op1 = (Local) stmt.getOp1();\r\n                            if (stmt.getOp2().vt == LOCAL) {\r\n                                Local op2 = (Local) stmt.getOp2();\r\n                                tmp[op1._ls_index] = tmp[op2._ls_index];\r\n                                return stmt;\r\n                            } else if (stmt.getOp2().vt == NEW) {\r\n                                tmp[op1._ls_index] = new Vx(init.get(op1), false);\r\n                                return stmt;\r\n                            } else {\r\n                                travel(stmt.getOp2());\r\n                                tmp[op1._ls_index] = IGNORED;\r\n                                return stmt;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (stmt.st == LABEL) {\r\n                        LabelStmt labelStmt = (LabelStmt) stmt;\r\n                        if (labelStmt.phis != null) {\r\n                            for (AssignStmt phi : labelStmt.phis) {\r\n                                Local local = (Local) phi.getOp1();\r\n                                tmp[local._ls_index] = IGNORED;\r\n                            }\r\n                        }\r\n                        return stmt;\r\n                    }\r\n                    return super.travel(stmt);\r\n                }\r\n\r\n                @Override\r\n                public Value travel(Value op) {\r\n                    if (op.vt == INVOKE_SPECIAL) {\r\n                        if (op.getOps().length >= 1) {\r\n                            InvokeExpr ie = (InvokeExpr) op;\r\n                            if (\"<init>\".equals(ie.getName())) {\r\n                                Value thiz = op.getOps()[0];\r\n                                if (thiz.vt == LOCAL) {\r\n                                    Local local = (Local) thiz;\r\n                                    Vx vx = tmp[local._ls_index];\r\n                                    TObject object = vx.obj;\r\n                                    if (object != null) {\r\n                                        if (object.invokeStmt != null) {\r\n                                            object.useBeforeInit = true;\r\n                                        } else {\r\n                                            vx.init = true;\r\n                                            object.invokeStmt = current;\r\n                                            for (int i = 0; i < tmp.length; i++) {\r\n                                                Vx s = tmp[i];\r\n                                                if (s != null && s.obj == object) {\r\n                                                    tmp[i] = IGNORED;\r\n                                                }\r\n                                            }\r\n                                            keepFrame = true;\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                    op = super.travel(op);\r\n\r\n                    if (op.vt == LOCAL) {\r\n                        use((Local) op);\r\n                    }\r\n\r\n                    return op;\r\n                }\r\n            };\r\n\r\n            @Override\r\n            public Vx[] merge(Vx[] srcFrame, Vx[] distFrame, Stmt src, Stmt dist) {\r\n                if (distFrame == null) {\r\n                    distFrame = new Vx[size];\r\n                    System.arraycopy(srcFrame, 0, distFrame, 0, size);\r\n                } else {\r\n                    for (int i = 0; i < size; i++) {\r\n                        Vx s = srcFrame[i];\r\n                        Vx d = distFrame[i];\r\n                        if (s != null) {\r\n                            if (d == null) {\r\n                                distFrame[i] = s;\r\n                            } else {\r\n                                if (s != d) {\r\n                                    TObject obj = s.obj;\r\n                                    if (obj != null) {\r\n                                        obj.useBeforeInit = true;\r\n                                    }\r\n                                    obj = d.obj;\r\n                                    if (obj != null) {\r\n                                        obj.useBeforeInit = true;\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (dist.st == LABEL) {\r\n                    List<AssignStmt> phis = ((LabelStmt) dist).phis;\r\n                    if (phis != null && phis.size() > 0) {\r\n                        for (AssignStmt phi : phis) {\r\n                            for (Value value : phi.getOp2().getOps()) {\r\n                                Local local = (Local) value;\r\n                                int i = local._ls_index;\r\n                                Vx s = srcFrame[i];\r\n                                Vx d = distFrame[i];\r\n                                if (d != null) {\r\n                                    if (!d.init) {\r\n                                        TObject obj = d.obj;\r\n                                        if (obj != null) {\r\n                                            obj.useBeforeInit = true;\r\n                                        }\r\n                                    }\r\n                                } else if (s != null) {\r\n                                    if (!s.init) {\r\n                                        TObject obj = s.obj;\r\n                                        if (obj != null) {\r\n                                            obj.useBeforeInit = true;\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                return distFrame;\r\n            }\r\n\r\n            @Override\r\n            public Vx[] initFirstFrame(Stmt first) {\r\n                return new Vx[size];\r\n            }\r\n\r\n            @Override\r\n            public Vx[] exec(Vx[] frame, Stmt stmt) {\r\n                keepFrame = false;\r\n                System.arraycopy(frame, 0, tmp, 0, size);\r\n                stmtTraveler.travel(stmt);\r\n                if (stmt._cfg_froms.size() > 1) {\r\n                    keepFrame = true;\r\n                }\r\n\r\n                if (!keepFrame) {\r\n                    stmt.frame = null;\r\n                }\r\n                return tmp;\r\n            }\r\n\r\n            void use(Local local) {\r\n                Vx vx = tmp[local._ls_index];\r\n                if (!vx.init) {\r\n                    TObject object = vx.obj;\r\n                    if (object != null) {\r\n                        object.useBeforeInit = true;\r\n                    }\r\n\r\n                    tmp[local._ls_index] = IGNORED;\r\n                }\r\n\r\n            }\r\n        });\r\n        for (Iterator<Map.Entry<Local, TObject>> iterator = init.entrySet().iterator(); iterator.hasNext(); ) {\r\n            Map.Entry<Local, TObject> e = iterator.next();\r\n            boolean keep = true;\r\n            TObject obj = e.getValue();\r\n            if (obj.useBeforeInit) {\r\n                keep = false;\r\n            }\r\n            if (obj.invokeStmt == null) {\r\n                keep = false;\r\n            }\r\n            if (!keep) {\r\n                iterator.remove();\r\n            }\r\n        }\r\n    }\r\n\r\n    InvokeExpr findInvokeExpr(Stmt p, InvokeExpr ie) {\r\n        if (p.st == ASSIGN) {\r\n            if (p.getOp2().vt == INVOKE_SPECIAL) {\r\n                ie = (InvokeExpr) p.getOp2();\r\n            }\r\n        } else if (p.st == VOID_INVOKE) {\r\n            ie = (InvokeExpr) p.getOp();\r\n        }\r\n        return ie;\r\n    }\r\n\r\n    static class TObject {\r\n        public Stmt invokeStmt;\r\n        Local local;\r\n        boolean useBeforeInit;\r\n        private AssignStmt init;\r\n\r\n        TObject(Local local, AssignStmt init) {\r\n            this.local = local;\r\n            this.init = init;\r\n        }\r\n    }\r\n\r\n    static class Vx {\r\n        boolean init;\r\n        TObject obj;\r\n\r\n\r\n        public Vx(TObject obj, boolean init) {\r\n            this.obj = obj;\r\n            this.init = init;\r\n        }\r\n    }\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NpeTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.StmtSearcher;\nimport com.googlecode.dex2jar.ir.StmtTraveler;\nimport com.googlecode.dex2jar.ir.expr.Constant;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\n\n/**\n * Replace MUST be NullPointerException stmt to 'throw new NullPointerException()'\n *\n * Replace MUST be 'divide by zero' stmt to 'throw new ArithmeticException(\"divide by zero\")'\n */\npublic class NpeTransformer extends StatedTransformer {\n    private static class MustThrowException extends RuntimeException {\n    }\n\n    private static final MustThrowException NPE = new MustThrowException();\n    private static final MustThrowException DIVE = new MustThrowException();\n    private static final MustThrowException NEGATIVE_ARRAY_SIZE = new MustThrowException();\n\n    @Override\n    public boolean transformReportChanged(IrMethod method) {\n        boolean changed = false;\n        if (method.locals.size() == 0) {\n            return false;\n        }\n        StmtSearcher st = new StmtSearcher() {\n            @Override\n            public void travel(Stmt stmt) {\n                if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {\n                    if (isNull(stmt.getOp1())) {\n                        throw NPE;\n                    }\n                }\n                super.travel(stmt);\n            }\n\n            @Override\n            public void travel(Value op) {\n                switch (op.vt) {\n                case INVOKE_VIRTUAL:\n                case INVOKE_SPECIAL:\n                case INVOKE_INTERFACE: {\n                    if (isNull(op.getOps()[0])) {\n                        throw NPE;\n                    }\n                }\n                    break;\n                case ARRAY: {\n                    if (isNull(op.getOp1())) {\n                        throw NPE;\n                    }\n                }\n                    break;\n                case FIELD: {\n                    if (isNull(op.getOp())) {\n                        throw NPE;\n                    }\n                }\n                    break;\n                    case IDIV:\n                        if (op.getOp2().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp2();\n                            if (((Number) constant.value).intValue() == 0) {\n                                throw DIVE;\n                            }\n                        }\n                        break;\n                    case LDIV:\n                        if (op.getOp2().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp2();\n                            if (((Number) constant.value).longValue() == 0) {\n                                throw DIVE;\n                            }\n                        }\n                        break;\n                    case NEW_ARRAY:\n                        if (op.getOp().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp();\n                            if (((Number) constant.value).intValue() < 0) {\n                                throw NEGATIVE_ARRAY_SIZE;\n                            }\n                        }\n                        break;\n                    case NEW_MUTI_ARRAY:\n                        for (Value size : op.getOps()) {\n                            if (size.vt == Value.VT.CONSTANT) {\n                                Constant constant = (Constant) size;\n                                if (((Number) constant.value).intValue() < 0) {\n                                    throw NEGATIVE_ARRAY_SIZE;\n                                }\n                            }\n                        }\n                        break;\n                default:\n                }\n            }\n\n        };\n        for (Stmt p = method.stmts.getFirst(); p != null;) {\n            try {\n                st.travel(p);\n                p = p.getNext();\n            } catch (MustThrowException e) {\n                replace(method, p);\n                Stmt q = p.getNext();\n                method.stmts.remove(p);\n                changed = true;\n                p = q;\n            }\n        }\n        return changed;\n    }\n\n    private void replace(final IrMethod m, final Stmt p) {\n        StmtTraveler traveler = new StmtTraveler() {\n            @Override\n            public Value travel(Value op) {\n                switch (op.vt) {\n                case INVOKE_VIRTUAL:\n                case INVOKE_SPECIAL:\n                case INVOKE_INTERFACE: {\n                    Value ops[] = op.getOps();\n                    if (isNull(ops[0])) {\n                        for (int i = 1; i < ops.length; i++) {\n                            travel(ops[i]);\n                        }\n                        throw NPE;\n                    }\n                }\n                    break;\n                case ARRAY: {\n                    if (isNull(op.getOp1())) {\n                        travel(op.getOp2());\n                        throw NPE;\n                    }\n                }\n                    break;\n                case FIELD: {\n                    if (isNull(op.getOp())) {\n                        throw NPE;\n                    }\n                }\n                    break;\n                    case IDIV:\n                        if (op.getOp2().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp2();\n                            if (((Number) constant.value).intValue() == 0) {\n                                travel(op.getOp1());\n                                throw DIVE;\n                            }\n                        }\n                        break;\n                    case LDIV:\n                        if (op.getOp2().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp2();\n                            if (((Number) constant.value).longValue() == 0) {\n                                travel(op.getOp1());\n                                throw DIVE;\n                            }\n                        }\n                        break;\n                    case NEW_ARRAY:\n                        if (op.getOp().vt == Value.VT.CONSTANT) {\n                            Constant constant = (Constant) op.getOp();\n                            if (((Number) constant.value).intValue() < 0) {\n                                throw NEGATIVE_ARRAY_SIZE;\n                            }\n                        }\n                        break;\n                    case NEW_MUTI_ARRAY:\n                        for (Value size : op.getOps()) {\n                            if (size.vt == Value.VT.CONSTANT) {\n                                Constant constant = (Constant) size;\n                                if (((Number) constant.value).intValue() < 0) {\n                                    throw NEGATIVE_ARRAY_SIZE;\n                                }else {\n                                    travel(size);\n                                }\n                            }\n                        }\n                        break;\n                default:\n                }\n                Value sop = super.travel(op);\n                if (sop.vt == Value.VT.LOCAL || sop.vt == Value.VT.CONSTANT) {\n                    return sop;\n                } else {\n                    Local local = new Local();\n                    m.locals.add(local);\n                    m.stmts.insertBefore(p, Stmts.nAssign(local, sop));\n                    return local;\n                }\n            }\n        };\n        try {\n            switch (p.et) {\n            case E0:\n                // impossible\n                break;\n            case E1:\n                traveler.travel(p.getOp());\n                break;\n            case E2:\n                if (p.st == Stmt.ST.ASSIGN) {\n                    switch (p.getOp1().vt) {\n                    case ARRAY:\n                        traveler.travel(p.getOp1().getOp1());\n                        traveler.travel(p.getOp1().getOp2());\n                        traveler.travel(p.getOp2());\n                        break;\n                    case FIELD:\n                        traveler.travel(p.getOp1().getOp());\n                        traveler.travel(p.getOp2());\n                        break;\n                    case STATIC_FIELD:\n                    case LOCAL:\n                        traveler.travel(p.getOp2());\n                        break;\n                    default:\n                        // impossible\n                    }\n                } else if (p.st == Stmt.ST.FILL_ARRAY_DATA) {\n                    if (isNull(p.getOp1())) {\n                        throw NPE;\n                    } else {\n                        traveler.travel(p.getOp1());\n                    }\n                }\n                break;\n            case En:\n            }\n        } catch (MustThrowException e) {\n            if (e == NPE) {\n                m.stmts.insertBefore(p,\n                        Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], \"Ljava/lang/NullPointerException;\")));\n            } else if (e == DIVE) {\n                m.stmts.insertBefore(p,\n                        Stmts.nThrow(Exprs.nInvokeNew(new Value[]{Exprs.nString(\"divide by zero\")}, new String[]{\"Ljava/lang/String;\"}, \"Ljava/lang/ArithmeticException;\")));\n            } else if (e == NEGATIVE_ARRAY_SIZE) {\n                m.stmts.insertBefore(p,\n                        Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], \"Ljava/lang/NegativeArraySizeException;\")));\n            }\n        }\n    }\n\n    static boolean isNull(Value v) {\n        if (v.vt == Value.VT.CONSTANT) {\n            Constant cst = (Constant) v;\n            if (Constant.Null.equals(cst.value)) {\n                return true;\n            } else if (cst.value instanceof Number) {\n                return ((Number) cst.value).intValue() == 0;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/RemoveConstantFromSSA.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\n\nimport java.util.*;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Constant;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\n\n/**\n * 1. Remove constant AssignStmt.\n * \n * <pre>\n * a = &quot;123&quot;;\n * return a;\n * </pre>\n * \n * to\n * \n * <pre>\n * return &quot;123&quot;;\n * </pre>\n * \n * 2. Remove Phi if all value are equal\n * \n * <pre>\n * a = &quot;123&quot;;\n * // ...\n * b = &quot;123&quot;;\n * // ...\n * c = PHI(a, b);\n * return c;\n * </pre>\n * \n * to\n * \n * <pre>\n * // ...\n * return &quot;123&quot;;\n * </pre>\n */\npublic class RemoveConstantFromSSA extends StatedTransformer {\n\n    public static final Comparator<Local> LOCAL_COMPARATOR = new Comparator<Local>() {\n        @Override\n        public int compare(Local local, Local t1) {\n            return Integer.compare(local._ls_index, t1._ls_index);\n        }\n    };\n\n    @Override\n    public boolean transformReportChanged(IrMethod method) {\n        boolean changed = false;\n        List<AssignStmt> assignStmtList = new ArrayList<>();\n        Map<Local, Object> cstMap = new HashMap<>();\n        for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\n            if (p.st == Stmt.ST.ASSIGN) {\n                AssignStmt as = (AssignStmt) p;\n                if (as.getOp1().vt == Value.VT.LOCAL) {\n                    if (as.getOp2().vt == Value.VT.CONSTANT) {\n                        assignStmtList.add(as);\n                        cstMap.put((Local) as.getOp1(), ((Constant) as.getOp2()).value);\n                    } else if (as.getOp2().vt == Value.VT.LOCAL) {\n                        cstMap.put((Local) as.getOp1(), as.getOp2());\n                    }\n                }\n            }\n        }\n        if (assignStmtList.size() == 0) {\n            return false;\n        }\n        RemoveLocalFromSSA.fixReplace(cstMap);\n        final Map<Local, Value> toReplace = new HashMap<>();\n        Set<Value> usedInPhi = new HashSet<>();\n        List<LabelStmt> phiLabels = method.phiLabels;\n        if (phiLabels != null) {\n            boolean loopAgain = true;\n            while (loopAgain) {\n                loopAgain = false;\n                usedInPhi.clear();\n                for (Iterator<LabelStmt> it = phiLabels.iterator(); it.hasNext();) {\n                    LabelStmt labelStmt = it.next();\n                    if (labelStmt.phis != null) {\n                        for (Iterator<AssignStmt> it2 = labelStmt.phis.iterator(); it2.hasNext();) {\n                            AssignStmt phi = it2.next();\n                            Value[] vs = phi.getOp2().getOps();\n                            Object sameCst = null;\n                            boolean allEqual = true;\n                            for (Value p : vs) {\n                                Object cst = cstMap.get(p);\n                                if (cst == null) {\n                                    allEqual = false;\n                                    break;\n                                }\n                                if (sameCst == null) {\n                                    sameCst = cst;\n                                } else if (!sameCst.equals(cst)) {\n                                    allEqual = false;\n                                    break;\n                                }\n                            }\n                            if (allEqual) { // all are same constant\n                                cstMap.put((Local) phi.getOp1(), sameCst);\n                                if (sameCst instanceof Local) {\n                                    phi.setOp2((Value) sameCst);\n                                } else {\n                                    phi.setOp2(Exprs.nConstant(sameCst));\n                                    assignStmtList.add(phi);\n                                }\n                                it2.remove();\n                                method.stmts.insertAfter(labelStmt, phi);\n                                changed = true;\n                                loopAgain = true; // loop again\n                            } else {\n                                usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));\n                            }\n                        }\n                        if (labelStmt.phis.size() == 0) {\n                            it.remove();\n                        }\n                    }\n                }\n            }\n        }\n\n        for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext();) {\n            AssignStmt as = it.next();\n            if (!usedInPhi.contains(as.getOp1())) {\n                it.remove();\n                method.stmts.remove(as);\n                method.locals.remove(as.getOp1());\n                changed = true;\n            }\n            toReplace.put((Local) as.getOp1(), as.getOp2());\n\n        }\n\n        Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {\n            @Override\n            public Value onAssign(Local v, AssignStmt as) {\n                return v;\n            }\n\n            @Override\n            public Value onUse(Local v) {\n                Value n = toReplace.get(v);\n                return n == null ? v : n.clone();\n            }\n        }, false);\n        return changed;\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/RemoveLocalFromSSA.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport java.util.*;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\r\n\r\npublic class RemoveLocalFromSSA extends StatedTransformer {\r\n    static <T extends Value> void replaceAssign(List<AssignStmt> assignStmtList, Map<Local, T> toReplace) {\r\n        for (AssignStmt as : assignStmtList) {\r\n            Value right = as.getOp2();\r\n            T to = toReplace.get(right);\r\n            if (to != null) {\r\n                as.setOp2(to);\r\n            }\r\n        }\r\n    }\r\n\r\n    private boolean simpleAssign(List<LabelStmt> phiLabels, List<AssignStmt> assignStmtList,\r\n                                 Map<Local, Local> toReplace, StmtList stmts) {\r\n        Set<Value> usedInPhi = new HashSet<>();\r\n        if (phiLabels != null) {\r\n            for (LabelStmt labelStmt : phiLabels) {\r\n                for (AssignStmt phi : labelStmt.phis) {\r\n                    usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));\r\n                }\r\n            }\r\n        }\r\n        boolean changed = false;\r\n        for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {\r\n            AssignStmt as = it.next();\r\n            if (!usedInPhi.contains(as.getOp1())) {\r\n                it.remove();\r\n                stmts.remove(as);\r\n                toReplace.put((Local) as.getOp1(), (Local) as.getOp2());\r\n                changed = true;\r\n            }\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    private void replacePhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace, Set<Value> set) {\r\n        if (phiLabels != null) {\r\n            for (LabelStmt labelStmt : phiLabels) {\r\n                for (AssignStmt phi : labelStmt.phis) {\r\n                    Value[] ops = phi.getOp2().getOps();\r\n                    for (Value op : ops) {\r\n                        Value n = toReplace.get(op);\r\n                        if (n != null) {\r\n                            set.add(n);\r\n                        } else {\r\n                            set.add(op);\r\n                        }\r\n                    }\r\n                    set.remove(phi.getOp1());\r\n                    phi.getOp2().setOps(set.toArray(new Value[set.size()]));\r\n                    set.clear();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    static class PhiObject {\r\n        Set<PhiObject> parent = new HashSet<>();\r\n        Set<PhiObject> children = new HashSet<>();\r\n        Local local;\r\n        boolean isInitByPhi = false;\r\n    }\r\n\r\n    public static PhiObject getOrCreate(Map<Local, PhiObject> map, Local local) {\r\n        PhiObject po = map.get(local);\r\n        if (po == null) {\r\n            po = new PhiObject();\r\n            po.local = local;\r\n            map.put(local, po);\r\n        }\r\n        return po;\r\n    }\r\n\r\n    public static void linkPhiObject(PhiObject parent, PhiObject child) {\r\n        parent.children.add(child);\r\n        child.parent.add(parent);\r\n    }\r\n\r\n\r\n    private boolean simplePhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace, Set<Value> set) {\r\n        boolean changed = false;\r\n        if (phiLabels != null) {\r\n            for (Iterator<LabelStmt> itLabel = phiLabels.iterator(); itLabel.hasNext(); ) {\r\n                LabelStmt labelStmt = itLabel.next();\r\n                for (Iterator<AssignStmt> it = labelStmt.phis.iterator(); it.hasNext(); ) {\r\n                    AssignStmt phi = it.next();\r\n                    set.addAll(Arrays.asList(phi.getOp2().getOps()));\r\n                    set.remove(phi.getOp1());\r\n                    if (set.size() == 1) {\r\n                        it.remove();\r\n                        changed = true;\r\n                        toReplace.put((Local) phi.getOp1(), (Local) set.iterator().next());\r\n                    }\r\n                    set.clear();\r\n                }\r\n                if (labelStmt.phis.size() == 0) {\r\n                    labelStmt.phis = null;\r\n                    itLabel.remove();\r\n                }\r\n            }\r\n        }\r\n        return changed;\r\n    }\r\n\r\n    private boolean removeLoopFromPhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace) {\r\n        boolean changed = false;\r\n        if (phiLabels != null) {\r\n            Set<Local> toDeletePhiAssign = new HashSet<>();\r\n            Map<Local, PhiObject> phis;\r\n            // detect loop init in phi\r\n            phis = collectPhiObjects(phiLabels);\r\n            Queue<PhiObject> q = new UniqueQueue<>();\r\n            q.addAll(phis.values());\r\n            while (!q.isEmpty()) {\r\n                PhiObject po = q.poll();\r\n                for (PhiObject child : po.children) {\r\n                    if (child.isInitByPhi) {\r\n                        if (child.parent.addAll(po.parent)) {\r\n                            q.add(child);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            for (PhiObject po : phis.values()) {\r\n                if (po.isInitByPhi) {\r\n                    Local local = null;\r\n                    for (PhiObject p : po.parent) {\r\n                        if (!p.isInitByPhi) {\r\n                            if (local == null) { // the first non-phi value\r\n                                local = p.local;\r\n                            } else {\r\n                                local = null;\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (local != null) {\r\n                        toReplace.put(po.local, local);\r\n                        toDeletePhiAssign.add(po.local);\r\n                        changed = true;\r\n                    }\r\n                }\r\n            }\r\n            for (Iterator<LabelStmt> itLabel = phiLabels.iterator(); itLabel.hasNext(); ) {\r\n                LabelStmt labelStmt = itLabel.next();\r\n                for (Iterator<AssignStmt> it = labelStmt.phis.iterator(); it.hasNext(); ) {\r\n                    AssignStmt phi = it.next();\r\n                    if (toDeletePhiAssign.contains(phi.getOp1())) {\r\n                        it.remove();\r\n                    }\r\n                }\r\n                if (labelStmt.phis.size() == 0) {\r\n                    labelStmt.phis = null;\r\n                    itLabel.remove();\r\n                }\r\n            }\r\n        }\r\n        return changed;\r\n    }\r\n\r\n    private Map<Local, PhiObject> collectPhiObjects(List<LabelStmt> phiLabels) {\r\n        Map<Local, PhiObject> phis;\r\n        phis = new HashMap<>();\r\n        for (LabelStmt labelStmt : phiLabels) {\r\n            for (AssignStmt as : labelStmt.phis) {\r\n                Local local = (Local) as.getOp1();\r\n                PhiObject child = getOrCreate(phis, local);\r\n                child.isInitByPhi = true;\r\n                for (Value op : as.getOp2().getOps()) {\r\n                    if (op == local) {\r\n                        continue;\r\n                    }\r\n                    PhiObject parent = getOrCreate(phis, (Local) op);\r\n                    linkPhiObject(parent, child);\r\n                }\r\n            }\r\n        }\r\n        return phis;\r\n    }\r\n\r\n    static <T> void fixReplace(Map<Local, T> toReplace) {\r\n        List<Map.Entry<Local, T>> set = new ArrayList<>(toReplace.entrySet());\r\n        Collections.sort(set, new Comparator<Map.Entry<Local, T>>() {\r\n            @Override\r\n            public int compare(Map.Entry<Local, T> localTEntry, Map.Entry<Local, T> t1) {\r\n                return Integer.compare(localTEntry.getKey()._ls_index, t1.getKey()._ls_index);\r\n            }\r\n        });\r\n\r\n        boolean changed = true;\r\n        while (changed) {\r\n            changed = false;\r\n            for (Map.Entry<Local, T> e : set) {\r\n                T b = e.getValue();\r\n                if(b instanceof  Local) {\r\n                    T n = toReplace.get(b);\r\n                    if (n != null && b != n) {\r\n                        changed = true;\r\n                        e.setValue(n);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public boolean transformReportChanged(IrMethod method) {\r\n        boolean irChanged = false;\r\n        List<AssignStmt> assignStmtList = new ArrayList<>();\r\n        List<LabelStmt> phiLabels = method.phiLabels;\r\n        for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\r\n            if (p.st == Stmt.ST.ASSIGN) {\r\n                AssignStmt as = (AssignStmt) p;\r\n                if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.LOCAL) {\r\n                    assignStmtList.add(as);\r\n                }\r\n            }\r\n        }\r\n        final Map<Local, Local> toReplace = new HashMap<>();\r\n        Set<Value> set = new HashSet<>();\r\n        boolean changed = true;\r\n        while (changed) {\r\n            changed = false;\r\n\r\n            if (removeLoopFromPhi(phiLabels, toReplace)) {\r\n                fixReplace(toReplace);\r\n                replacePhi(phiLabels, toReplace, set);\r\n            }\r\n\r\n            while (simplePhi(phiLabels, toReplace, set)) {// remove a = phi(b)\r\n                fixReplace(toReplace);\r\n                replacePhi(phiLabels, toReplace, set);\r\n            }\r\n            while (simpleAssign(phiLabels, assignStmtList, toReplace, method.stmts)) {// remove a=b\r\n                fixReplace(toReplace);\r\n                replaceAssign(assignStmtList, toReplace);\r\n                changed = true;\r\n                irChanged = true;\r\n            }\r\n            replacePhi(phiLabels, toReplace, set);\r\n        }\r\n\r\n        for (Local local : toReplace.keySet()) {\r\n            method.locals.remove(local);\r\n            irChanged = true;\r\n        }\r\n        if (toReplace.size() > 0) {\r\n            Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {\r\n                @Override\r\n                public Value onAssign(Local v, AssignStmt as) {\r\n                    return v;\r\n                }\r\n\r\n                @Override\r\n                public Value onUse(Local v) {\r\n                    Local n = toReplace.get(v);\r\n                    return n == null ? v : n;\r\n                }\r\n            }, true);\r\n        }\r\n        return irChanged;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/SSATransformer.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.Exprs;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.*;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack;\r\nimport com.googlecode.dex2jar.ir.ts.an.AnalyzeValue;\r\nimport com.googlecode.dex2jar.ir.ts.an.BaseAnalyze;\r\n\r\nimport java.util.*;\r\n\r\n/**\r\n * Transform Stmt to SSA form and count local read\r\n *\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class SSATransformer implements Transformer {\r\n\r\n    private void cleanTagsAndReIndex(IrMethod method) {\r\n        int i = 0;\r\n        for (Local local : method.locals) {\r\n            local.tag = null;\r\n            local._ls_index = i++;\r\n        }\r\n    }\r\n\r\n    private void deleteDeadCode(IrMethod method) {\r\n        for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {\r\n            Stmt stmt = it.next();\r\n            if (!stmt.visited && stmt.st != ST.LABEL) {\r\n                it.remove();\r\n            }\r\n        }\r\n    }\r\n\r\n    private void replaceLocalsWithSSA(final IrMethod method) {\r\n        final List<Local> locals = method.locals;\r\n        locals.clear();\r\n        StmtList stmts = method.stmts;\r\n\r\n        TravelCallBack tcb = new TravelCallBack() {\r\n\r\n            @Override\r\n            public Value onAssign(Local a, AssignStmt as) {\r\n                if (a._ls_index < 0) {\r\n                    locals.add(a);\r\n                    return a;\r\n                }\r\n                SSAValue lsv = (SSAValue) a.tag;\r\n                Local b = lsv.local;\r\n                locals.add(b);\r\n                return b;\r\n            }\r\n\r\n            @Override\r\n            public Value onUse(Local a) {\r\n                if (a._ls_index < 0) {\r\n                    return a;\r\n                }\r\n                SSAValue lsv = (SSAValue) a.tag;\r\n                Local b = lsv.local;\r\n                return b;\r\n            }\r\n\r\n        };\r\n        Set<Value> froms = new HashSet<>();\r\n        List<LabelStmt> phiLabels = new ArrayList<>();\r\n        // 2. we are looking for Phis and insert Phi node to the code\r\n        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {\r\n            if (p.st == ST.LABEL) {\r\n                LabelStmt labelStmt = (LabelStmt) p;\r\n                List<AssignStmt> phis = null;\r\n                SSAValue[] frame = (SSAValue[]) p.frame;\r\n                if (frame != null) {\r\n                    for (SSAValue v : frame) {\r\n                        if (v == null || !v.used) {\r\n                            continue;\r\n                        }\r\n                        if (v.parent != null) {\r\n                            froms.add(v.parent.local);\r\n                        }\r\n                        if (v.otherParents != null) {\r\n                            for (SSAValue parent : v.otherParents) {\r\n                                froms.add(parent.local);\r\n                            }\r\n                        }\r\n                        froms.remove(v.local);\r\n                        if (phis == null) {\r\n                            phis = new ArrayList<>();\r\n                        }\r\n                        locals.add(v.local);\r\n                        phis.add(Stmts.nAssign(v.local, Exprs.nPhi(froms.toArray(new Value[froms.size()]))));\r\n                        froms.clear();\r\n                    }\r\n                }\r\n                labelStmt.phis = phis;\r\n                if (phis != null) {\r\n                    phiLabels.add(labelStmt);\r\n                }\r\n            } else {\r\n                Cfg.travelMod(p, tcb, true);\r\n            }\r\n            p.frame = null;\r\n        }\r\n        if (phiLabels.size() > 0) {\r\n            method.phiLabels = phiLabels;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void transform(final IrMethod method) {\r\n\r\n        boolean needSSA = prepare(method);\r\n        if (needSSA) {\r\n            // 1. analyze and build value graph\r\n            new SSAAnalyze(method).analyze();\r\n            // 2. delete dead code\r\n            deleteDeadCode(method);\r\n            // 3. replace locals with SSA-locals\r\n            replaceLocalsWithSSA(method);\r\n        }\r\n\r\n        // 4. clean tags on Local\r\n        cleanTagsAndReIndex(method);\r\n    }\r\n\r\n    private boolean prepare(final IrMethod method) {\r\n        int index = Cfg.reIndexLocal(method);\r\n\r\n        final int readCounts[] = new int[index];\r\n        final int writeCounts[] = new int[index];\r\n        Cfg.travel(method.stmts, new TravelCallBack() {\r\n            @Override\r\n            public Value onAssign(Local v, AssignStmt as) {\r\n                writeCounts[v._ls_index]++;\r\n                return v;\r\n            }\r\n\r\n            @Override\r\n            public Value onUse(Local v) {\r\n                readCounts[v._ls_index]++;\r\n                return v;\r\n            }\r\n        }, true);\r\n\r\n        boolean needTravel = false;\r\n        boolean needSSAAnalyze = false;\r\n        index = 0;\r\n        List<Local> oldLocals = method.locals;\r\n        List<Local> locals = new ArrayList<>(oldLocals);\r\n        oldLocals.clear();\r\n\r\n        for (Local local : locals) {\r\n            int idx = local._ls_index;\r\n            int read = readCounts[idx];\r\n            int write = writeCounts[idx];\r\n            if (read > 0 && write == 0) {\r\n                // TODO if we need throw exception ?\r\n                // or the code is dead?\r\n            }\r\n\r\n            if (read == 0 && write == 0) {\r\n                // ignore the local\r\n            } else {\r\n                if (write <= 1) {\r\n                    // no phi require\r\n                    local._ls_index = -1;\r\n                    oldLocals.add(local);\r\n                } else if (read == 0) {\r\n                    local._ls_index = -2;\r\n                    needTravel = true;\r\n                    // we are going to duplicate each usage of the local and add to method.locals,\r\n                    // so not add the original local to method.locals\r\n                } else {\r\n                    needSSAAnalyze = true;\r\n                    local._ls_index = index++;\r\n                    oldLocals.add(local);\r\n                }\r\n            }\r\n        }\r\n        if (needSSAAnalyze || needTravel) {\r\n            Cfg.travelMod(method.stmts, new TravelCallBack() {\r\n\r\n                @Override\r\n                public Value onAssign(Local v, AssignStmt as) {\r\n                    if (v._ls_index == -1) {\r\n                        return v;\r\n                    } else if (v._ls_index == -2) {\r\n                        Local n = (Local) v.clone();\r\n                        method.locals.add(n);\r\n                        return n;\r\n                    }\r\n                    // others\r\n                    return v.clone();\r\n                }\r\n\r\n                @Override\r\n                public Value onUse(Local v) {\r\n                    if (v._ls_index == -1) {\r\n                        return v;\r\n                    }\r\n                    return v.clone();\r\n                }\r\n            }, true);\r\n        }\r\n        return needSSAAnalyze;\r\n    }\r\n\r\n    static class SSAAnalyze extends BaseAnalyze<SSAValue> {\r\n        public int nextIndex;\r\n\r\n        public SSAAnalyze(IrMethod method) {\r\n            super(method, false);\r\n        }\r\n\r\n        @Override\r\n        protected void afterExec(SSAValue[] frame, Stmt stmt) {\r\n            if (!DEBUG) {\r\n                // remove frame to save memory\r\n                if (stmt._cfg_froms.size() < 2) {\r\n                    // we only care stmt only has one or less parent,\r\n                    // the parent must be visited already.\r\n                    // if more than 1 parent, the other may not been visited at\r\n                    // the moment\r\n                    setFrame(stmt, null);\r\n                }\r\n            }\r\n        }\r\n\r\n        @Override\r\n        public Local onUse(Local local) {\r\n            if (local._ls_index < 0) {\r\n                return local;\r\n            }\r\n            return super.onUse(local);\r\n        }\r\n\r\n        @Override\r\n        public Local onAssign(Local local, AssignStmt as) {\r\n            if (local._ls_index < 0) {\r\n                return local;\r\n            }\r\n            return super.onAssign(local, as);\r\n        }\r\n\r\n        @Override\r\n        protected void analyzeValue() {\r\n            Set<SSAValue> set = markUsed();\r\n            aValues.clear();\r\n            aValues = null;\r\n            if (DEBUG) {\r\n                clearLsEmptyValueFromFrame();\r\n            }\r\n            for (SSAValue v0 : set) {\r\n                SSAValue v = v0;\r\n                if (v.used && v.local == null) {\r\n                    v.local = new Local(nextIndex++);\r\n                }\r\n            }\r\n        }\r\n\r\n        protected void clearLsEmptyValueFromFrame() {\r\n            for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\r\n                SSAValue[] frame = (SSAValue[]) p.frame;\r\n                if (frame != null) {\r\n                    for (int i = 0; i < frame.length; i++) {\r\n                        SSAValue r = frame[i];\r\n                        if (r != null && !r.used) {\r\n                            frame[i] = null;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        @Override\r\n        protected void init() {\r\n            super.init();\r\n            nextIndex = method.locals.size();\r\n        }\r\n\r\n        @Override\r\n        protected void initCFG() {\r\n            Cfg.createCFG(this.method);\r\n        }\r\n\r\n        protected Set<SSAValue> markUsed() {\r\n            Set<SSAValue> used = new HashSet<SSAValue>(aValues.size() / 2);\r\n            Queue<SSAValue> q = new UniqueQueue<>();\r\n            q.addAll(aValues);\r\n            while (!q.isEmpty()) {\r\n                SSAValue v = q.poll();\r\n                if (v.used) {\r\n                    used.add(v);\r\n                    {\r\n                        SSAValue p = v.parent;\r\n                        if (p != null) {\r\n                            if (!p.used) {\r\n                                p.used = true;\r\n                                q.add(p);\r\n                            }\r\n                        }\r\n                    }\r\n                    if (v.otherParents != null) {\r\n                        for (SSAValue p : v.otherParents) {\r\n                            if (!p.used) {\r\n                                p.used = true;\r\n                                q.add(p);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                }\r\n            }\r\n            return used;\r\n        }\r\n\r\n        @Override\r\n        public SSAValue[] merge(SSAValue[] frame, SSAValue[] distFrame, Stmt src, Stmt dist) {\r\n            if (distFrame != null) {\r\n                relationMerge(frame, dist, distFrame);\r\n            } else {\r\n                if (dist._cfg_froms.size() > 1) {// detail mode\r\n                    distFrame = newFrame();\r\n                    relationMerge(frame, dist, distFrame);\r\n                } else if (needCopyFrame(src)) {\r\n                    distFrame = newFrame();\r\n                    System.arraycopy(frame, 0, distFrame, 0, distFrame.length);\r\n                } else {\r\n                    distFrame = frame;\r\n                }\r\n            }\r\n            return distFrame;\r\n        }\r\n\r\n        private static boolean needCopyFrame(Stmt src) {\r\n            int c = 0;\r\n            if (src.exceptionHandlers != null) {\r\n                c += src.exceptionHandlers.size();\r\n                if (c > 1) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (src.st.canContinue()) {\r\n                c += 1;\r\n                if (c > 1) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (src.st.canBranch()) {\r\n                c += 1;\r\n                if (c > 1) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (src.st.canSwitch()) {\r\n                c += 1;\r\n                BaseSwitchStmt bss = (BaseSwitchStmt) src;\r\n                c += bss.targets.length;\r\n            }\r\n            return c > 1;\r\n        }\r\n\r\n        @Override\r\n        protected SSAValue[] newFrame(int size) {\r\n            return new SSAValue[size];\r\n        }\r\n\r\n        @Override\r\n        protected SSAValue newValue() {\r\n            return new SSAValue();\r\n        }\r\n\r\n        @Override\r\n        protected SSAValue onAssignLocal(Local local, Value value) {\r\n            SSAValue aValue = newValue();\r\n            aValue.local = local;\r\n            local.tag = aValue;\r\n            return aValue;\r\n        }\r\n\r\n        @Override\r\n        protected void onUseLocal(SSAValue aValue, Local local) {\r\n            local.tag = aValue;\r\n            aValue.used = true;\r\n        }\r\n\r\n        protected void relationMerge(SSAValue[] frame, Stmt dist, SSAValue[] distFrame) {\r\n            for (int i = 0; i < localSize; i++) {\r\n                SSAValue srcValue = (SSAValue) frame[i];\r\n                if (srcValue != null) {\r\n                    SSAValue distValue = (SSAValue) distFrame[i];\r\n                    if (distValue == null) {\r\n                        if (!dist.visited) {\r\n                            distValue = newValue();\r\n                            aValues.add(distValue);\r\n                            distFrame[i] = distValue;\r\n                            linkParentChildren(srcValue, distValue);\r\n                        }\r\n                    } else {\r\n                        linkParentChildren(srcValue, distValue);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        private void linkParentChildren(SSAValue p, SSAValue c) {\r\n            if (c.parent == null) {\r\n                c.parent = p;\r\n            } else if (c.parent == p) {\r\n                return;\r\n            } else {\r\n                Set<SSAValue> ps = c.otherParents;\r\n                if (ps == null) {\r\n                    c.otherParents = ps = new HashSet<>(3);\r\n                }\r\n                ps.add(p);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static class SSAValue implements AnalyzeValue {\r\n        public Local local;\r\n        public Set<SSAValue> otherParents;\r\n        public boolean used = false;\r\n        public SSAValue parent;\r\n\r\n        @Override\r\n        public char toRsp() {\r\n            return used ? 'x' : '.';\r\n        }\r\n\r\n        @Override\r\n        public String toString() {\r\n            if (local != null) {\r\n                return local.toString();\r\n            } else {\r\n                return \"N\";\r\n            }\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/StatedTransformer.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\n\r\npublic abstract class StatedTransformer implements Transformer {\r\n    public abstract boolean transformReportChanged(IrMethod method);\r\n\r\n    @Override\r\n    public void transform(IrMethod method) {\r\n        transformReportChanged(method);\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/Transformer.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\n\r\n/**\r\n * TODO DOC\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic interface Transformer {\r\n\r\n    public void transform(IrMethod method);\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/TypeTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.TypeClass;\nimport com.googlecode.dex2jar.ir.expr.*;\nimport com.googlecode.dex2jar.ir.expr.Value.*;\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\n\nimport java.util.*;\n\n/**\n * Type and correct Exprs\n *\n * @author Bob Pan\n */\npublic class TypeTransformer implements Transformer {\n\n    private static final String[] possibleIntTypes = new String[]{\"B\", \"S\", \"C\", \"I\"};\n\n    @Override\n    public void transform(IrMethod irMethod) {\n        TypeAnalyze ta = new TypeAnalyze(irMethod);\n        List<TypeRef> refs = ta.analyze();\n\n        for (TypeRef ref : refs) {\n            String type = ref.getType();\n\n            if (type == null) {\n                System.err.println(ref);\n                continue;\n            }\n\n            if (ref.value.vt == VT.CONSTANT) {\n                Constant cst = (Constant) ref.value;\n                switch (type.charAt(0)) {\n                    case '[':\n                    case 'L':\n                        if (Integer.valueOf(0).equals(cst.value)) {\n                            cst.value = Constant.Null;\n                        }\n                        if (type.equals(\"[F\") && cst.value instanceof int[]) {\n                            int x[] = (int[]) cst.value;\n                            float f[] = new float[x.length];\n                            for (int i = 0; i < x.length; i++) {\n                                f[i] = Float.intBitsToFloat(x[i]);\n                            }\n                            cst.value = f;\n                        }\n                        if (type.equals(\"[D\") && cst.value instanceof long[]) {\n                            long x[] = (long[]) cst.value;\n                            double f[] = new double[x.length];\n                            for (int i = 0; i < x.length; i++) {\n                                f[i] = Double.longBitsToDouble(x[i]);\n                            }\n                            cst.value = f;\n                        }\n                        break;\n                    case 'F':\n                        if (!(cst.value instanceof Float)) {\n                            cst.value = Float.intBitsToFloat(((Number) cst.value).intValue());\n                        }\n                        break;\n                    case 'D':\n                        if (!(cst.value instanceof Double)) {\n                            cst.value = Double.longBitsToDouble(((Number) cst.value).longValue());\n                        }\n                        break;\n                    default:\n                }\n            }\n            Value value = ref.value;\n            value.valueType = type;\n            value.tag = null;\n            ref.clear();\n        }\n    }\n\n    enum Relation {\n\n        R_sameValues {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.sameValues;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.sameValues = v;\n            }\n        }, R_gArrayValues {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.gArrayValues;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.gArrayValues = v;\n            }\n        }, R_sArrayValues {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.sArrayValues;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.sArrayValues = v;\n            }\n        }, R_arrayRoots {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.arrayRoots;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.arrayRoots = v;\n            }\n        }, R_parents {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.parents;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.parents = v;\n            }\n        }, R_children {\n            @Override\n            Set<TypeRef> get(TypeRef obj) {\n                return obj.children;\n            }\n\n            @Override\n            void set(TypeRef obj, Set<TypeRef> v) {\n                obj.children = v;\n            }\n        };\n\n        abstract Set<TypeRef> get(TypeRef obj);\n\n        abstract void set(TypeRef obj, Set<TypeRef> v);\n    }\n\n    public static class TypeRef {\n\n        public final Value value;\n        /**\n         * same use, have same\n         */\n        public Set<TypeRef> sameValues = null;\n        /**\n         * reference to values\n         */\n        public Set<TypeRef> gArrayValues = null;\n        public Set<TypeRef> sArrayValues = null;\n        /**\n         * reference to root\n         */\n        public Set<TypeRef> arrayRoots = null;\n\n        public Set<TypeRef> parents = null;\n        public Set<TypeRef> children = null;\n\n        public TypeClass clz = TypeClass.UNKNOWN;\n        public String provideDesc = null;\n        public Set<String> uses;\n\n        private TypeRef next;\n\n        public void merge(TypeRef other) {\n            assert this.next == null;\n            TypeRef a = this;\n            TypeRef b = other.getReal();\n            if (a == b) {\n                return;\n            }\n\n            b.next = a;\n\n            relationMerge(a, b, Relation.R_sameValues);\n            relationMerge(a, b, Relation.R_gArrayValues);\n            relationMerge(a, b, Relation.R_sArrayValues);\n            relationMerge(a, b, Relation.R_arrayRoots);\n            relationMerge(a, b, Relation.R_parents);\n            relationMerge(a, b, Relation.R_children);\n\n            if (a.provideDesc == null) {\n                a.provideDesc = b.provideDesc;\n            } else if (b.provideDesc != null) {\n                a.provideDesc = TypeAnalyze.mergeProviderType(a.provideDesc, b.provideDesc);\n            }\n            b.provideDesc = null;\n            if (b.uses != null) {\n                if (a.uses == null) {\n                    a.uses = b.uses;\n                } else {\n                    a.uses.addAll(b.uses);\n                }\n                b.uses = null;\n            }\n\n        }\n\n        private static void relationMerge(TypeRef a, TypeRef b, Relation r) {\n            Set<TypeRef> bv = r.get(b);\n            if (bv != null) {\n                Set<TypeRef> av = r.get(a);\n                Set<TypeRef> merged;\n                if (av == null) {\n                    merged = bv;\n                    r.set(a, merged);\n                } else {\n                    merged = av;\n                    merged.addAll(bv);\n                }\n                merged.remove(a);\n                merged.remove(b);\n                r.set(b, null);\n            }\n        }\n\n        private TypeRef getReal() {\n            TypeRef x = this;\n            while (x.next != null) {\n                x = x.next;\n            }\n            if (x != this) {\n                this.next = x;\n            }\n            return x;\n        }\n\n        public TypeRef(Value value) {\n            super();\n            this.value = value;\n        }\n\n        @Override\n        public String toString() {\n            TypeRef real = getReal();\n            String p = real.uses == null ? \"[]\" : real.uses.toString();\n            return real.clz + \"::\" + value + \": \" + real.provideDesc + \" > {\" + p.substring(1, p.length() - 1) + \"}\";\n        }\n\n        public String getType() {\n            TypeRef thiz = getReal();\n            TypeClass clz = thiz.clz;\n            if (clz == TypeClass.OBJECT) {\n                if (thiz.provideDesc.length() == 1) {\n                    return \"Ljava/lang/Object;\";\n                } else {\n                    return thiz.provideDesc;\n                }\n            }\n            if (clz.fixed && clz != TypeClass.INT) {\n                if (thiz.provideDesc == null) {\n                    throw new RuntimeException();\n                }\n                return thiz.provideDesc;\n            }\n            if (clz == TypeClass.JD) { // prefere Long if wide\n                return \"J\";\n            }\n            if (thiz.uses != null) {\n                for (String t : possibleIntTypes) {\n                    if (thiz.uses.contains(t)) {\n                        return t;\n                    }\n                }\n            }\n\n            switch (clz) {\n                case ZI:\n                    return \"I\";\n                case ZIFL:\n                case ZIF:\n                case ZIL:\n                    return \"Z\";\n                case INT:\n                case IF:\n                    return \"I\";\n                default:\n            }\n            throw new RuntimeException();\n        }\n\n        public boolean updateTypeClass(TypeClass clz) {\n            assert this.next == null;\n            TypeClass thizClz = this.clz;\n            TypeClass merged = TypeClass.merge(thizClz, clz);\n            if (merged == thizClz) {\n                return false;\n            }\n            this.clz = merged;\n            return true;\n        }\n\n        public void clear() {\n            this.sArrayValues = null;\n            this.gArrayValues = null;\n            this.arrayRoots = null;\n            this.parents = null;\n            this.children = null;\n            this.sameValues = null;\n        }\n\n        String getProvideDesc() {\n            return getReal().provideDesc;\n        }\n\n        public boolean addUses(String ele) {\n            assert this.next == null;\n            TypeRef t = this;\n            if (t.uses != null) {\n                return t.uses.add(ele);\n            } else {\n                t.uses = new HashSet<>();\n                return t.uses.add(ele);\n            }\n        }\n\n        public boolean addAllUses(Set<String> uses) {\n            assert this.next == null;\n            if (uses != null) {\n                return uses.addAll(uses);\n            } else {\n                uses = new HashSet<>();\n                return uses.addAll(uses);\n            }\n        }\n    }\n\n    private static class TypeAnalyze {\n        protected IrMethod method;\n        private List<TypeRef> refs = new ArrayList<>();\n\n        public TypeAnalyze(IrMethod method) {\n            super();\n            this.method = method;\n        }\n\n        public List<TypeRef> analyze() {\n            sxStmt();\n            fixTypes();\n            return refs;\n        }\n\n        private void fixTypes() {\n            // 1. collect all Array Roots\n            Set<TypeRef> arrayRoots = new HashSet<>();\n            for (TypeRef ref : refs) {\n                ref = ref.getReal();\n                if (ref.gArrayValues != null || ref.sArrayValues != null) {\n                    arrayRoots.add(ref);\n                }\n                mergeArrayRelation(ref, Relation.R_gArrayValues);\n                mergeArrayRelation(ref, Relation.R_sArrayValues);\n                mergeArrayRelation(ref, Relation.R_arrayRoots);\n            }\n\n            UniqueQueue<TypeRef> q = new UniqueQueue<>();\n            q.addAll(refs);\n            while (!q.isEmpty()) {\n                // 2. merge provided type to children. merge uses to parent. merge TypeClass to sameValues\n                while (!q.isEmpty()) {\n                    TypeRef ref = q.poll();\n                    copyTypes(q, ref);\n                }\n                // 3. merge type from Array Roots to Array Values\n                for (TypeRef ref : arrayRoots) {\n                    ref = ref.getReal();\n                    String provideDesc = ref.provideDesc;\n                    if (provideDesc != null && provideDesc.charAt(0) == '[') {\n                        String ele = provideDesc.substring(1);\n\n                        TypeClass clz = TypeClass.clzOf(ele);\n                        if (ref.gArrayValues != null) {\n                            for (TypeRef p : ref.gArrayValues) {\n                                p = p.getReal();\n                                if (p.updateTypeClass(clz)) {\n                                    q.add(p);\n                                }\n                                mergeTypeToArrayGetValue(ele, p, q);\n                            }\n                        }\n                        if (ref.sArrayValues != null) {\n                            for (TypeRef p : ref.sArrayValues) {\n                                p = p.getReal();\n                                if (p.updateTypeClass(clz)) {\n                                    q.add(p);\n                                }\n                                if (p.addUses(ele)) {\n                                    q.add(p);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private void mergeArrayRelation(TypeRef ref, Relation r) {\n            Set<TypeRef> v = r.get(ref);\n            if (v != null && v.size() > 1) {\n                List<TypeRef> copy = new ArrayList<>(v);\n                TypeRef mergeTo = copy.get(0).getReal();\n                for (int i = 1; i < copy.size(); i++) {\n                    mergeTo.merge(copy.get(i));\n                }\n            }\n        }\n\n        private static void mergeTypeToArrayGetValue(String type, TypeRef target, UniqueQueue<TypeRef> q) {\n            target = target.getReal();\n            if (target.provideDesc == null) {\n                target.provideDesc = type;\n                q.add(target);\n            } else {\n                String mergedType = mergeTypeEx(type, target.provideDesc);\n                if (!mergedType.equals(target.provideDesc)) {\n                    target.provideDesc = mergedType;\n                    q.add(target);\n                }\n            }\n        }\n\n        private static void mergeTypeToSubRef(String type, TypeRef target, UniqueQueue<TypeRef> q) {\n            if (target.provideDesc == null) {\n                target.provideDesc = type;\n                q.add(target);\n            } else {\n                String mergedType = mergeProviderType(type, target.provideDesc);\n                if (!mergedType.equals(target.provideDesc)) {\n                    target.provideDesc = mergedType;\n                    q.add(target);\n                }\n            }\n        }\n\n        /**\n         * [[B + [[D -> [L\n         * [B + L -> [B\n         * [[B + [B -> [[B\n         *\n         * @param a\n         * @param b\n         * @return\n         */\n        private static String mergeTypeEx(String a, String b) {\n            if (a.equals(b)) {\n                return a;\n            }\n            int as = countArrayDim(a);\n            int bs = countArrayDim(b);\n            if (as > bs) {\n                return a;\n            } else if (bs > as) {\n                return b;\n            } else { // as==bs;\n                String elementTypeA = a.substring(as);\n                String elementTypeB = a.substring(bs);\n                TypeClass ta = TypeClass.clzOf(elementTypeA);\n                TypeClass tb = TypeClass.clzOf(elementTypeB);\n                if (ta.fixed && !tb.fixed) {\n                    return a;\n                } else if (!ta.fixed && tb.fixed) {\n                    return b;\n                } else if (ta.fixed && tb.fixed) {\n                    if (ta != tb) {\n                        if (as == 0) {\n                            throw new RuntimeException();\n                        }\n                        return buildArray(as - 1, \"L\");\n                    }\n                    if (ta == TypeClass.INT) {\n                        String chooseType = \"I\";\n                        for (int i = possibleIntTypes.length - 1; i >= 0; i--) {\n                            String t = possibleIntTypes[i];\n                            if (a.equals(t) || b.equals(t)) {\n                                chooseType = t;\n                                break;\n                            }\n                        }\n                        return buildArray(as, chooseType);\n                    } else {\n                        return buildArray(as, \"L\");\n                    }\n                } else { // !ta.fixed && !tb.fixed\n                    return buildArray(as, TypeClass.merge(ta, tb).name);\n                }\n            }\n        }\n\n        private void copyTypes(UniqueQueue<TypeRef> q, TypeRef ref) {\n            ref = ref.getReal();\n            TypeClass clz = ref.clz;\n\n            switch (clz) {\n                case BOOLEAN:\n                case FLOAT:\n                case LONG:\n                case DOUBLE:\n                case VOID:\n                    ref.provideDesc = clz.name;\n                    break;\n                default:\n            }\n            String provideDesc = ref.provideDesc;\n            if (provideDesc == null && ref.parents != null && ref.parents.size() > 1) {\n                if (isAllParentSetted(ref)) {\n                    ref.provideDesc = provideDesc = mergeParentType(ref.parents);\n                }\n            }\n            if (ref.parents != null) {\n                for (TypeRef p : ref.parents) {\n                    p = p.getReal();\n                    if (p.updateTypeClass(clz)) {\n                        q.add(p);\n                    }\n                    if (ref.uses != null) {\n                        if (p.addAllUses(ref.uses)) {\n                            q.add(p);\n                        }\n                    }\n                }\n            }\n            if (ref.children != null) {\n                for (TypeRef p : ref.children) {\n                    p = p.getReal();\n                    if (p.updateTypeClass(clz)) {\n                        q.add(p);\n                    }\n\n                    if (provideDesc != null) {\n                        mergeTypeToSubRef(provideDesc, p, q);\n                    }\n                }\n            }\n            if (ref.sameValues != null) {\n                for (TypeRef p : ref.sameValues) {\n                    p = p.getReal();\n                    if (p.updateTypeClass(clz)) {\n                        q.add(p);\n                    }\n                }\n            }\n        }\n\n        private boolean isAllParentSetted(TypeRef ref) {\n            boolean allAreSet = true;\n            for (TypeRef p : ref.parents) {\n                if (p.getProvideDesc() == null) {\n                    allAreSet = false;\n                    break;\n                }\n            }\n            return allAreSet;\n        }\n\n        private static String mergeObjectType(String a, String b) {\n            if (a.equals(b)) {\n                return a;\n            }\n            if (\"L\".endsWith(a)) {\n                return b;\n            } else if (\"L\".equals(b)) {\n                return a;\n            }\n            if (a.compareTo(b) > 0) {\n                return a;\n            } else {\n                return b;\n            }\n        }\n\n        private static String mergeProviderType(String a, String b) {\n            if (a.equals(b)) {\n                return a;\n            }\n            TypeClass ta = TypeClass.clzOf(a);\n            TypeClass tb = TypeClass.clzOf(b);\n            if (ta.fixed && !tb.fixed) {\n                return a;\n            } else if (!ta.fixed && tb.fixed) {\n                return b;\n            } else if (ta.fixed && tb.fixed) {\n                // special allow merge of Z and I\n                if ((ta == TypeClass.INT && tb == TypeClass.BOOLEAN) || (tb == TypeClass.INT && ta == TypeClass.BOOLEAN)) {\n                    return \"I\";\n                }\n                if (ta != tb) {\n                    throw new RuntimeException();\n                }\n                if (ta == TypeClass.INT) {\n                    for (int i = possibleIntTypes.length - 1; i >= 0; i--) {\n                        String t = possibleIntTypes[i];\n                        if (a.equals(t) || b.equals(t)) {\n                            return t;\n                        }\n                    }\n                    return \"I\";\n                } else if (ta == TypeClass.OBJECT) {\n                    // [[B + [[C = [Ljava/langObject;\n                    int as = countArrayDim(a);\n                    int bs = countArrayDim(b);\n                    if (as == 0 || bs == 0) {\n                        return mergeObjectType(a, b);\n                    } else {\n                        String elementTypeA = a.substring(as);\n                        String elementTypeB = a.substring(bs);\n                        if (as < bs) {\n                            return buildArray(elementTypeB.charAt(0) == 'L' ? bs : bs - 1, \"L\");\n                        } else if (bs > as) {\n                            return buildArray(elementTypeA.charAt(0) == 'L' ? as : as - 1, \"L\");\n                        } else { // as==bs\n                            if (elementTypeA.charAt(0) != 'L' || elementTypeB.charAt(0) != 'L') {\n                                return buildArray(as - 1, \"L\");\n                            } else {\n                                return buildArray(as, \"L\");\n                            }\n                        }\n                    }\n                } else {\n                    throw new RuntimeException();\n                }\n            } else { // !ta.fixed && !tb.fixed\n                return TypeClass.merge(ta, tb).name;\n            }\n        }\n\n        private static String buildArray(int dim, String s) {\n            if (dim == 0) {\n                return s;\n            }\n            StringBuilder sb = new StringBuilder();\n            for (int i = 0; i < dim; i++) {\n                sb.append('[');\n            }\n            sb.append(s);\n            return sb.toString();\n        }\n\n        private static int countArrayDim(String a) {\n            int i = 0;\n            while (a.charAt(i) == '[') {\n                i++;\n            }\n            return i;\n        }\n\n        private String mergeParentType(Set<TypeRef> parents) {\n            Iterator<TypeRef> it = parents.iterator();\n            String a = it.next().getProvideDesc();\n            while (it.hasNext()) {\n                a = mergeProviderType(a, it.next().getProvideDesc());\n            }\n            return a;\n        }\n\n        private void e0expr(E0Expr op, boolean getValue) {\n            switch (op.vt) {\n                case LOCAL:\n                    break;\n                case NEW:\n                    NewExpr newExpr = (NewExpr) op;\n                    provideAs(newExpr, newExpr.type);\n                    break;\n                case THIS_REF:\n                case PARAMETER_REF:\n                case EXCEPTION_REF:\n                    RefExpr refExpr = (RefExpr) op;\n                    String refType = refExpr.type;\n                    if (refType == null && op.vt == VT.EXCEPTION_REF) {\n                        refType = \"Ljava/lang/Throwable;\";\n                    }\n                    provideAs(refExpr, refType);\n                    break;\n                case STATIC_FIELD:\n                    StaticFieldExpr fe = (StaticFieldExpr) op;\n                    if (getValue) {// getfield\n                        provideAs(fe, fe.type);\n                    } else {// putfield\n                        useAs(fe, fe.type);\n                    }\n                    break;\n                case CONSTANT:\n                    Constant cst = (Constant) op;\n                    Object value = cst.value;\n                    if (value instanceof String) {\n                        provideAs(cst, \"Ljava/lang/String;\");\n                    } else if (value instanceof DexType) {\n                        provideAs(cst, \"Ljava/lang/Class;\");\n                    } else if (value instanceof Number) {\n                        if (value instanceof Integer || value instanceof Byte || value instanceof Short) {\n                            int a = ((Number) value).intValue();\n                            if (a == 0) {\n                                provideAs(cst, TypeClass.ZIFL.name); // zero, false or, float\n                            } else if (a == 1) {\n                                provideAs(cst, TypeClass.ZIF.name);\n                            } else {\n                                provideAs(cst, TypeClass.IF.name);\n                            }\n                        } else if (value instanceof Long) {\n                            provideAs(cst, \"w\");\n                        } else if (value instanceof Float) {\n                            provideAs(cst, \"F\");\n                        } else if (value instanceof Double) {\n                            provideAs(cst, \"D\");\n                        }\n                    } else if (value instanceof Character) {\n                        provideAs(cst, \"C\");\n                    } else {\n                        provideAs(cst, \"L\");\n                    }\n                    break;\n                default:\n            }\n        }\n\n        private void e1expr(E1Expr e1, boolean getValue) {\n            Value v = e1.op;\n            switch (e1.vt) {\n                case CAST:\n                    CastExpr ce = (CastExpr) e1;\n                    if (ce.to.equals(\"B\")) { // special case for I2B\n                        useAs(v, TypeClass.ZI.name);\n                        provideAs(e1, TypeClass.ZI.name);\n                    } else {\n                        useAs(v, ce.from);\n                        provideAs(e1, ce.to);\n                    }\n                    break;\n                case FIELD:\n                    FieldExpr fe = (FieldExpr) e1;\n                    if (getValue) {// getfield\n                        provideAs(fe, fe.type);\n                    } else {// putfield\n                        useAs(fe, fe.type);\n                    }\n                    if (v != null) {\n                        useAs(v, fe.owner);\n                    }\n                    break;\n\n                case CHECK_CAST: {\n                    TypeExpr te = (TypeExpr) e1;\n                    provideAs(te, te.type);\n                    useAs(v, \"L\");\n                }\n                break;\n                case INSTANCE_OF: {\n                    TypeExpr te = (TypeExpr) e1;\n                    provideAs(te, \"Z\");\n                    useAs(v, \"L\");\n                }\n                break;\n                case NEW_ARRAY: {\n                    TypeExpr te = (TypeExpr) e1;\n                    provideAs(te, \"[\" + te.type);\n                    useAs(v, \"I\");\n                }\n                break;\n                case LENGTH: {\n                    UnopExpr ue = (UnopExpr) e1;\n                    provideAs(ue, \"I\");\n                    useAs(v, \"[?\");\n                }\n                break;\n                case NEG:\n                case NOT: {\n                    UnopExpr ue = (UnopExpr) e1;\n                    provideAs(ue, ue.type);\n                    useAs(v, ue.type);\n                }\n                break;\n                default:\n            }\n            if (v != null) {\n                exExpr(v);\n            }\n        }\n\n        private void e2expr(E2Expr e2, boolean getValue) {\n            Value a = e2.op1.trim();\n            Value b = e2.op2.trim();\n            switch (e2.vt) {\n                case ARRAY:\n                    useAs(b, \"I\");\n                    String elementType = ((ArrayExpr) e2).elementType;\n                    // TypeClass ts = TypeClass.clzOf(elementType);\n                    useAs(a, \"[\" + elementType);\n                    if (getValue) {\n                        provideAs(e2, elementType);\n\n                        linkGetArray(a, e2);\n                    } else {\n                        useAs(e2, elementType);\n\n                        linkSetArray(a, e2);\n                    }\n                    break;\n                case LCMP:\n                case FCMPG:\n                case FCMPL:\n                case DCMPG:\n                case DCMPL: {\n                    BinopExpr be = (BinopExpr) e2;\n                    useAs(a, be.type);\n                    useAs(b, be.type);\n                    provideAs(e2, \"I\");\n                }\n                break;\n                case EQ:\n                case NE: {\n                    useAs(e2.getOp2(), TypeClass.ZIL.name);\n                    useAs(e2.getOp1(), TypeClass.ZIL.name);\n                    linkSameAs(e2.getOp1(), e2.getOp2());\n                    provideAs(e2, \"Z\");\n                }\n                break;\n                case GE:\n                case GT:\n                case LE:\n                case LT: {\n                    BinopExpr be = (BinopExpr) e2;\n                    useAs(a, be.type);\n                    useAs(b, be.type);\n                    provideAs(e2, \"Z\");\n                }\n                break;\n                case ADD:\n                case SUB:\n                case IDIV:\n                case LDIV:\n                case FDIV:\n                case DDIV:\n                case MUL:\n                case REM: {\n                    BinopExpr be = (BinopExpr) e2;\n                    useAs(a, be.type);\n                    useAs(b, be.type);\n                    provideAs(e2, be.type);\n                }\n                break;\n                case OR:\n                case AND:\n                case XOR: {\n                    BinopExpr be = (BinopExpr) e2;\n                    useAs(a, be.type);\n                    useAs(b, be.type);\n                    // linkSameAs(a, b);\n                    if (\"J\".equals(be.type) || \"w\".equals(be.type)) {\n                        provideAs(e2, be.type);\n                    } else {\n                        provideAs(e2, TypeClass.ZI.name);\n                    }\n                }\n                break;\n                case SHL:\n                case SHR:\n                case USHR: {\n                    BinopExpr be = (BinopExpr) e2;\n                    useAs(a, be.type);\n                    useAs(b, \"I\");\n                    provideAs(e2, be.type);\n                }\n                break;\n                default:\n                    throw new UnsupportedOperationException();\n            }\n            if (a != null) {\n                exExpr(a);\n            }\n            if (b != null) {\n                exExpr(b);\n            }\n        }\n\n        private void linkSameAs(Value a, Value b) {\n            TypeRef aa = getDefTypeRef(a);\n            TypeRef bb = getDefTypeRef(b);\n            if (aa.sameValues == null) {\n                aa.sameValues = new HashSet<>(3);\n            }\n            if (bb.sameValues == null) {\n                bb.sameValues = new HashSet<>(3);\n            }\n            aa.sameValues.add(bb);\n            bb.sameValues.add(aa);\n        }\n\n        private void enexpr(EnExpr enExpr) {\n            Value vbs[] = enExpr.ops;\n            switch (enExpr.vt) {\n                case INVOKE_NEW:\n                case INVOKE_INTERFACE:\n                case INVOKE_SPECIAL:\n                case INVOKE_STATIC:\n                case INVOKE_VIRTUAL:\n                case INVOKE_POLYMORPHIC:\n                case INVOKE_CUSTOM: {\n                    AbstractInvokeExpr ice = (AbstractInvokeExpr) enExpr;\n                    String type = ice.getProto().getReturnType();\n                    provideAs(enExpr, type);\n                    useAs(enExpr, type); // no one else will use it\n\n                    String argTypes[] = ice.getProto().getParameterTypes();\n                    if (argTypes.length == vbs.length) {\n                        for (int i = 0; i < vbs.length; i++) {\n                            useAs(vbs[i], argTypes[i]);\n                        }\n                    } else if (argTypes.length + 1 == vbs.length) {\n                        useAs(vbs[0], \"L\");\n                        for (int i = 1; i < vbs.length; i++) {\n                            useAs(vbs[i], argTypes[i - 1]);\n                        }\n                    } else {\n                        throw new RuntimeException();\n                    }\n                }\n                break;\n\n                case FILLED_ARRAY:\n                    FilledArrayExpr fae = (FilledArrayExpr) enExpr;\n                    for (Value vb : vbs) {\n                        useAs(vb, fae.type);\n                    }\n                    provideAs(fae, \"[\" + fae.type);\n                    break;\n                case NEW_MUTI_ARRAY:\n                    NewMutiArrayExpr nmae = (NewMutiArrayExpr) enExpr;\n                    for (Value vb : vbs) {\n                        useAs(vb, \"I\");\n                    }\n                    StringBuilder sb = new StringBuilder();\n                    for (int i = 0; i < nmae.dimension; i++) {\n                        sb.append('[');\n                    }\n                    sb.append(nmae.baseType);\n                    provideAs(nmae, sb.toString());\n                    break;\n                case PHI:\n                    for (Value vb : vbs) {\n                        linkFromTo(vb, enExpr);\n                    }\n                    break;\n                default:\n            }\n            for (Value vb : enExpr.ops) {\n                exExpr(vb);\n            }\n        }\n\n        private void exExpr(Value op) {\n            exExpr(op, true);\n        }\n\n        private void exExpr(Value op, boolean getValue) {\n\n            switch (op.et) {\n                case E0:\n                    e0expr((E0Expr) op, getValue);\n                    break;\n                case E1:\n                    e1expr((E1Expr) op, getValue);\n                    break;\n                case E2:\n                    e2expr((E2Expr) op, getValue);\n                    break;\n                case En:\n                    enexpr((EnExpr) op);\n                    break;\n            }\n        }\n\n        private TypeRef getDefTypeRef(Value v) {\n            Object object = v.tag;\n            TypeRef typeRef;\n            if (object == null || !(object instanceof TypeRef)) {\n                typeRef = new TypeRef(v);\n                refs.add(typeRef);\n                v.tag = typeRef;\n            } else {\n                typeRef = (TypeRef) object;\n            }\n            return typeRef;\n        }\n\n        private void linkGetArray(Value array, Value v) {\n            TypeRef root = getDefTypeRef(array);\n            TypeRef value = getDefTypeRef(v);\n            if (root.gArrayValues == null) {\n                root.gArrayValues = new HashSet<>(3);\n            }\n            root.gArrayValues.add(value);\n            if (value.arrayRoots == null) {\n                value.arrayRoots = new HashSet<>(3);\n            }\n            value.arrayRoots.add(root);\n        }\n\n        private void linkSetArray(Value array, Value v) {\n            TypeRef root = getDefTypeRef(array);\n            TypeRef value = getDefTypeRef(v);\n            if (root.sArrayValues == null) {\n                root.sArrayValues = new HashSet<>(3);\n            }\n            root.sArrayValues.add(value);\n            if (value.arrayRoots == null) {\n                value.arrayRoots = new HashSet<>(3);\n            }\n            value.arrayRoots.add(root);\n        }\n\n        private void linkFromTo(Value from, Value to) {\n            TypeRef tFrom = getDefTypeRef(from);\n            TypeRef tTo = getDefTypeRef(to);\n            if (tFrom.children == null) {\n                tFrom.children = new HashSet<>();\n            }\n            tFrom.children.add(tTo);\n            if (tTo.parents == null) {\n                tTo.parents = new HashSet<>();\n            }\n            tTo.parents.add(tFrom);\n        }\n\n        private void provideAs(Value op, String type) {\n            TypeRef typeRef = getDefTypeRef(op).getReal();\n            typeRef.provideDesc = (type);\n            typeRef.updateTypeClass(TypeClass.clzOf(type));\n        }\n\n        private void s1stmt(E1Stmt s) {\n            if (s.st == ST.GOTO) {\n                return;\n            }\n            Value op = s.op;\n            switch (s.st) {\n                case LOOKUP_SWITCH:\n                case TABLE_SWITCH:\n                    useAs(op, \"I\");\n                    break;\n                case GOTO:\n                    break;\n                case IF:\n                    useAs(op, \"Z\");\n                    break;\n                case LOCK:\n                case UNLOCK:\n                    useAs(op, \"L\");\n                    break;\n                case THROW:\n                    useAs(op, \"Ljava/lang/Throwable;\");\n                    break;\n                case RETURN:\n                    useAs(op, method.ret);\n                    break;\n                default:\n            }\n            exExpr(op);\n        }\n\n        private void s2stmt(E2Stmt s) {\n            if (s.st == ST.FILL_ARRAY_DATA) {\n                linkFromTo(s.op1, s.op2);\n            } else {\n                Value from = s.op2;\n                Value to = s.op1;\n                linkFromTo(from, to);\n                exExpr(from);\n                exExpr(to, false);\n            }\n        }\n\n        private void sxStmt() {\n            for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\n                switch (p.et) {\n                    case E0:\n                        // label, nop and return-void\n                        if (p.st == ST.LABEL) {\n                            LabelStmt labelStmt = (LabelStmt) p;\n                            if (labelStmt.phis != null) {\n                                for (AssignStmt phi : labelStmt.phis) {\n                                    s2stmt(phi);\n                                }\n                            }\n                        }\n                        break;\n                    case E1:\n                        s1stmt((E1Stmt) p);\n                        break;\n                    case E2:\n                        s2stmt((E2Stmt) p);\n                        break;\n                    case En:\n                        // no stmt yet\n                        // enstmt((EnStmt) p, refs, relationRefs);\n                        break;\n                }\n            }\n        }\n\n        @Override\n        public String toString() {\n            StringBuilder sb = new StringBuilder();\n            for (TypeRef ref : refs) {\n                sb.append(ref).append(\"\\n\");\n            }\n            return sb.toString();\n        }\n\n        private void useAs(Value op, String type) {\n            TypeRef typeRef = getDefTypeRef(op);\n            typeRef.addUses(type);\n            typeRef.updateTypeClass(TypeClass.clzOf(type));\n        }\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/UnSSATransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.Set;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.PhiExpr;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\nimport com.googlecode.dex2jar.ir.stmt.JumpStmt;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\nimport com.googlecode.dex2jar.ir.ts.an.AnalyzeValue;\nimport com.googlecode.dex2jar.ir.ts.an.BaseAnalyze;\n\n/**\n * Remove {@link PhiExpr}s, add a=x to each CFG from.\n * \n * TODO clean frame\n * \n * @author bob\n */\npublic class UnSSATransformer implements Transformer {\n\n    private static final boolean DEBUG = false;\n\n    protected static final Comparator<RegAssign> OrderRegAssignByExcludeSizeDesc = new Comparator<RegAssign>() {\n\n        @Override\n        public int compare(RegAssign o1, RegAssign o2) {\n            return o2.excludes.size() - o1.excludes.size();\n        }\n    };\n\n    public UnSSATransformer() {\n        super();\n    }\n\n    /**\n     * there is somewhere both a and its possible x is both live, insert a=x, will change the meaning for example\n     * \n     * <pre>\n     *                      L0:\n     *                      a = phi(b, ... )\n     *                      b = 234;\n     *                      if a>0 goto L0: // a, b both live here\n     *                      ...\n     * </pre>\n     * \n     * after insert a=b before the if stmt, the programe change to\n     * \n     * <pre>\n     *                      L0:\n     *                      // a = phi(b, ... )\n     *                      b = 234;\n     *                      a = b\n     *                      if a>0 goto L0:\n     *                      ...\n     * </pre>\n     * \n     * the solution is by introduce a new local x\n     * \n     * <pre>\n     *                      L0:\n     *                      x = phi(b, ... )\n     *                      a = x\n     *                      b = 234;\n     *                      if a>0 goto L0: // a, b both live here\n     *                      ...\n     * </pre>\n     * \n     * insert x = b is ok now\n     * \n     * <pre>\n     *                      L0:\n     *                      // x = phi(b, ... )\n     *                      a = x\n     *                      b = 234;\n     *                      x = b\n     *                      if a>0 goto L0: // a, b both live here\n     *                      ...\n     * </pre>\n     * \n     * @param phiLabels\n     */\n    private void fixPhi(IrMethod method, Collection<LabelStmt> phiLabels) {\n        for (LabelStmt labelStmt : phiLabels) {\n            List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;\n\n            for (AssignStmt phi : phis) {\n\n                Local a = (Local) phi.getOp1();\n                PhiExpr b = (PhiExpr) phi.getOp2();\n                boolean introduceNewLocal = false;\n                RegAssign aReg = (RegAssign) a.tag;\n                for (Value op : b.getOps()) {\n                    RegAssign bReg = (RegAssign) ((Local) op).tag;\n                    if (aReg.excludes.contains(bReg)) {\n                        introduceNewLocal = true;\n                        break;\n                    }\n                }\n                if (introduceNewLocal) {\n                    Local newLocal = (Local) a.clone();\n                    if (DEBUG) {\n                        newLocal.debugName = \"x\" + method.locals.size();\n                    }\n                    phi.op1 = newLocal;\n                    RegAssign newRegAssign = new RegAssign();\n                    newLocal.tag = newRegAssign;\n\n                    method.locals.add(newLocal);\n                    Stmt newAssigStmt = Stmts.nAssign(a, newLocal);\n                    Stmt next = labelStmt.getNext();\n                    if (next != null && next.st == ST.IDENTITY && next.getOp2().vt == VT.EXCEPTION_REF) {\n                        // it's a handler, insert after the exception ref\n                        method.stmts.insertAfter(next, newAssigStmt);\n                    } else {\n                        method.stmts.insertAfter(labelStmt, newAssigStmt);\n                    }\n                    LiveV[] frame = (LiveV[]) labelStmt.frame;\n                    if (DEBUG) {\n                        LiveV[] copy = frame.clone();\n                        LiveV n = new LiveV();\n                        n.local = a;\n                        n.used = true;\n                        copy[a._ls_index] = new LiveV();\n                        newAssigStmt.frame = copy;\n                    }\n                    LiveV thePhi = frame[a._ls_index];\n                    thePhi.local = newLocal;\n                    for (LiveV v : frame) {\n                        if (v != null && v.used) {\n                            RegAssign s = (RegAssign) v.local.tag;\n                            s.excludes.add(newRegAssign);\n                            newRegAssign.excludes.add(s);\n                        }\n                    }\n\n                }\n            }\n        }\n    }\n\n    private void insertAssignPath(IrMethod method, Collection<LabelStmt> phiLabels) {\n        // FIXME the phi in Exception handler is buggy\n        List<AssignStmt> buff = new ArrayList<>();\n        for (LabelStmt labelStmt : phiLabels) {\n            List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;\n            LiveV[] frame = (LiveV[]) labelStmt.frame;\n            for (Stmt from : labelStmt._cfg_froms) {\n                if (from.visited) { // at lease it is reached by cfg\n                    for (AssignStmt phi : phis) {\n                        Local a = (Local) phi.getOp1();\n                        LiveV v = frame[a._ls_index];\n                        Local local = v.stmt2regMap.get(from);\n                        if (local != a) {\n                            buff.add(Stmts.nAssign(a, local));\n                        }\n                    }\n                    insertAssignPath(method.stmts, from, labelStmt, buff);\n                    buff.clear();\n                }\n            }\n        }\n    }\n\n    private void insertAssignPath(StmtList stmts, Stmt from, LabelStmt labelStmt, List<AssignStmt> buff) {\n        boolean insertBeforeFromStmt;\n        if (from.exceptionHandlers != null && from.exceptionHandlers.contains(labelStmt)) {\n            insertBeforeFromStmt = true;\n        } else {\n            switch (from.st) {\n            case GOTO:\n            case IF:\n                JumpStmt jumpStmt = (JumpStmt) from;\n                insertBeforeFromStmt = jumpStmt.getTarget().equals(labelStmt); //\n                break;\n            case TABLE_SWITCH:\n            case LOOKUP_SWITCH:\n                insertBeforeFromStmt = true;\n                break;\n            default:\n                insertBeforeFromStmt = false;\n                break;\n            }\n        }\n        if (insertBeforeFromStmt) {\n            for (AssignStmt as : buff) {\n                stmts.insertBefore(from, as);\n            }\n        } else {\n            for (AssignStmt as : buff) {\n                stmts.insertAfter(from, as);\n            }\n        }\n        LiveV[] frame = (LiveV[]) from.frame;\n        List<LiveV> newLiveVs = new ArrayList<>(buff.size());\n        for (AssignStmt as : buff) {\n            Local left = (Local) as.getOp1();\n            {\n                LiveV liveV = new LiveV();\n                liveV.local = left;\n                liveV.used = true;\n                newLiveVs.add(liveV);\n            }\n            RegAssign leftRegAssign = (RegAssign) left.tag;\n            Local right = (Local) as.getOp2();\n            int toSkip = right._ls_index;\n            for (int i = 0; i < frame.length; i++) {\n                if (i == toSkip) {\n                    continue;\n                }\n                LiveV v = frame[i];\n                if (v != null && v.used) {\n                    RegAssign assign = (RegAssign) v.local.tag;\n                    assign.excludes.add(leftRegAssign);\n                    leftRegAssign.excludes.add(assign);\n                }\n            }\n            for (AssignStmt as2 : buff) {\n                RegAssign assign = (RegAssign) ((Local) as2.getOp1()).tag;\n                assign.excludes.add(leftRegAssign);\n                leftRegAssign.excludes.add(assign);\n            }\n        }\n\n        LiveV[] newFrame = new LiveV[frame.length + newLiveVs.size()];\n        System.arraycopy(frame, 0, newFrame, 0, frame.length);\n        for (int i = 0; i < newLiveVs.size(); i++) {\n            newFrame[i + frame.length] = newLiveVs.get(i);\n        }\n\n    }\n\n    @Override\n    public void transform(IrMethod method) {\n        if (method.phiLabels == null || method.phiLabels.size() == 0) {\n            return;\n        }\n\n        // fix issue in github 186\n        // .?.....?.?.?.x?x.x..?x.?.??.x.... | L24e82f43: // [a15 = φ(a4, a23), a17 = φ(a5, a20)]\n        // .?x....?.?.?.x?x.x..?x.?.??.x.... | L16e1a441: // [a2 = φ(a4, a15)]\n        // the local a15 is fixed to x15 in fixPhi\n        // .?.....?.?.?.x?x.x..?x.?.??.x.... | L24e82f43: // [x15 = φ(a4, a23), a17 = φ(a5, a20)]\n        //                                   | a15 = x15\n        // .?x....?.?.?.x?x.x..?x.?.??.x.... | L16e1a441: // [a2 = φ(a4, a15)]\n        //  after that, when demote a2, it is inserted after L24e82f43, which will cause a15 undefined\n        // .?.....?.?.?.x?x.x..?x.?.??.x.... | L24e82f43: // [x15 = φ(a4, a23), a17 = φ(a5, a20)]\n        //                                   | a2 = a15\n        //                                   | a15 = x15\n        // .?x....?.?.?.x?x.x..?x.?.??.x.... | L16e1a441: // [a2 = φ(a4, a15)]\n\n        // this is simple fix to github 186\n        // insert a Nop between two LabelStmt if both have phis\n        for (LabelStmt phiLabel : method.phiLabels) {\n            Stmt stmt = phiLabel.getNext();\n            if (stmt.st == ST.LABEL) {\n                LabelStmt labelStmt2 = (LabelStmt) stmt;\n                if (labelStmt2.phis != null && labelStmt2.phis.size() > 0) {\n                    method.stmts.insertAfter(phiLabel, Stmts.nNop());\n                }\n            }\n        }\n\n        // 1. Live analyze the method,\n        // a. remove Phi,\n        // b. record parameter reference\n        LiveA liveA = new LiveA(method);\n        liveA.analyze();\n\n        genRegGraph(method, liveA);\n\n        // 2. insert x=y\n        fixPhi(method, method.phiLabels);\n        insertAssignPath(method, method.phiLabels);\n\n        // 4. clean up\n        for (Local local : method.locals) {\n            local.tag = null;\n        }\n        for (Stmt stmt : method.stmts) {\n            stmt.frame = null;\n        }\n        for (LabelStmt labelStmt : method.phiLabels) {\n            labelStmt.phis = null;\n        }\n        method.phiLabels = null;\n    }\n\n    private void genRegGraph(IrMethod method, LiveA liveA) {\n        for (Local local : method.locals) {\n            local.tag = new RegAssign();\n        }\n\n        Set<Stmt> tos = new HashSet<>();\n        for (Stmt stmt : method.stmts) {\n            if ((stmt.st == ST.ASSIGN || stmt.st == ST.IDENTITY) && stmt.getOp1().vt == VT.LOCAL) {\n                Local localAssignTo = (Local) stmt.getOp1();\n                RegAssign regAssignTo = (RegAssign) localAssignTo.tag;\n                Set<Integer> excludeIdx = new HashSet<>();\n                Cfg.collectTos(stmt, tos);\n                for (Stmt target : tos) {\n                    LiveV frame[] = (LiveV[]) target.frame;\n                    if (frame == null) {\n                        continue;\n                    }\n                    // exclude thisReg and phiReg\n                    excludeIdx.clear();\n                    excludeIdx.add(localAssignTo._ls_index);\n                    if (target.st == ST.LABEL) {\n                        LabelStmt label = (LabelStmt) target;\n                        if (label.phis != null) {\n                            for (AssignStmt phiAssignStmt : (List<AssignStmt>) label.phis) {\n                                Local phiLocal = (Local) phiAssignStmt.getOp1();\n                                excludeIdx.add(phiLocal._ls_index);\n                            }\n                        }\n                    }\n                    for (int i = 0; i < frame.length; i++) {\n                        if (excludeIdx.contains(i)) {\n                            continue;\n                        }\n                        LiveV v = frame[i];\n                        if (v != null && v.used) {\n                            RegAssign b = (RegAssign) v.local.tag;\n                            regAssignTo.excludes.add(b);\n                            b.excludes.add(regAssignTo);\n                        }\n                    }\n                }\n                tos.clear();\n            } else if (stmt.st == ST.LABEL) { //\n                LabelStmt label = (LabelStmt) stmt;\n                if (label.phis != null) {\n                    for (AssignStmt phiAssignStmt : (List<AssignStmt>) label.phis) {\n                        Local phiLocal = (Local) phiAssignStmt.getOp1();\n                        RegAssign a = (RegAssign) phiLocal.tag;\n                        LiveV frame[] = (LiveV[]) stmt.frame;\n                        for (LiveV v : frame) {\n                            if (v != null && v.used) {\n                                RegAssign b = (RegAssign) v.local.tag;\n                                a.excludes.add(b);\n                                b.excludes.add(a);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (DEBUG) {\n            System.out.println(liveA.toString());\n        }\n    }\n\n    protected static class LiveA extends BaseAnalyze<LiveV> {\n        static Comparator<LiveV> sortByHopsASC = new Comparator<LiveV>() {\n\n            @Override\n            public int compare(LiveV arg0, LiveV arg1) {\n                return arg0.hops - arg1.hops;\n            }\n        };\n\n        public LiveA(IrMethod method) {\n            super(method);\n        }\n\n        @Override\n        protected void analyzeValue() {\n            markUsed();\n\n            if (UnSSATransformer.DEBUG) {\n                clearUnUsedFromFrame();\n            }\n\n        }\n\n        protected void clearUnUsedFromFrame() {\n            for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\n                LiveV[] frame = (LiveV[]) p.frame;\n                if (frame != null) {\n                    for (int i = 0; i < frame.length; i++) {\n                        LiveV r = frame[i];\n                        if (r != null) {\n                            if (!r.used) {\n                                frame[i] = null;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        protected Set<LiveV> markUsed() {\n            Set<LiveV> used = new HashSet<LiveV>(aValues.size() / 2);\n            Queue<LiveV> q = new UniqueQueue<>();\n            q.addAll(aValues);\n\n            while (!q.isEmpty()) {\n                LiveV v = q.poll();\n                if (v.used) {\n                    if (used.contains(v)) {\n                        continue;\n                    }\n                    used.add(v);\n                    {\n                        LiveV parent = v.parent;\n                        if (parent != null && !parent.used) {\n                            parent.used = true;\n                            q.add(parent);\n                        }\n                    }\n                    {\n                        List<LiveV> otherParent = v.otherParents;\n                        if (otherParent != null && otherParent.size() > 0) {\n                            for (LiveV parent : otherParent) {\n                                if (parent != null && !parent.used) {\n                                    parent.used = true;\n                                    q.add(parent);\n                                }\n                            }\n                            v.otherParents = null;\n                        }\n                    }\n                }\n            }\n            for (LiveV v : aValues) {\n                v.parent = null;\n            }\n            aValues = null;\n\n            return used;\n        }\n\n        @SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n        @Override\n        public LiveV[] merge(LiveV[] srcFrame, LiveV[] distFrame, Stmt src, Stmt dist) {\n\n            Map<Integer, AssignStmt> phiLives = new HashMap<>();\n            if (dist.st == ST.LABEL) {\n                LabelStmt label = (LabelStmt) dist;\n                if (label.phis != null) {// we got phis here\n                    // travel each phi assignment, find where the phiLocal from\n                    for (AssignStmt phiAssignStmt : (List<AssignStmt>) label.phis) {\n                        Local phiLocal = (Local) phiAssignStmt.getOp1();\n                        phiLives.put(phiLocal._ls_index, phiAssignStmt);\n                    }\n                }\n            }\n            // relationship\n            boolean firstMerge = false;\n            if (distFrame == null) { // distFrame is not visited\n                distFrame = newFrame(); // init the distFrame\n                firstMerge = true;\n\n                // merge each value to distFrame if value is not null;\n                for (int i = 0; i < distFrame.length; i++) {\n                    if (phiLives.containsKey(i)) { // skip phi\n                        continue;\n                    }\n                    LiveV srcV = srcFrame[i];\n                    if (srcV != null) {\n                        LiveV distV = newValue();\n                        aValues.add(distV);\n                        distV.parent = srcV;\n                        distV.hops = srcV.hops + 1;\n                        distV.local = srcV.local;\n                        distFrame[i] = distV;\n                    }\n                }\n            }\n\n            if (!firstMerge) {\n                // skip merge phi\n                for (int i = 0; i < distFrame.length; i++) {\n                    if (phiLives.containsKey(i)) {\n                        continue;\n                    }\n                    LiveV srcV = srcFrame[i];\n                    LiveV distV = distFrame[i];\n                    if (srcV != null && distV != null) {\n                        if (distV.otherParents == null) {\n                            distV.otherParents = new ArrayList(5);\n                        }\n                        distV.otherParents.add(srcV);\n                    }\n                }\n            }\n\n            // deal with phi\n            for (AssignStmt phiAssignStmt : phiLives.values()) {\n                Local phiLocal = (Local) phiAssignStmt.getOp1();\n\n                LiveV distValue;\n                if (firstMerge) {\n                    distValue = new LiveV();\n                    distValue.local = phiLocal;\n                    distValue.stmt2regMap = new HashMap<>();\n                    distFrame[phiLocal._ls_index] = distValue;\n                } else {\n                    distValue = distFrame[phiLocal._ls_index];\n                }\n\n                List<LiveV> liveVs = new ArrayList();\n\n                LiveV possiblePhiLocal = srcFrame[phiLocal._ls_index];\n                if (possiblePhiLocal != null) {\n                    liveVs.add(possiblePhiLocal);\n                }\n\n                for (Value p0 : phiAssignStmt.getOp2().getOps()) {\n                    Local srcLocal = (Local) p0;\n                    LiveV s = srcFrame[srcLocal._ls_index];\n                    if (s != null) {\n                        liveVs.add(s);\n                    }\n                }\n                Collections.sort(liveVs, sortByHopsASC);\n                LiveV a = liveVs.get(0); // this value assign to\n                                         // phiLocal in srcFrame\n                a.used = true;\n                distValue.stmt2regMap.put(src, a.local);\n            }\n            return distFrame;\n        }\n\n        @Override\n        protected LiveV[] newFrame(int size) {\n            return new LiveV[size];\n        }\n\n        @Override\n        protected LiveV newValue() {\n            return new LiveV();\n        }\n\n        @Override\n        protected LiveV onAssignLocal(Local local, Value value) {\n            LiveV v = super.onAssignLocal(local, value);\n            v.local = local;\n            v.used = true;\n            return v;\n        }\n\n        @Override\n        protected void onUseLocal(LiveV aValue, Local local) {\n            aValue.used = true;\n        }\n\n    }\n\n    private static class LiveV implements AnalyzeValue {\n        public int hops;\n        public Local local;\n        public LiveV parent;\n        public boolean used;\n        public List<LiveV> otherParents;\n        /**\n         * for a Phi local, record where the this assigned from, for\n         * \n         * <pre>\n         *     s0: a0=1\n         *     s1: if x goto s3\n         *     s2: a1=2\n         *     s3: a= phi(a0, a1)\n         * </pre>\n         * \n         * the value is s0 : a0 s2 : a1\n         */\n        Map<Stmt, Local> stmt2regMap;\n\n        @Override\n        public char toRsp() {\n            return used ? 'x' : '?';\n        }\n\n        @Override\n        public String toString() {\n            return local + \"|\" + hops;\n        }\n    }\n\n    /**\n     * designed for assign index to Local, each Object is related to a Local\n     */\n    protected static class RegAssign {\n        /**\n         * can not have same index with\n         */\n        public Set<RegAssign> excludes = new HashSet<RegAssign>();\n\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/UniqueQueue.java",
    "content": "package com.googlecode.dex2jar.ir.ts;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Set;\n\npublic class UniqueQueue<T> extends LinkedList<T> {\n    Set<T> set = new HashSet<>();\n\n    public UniqueQueue() {\n    }\n\n    @Override\n    public boolean addAll(Collection<? extends T> c) {\n        boolean result = false;\n        for (T t : c) {\n            if (add(t)) {\n                result = true;\n            }\n        }\n        return result;\n\n    }\n\n    @Override\n    public boolean add(T t) {\n        if (set.add(t)) {\n            super.add(t);\n        }\n        return true;\n    }\n\n    public T poll() {\n        T t = super.poll();\n        set.remove(t);\n        return t;\n    }\n\n    @Override\n    public T pop() {\n        T t = super.pop();\n        set.remove(t);\n        return t;\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/VoidInvokeTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\n\n/**\n * convert\n * \n * <pre>\n * a = b.get();\n * </pre>\n * \n * to\n * \n * <pre>\n * b.get();\n * </pre>\n * \n * if a is not used in other place.\n */\npublic class VoidInvokeTransformer extends StatedTransformer {\n    @Override\n    public boolean transformReportChanged(IrMethod method) {\n        if (method.locals.size() == 0) {\n            return false;\n        }\n        int reads[] = Cfg.countLocalReads(method);\n        boolean changed = false;\n        for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\n            if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) {\n                Local left = (Local) p.getOp1();\n                if (reads[left._ls_index] == 0) {\n                    switch (p.getOp2().vt) {\n                    case INVOKE_INTERFACE:\n                    case INVOKE_NEW:\n                    case INVOKE_SPECIAL:\n                    case INVOKE_STATIC:\n                    case INVOKE_VIRTUAL:\n                        method.locals.remove(left);\n                        Stmt nVoidInvoke = Stmts.nVoidInvoke(p.getOp2());\n                        method.stmts.replace(p, nVoidInvoke);\n                        p = nVoidInvoke;\n                        changed = true;\n                        break;\n                    default:\n                        break;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    @Override\n    public void transform(IrMethod method) {\n        transformReportChanged(method);\n\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/ZeroTransformer.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.Constant;\r\nimport com.googlecode.dex2jar.ir.expr.Exprs;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * dex mix use as integer 0 and object null. the following code is validate in dex, but invalidate in .class\r\n * \r\n * <pre>\r\n *     a=0\r\n *     if x>0 goto L1\r\n *     L2: [b=phi(a,c)]\r\n *     useAsObject(b);\r\n *     c=getAnotherObject();\r\n *     goto L2:\r\n *     L1: [d=phi(a,e)]\r\n *     useAsInt(d);\r\n *     e=123\r\n *     goto L1:\r\n * </pre>\r\n * \r\n * we transform the code to\r\n * \r\n * <pre>\r\n *     a1=0\r\n *     a=0\r\n *     if x>0 goto L1\r\n *     a2=0\r\n *     L2: [b=phi(a1,c)]\r\n *     useAsObject(b);\r\n *     c=getAnotherObject();\r\n *     goto L2:\r\n *     L1: [d=phi(a,e)]\r\n *     useAsInt(d);\r\n *     e=123\r\n *     goto L1:\r\n * </pre>\r\n */\r\npublic class ZeroTransformer extends StatedTransformer {\r\n\r\n    @Override\r\n    public boolean transformReportChanged(IrMethod method) {\r\n        boolean changed = false;\r\n        List<AssignStmt> assignStmtList = new ArrayList<>();\r\n\r\n        for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {\r\n            if (p.st == Stmt.ST.ASSIGN) {\r\n                AssignStmt as = (AssignStmt) p;\r\n                if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.CONSTANT) {\r\n                    Constant cst = (Constant) as.getOp2();\r\n                    Object value = cst.value;\r\n                    if (value instanceof Number && !((value instanceof Long) || (value instanceof Double))) {\r\n                        int v = ((Number) value).intValue();\r\n                        if (v == 0 || v == 1) {\r\n                            assignStmtList.add(as);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (assignStmtList.size() == 0) {\r\n            return false;\r\n        }\r\n        List<LabelStmt> phiLabels = method.phiLabels;\r\n        if (phiLabels != null) {\r\n            for (AssignStmt as : assignStmtList) {\r\n                Local local = (Local) as.getOp1();\r\n                boolean first = true;\r\n                for (LabelStmt labelStmt : phiLabels) {\r\n                    for (AssignStmt phi : labelStmt.phis) {\r\n                        Value[] vs = phi.getOp2().getOps();\r\n                        for (int i = 0; i < vs.length; i++) {\r\n                            Value v = vs[i];\r\n                            if (v == local) {\r\n                                if (first) {\r\n                                    first = false;\r\n                                } else {\r\n                                    Local nLocal = Exprs.nLocal(-1);\r\n                                    method.locals.add(nLocal);\r\n                                    changed = true;\r\n                                    method.stmts.insertBefore(as, Stmts.nAssign(nLocal, as.getOp2().clone()));\r\n                                    vs[i] = nLocal;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return changed;\r\n    }\r\n}"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/an/AnalyzeValue.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts.an;\n\npublic interface AnalyzeValue {\n\n    public char toRsp();\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/an/BaseAnalyze.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.ir.ts.an;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg.FrameVisitor;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n@SuppressWarnings({\"unchecked\"})\r\npublic abstract class BaseAnalyze<T extends AnalyzeValue> implements FrameVisitor<T[]>, TravelCallBack {\r\n    protected static final boolean DEBUG = false;\r\n\r\n    public List<T> aValues = new ArrayList<T>();\r\n    private boolean reindexLocal;\r\n    private T[] currentFrame;\r\n\r\n    protected int localSize;\r\n\r\n    protected IrMethod method;\r\n\r\n    private T[] tmpFrame;\r\n\r\n    public BaseAnalyze(IrMethod method) {\r\n        this(method,true);\r\n    }\r\n\r\n    public BaseAnalyze(IrMethod method, boolean reindexLocal) {\r\n        super();\r\n        this.method = method;\r\n        if (!reindexLocal) {\r\n            // override the localSize value to the max local index+1\r\n            int maxReg = -1;\r\n            for (Local local : method.locals) {\r\n                if (local._ls_index > maxReg) {\r\n                    maxReg = local._ls_index;\r\n                }\r\n            }\r\n            this.localSize = maxReg + 1;\r\n        } else {\r\n            this.localSize = method.locals.size();\r\n        }\r\n        this.reindexLocal = reindexLocal;\r\n    }\r\n\r\n    public void analyze() {\r\n        init();\r\n        analyze0();\r\n        analyzeValue();\r\n    }\r\n\r\n    protected void analyze0() {\r\n        tmpFrame = newFrame(localSize);\r\n        Cfg.dfs(method.stmts, this);\r\n        tmpFrame = null;\r\n    }\r\n\r\n    protected void analyzeValue() {\r\n    }\r\n\r\n    protected void afterExec(T[] frame, Stmt stmt) {\r\n\r\n    }\r\n\r\n    @Override\r\n    public T[] exec(T[] frame, Stmt stmt) {\r\n        this.currentFrame = frame;\r\n        try {\r\n            Cfg.travel(stmt, this, false);\r\n        } catch (Exception ex) {\r\n            throw new RuntimeException(\"fail exe \" + stmt, ex);\r\n        }\r\n        frame = this.currentFrame;\r\n        this.currentFrame = null;\r\n        afterExec(frame, stmt);\r\n        return frame;\r\n    }\r\n\r\n    protected T getFromFrame(int idx) {\r\n        return (T) currentFrame[idx];\r\n    }\r\n\r\n    protected T[] getFrame(Stmt stmt) {\r\n        return (T[]) stmt.frame;\r\n    }\r\n\r\n    protected void setFrame(Stmt stmt, T[] frame) {\r\n        stmt.frame = frame;\r\n    }\r\n\r\n    protected void init() {\r\n        if (reindexLocal) {\r\n            int index = 0;\r\n            for (Local local : method.locals) {\r\n                local._ls_index = index;\r\n                index++;\r\n            }\r\n        }\r\n        if (DEBUG) {\r\n            int idx = 0;\r\n            for (Stmt s : method.stmts) {\r\n                if (s.st == Stmt.ST.LABEL) {\r\n                    LabelStmt label = (LabelStmt) s;\r\n                    label.displayName = \"L\" + idx++;\r\n                }\r\n            }\r\n        }\r\n        initCFG();\r\n    }\r\n\r\n    protected void initCFG() {\r\n        Cfg.createCFG(method);\r\n    }\r\n\r\n    protected T[] newFrame() {\r\n        return newFrame(localSize);\r\n    }\r\n\r\n    @Override\r\n    public T[] initFirstFrame(Stmt first) {\r\n        return newFrame(localSize);\r\n    }\r\n\r\n    protected abstract T[] newFrame(int size);\r\n\r\n    protected abstract T newValue();\r\n\r\n    @Override\r\n    public Local onAssign(Local local, AssignStmt as) {\r\n        System.arraycopy(currentFrame, 0, tmpFrame, 0, localSize);\r\n        currentFrame = tmpFrame;\r\n        T aValue = onAssignLocal(local, as.op2);\r\n        aValues.add(aValue);\r\n        currentFrame[local._ls_index] = aValue;\r\n        return local;\r\n    }\r\n\r\n    protected T onAssignLocal(Local local, Value value) {\r\n        return newValue();\r\n    }\r\n\r\n    @Override\r\n    public Local onUse(Local local) {\r\n        T aValue = (T) currentFrame[local._ls_index];\r\n        onUseLocal(aValue, local);\r\n        return local;\r\n    }\r\n\r\n    protected void onUseLocal(T aValue, Local local) {\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        StringBuilder sb = new StringBuilder();\r\n        for (Stmt stmt = method.stmts.getFirst(); stmt != null; stmt = stmt.getNext()) {\r\n            T[] frame = (T[]) stmt.frame;\r\n            if (frame != null) {\r\n                for (T p : frame) {\r\n                    if (p == null) {\r\n                        sb.append('.');\r\n                    } else {\r\n                        sb.append(p.toRsp());\r\n                    }\r\n                }\r\n                sb.append(\" | \");\r\n            }\r\n            sb.append(stmt.toString()).append('\\n');\r\n        }\r\n        return sb.toString();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/an/SimpleLiveAnalyze.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts.an;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.ts.UniqueQueue;\n\nimport java.util.*;\n\npublic class SimpleLiveAnalyze extends BaseAnalyze<SimpleLiveValue> {\n    protected Set<SimpleLiveValue> markUsed() {\n        Set<SimpleLiveValue> used = new HashSet<SimpleLiveValue>(aValues.size() / 2);\n        Queue<SimpleLiveValue> q = new UniqueQueue<>();\n        for (SimpleLiveValue sv : aValues) {\n            if (sv.used) {\n                q.add(sv);\n                while (!q.isEmpty()) {\n                    SimpleLiveValue v = q.poll();\n                    if (v.used) {\n                        if (used.contains(v)) {\n                            continue;\n                        }\n                        used.add(v);\n                        {\n                            SimpleLiveValue p = v.parent;\n                            if (p != null) {\n                                if (!p.used) {\n                                    p.used = true;\n                                    q.add(p);\n                                }\n                            }\n                        }\n                        if (v.otherParents != null) {\n                            for (SimpleLiveValue p : v.otherParents) {\n                                if (!p.used) {\n                                    p.used = true;\n                                    q.add(p);\n                                }\n                            }\n                            v.otherParents = null;\n                        }\n                    }\n                }\n            }\n        }\n\n        return used;\n    }\n\n    @Override\n    protected void analyzeValue() {\n        markUsed();\n    }\n\n    public int getLocalSize() {\n        return localSize;\n    }\n\n    public SimpleLiveAnalyze(IrMethod method, boolean reindexLocal) {\n        super(method, reindexLocal);\n    }\n\n    @Override\n    protected SimpleLiveValue onAssignLocal(Local local, Value value) {\n        SimpleLiveValue v = super.onAssignLocal(local, value);\n        v.used = true;\n        return v;\n    }\n\n    @Override\n    protected void onUseLocal(SimpleLiveValue aValue, Local local) {\n        aValue.used = true;\n        super.onUseLocal(aValue, local);\n    }\n\n    @Override\n    public SimpleLiveValue[] merge(SimpleLiveValue[] srcFrame, SimpleLiveValue[] distFrame, Stmt src, Stmt dist) {\n        if (distFrame == null) {\n            distFrame = new SimpleLiveValue[this.localSize];\n            for (int i = 0; i < srcFrame.length; i++) {\n                SimpleLiveValue sV = srcFrame[i];\n                if (sV != null) {\n                    SimpleLiveValue dV = new SimpleLiveValue();\n                    aValues.add(dV);\n                    dV.parent = sV;\n                    distFrame[i] = dV;\n                }\n            }\n        } else {\n            for (int i = 0; i < srcFrame.length; i++) {\n                SimpleLiveValue sV = srcFrame[i];\n                SimpleLiveValue dV = distFrame[i];\n                if (sV != null && dV != null) {\n                    List<SimpleLiveValue> ps = dV.otherParents;\n                    if (ps == null) {\n                        dV.otherParents = ps = new ArrayList<>(3);\n                    }\n                    ps.add(sV);\n                }\n            }\n        }\n        return distFrame;\n    }\n\n    @Override\n    protected SimpleLiveValue[] newFrame(int size) {\n        return new SimpleLiveValue[size];\n    }\n\n    @Override\n    protected SimpleLiveValue newValue() {\n        return new SimpleLiveValue();\n    }\n}"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/an/SimpleLiveValue.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts.an;\n\nimport java.util.List;\n\npublic class SimpleLiveValue implements AnalyzeValue {\n    public boolean used = false;\n\n    public SimpleLiveValue parent;\n    public List<SimpleLiveValue> otherParents;\n\n    @Override\n    public char toRsp() {\n        return used ? 'x' : '.';\n    }\n}"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/array/ArrayElementTransformer.java",
    "content": "package com.googlecode.dex2jar.ir.ts.array;\r\n\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.StmtTraveler;\r\nimport com.googlecode.dex2jar.ir.expr.*;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg;\r\nimport com.googlecode.dex2jar.ir.ts.StatedTransformer;\r\n\r\nimport java.lang.reflect.Array;\r\nimport java.util.*;\r\n\r\n/**\r\n * require SSA, element index are const\r\n * <p/>\r\n * transformer\r\n * <pre>\r\n *     ...\r\n *     a[4]=\"abc\"\r\n *     return a[4]\r\n * </pre>\r\n * to\r\n * <pre>\r\n *     ...\r\n *     a[4]=\"abc\"\r\n *     return \"abc\"\r\n * </pre>\r\n */\r\npublic class ArrayElementTransformer extends StatedTransformer {\r\n    @Override\r\n    public boolean transformReportChanged(IrMethod method) {\r\n\r\n        Set<Local> arrays = searchForArrayObject(method);\r\n        if (arrays.size() == 0) {\r\n            return false;\r\n        }\r\n        for (Local local : method.locals) {\r\n            local._ls_index = -1;\r\n        }\r\n        int i = 0;\r\n        for (Local local : arrays) {\r\n            local._ls_index = i++;\r\n        }\r\n        final int size = i;\r\n        Cfg.createCFG(method);\r\n        final List<ArrayValue> values = new ArrayList<>();\r\n        final List<Stmt> used = new ArrayList<>();\r\n        Cfg.dfs(method.stmts, new Cfg.FrameVisitor<ArrayValue[]>() {\r\n\r\n            Set<Integer> phis = new HashSet<>();\r\n\r\n            @Override\r\n            public ArrayValue[] merge(ArrayValue[] srcFrame, ArrayValue[] distFrame, Stmt src, Stmt dist) {\r\n                if (dist.st == Stmt.ST.LABEL) {\r\n                    LabelStmt labelStmt = (LabelStmt) dist;\r\n                    if (labelStmt.phis != null) {\r\n                        for (AssignStmt phi : labelStmt.phis) {\r\n                            int idx = ((Local) phi.getOp1())._ls_index;\r\n                            if (idx >= 0) {\r\n                                phis.add(idx);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                if (distFrame == null) {\r\n                    distFrame = new ArrayValue[size];\r\n                    for (int i = 0; i < size; i++) {\r\n                        if (phis.contains(i)) {\r\n                            ArrayValue aov = new ArrayValue();\r\n                            values.add(aov);\r\n                            aov.s = ArrayValue.S.UNKNOWN;\r\n                            aov.indexType = ArrayValue.IndexType.NONE;\r\n                            aov.stmt = dist;\r\n                            distFrame[i] = aov;\r\n                        } else {\r\n                            ArrayValue arc = srcFrame[i];\r\n                            if (arc != null) {\r\n                                ArrayValue aov = new ArrayValue();\r\n                                values.add(aov);\r\n                                aov.s = ArrayValue.S.INHERIT;\r\n                                aov.indexType = ArrayValue.IndexType.NONE;\r\n                                aov.stmt = dist;\r\n                                aov.parent = arc;\r\n                                distFrame[i] = aov;\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    for (int i = 0; i < size; i++) {\r\n                        if (phis.contains(i)) {\r\n                            continue;\r\n                        }\r\n                        ArrayValue arc = srcFrame[i];\r\n                        ArrayValue aov = distFrame[i];\r\n                        if (arc != null && aov != null) {\r\n                            if (aov.parent == null) {\r\n                                aov.parent = arc;\r\n                            } else if (!aov.parent.equals(arc)) {\r\n                                if (aov.otherParents == null) {\r\n                                    aov.otherParents = new HashSet<>();\r\n                                }\r\n                                aov.otherParents.add(arc);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                phis.clear();\r\n                return distFrame;\r\n            }\r\n\r\n            @Override\r\n            public ArrayValue[] initFirstFrame(Stmt first) {\r\n                return new ArrayValue[size];\r\n            }\r\n\r\n            ArrayValue[] tmp = new ArrayValue[size];\r\n            Stmt currentStmt;\r\n\r\n\r\n            @Override\r\n            public ArrayValue[] exec(ArrayValue[] frame, Stmt stmt) {\r\n                currentStmt = stmt;\r\n                System.arraycopy(frame, 0, tmp, 0, size);\r\n                if (stmt.st == Stmt.ST.ASSIGN) {\r\n                    // create an array\r\n                    if (stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) stmt.getOp1();\r\n                        use(stmt.getOp2());\r\n                        if (local._ls_index >= 0) {\r\n                            Value op2 = stmt.getOp2();\r\n                            if (op2.vt == Value.VT.NEW_ARRAY) {\r\n                                ArrayValue av = new ArrayValue();\r\n                                av.s = ArrayValue.S.DEFAULT;\r\n                                av.size = op2.getOp();\r\n                                values.add(av);\r\n                                tmp[local._ls_index] = av;\r\n                            } else if (op2.vt == Value.VT.FILLED_ARRAY) {\r\n                                ArrayValue av = new ArrayValue();\r\n                                av.s = ArrayValue.S.DEFAULT;\r\n                                av.indexType = ArrayValue.IndexType.CONST;\r\n                                av.stmt = stmt;\r\n                                FilledArrayExpr fae = (FilledArrayExpr) stmt.getOp2();\r\n                                av.size = Exprs.nInt(fae.getOps().length);\r\n                                Value[] ops = fae.getOps();\r\n                                for (int i = 0; i < ops.length; i++) {\r\n                                    av.elements1.put(i, ops[i]);\r\n                                }\r\n                                values.add(av);\r\n                                tmp[local._ls_index] = av;\r\n                            } else if (op2.vt == Value.VT.CONSTANT) {\r\n                                Object cst = ((Constant) op2).value;\r\n                                if (cst != null && !cst.equals(Constant.Null) && cst.getClass().isArray()) {\r\n                                    ArrayValue av = new ArrayValue();\r\n                                    av.s = ArrayValue.S.DEFAULT;\r\n                                    av.indexType = ArrayValue.IndexType.CONST;\r\n                                    av.stmt = stmt;\r\n                                    int size = Array.getLength(cst);\r\n                                    av.size = Exprs.nInt(size);\r\n                                    for (int i = 0; i < size; i++) {\r\n                                        av.elements1.put(i, Exprs.nConstant(Array.get(cst, size)));\r\n                                    }\r\n                                    values.add(av);\r\n                                    tmp[local._ls_index] = av;\r\n                                } else {\r\n                                    ArrayValue av = new ArrayValue();\r\n                                    values.add(av);\r\n                                    av.s = ArrayValue.S.UNKNOWN;\r\n                                    av.indexType = ArrayValue.IndexType.NONE;\r\n                                    av.stmt = stmt;\r\n                                    tmp[local._ls_index] = av;\r\n                                }\r\n                            } else {\r\n                                ArrayValue av = new ArrayValue();\r\n                                values.add(av);\r\n                                av.s = ArrayValue.S.UNKNOWN;\r\n                                av.indexType = ArrayValue.IndexType.NONE;\r\n                                av.stmt = stmt;\r\n                                tmp[local._ls_index] = av;\r\n                            }\r\n                        }\r\n                        // assign index1\r\n                    } else if (stmt.getOp1().vt == Value.VT.ARRAY) {\r\n                        use(stmt.getOp2());\r\n                        ArrayExpr ae = (ArrayExpr) stmt.getOp1();\r\n                        if (ae.getOp1().vt == Value.VT.LOCAL) {\r\n                            Local local = (Local) ae.getOp1();\r\n                            Value index = ae.getOp2();\r\n                            if (local._ls_index >= 0) {\r\n                                if (index.vt == Value.VT.CONSTANT) {\r\n                                    ArrayValue parent = tmp[local._ls_index];\r\n                                    ArrayValue av = new ArrayValue();\r\n                                    values.add(av);\r\n                                    av.parent = parent;\r\n                                    av.elements1.put(((Number) (((Constant) index).value)).intValue(), stmt.getOp2());\r\n                                    av.indexType = ArrayValue.IndexType.CONST;\r\n                                    av.s = ArrayValue.S.INHERIT;\r\n                                    av.stmt = stmt;\r\n                                    tmp[local._ls_index] = av;\r\n                                } else if (index.vt == Value.VT.LOCAL) {\r\n                                    ArrayValue parent = tmp[local._ls_index];\r\n                                    ArrayValue av = new ArrayValue();\r\n                                    values.add(av);\r\n                                    av.parent = parent;\r\n                                    av.elements1.put(index, stmt.getOp2());\r\n                                    av.indexType = ArrayValue.IndexType.LOCAL;\r\n                                    av.s = ArrayValue.S.INHERIT;\r\n                                    av.stmt = stmt;\r\n                                    tmp[local._ls_index] = av;\r\n                                } else {\r\n                                    ArrayValue av = new ArrayValue();\r\n                                    values.add(av);\r\n                                    av.s = ArrayValue.S.UNKNOWN;\r\n                                    av.indexType = ArrayValue.IndexType.NONE;\r\n                                    av.stmt = stmt;\r\n                                    tmp[local._ls_index] = av;\r\n                                }\r\n                            } else {\r\n                                use(stmt.getOp1());\r\n                            }\r\n                        } else {\r\n                            use(stmt.getOp1());\r\n                        }\r\n\r\n                    } else {\r\n                        use(stmt.getOp1());\r\n                        use(stmt.getOp2());\r\n                    }\r\n                    // assign index2\r\n                } else if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                    if (stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) stmt.getOp1();\r\n                        if (local._ls_index >= 0) {\r\n                            Object array = ((Constant) stmt.getOp2()).value;\r\n                            ArrayValue parent = tmp[local._ls_index];\r\n                            ArrayValue av = new ArrayValue();\r\n                            values.add(av);\r\n                            av.parent = parent;\r\n                            int size = Array.getLength(array);\r\n                            av.size = Exprs.nInt(size);\r\n                            for (int i = 0; i < size; i++) {\r\n                                av.elements1.put(i, Exprs.nConstant(Array.get(array, i)));\r\n                            }\r\n                            av.indexType = ArrayValue.IndexType.CONST;\r\n                            av.s = ArrayValue.S.INHERIT;\r\n                            av.stmt = stmt;\r\n                            tmp[local._ls_index] = av;\r\n                        }\r\n                    } else {\r\n                        use(stmt.getOp1());\r\n                    }\r\n                } else {\r\n                    switch (stmt.et) {\r\n                        case E0:\r\n                            break;\r\n                        case E1:\r\n                            use(stmt.getOp());\r\n                            break;\r\n                        case E2:\r\n                            use(stmt.getOp1());\r\n                            use(stmt.getOp2());\r\n                            break;\r\n                        case En:\r\n                            throw new RuntimeException();\r\n                    }\r\n                }\r\n\r\n                return tmp;\r\n            }\r\n\r\n            private void use(Value v) {\r\n                switch (v.et) {\r\n                    case E0:\r\n                        break;\r\n                    case E1:\r\n                        use(v.getOp());\r\n                        break;\r\n                    case E2:\r\n                        Value op1 = v.getOp1();\r\n                        Value op2 = v.getOp2();\r\n                        use(op1);\r\n                        use(op2);\r\n                        if (v.vt == Value.VT.ARRAY) {\r\n                            if (op1.vt == Value.VT.LOCAL && (op2.vt == Value.VT.LOCAL || op2.vt == Value.VT.CONSTANT)) {\r\n                                Local local = (Local) op1;\r\n                                if (local._ls_index > 0) {\r\n                                    used.add(currentStmt);\r\n                                }\r\n                            }\r\n                        }\r\n                        break;\r\n                    case En:\r\n                        for (Value op : v.getOps()) {\r\n                            use(op);\r\n                        }\r\n                        break;\r\n                }\r\n            }\r\n        });\r\n\r\n\r\n        // TODO travel stmt to find must-be array element\r\n\r\n        for (Stmt p : method.stmts) {\r\n\r\n        }\r\n        new StmtTraveler() {\r\n            @Override\r\n            public Value travel(Value op) {\r\n                op = super.travel(op);\r\n                if (op.vt == Value.VT.ARRAY) {\r\n\r\n                }\r\n                return op;\r\n            }\r\n        }.travel(method.stmts);\r\n\r\n        return false;\r\n    }\r\n\r\n    public static void main(String... args) {\r\n        IrMethod m = new IrMethod();\r\n        m.isStatic = true;\r\n        m.name = \"a\";\r\n        m.args = new String[0];\r\n        m.ret = \"[Ljava/lang/String;\";\r\n        m.owner = \"La;\";\r\n\r\n        Local array = Exprs.nLocal(1);\r\n        m.locals.add(array);\r\n\r\n        m.stmts.add(Stmts.nAssign(array, Exprs.nNewArray(\"Ljava/lang/String;\", Exprs.nInt(2))));\r\n        m.stmts.add(Stmts.nAssign(Exprs.nArray(array, Exprs.nInt(1), \"Ljava/lang/String;\"), Exprs.nString(\"123\")));\r\n        m.stmts.add(Stmts.nAssign(Exprs.nArray(array, Exprs.nInt(0), \"Ljava/lang/String;\"), Exprs.nString(\"456\")));\r\n        m.stmts.add(Stmts.nReturn(array));\r\n        new ArrayElementTransformer().transform(m);\r\n    }\r\n\r\n    private Set<Local> searchForArrayObject(IrMethod method) {\r\n        final Set<Local> arrays = new HashSet<>();\r\n        for (Stmt stmt : method.stmts) {\r\n            if (stmt.st == Stmt.ST.ASSIGN) {\r\n                // create an array\r\n                if (stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                    Local local = (Local) stmt.getOp1();\r\n                    if (stmt.getOp2().vt == Value.VT.NEW_ARRAY || stmt.getOp2().vt == Value.VT.FILLED_ARRAY) {\r\n                        arrays.add(local);\r\n                    }\r\n                    // assign index1\r\n                } else if (stmt.getOp1().vt == Value.VT.ARRAY) {\r\n                    ArrayExpr ae = (ArrayExpr) stmt.getOp1();\r\n                    if (ae.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) ae.getOp1();\r\n                        arrays.add(local);\r\n                    }\r\n\r\n                }\r\n                // assign index2\r\n            } else if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                if (stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                    Local local = (Local) stmt.getOp1();\r\n                    arrays.add(local);\r\n                }\r\n            }\r\n        }\r\n        return arrays;\r\n    }\r\n\r\n    static class ArrayValue {\r\n        enum S {\r\n            /**\r\n             * all element are default value. that is null for object and 0 for primitive\r\n             */\r\n            DEFAULT,\r\n            /**\r\n             * all element are unknown value\r\n             */\r\n            UNKNOWN,\r\n            /**\r\n             * the element value is based on its parent\r\n             */\r\n            INHERIT\r\n        }\r\n\r\n        enum IndexType {\r\n            CONST, LOCAL, NONE\r\n        }\r\n\r\n\r\n        IndexType indexType = IndexType.NONE;\r\n        S s = S.INHERIT;\r\n        ArrayValue parent;\r\n        Value size;\r\n        Set<ArrayValue> otherParents;\r\n        Map<Object, Value> elements1 = new HashMap<>();\r\n        Stmt stmt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/array/ArrayNullPointerTransformer.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.ts.array;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.ArrayExpr;\nimport com.googlecode.dex2jar.ir.expr.Constant;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.FieldExpr;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\nimport com.googlecode.dex2jar.ir.expr.Value.E2Expr;\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\nimport com.googlecode.dex2jar.ir.ts.Transformer;\n\n/**\n * run after {@link com.googlecode.dex2jar.ir.ts.ConstTransformer}, to deal with following code\n * \n * <pre>\n * int[] a = null;\n * int b = a[1];\n * </pre>\n * \n * replace {@code int b = a[1];} to {@code throw new NullPointException()}, and we get\n * \n * <pre>\n * int[] a = null;\n * throw new NullPointException();\n * </pre>\n * \n * @author Panxiaobo\n * \n */\npublic class ArrayNullPointerTransformer implements Transformer {\n\n    @Override\n    public void transform(IrMethod irMethod) {\n        for (Stmt p = irMethod.stmts.getFirst(); p != null;) {\n            if (arrayNPE(p)) {\n                Stmt q = p.getNext();\n                replaceNPE(irMethod.stmts, irMethod.locals, p);\n                p = q;\n                continue;\n            }\n            p = p.getNext();\n        }\n    }\n\n    private void replaceNPE(StmtList stmts, List<Local> locals, Stmt p) {\n        List<Value> values = new ArrayList<Value>();\n        switch (p.et) {\n        case E1:\n            tryAdd(((E1Stmt) p).op.trim(), values);\n            break;\n        case E2:\n            E2Stmt e2 = (E2Stmt) p;\n            switch (e2.op1.trim().vt) {\n            case LOCAL:\n                tryAdd(e2.op2.trim(), values);\n                break;\n            case ARRAY:\n                ArrayExpr ae = (ArrayExpr) e2.op1.trim();\n                if (tryAdd(ae.op1.trim(), values)) {\n                    if (tryAdd(ae.op2.trim(), values)) {\n                        tryAdd(e2.op2.trim(), values);\n                    }\n                }\n                break;\n            case FIELD:// putfield\n                FieldExpr fe = (FieldExpr) e2.op1.trim();\n                if (fe.op == null || fe.op.trim() == null || tryAdd(fe.op.trim(), values)) {\n                    tryAdd(e2.op2.trim(), values);\n                }\n                break;\n            default:\n                if (tryAdd(e2.op2.trim(), values)) {\n                    tryAdd(e2.op1.trim(), values);\n                }\n            }\n        default:\n        }\n        for (Value value : values) {\n            switch (value.vt) {\n            case CONSTANT:\n            case LOCAL:\n                break;\n            default:\n                Local n = Exprs.nLocal(\"xxx\");\n                locals.add(n);\n                stmts.insertBefore(p, Stmts.nAssign(n, value));\n            }\n        }\n        stmts.insertBefore(p,\n                Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], \"Ljava/lang/NullPointerException;\")));\n        stmts.remove(p);\n    }\n\n    private boolean tryAdd(Value value, List<Value> values) {\n        if (!arrayNPE(value)) {\n            values.add(value);\n            return true;\n        } else {\n            switch (value.et) {\n            case E0:\n                values.add(value);\n                break;\n            case E1:\n                E1Expr e1 = (E1Expr) value;\n                if (e1.op == null || e1.op.trim() == null) {\n                    return false;\n                }\n                tryAdd(e1.op.trim(), values);\n                break;\n            case E2:\n                E2Expr e2 = (E2Expr) value;\n                if (e2.vt == VT.ARRAY && e2.op1.trim().vt == VT.CONSTANT) {\n                    Constant cst = (Constant) e2.op1.trim();\n                    if (cst.value.equals(Integer.valueOf(0))) {\n                        tryAdd(e2.op2.trim(), values);\n                        return false;\n                    }\n                }\n                if (tryAdd(e2.op1.trim(), values)) {\n                    tryAdd(e2.op2.trim(), values);\n                }\n\n            case En:\n                for (Value vb : ((EnExpr) value).ops) {\n                    if (!tryAdd(vb.trim(), values)) {\n                        break;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    private boolean arrayNPE(Stmt p) {\n        switch (p.et) {\n        case E0:\n            return false;\n        case E1:\n            if (p.st == ST.GOTO) {\n                return false;\n            }\n            return arrayNPE(((E1Stmt) p).op.trim());\n        case E2:\n            E2Stmt e2 = (E2Stmt) p;\n            switch (e2.op1.trim().vt) {\n            case ARRAY:\n            case FIELD:\n                return arrayNPE(e2.op1.trim()) || arrayNPE(e2.op2.trim());\n            default:\n                return arrayNPE(e2.op2.trim()) || arrayNPE(e2.op1.trim());\n            }\n        case En:\n            return false;\n        }\n        return false;\n    }\n\n    private boolean arrayNPE(Value value) {\n        switch (value.et) {\n        case E0:\n            return false;\n        case E1:\n            E1Expr e1 = (E1Expr) value;\n            if (e1.op == null || e1.op.trim() == null) {\n                return false;\n            }\n            return arrayNPE(e1.op.trim());\n        case E2:\n            E2Expr e2 = (E2Expr) value;\n            if (e2.vt == VT.ARRAY && e2.op1.trim().vt == VT.CONSTANT) {\n                Constant cst = (Constant) e2.op1.trim();\n                if (cst.value.equals(Integer.valueOf(0))) {\n                    return true;\n                }\n            }\n            return arrayNPE(e2.op1.trim()) || arrayNPE(e2.op2.trim());\n\n        case En:\n            for (Value vb : ((EnExpr) value).ops) {\n                if (arrayNPE(vb.trim())) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/array/FillArrayTransformer.java",
    "content": "package com.googlecode.dex2jar.ir.ts.array;\r\n\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.expr.*;\r\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\nimport com.googlecode.dex2jar.ir.ts.Cfg;\r\nimport com.googlecode.dex2jar.ir.ts.StatedTransformer;\r\nimport com.googlecode.dex2jar.ir.ts.UniqueQueue;\r\n\r\nimport java.lang.reflect.Array;\r\nimport java.util.*;\r\n\r\n/**\r\n * require SSA, usually run after ConstTransformer 1. array is fixed size. 2. array object init and use once, (exclude\r\n * the element assignment) 3. all elements are init with fixed index before use. 4. the array is not in PhiExpr 5. and\r\n * for array object init at A, use at B; A and B must in same loop/path, so G(A->B), G(A->C->B), G(A->C,A->D,C->B,D->B),\r\n * G(A->C,C->D,D->C,C->B) and G(A->C,C->A,C->B) is ok to transform, but for G(A->C,C->B,B->D,D->C), B is in a loop\r\n * (B->D->C->B), should not transformed.\r\n * <p/>\r\n * transform\r\n * \r\n * <pre>\r\n *     a=new String[3]\r\n *     a[0]=\"123\"\r\n *     a[2]=\"1234\"\r\n *     a[1]=\"12345\"\r\n *     return a\r\n * </pre>\r\n * \r\n * to\r\n * \r\n * <pre>\r\n *     return new String[3] { \"123\", \"12345\", \"1234\" }\r\n * </pre>\r\n * \r\n * 1. This Transformer is useful when cleanup the tool-injected reflection code\r\n * \r\n * <pre>\r\n *     // before transform\r\n *     ...\r\n *     Class a[]=new Class[2]\r\n *     a[0]=String.class\r\n *     a[1]=int.class\r\n *     Method m=x.getMethod(\"methodA\",a)\r\n *     Object b[]=new Object[2]\r\n *     b[0]=\"123\";\r\n *     b[1]=Integer.valueOf(1);\r\n *     m.invoke(c,b)\r\n *     // after transform\r\n *     Method m=x.getMethod(\"methodA\", new Class[2] { String.class ,int.class });\r\n *     m.invoke(b,new Object[]{\"123\",Integer.valueOf(1)})\r\n * </pre>\r\n * \r\n * 2. Suggest decompilers generate better code\r\n * \r\n * <pre>\r\n *     // for following code, before transform, the decompiler generate same source\r\n *     Object[]a=new Object[2];\r\n *     a[0]=b;\r\n *     a[1]=c\r\n *     String.format(\"b is %s, c is %s\",a)\r\n *     // after transform, then decompile generate the following source\r\n *     String.format(\"b is %s, c is %s\",b,c)\r\n * </pre>\r\n * \r\n * FIXME also handle not full filled array\r\n * \r\n * <pre>\r\n * int a[] = new int[5];\r\n * // a[0]=0;\r\n * a[1] = 1;\r\n * a[2] = 3;\r\n * a[3] = 4;\r\n * a[4] = 7;\r\n * </pre>\r\n */\r\npublic class FillArrayTransformer extends StatedTransformer {\r\n    private static class ArrayObject {\r\n        int size;\r\n        String type;\r\n        AssignStmt init;\r\n        List<Stmt> putItem = new ArrayList<>();\r\n        List<Stmt> used = new ArrayList<>();\r\n\r\n        private ArrayObject(int size, String type, AssignStmt init) {\r\n            this.size = size;\r\n            this.type = type;\r\n            this.init = init;\r\n        }\r\n    }\r\n\r\n    public static void main(String... args) {\r\n        IrMethod m = new IrMethod();\r\n        m.isStatic = true;\r\n        m.name = \"a\";\r\n        m.args = new String[0];\r\n        m.ret = \"[Ljava/lang/String;\";\r\n        m.owner = \"La;\";\r\n\r\n        Local array = Exprs.nLocal(1);\r\n        m.locals.add(array);\r\n        m.stmts.add(Stmts.nAssign(array, Exprs.nNewArray(\"Ljava/lang/String;\", Exprs.nInt(2))));\r\n        m.stmts.add(Stmts.nAssign(Exprs.nArray(array, Exprs.nInt(1), \"Ljava/lang/String;\"), Exprs.nString(\"123\")));\r\n        m.stmts.add(Stmts.nAssign(Exprs.nArray(array, Exprs.nInt(0), \"Ljava/lang/String;\"), Exprs.nString(\"456\")));\r\n        m.stmts.add(Stmts.nReturn(array));\r\n        new FillArrayTransformer().transform(m);\r\n        System.out.println(m);\r\n    }\r\n\r\n    @Override\r\n    public boolean transformReportChanged(IrMethod method) {\r\n\r\n        // find array match fixed size,fixed index, not in phi\r\n        final Map<Local, ArrayObject> arraySizes = searchForArrayObject(method);\r\n\r\n        if (arraySizes.size() == 0) {\r\n            return false;\r\n        }\r\n\r\n        makeSureAllElementAreAssigned(arraySizes);\r\n        if (arraySizes.size() == 0) {\r\n            return false;\r\n        }\r\n\r\n        makeSureArrayUsedAfterAllElementAssigned(method, arraySizes);\r\n\r\n        if (arraySizes.size() == 0) {\r\n            return false;\r\n        }\r\n\r\n        replace(method, arraySizes);\r\n\r\n        return true;\r\n    }\r\n\r\n    private void replace(IrMethod method, Map<Local, ArrayObject> arraySizes) {\r\n        final List<FilledArrayExpr> filledArrayExprs = new ArrayList<>();\r\n        for (Map.Entry<Local, ArrayObject> e : arraySizes.entrySet()) {\r\n            final Local local0 = e.getKey();\r\n            final ArrayObject ao = e.getValue();\r\n            final Value t[] = new Value[ao.size];\r\n            for (Iterator<Stmt> it = ao.putItem.iterator(); it.hasNext();) {\r\n                Stmt p = it.next();\r\n                if (p.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                    Local local = (Local) p.getOp1();\r\n                    if (local == local0) {\r\n                        Object vs = ((Constant) p.getOp2()).value;\r\n                        int endPos = Array.getLength(vs);\r\n                        for (int j = 0; j < endPos; j++) {\r\n                            t[j] = Exprs.nConstant(Array.get(vs, j));\r\n                        }\r\n                    }\r\n                } else { // ASSIGN\r\n                    ArrayExpr ae = (ArrayExpr) p.getOp1();\r\n                    Local local = (Local) ae.getOp1();\r\n                    if (local == local0) {\r\n                        int idx = ((Number) ((Constant) ae.getOp2()).value).intValue();\r\n                        Value op2 = p.getOp2();\r\n                        if (op2.vt != Value.VT.LOCAL && op2.vt != Value.VT.CONSTANT) {\r\n                            Local n = new Local(-1);\r\n                            method.locals.add(n);\r\n                            method.stmts.insertBefore(p, Stmts.nAssign(n, op2));\r\n                            op2 = n;\r\n                        }\r\n                        t[idx] = op2;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // for code\r\n            // b=new Object[1]\r\n            // b[0]=null\r\n            // a =new Object[1]\r\n            // a =b;\r\n            // use(a)\r\n            // if a is replace before b, the code\r\n            // b=new Object[1]\r\n            // b[0]=null\r\n            // use(new Object[]{b})\r\n            // the used stmt of b is outdated, so we have to search pre replaced arrays\r\n\r\n            method.locals.remove(local0);\r\n            method.stmts.remove(ao.init);\r\n            for (Stmt p : ao.putItem) {\r\n                method.stmts.remove(p);\r\n            }\r\n            Cfg.TravelCallBack tcb = new Cfg.TravelCallBack() {\r\n                @Override\r\n                public Value onAssign(Local v, AssignStmt as) {\r\n                    return v;\r\n                }\r\n\r\n                @Override\r\n                public Value onUse(Local v) {\r\n                    if (local0 == v) {\r\n                        FilledArrayExpr fae = Exprs.nFilledArray(ao.type, t);\r\n                        filledArrayExprs.add(fae);\r\n                        return fae;\r\n                    }\r\n                    return v;\r\n                }\r\n            };\r\n\r\n            if (ao.used.size() == 1) {\r\n                Stmt stmt = ao.used.get(0);\r\n                if (method.stmts.contains(stmt)) { // the stmt is not removed by pre array replacement\r\n                    Cfg.travelMod(stmt, tcb, false);\r\n                } else {\r\n                    int size = filledArrayExprs.size();\r\n                    for (int i = 0; i < size; i++) {\r\n                        Cfg.travelMod(filledArrayExprs.get(i), tcb);\r\n                    }\r\n                }\r\n            } else if (ao.used.size() == 0) {\r\n                // the array is never used, ignore\r\n            } else {\r\n                throw new RuntimeException(\"array is used multiple times\");\r\n            }\r\n        }\r\n    }\r\n\r\n    // FIXME poor performance\r\n    private void makeSureArrayUsedAfterAllElementAssigned(IrMethod method, final Map<Local, ArrayObject> arraySizes) {\r\n\r\n        for (Local local : method.locals) {\r\n            local._ls_index = -1;\r\n        }\r\n        final int MAX = 50;\r\n        if (arraySizes.size() < MAX) {\r\n            makeSureArrayUsedAfterAllElementAssigned0(method, arraySizes);\r\n        } else {\r\n\r\n            // this method consumes too many memory, case 'java.lang.OutOfMemoryError: Java heap space', we have to cut\r\n            // it\r\n            Map<Local, ArrayObject> keptInAll = new HashMap<>();\r\n            Map<Local, ArrayObject> keptInPart = new HashMap<>();\r\n            List<Local> arrays = new ArrayList<>(MAX);\r\n\r\n            Iterator<Map.Entry<Local, ArrayObject>> it = arraySizes.entrySet().iterator();\r\n            while (it.hasNext()) {\r\n                for (int i = 0; i < MAX && it.hasNext(); i++) {\r\n                    Map.Entry<Local, ArrayObject> e = it.next();\r\n                    keptInPart.put(e.getKey(), e.getValue());\r\n                    it.remove();\r\n                    arrays.add(e.getKey());\r\n                }\r\n                makeSureArrayUsedAfterAllElementAssigned0(method, keptInPart);\r\n                for (Local local : arrays) {\r\n                    local._ls_index = -1;\r\n                }\r\n                arrays.clear();\r\n                keptInAll.putAll(keptInPart);\r\n                keptInPart.clear();\r\n            }\r\n            arraySizes.putAll(keptInAll);\r\n        }\r\n\r\n        Cfg.reIndexLocal(method);\r\n\r\n    }\r\n\r\n    private void makeSureArrayUsedAfterAllElementAssigned0(IrMethod method, final Map<Local, ArrayObject> arraySizes) {\r\n        int i = 0;\r\n        for (Local local : arraySizes.keySet()) {\r\n            local._ls_index = i++;\r\n        }\r\n\r\n        final int size = i;\r\n        final List<ArrayObjectValue> values = new ArrayList<>();\r\n        Cfg.dfs(method.stmts, new Cfg.FrameVisitor<ArrayObjectValue[]>() {\r\n\r\n            @Override\r\n            public ArrayObjectValue[] merge(ArrayObjectValue[] srcFrame, ArrayObjectValue[] distFrame, Stmt src,\r\n                    Stmt dist) {\r\n                if (distFrame == null) {\r\n                    distFrame = new ArrayObjectValue[size];\r\n                    for (int i = 0; i < size; i++) {\r\n                        ArrayObjectValue arc = srcFrame[i];\r\n                        if (arc != null) {\r\n                            ArrayObjectValue aov = new ArrayObjectValue(arc.local);\r\n                            values.add(aov);\r\n                            aov.array = arc.array;\r\n                            aov.parent = arc;\r\n                            aov.pos = (BitSet) arc.pos.clone();\r\n                            distFrame[i] = aov;\r\n                        }\r\n                    }\r\n                } else {\r\n                    for (int i = 0; i < size; i++) {\r\n                        ArrayObjectValue arc = srcFrame[i];\r\n                        ArrayObjectValue aov = distFrame[i];\r\n                        if (arc != null && aov != null) {\r\n                            if (aov.otherParent == null) {\r\n                                aov.otherParent = new HashSet<>();\r\n                            }\r\n                            aov.otherParent.add(arc);\r\n                        }\r\n                    }\r\n                }\r\n                return distFrame;\r\n            }\r\n\r\n            @Override\r\n            public ArrayObjectValue[] initFirstFrame(Stmt first) {\r\n                return new ArrayObjectValue[size];\r\n            }\r\n\r\n            ArrayObjectValue tmp[] = initFirstFrame(null);\r\n            Stmt currentStmt;\r\n\r\n            @Override\r\n            public ArrayObjectValue[] exec(ArrayObjectValue[] frame, Stmt stmt) {\r\n                currentStmt = stmt;\r\n                System.arraycopy(frame, 0, tmp, 0, size);\r\n                if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                    if (stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) stmt.getOp1();\r\n                        if (local._ls_index >= 0) {\r\n                            ArrayObjectValue av = tmp[local._ls_index];\r\n                            Constant cst = (Constant) stmt.getOp2();\r\n                            int endPos = Array.getLength(cst.value);\r\n                            av.pos.set(0, endPos);\r\n                        }\r\n                    } else {\r\n                        use(stmt.getOp1());\r\n                    }\r\n                } else if (stmt.st == Stmt.ST.ASSIGN && stmt.getOp1().vt == Value.VT.ARRAY) {\r\n                    use(stmt.getOp2());\r\n                    ArrayExpr ae = (ArrayExpr) stmt.getOp1();\r\n                    if (ae.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) ae.getOp1();\r\n                        if (local._ls_index >= 0) {\r\n                            int index = ((Number) ((Constant) ae.getOp2()).value).intValue();\r\n                            ArrayObjectValue av = tmp[local._ls_index];\r\n                            av.pos.set(index);\r\n                        } else {\r\n                            use(ae);\r\n                        }\r\n                    } else {\r\n                        use(ae);\r\n                    }\r\n                } else if (stmt.st == Stmt.ST.ASSIGN && stmt.getOp1().vt == Value.VT.LOCAL) {\r\n                    Local local = (Local) stmt.getOp1();\r\n                    use(stmt.getOp2());\r\n\r\n                    if (local._ls_index >= 0) {\r\n                        ArrayObjectValue aov = new ArrayObjectValue(local);\r\n                        aov.array = arraySizes.get(local);\r\n                        aov.pos = new BitSet();\r\n                        values.add(aov);\r\n                        tmp[local._ls_index] = aov;\r\n                    }\r\n                } else {\r\n                    switch (stmt.et) {\r\n                    case E0:\r\n                        break;\r\n                    case E1:\r\n                        use(stmt.getOp());\r\n                        break;\r\n                    case E2:\r\n                        use(stmt.getOp1());\r\n                        use(stmt.getOp2());\r\n                        break;\r\n                    case En:\r\n                        throw new RuntimeException();\r\n                    }\r\n                }\r\n                return tmp;\r\n            }\r\n\r\n            private void use(Value v) {\r\n                switch (v.et) {\r\n                case E0:\r\n                    if (v.vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) v;\r\n                        if (local._ls_index >= 0) {\r\n                            ArrayObjectValue aov = tmp[local._ls_index];\r\n                            aov.array.used.add(currentStmt);\r\n                            aov.used = true;\r\n                        }\r\n                    }\r\n                    break;\r\n                case E1:\r\n                    use(v.getOp());\r\n                    break;\r\n                case E2:\r\n                    use(v.getOp1());\r\n                    use(v.getOp2());\r\n                    break;\r\n                case En:\r\n                    for (Value op : v.getOps()) {\r\n                        use(op);\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n        });\r\n\r\n        Set<ArrayObjectValue> used = markUsed(values);\r\n\r\n        // check if ArrayObjectValue have different parent assignment\r\n        for (ArrayObjectValue avo : used) {\r\n            if (avo.array.used.size() > 1) {\r\n                arraySizes.remove(avo.local);\r\n            } else {\r\n                if (avo.parent != null && avo.otherParent != null) {\r\n                    // BitSet bs = avo.pos;\r\n                    BitSet p = avo.parent.pos;\r\n                    for (ArrayObjectValue ps : avo.otherParent) {\r\n                        if (!p.equals(ps.pos)) {\r\n                            arraySizes.remove(avo.local);\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        // check for un full init array\r\n        for (Iterator<Map.Entry<Local, ArrayObject>> it = arraySizes.entrySet().iterator(); it.hasNext();) {\r\n            Map.Entry<Local, ArrayObject> e = it.next();\r\n            Local local = e.getKey();\r\n            ArrayObject arrayObject = e.getValue();\r\n            for (Stmt use : arrayObject.used) {\r\n                ArrayObjectValue frame[] = (ArrayObjectValue[]) use.frame;\r\n                ArrayObjectValue aov = frame[local._ls_index];\r\n                BitSet pos = aov.pos;\r\n                if (pos.nextClearBit(0) < arrayObject.size || pos.nextSetBit(arrayObject.size) >= 0) {\r\n                    it.remove();\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        // clean up\r\n        for (Stmt stmt : method.stmts) {\r\n            stmt.frame = null;\r\n        }\r\n    }\r\n\r\n    protected Set<ArrayObjectValue> markUsed(Collection<ArrayObjectValue> values) {\r\n        Set<ArrayObjectValue> used = new HashSet<>(values.size() / 2);\r\n        Queue<ArrayObjectValue> q = new UniqueQueue<>();\r\n        q.addAll(values);\r\n        values.clear();\r\n        while (!q.isEmpty()) {\r\n            ArrayObjectValue v = q.poll();\r\n            if (v.used) {\r\n                if (used.contains(v)) {\r\n                    continue;\r\n                }\r\n                used.add(v);\r\n                {\r\n                    ArrayObjectValue p = v.parent;\r\n                    if (p != null) {\r\n                        if (!p.used) {\r\n                            p.used = true;\r\n                            q.add(p);\r\n                        }\r\n                    }\r\n                }\r\n                if (v.otherParent != null) {\r\n                    for (ArrayObjectValue p : v.otherParent) {\r\n                        if (!p.used) {\r\n                            p.used = true;\r\n                            q.add(p);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return used;\r\n    }\r\n\r\n    private void makeSureAllElementAreAssigned(Map<Local, ArrayObject> arraySizes) {\r\n        BitSet pos = new BitSet();\r\n        for (Iterator<Map.Entry<Local, ArrayObject>> it = arraySizes.entrySet().iterator(); it.hasNext();) {\r\n            Map.Entry<Local, ArrayObject> e = it.next();\r\n            ArrayObject arrayObject = e.getValue();\r\n            boolean needRemove = false;\r\n            for (Stmt p : arrayObject.putItem) {\r\n                if (p.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                    int endPos = Array.getLength(((Constant) p.getOp2()).value);\r\n                    int next = pos.nextSetBit(0);\r\n                    if (next < 0 || next >= endPos) {// not set in range\r\n                        pos.set(0, endPos);\r\n                    } else {// setted in range\r\n                        needRemove = true;\r\n                        break;\r\n                    }\r\n                } else { // ASSIGN\r\n                    ArrayExpr ae = (ArrayExpr) p.getOp1();\r\n                    int idx = ((Number) ((Constant) ae.getOp2()).value).intValue();\r\n                    if (!pos.get(idx)) {\r\n                        pos.set(idx);\r\n                    } else {\r\n                        needRemove = true;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n            if (needRemove || pos.nextClearBit(0) < arrayObject.size || pos.nextSetBit(arrayObject.size) >= 0) {\r\n                it.remove();\r\n            }\r\n            pos.clear();\r\n        }\r\n    }\r\n\r\n    private Map<Local, ArrayObject> searchForArrayObject(IrMethod method) {\r\n\r\n        final Map<Local, ArrayObject> arraySizes = new HashMap<>();\r\n        if (method.locals.size() == 0) {\r\n            return arraySizes;\r\n        }\r\n        Cfg.createCFG(method);\r\n        Cfg.dfsVisit(method, new Cfg.DfsVisitor() {\r\n            @Override\r\n            public void onVisit(Stmt p) {\r\n                if (p.st == Stmt.ST.ASSIGN) {\r\n                    if (p.getOp2().vt == Value.VT.NEW_ARRAY && p.getOp1().vt == Value.VT.LOCAL) {\r\n                        TypeExpr ae = (TypeExpr) p.getOp2();\r\n                        if (ae.getOp().vt == Value.VT.CONSTANT) {\r\n                            int size = ((Number) ((Constant) ae.getOp()).value).intValue();\r\n\r\n                            // https://bitbucket.org/pxb1988/dex2jar/issues/2/decompiler-error\r\n                            // the following code may used in a java\r\n                            // try{\r\n                            //   new int[-1];\r\n                            // } catch(Exception e) {\r\n                            //   ...\r\n                            // }\r\n                            if (size >= 0) {\r\n                                arraySizes.put((Local) p.getOp1(), new ArrayObject(size, ae.type, (AssignStmt) p));\r\n                            }\r\n                        }\r\n                    } else if (p.getOp1().vt == Value.VT.ARRAY) {\r\n                        ArrayExpr ae = (ArrayExpr) p.getOp1();\r\n                        if (ae.getOp1().vt == Value.VT.LOCAL) {\r\n                            Local local = (Local) ae.getOp1();\r\n                            ArrayObject arrayObject = arraySizes.get(local);\r\n                            if (arrayObject != null) {\r\n                                if (ae.getOp2().vt == Value.VT.CONSTANT) {\r\n                                    arrayObject.putItem.add(p);\r\n                                } else {\r\n                                    arraySizes.remove(local);\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                } else if (p.st == Stmt.ST.FILL_ARRAY_DATA) {\r\n                    if (p.getOp1().vt == Value.VT.LOCAL) {\r\n                        Local local = (Local) p.getOp1();\r\n                        ArrayObject arrayObject = arraySizes.get(local);\r\n                        if (arrayObject != null) {\r\n                            arrayObject.putItem.add(p);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n        if (arraySizes.size() > 0) {\r\n            Set<Local> set = new HashSet<Local>();\r\n            if (method.phiLabels != null) {\r\n                for (LabelStmt labelStmt : method.phiLabels) {\r\n                    if (labelStmt.phis != null) {\r\n                        for (AssignStmt as : labelStmt.phis) {\r\n                            set.add((Local) as.getOp1());\r\n                            for (Value v : as.getOp2().getOps()) {\r\n                                set.add((Local) v);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            if (set.size() > 0) {\r\n                for (Local local : set) {\r\n                    arraySizes.remove(local);\r\n                }\r\n            }\r\n        }\r\n        return arraySizes;\r\n    }\r\n\r\n    static class ArrayObjectValue {\r\n        BitSet pos;\r\n        Local local;\r\n        ArrayObject array;\r\n        ArrayObjectValue parent;\r\n        Set<ArrayObjectValue> otherParent;\r\n        boolean used;\r\n\r\n        public ArrayObjectValue(Local local) {\r\n            this.local = local;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/AggTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.ts.AggTransformer;\nimport com.googlecode.dex2jar.ir.ts.SSATransformer;\n\npublic class AggTransformerTest extends BaseTransformerTest<AggTransformer> {\n    @Test\n    public void t001() {\n        Local a = addLocal(\"a\");\n        addStmt(nAssign(a, nNewIntArray(nInt(5))));\n        addStmt(nReturn(a));\n        transform();\n        Assert.assertEquals(\"only `return new int[5]` should left.\", 1, stmts.getSize());\n        Assert.assertEquals(\"no local should left\", 0, locals.size());\n    }\n\n    @Test\n    public void t002() {\n\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n\n        addStmt(nAssign(a, nNewIntArray(nInt(5))));\n        addStmt(nAssign(b, nInt(2)));\n        addStmt(nAssign(c, nArray(a, b, \"I\")));\n        addStmt(nReturn(c));\n        transform();\n        Assert.assertTrue(stmts.getSize() == 1);\n        Assert.assertTrue(locals.size() == 0);\n    }\n\n    @Test\n    public void test04() {\n\n        Local array = addLocal(\"array\");\n        Local index = addLocal(\"index\");\n        Local value = addLocal(\"value\");\n\n        addStmt(nAssign(array, nNewIntArray(nInt(5))));\n        addStmt(nAssign(index, niAdd(nInt(1999), nInt(3))));\n        addStmt(nAssign(value, niAdd(index, nInt(4))));\n        addStmt(nAssign(nArray(array, index, \"I\"), value));\n        addStmt(nReturnVoid());\n\n        transform();\n\n        Assert.assertTrue(method.locals.size() >= 2);\n    }\n\n    @Test\n    public void test05() {\n        String sbType = \"Ljava/lang/StringBuilder;\";\n        String sType = \"Ljava/lang/String;\";\n\n        Local b = addLocal(\"b\");\n        Local ex = addLocal(\"ex\");\n        Local c = addLocal(\"c\");\n        Local d = addLocal(\"d\");\n        Local e = addLocal(\"e\");\n        Local cst = addLocal(\"cst\");\n\n        addStmt(nAssign(b, nString(\"123\")));\n        addStmt(nAssign(c, Exprs.nInvokeNew(new Value[0], new String[0], sbType)));\n        addStmt(nAssign(d, c));\n        addStmt(nAssign(cst, nString(\"p1\")));\n        addStmt(nAssign(c,\n                Exprs.nInvokeVirtual(new Value[] { d, cst }, sbType, \"append\", new String[] { sType }, sbType)));\n        addStmt(nAssign(e, c));\n        addStmt(nAssign(cst, nString(\"p2\")));\n        addStmt(nAssign(c,\n                Exprs.nInvokeVirtual(new Value[] { e, cst }, sbType, \"append\", new String[] { sType }, sbType)));\n        addStmt(nAssign(c, Exprs.nInvokeVirtual(new Value[] { c }, sbType, \"toString\", new String[0], sType)));\n\n        addStmt(nReturn(c));\n        new SSATransformer().transform(method);\n        transform();\n        Assert.assertTrue(stmts.getSize() == 1);\n        Assert.assertTrue(locals.size() == 0);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/BaseTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.dex2jar.ir.stmt.*;\nimport org.junit.After;\nimport org.junit.Before;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.ts.Transformer;\n\npublic abstract class BaseTransformerTest<T extends Transformer> {\n\n    protected void transform() {\n        transformer.transform(this.method);\n    }\n\n    @Override\n    public String toString() {\n        return method.toString();\n    }\n\n    int labelIndex = 0;\n\n    protected LabelStmt newLabel() {\n        LabelStmt label = Stmts.nLabel();\n        label.displayName = \"L\" + labelIndex++;\n        return label;\n    }\n\n    public BaseTransformerTest() {\n        super();\n        Class<?> clz = getClass();\n        ParameterizedType t = (ParameterizedType) clz.getGenericSuperclass();\n        Class<?> transformerType = (Class<?>) t.getActualTypeArguments()[0];\n\n        try {\n            this.transformer = (Transformer) transformerType.newInstance();\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    final protected Transformer transformer;\n    protected IrMethod method = new IrMethod();\n    protected StmtList stmts;\n    protected List<Local> locals;\n\n\n    public Local addLocal(String name) {\n        Local local = Exprs.nLocal(name);\n        method.locals.add(local);\n        return local;\n    }\n\n    public <D extends Stmt> D addStmt(D stmt) {\n        method.stmts.add(stmt);\n        return stmt;\n    }\n\n    public AssignStmt attachPhi(LabelStmt labelStmt, AssignStmt phi) {\n        List<AssignStmt> s = labelStmt.phis;\n        if (s == null) {\n            labelStmt.phis = s = new ArrayList<>();\n        }\n        s.add(phi);\n        if (method.phiLabels == null) {\n            method.phiLabels = new ArrayList<>();\n        }\n        if (!method.phiLabels.contains(labelStmt)) {\n            method.phiLabels.add(labelStmt);\n        }\n        return phi;\n    }\n    \n    public void initMethod(boolean isStatic, String ret, String... args) {\n        method.ret = ret;\n        method.args = args;\n        method.isStatic = isStatic;\n    }\n\n    @After\n    public void reset() {\n        method = null;\n        stmts = null;\n        locals = null;\n        labelIndex = 0;\n    }\n\n    @Before\n    public void setup() {\n        method = new IrMethod();\n        method.owner = \"La/Clz;\";\n        method.name = \"call\";\n        method.ret = \"V\";\n        method.isStatic = true;\n        method.args = new String[0];\n        stmts = method.stmts;\n        locals = method.locals;\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/ConstTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nLocal;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nString;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Constant;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\nimport com.googlecode.dex2jar.ir.stmt.UnopStmt;\nimport com.googlecode.dex2jar.ir.ts.ConstTransformer;\n\npublic class ConstTransformerTest {\n\n    @Test\n    public void test00() {\n        IrMethod jm = new IrMethod();\n\n        Local a = nLocal(\"a\");\n        jm.locals.add(a);\n        jm.stmts.add(nAssign(a, nString(\"a String\")));\n        UnopStmt retStmt = nReturn(a);\n        jm.stmts.add(retStmt);\n        new ConstTransformer().transform(jm);\n\n        Assert.assertTrue(jm.locals.size() == 1);\n        Assert.assertTrue(jm.stmts.getSize() == 2);\n        Assert.assertEquals(\"a String\", ((Constant) retStmt.op.trim()).value);\n    }\n\n    @Test\n    public void test01() {// local in phi\n        IrMethod jm = new IrMethod();\n\n        Local a = nLocal(\"a\");\n        Local p = nLocal(\"p\");\n        jm.locals.add(a);\n        jm.locals.add(p);\n        jm.stmts.add(nAssign(a, nString(\"a String\")));\n        jm.stmts.add(nAssign(p, Exprs.nPhi(a)));\n        UnopStmt retStmt = nReturn(p);\n        jm.stmts.add(retStmt);\n        new ConstTransformer().transform(jm);\n\n        Assert.assertTrue(jm.locals.size() == 2);\n        Assert.assertTrue(jm.stmts.getSize() == 3);\n        Assert.assertEquals(\"a String\", ((Constant) retStmt.op.trim()).value);\n    }\n\n    @Test\n    public void test02() {// test local loop\n        IrMethod jm = new IrMethod();\n\n        Local a = nLocal(\"a\");\n        Local p = nLocal(\"p\");\n        Local q = nLocal(\"q\");\n        jm.locals.add(a);\n        jm.locals.add(p);\n        jm.locals.add(q);\n        jm.stmts.add(nAssign(a, nString(\"a String\")));\n        jm.stmts.add(nAssign(p, Exprs.nPhi(a, q)));\n        jm.stmts.add(nAssign(q, Exprs.nPhi(p)));\n        UnopStmt retStmt = nReturn(q);\n        jm.stmts.add(retStmt);\n        new ConstTransformer().transform(jm);\n\n        Assert.assertTrue(jm.locals.size() == 3);\n        Assert.assertTrue(jm.stmts.getSize() == 4);\n        Assert.assertEquals(\"a String\", ((Constant) retStmt.op.trim()).value);\n    }\n\n    @Test\n    public void test03() {// test local loop\n        IrMethod jm = new IrMethod();\n\n        Local a = nLocal(\"a\");\n        Local b = nLocal(\"b\");\n        Local p = nLocal(\"p\");\n        jm.locals.add(a);\n        jm.locals.add(b);\n        jm.locals.add(p);\n        jm.stmts.add(nAssign(a, nString(\"a String\")));\n        jm.stmts.add(nAssign(b, nString(\"b String\")));\n        jm.stmts.add(nAssign(p, Exprs.nPhi(a, b)));\n        UnopStmt retStmt = nReturn(p);\n        jm.stmts.add(retStmt);\n        new ConstTransformer().transform(jm);\n\n        Assert.assertTrue(jm.locals.size() == 3);\n        Assert.assertTrue(jm.stmts.getSize() == 4);\n        Assert.assertEquals(p, retStmt.op.trim());\n    }\n\n    @Test\n    public void test04() {\n        IrMethod jm = new IrMethod();\n\n        Local a = nLocal(\"a\");\n        Local b = nLocal(\"b\");\n        Local p = nLocal(\"p\");\n        jm.locals.add(a);\n        jm.locals.add(b);\n        jm.locals.add(p);\n        jm.stmts.add(nAssign(a, nString(new String(\"a String\"))));\n        jm.stmts.add(nAssign(b, nString(new String(\"a String\"))));\n        jm.stmts.add(nAssign(p, Exprs.nPhi(a, b)));\n        UnopStmt retStmt = nReturn(p);\n        jm.stmts.add(retStmt);\n        new ConstTransformer().transform(jm);\n\n        Assert.assertTrue(jm.locals.size() == 3);\n        Assert.assertTrue(jm.stmts.getSize() == 4);\n        Assert.assertEquals(VT.CONSTANT, retStmt.op.vt);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/ConstantStringTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\n\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class ConstantStringTest {\n    @Test\n    public void test() {\n        String s = Exprs.nString(\"a\\nb\").toString();\n        Assert.assertEquals(\"\\\"a\\\\nb\\\"\", s);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/DeadCodeTrnasformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\nimport com.googlecode.dex2jar.ir.ts.DeadCodeTransformer;\nimport org.junit.Assert;\nimport org.junit.Test;\n\npublic class DeadCodeTrnasformerTest extends BaseTransformerTest<DeadCodeTransformer> {\n    @Test\n    public void test09DeadCode() {\n        Stmt ret = addStmt(Stmts.nReturnVoid());\n        Stmt lb = addStmt(newLabel());\n        addStmt(Stmts.nReturnVoid());\n        transform();\n        Assert.assertSame(ret, method.stmts.getFirst());\n        Assert.assertSame(ret, method.stmts.getLast());\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/JimpleTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nAdd;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInt;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\nimport com.googlecode.dex2jar.ir.ts.JimpleTransformer;\n\npublic class JimpleTransformerTest extends BaseTransformerTest<JimpleTransformer> {\n\n    /**\n     * test for return 1+2+3;\n     */\n    @Test\n    public void test00Base() {\n        initMethod(true, \"I\");\n        addStmt(nReturn(nAdd(nAdd(nInt(1), nInt(2), \"I\"), nInt(3), \"I\")));\n        transform();\n\n        Assert.assertEquals(\"should expends to 3 stmts\", 3, method.stmts.getSize());\n        Assert.assertEquals(\"should expends to 2 locals\", 2, method.locals.size());\n\n        // System.out.println(super.method);\n    }\n\n    /**\n     * test for System.out.print(\"Hello JNI\");\n     */\n    @Test\n    public void test01HelloWord() {\n        initMethod(true, \"V\");\n        addStmt(Stmts.nVoidInvoke(Exprs.nInvokeVirtual(\n                new Value[] {//\n                Exprs.nStaticField(\"Ljava/lang/System;\", \"out\", \"Ljava/io/PrintStream;\"),//\n                        Exprs.nString(\"Hello JNI\") }, \"Ljava/io/PrintStream;\", \"println\",\n                new String[] { \"Ljava/lang/String;\" }, \"V\")));\n        transform();\n        Assert.assertEquals(\"should expends to 3 stmts\", 3, method.stmts.getSize());\n        Assert.assertEquals(\"should expends to 2 locals\", 2, method.locals.size());\n\n        // System.out.println(super.method);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/RemoveConstantFromSSATest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\nimport com.googlecode.dex2jar.ir.ts.AggTransformer;\nimport com.googlecode.dex2jar.ir.ts.RemoveConstantFromSSA;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\n\npublic class RemoveConstantFromSSATest extends BaseTransformerTest<RemoveConstantFromSSA> {\n    @Test\n    public void t001() {\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local c1 = addLocal(\"c1\");\n        Local c2 = addLocal(\"c2\");\n        Local cphi = addLocal(\"cphi\");\n        LabelStmt L1 = newLabel();\n        LabelStmt L2 = newLabel();\n\n        Stmt sa = addStmt(nAssign(a, nInt(5)));\n        Stmt sb = addStmt(nAssign(b, nInt(6)));\n        addStmt(nIf(niGt(a, b), L1));\n        addStmt(nAssign(c1, a));\n        addStmt(nGoto(L2));\n        addStmt(L1);\n        addStmt(nAssign(c2, b));\n        addStmt(L2);\n        attachPhi(L2, nAssign(cphi, Exprs.nPhi(c1, c2)));\n        addStmt(nReturn(cphi));\n\n        transform();\n        Assert.assertFalse(\"SA should remove from method\", method.stmts.contains(sa));\n        Assert.assertFalse(\"SB should remove from method\", method.stmts.contains(sb));\n    }\n\n    @Test\n    public void t002() {\n        Local a = addLocal(\"a\");\n        addStmt(nAssign(a, nInt(5)));\n        addStmt(nReturn(a));\n\n        transform();\n        Assert.assertTrue(\"no local should kept\", locals.size() == 0);\n    }\n\n    @Test\n    public void t003() {\n\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n\n        addStmt(nAssign(a, nNewIntArray(nInt(5))));\n        addStmt(nAssign(b, nInt(2)));\n        addStmt(nAssign(c, nArray(a, b, \"I\")));\n        addStmt(nReturn(c));\n        transform();\n        Assert.assertTrue(\"local b should removed\", !locals.contains(b));\n        Assert.assertTrue(locals.size() == 2);\n    }\n\n    @Test\n    public void t004() {\n\n        Local a0 = addLocal(\"a0\");\n        Local a1 = addLocal(\"a1\");\n        Local ax = addLocal(\"aX\");\n\n        LabelStmt L1 = newLabel();\n        LabelStmt L2 = newLabel();\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        addStmt(nAssign(a0, nString(\"123\")));\n        addStmt(nGoto(L2));\n        addStmt(L1);\n        addStmt(nAssign(a1, nNull()));\n        addStmt(L2);\n        attachPhi(L2, nAssign(ax, Exprs.nPhi(a0, a1)));\n        addStmt(nReturn(ax));\n\n        transform();\n        Assert.assertEquals(\"all local should kept\", 3, locals.size());\n    }\n\n    @Test\n    public void t005PhiValueEqual() {\n\n        Local a0 = addLocal(\"a0\");\n        Local a1 = addLocal(\"a1\");\n        Local ax = addLocal(\"aX\");\n\n        LabelStmt L1 = newLabel();\n        LabelStmt L2 = newLabel();\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        addStmt(nAssign(a0, nString(\"123\")));\n        addStmt(nGoto(L2));\n        addStmt(L1);\n        addStmt(nAssign(a1, nString(\"123\")));\n        addStmt(L2);\n        attachPhi(L2, nAssign(ax, Exprs.nPhi(a0, a1)));\n        Stmt ret = addStmt(nReturn(ax));\n\n        transform();\n        Assert.assertTrue(\"should return '123'\", ret.getOp().vt == Value.VT.CONSTANT);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/RemoveLocalFromSSATest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.ts.RemoveLocalFromSSA;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInt;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;\n\npublic class RemoveLocalFromSSATest extends BaseTransformerTest<RemoveLocalFromSSA> {\n    @Test\n    public void t001() {\n\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n\n        Stmt sa = addStmt(nAssign(a, nInt(0)));\n        addStmt(nAssign(b, a));\n        addStmt(nAssign(c, b));\n        Stmt sb = addStmt(nReturn(c));\n        transform();\n        Assert.assertEquals(sa.getOp1(), sb.getOp());\n        Assert.assertEquals(\"1 local should left\", 1, locals.size());\n    }\n\n\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/SSATransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\r\n\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\r\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\r\n\r\nimport org.junit.Assert;\r\nimport org.junit.Test;\r\n\r\nimport com.googlecode.dex2jar.ir.Trap;\r\nimport com.googlecode.dex2jar.ir.expr.Exprs;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.*;\r\nimport com.googlecode.dex2jar.ir.ts.RemoveLocalFromSSA;\r\nimport com.googlecode.dex2jar.ir.ts.SSATransformer;\r\n\r\npublic class SSATransformerTest extends BaseTransformerTest<SSATransformer> {\r\n\r\n    /**\r\n     * base test\r\n     */\r\n    @Test\r\n    public void test00Base() {\r\n\r\n        Local b = addLocal(\"b\");\r\n\r\n        AssignStmt st1 = addStmt(nAssign(b, nString(\"123\")));\r\n        AssignStmt st2 = addStmt(nAssign(b, nNull()));\r\n        UnopStmt st3 = addStmt(nReturn(b));\r\n\r\n        transform();\r\n\r\n        Assert.assertSame(st2.op1, st3.op);\r\n        Assert.assertNotSame(\"st1 and st1 must be cut\", st1.op1, st2.op1);\r\n        Assert.assertTrue(method.locals.size() == 2);\r\n    }\r\n\r\n    /**\r\n     * Test for huge local and stmt size\r\n     */\r\n    @Test\r\n    public void test01HugeLocalStmt() {\r\n        for (int i = 0; i < 2000; i++) {\r\n            Local b = addLocal(\"a\");\r\n            addStmt(nAssign(b, nString(\"123\")));\r\n        }\r\n        Local b = addLocal(\"a\");\r\n        for (int i = 0; i < 20000; i++) {\r\n            addStmt(nAssign(b, nString(\"123\")));\r\n        }\r\n        addStmt(nReturn(b));\r\n        transform();\r\n    }\r\n\r\n    /**\r\n     * test for Phi insert\r\n     */\r\n    @Test\r\n    public void test05PhiInGoto() {\r\n\r\n        Local b = addLocal(\"a\");\r\n\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\r\n        addStmt(nAssign(b, nString(\"123\")));\r\n        addStmt(nGoto(L2));\r\n        addStmt(L1);\r\n        addStmt(nAssign(b, nNull()));\r\n        addStmt(L2);\r\n        addStmt(nReturn(b));\r\n\r\n        transform();\r\n        Assert.assertEquals(3, method.locals.size());// phi inserted\r\n        assertPhiStmt(L2);\r\n    }\r\n\r\n    @Test\r\n    public void test06PhiInTrap() {\r\n        String exType = \"Ljava/lang/Exception;\";\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        LabelStmt L3 = newLabel();\r\n        LabelStmt L4 = newLabel();\r\n        method.traps.add(new Trap(L1, L2, new LabelStmt[] { L3 }, new String[] { exType }));\r\n\r\n        Local b = addLocal(\"a\");\r\n        Local ex = addLocal(\"ex\");\r\n\r\n        addStmt(L1);\r\n        addStmt(nAssign(b, nString(\"123\")));\r\n        addStmt(Stmts.nLock(b));\r\n        addStmt(L2);\r\n        addStmt(nGoto(L4));\r\n        addStmt(L3);\r\n        addStmt(nIdentity(ex, nExceptionRef(exType)));\r\n        addStmt(nAssign(b, nNull()));\r\n        addStmt(L4);\r\n        addStmt(nReturn(b));\r\n\r\n        transform();\r\n        Assert.assertEquals(4, method.locals.size());// phi inserted\r\n        assertPhiStmt(L4);\r\n    }\r\n\r\n    public void transform(){\r\n        super.transform();\r\n        new RemoveLocalFromSSA().transform(method);\r\n    }\r\n\r\n    @Test\r\n    public void test07MergeAtFirst() {\r\n\r\n        LabelStmt L0 = newLabel();\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        LabelStmt L3 = newLabel();\r\n\r\n        Local b = addLocal(\"b\");\r\n        Local c = addLocal(\"c\");\r\n\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(1), nInt(2)), L0));\r\n        addStmt(nAssign(b, nInt(3)));\r\n        addStmt(nGoto(L1));\r\n        addStmt(L0);\r\n        addStmt(nAssign(b, nInt(4)));\r\n        addStmt(L1);\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(1), nInt(2)), L2));\r\n        addStmt(Stmts.nReturnVoid());\r\n        addStmt(L2);\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(1), nInt(2)), L3));\r\n        addStmt(Stmts.nAssign(c,\r\n                Exprs.nInvokeStatic(new Value[] { b }, \"Ljava/lang/String;\", \"someMethod\", new String[] { \"I\" }, \"V\")));\r\n        addStmt(Stmts.nReturnVoid());\r\n        addStmt(L3);\r\n\r\n        addStmt(Stmts.nReturnVoid());\r\n\r\n        transform();\r\n\r\n        Assert.assertEquals(4, method.locals.size());\r\n        assertPhiStmt(L1);\r\n\r\n    }\r\n\r\n    @Test\r\n    public void test03NotInsertPhiInLoop() {\r\n\r\n        Local b = addLocal(\"a\");\r\n\r\n        addStmt(nAssign(b, nString(\"123\")));\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        addStmt(L1);\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L2));\r\n        addStmt(Stmts.nNop());\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L1));\r\n        addStmt(L2);\r\n        addStmt(nReturn(b));\r\n\r\n        transform();\r\n        Assert.assertEquals(1, method.locals.size());\r\n    }\r\n\r\n    @Test\r\n    public void test04NotInsertPhiLoop2() {\r\n\r\n        Local b = addLocal(\"a\");\r\n\r\n        addStmt(nAssign(b, nString(\"123\")));\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        addStmt(L1);\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L2));\r\n        addStmt(Stmts.nNop());\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L1));\r\n        addStmt(Stmts.nNop());\r\n        addStmt(L2);\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L1));\r\n        addStmt(Stmts.nNop());\r\n\r\n        addStmt(nReturn(b));\r\n\r\n        transform();\r\n        Assert.assertTrue(\"no phi should add\", method.locals.size() == 1);\r\n    }\r\n\r\n    @Test\r\n    public void test02NotInsertPhi() {\r\n\r\n        Local b = addLocal(\"a\");\r\n        addStmt(nAssign(b, nString(\"123\")));\r\n        LabelStmt L1 = newLabel();\r\n        addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L1));\r\n        addStmt(Stmts.nNop());\r\n        addStmt(L1);\r\n        addStmt(nReturn(b));\r\n\r\n        transform();\r\n        Assert.assertEquals(1, method.locals.size());\r\n    }\r\n\r\n    /**\r\n     * test for\r\n     * \r\n     * <pre>\r\n     * if (xxx) {\r\n     *     a = 1;\r\n     * } else {\r\n     *     a = 2;\r\n     * }// phi here\r\n     * \r\n     * if (xxx) {\r\n     *     if (xxx) {\r\n     *         a = 3;\r\n     *     }// phi here\r\n     *     return a;\r\n     * } else {\r\n     *     if (xxx) {\r\n     *         a = 4;\r\n     *     } // phi here\r\n     *     return a;\r\n     * }\r\n     * </pre>\r\n     */\r\n    @Test\r\n    public void test08() {\r\n\r\n        Local a = addLocal(\"a\");\r\n        LabelStmt L0 = newLabel();\r\n        LabelStmt L1 = newLabel();\r\n        LabelStmt L2 = newLabel();\r\n        LabelStmt L3 = newLabel();\r\n        LabelStmt L4 = newLabel();\r\n        LabelStmt L5 = newLabel();\r\n        {// if-else\r\n            addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L0));\r\n            {\r\n                addStmt(nAssign(a, nString(\"1\")));\r\n            }\r\n            addStmt(Stmts.nGoto(L1));\r\n            addStmt(L0);\r\n            {\r\n                addStmt(nAssign(a, nString(\"2\")));\r\n            }\r\n            addStmt(L1);// expect a phi here\r\n        }\r\n\r\n        {// if-else\r\n            addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L2));\r\n            {\r\n                { // if\r\n                    addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L4));\r\n                    addStmt(nAssign(a, nString(\"3\")));\r\n                    addStmt(L4);\r\n                }\r\n                addStmt(nReturn(a));\r\n            }\r\n            addStmt(Stmts.nGoto(L3));\r\n            addStmt(L2);\r\n            {\r\n                { // if\r\n                    addStmt(Stmts.nIf(Exprs.niEq(nInt(0), nInt(9)), L5));\r\n                    addStmt(nAssign(a, nString(\"4\")));\r\n                    addStmt(L5);\r\n                }\r\n                addStmt(nReturn(a));\r\n            }\r\n            addStmt(L3);\r\n        }\r\n        transform();\r\n\r\n        assertPhiStmt(L1);\r\n        assertPhiStmt(L4);\r\n        assertPhiStmt(L5);\r\n        Assert.assertEquals(7, method.locals.size());// 4 assign + 3 phi\r\n    }\r\n\r\n    private void assertPhiStmt(LabelStmt label) {\r\n        Assert.assertNotNull(label.phis);\r\n        Assert.assertTrue(label.phis.size() > 0);\r\n    }\r\n\r\n    /**\r\n     * for\r\n     * \r\n     * <pre>\r\n     *     a=12;\r\n     *     b=34;\r\n     *     c=a;\r\n     *     if c1=0 goto L1:\r\n     *     c=b;\r\n     *     L1:\r\n     *     return c;\r\n     * \r\n     * </pre>\r\n     * \r\n     */\r\n    @Test\r\n    public void test11NotDeleteAssignWherePhiIsConfused() {\r\n        Local a = addLocal(\"a\");\r\n        Local b = addLocal(\"b\");\r\n        Local c = addLocal(\"c\");\r\n        LabelStmt L1 = nLabel();\r\n        addStmt(nAssign(a, nString(\"12\")));\r\n        addStmt(nAssign(b, nString(\"34\")));\r\n        addStmt(nAssign(c, a));\r\n        Stmt jmp = addStmt(nIf(njGt(c, nInt(0)), L1));\r\n        addStmt(nAssign(c, b));\r\n        addStmt(L1);\r\n        addStmt(Stmts.nReturn(c));\r\n        transform();\r\n\r\n        Assert.assertNotSame(\"the c=b should not deleted\", jmp.getNext(), L1);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/StmtListTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nCast;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nGt;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInt;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nLocal;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nParameterRef;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nThisRef;\n\nimport org.junit.Test;\n\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\n\npublic class StmtListTest {\n    @Test\n    public void toStringTest() {\n\n        StmtList list = new StmtList();\n        Local a = nLocal(\"this\");\n        Local b = nLocal(\"b\");\n        Local c = nLocal(\"c\");\n        Local d = nLocal(\"d\");\n        LabelStmt L1 = Stmts.nLabel();\n\n        list.add(Stmts.nIdentity(a, nThisRef(\"La/Some;\")));\n        list.add(Stmts.nIdentity(b, nParameterRef(\"I\", 0)));\n        list.add(Stmts.nIdentity(c, nParameterRef(\"J\", 1)));\n        list.add(Stmts.nIdentity(d, nParameterRef(\"F\", 2)));\n        list.add(Stmts.nIf(nGt(b, nInt(0), \"I\"), L1));\n        list.add(Stmts.nAssign(c, nCast(d, \"F\", \"J\")));\n        list.add(L1);\n        list.toString();\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/TypeTransformerTest.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.ir.test;\n\nimport com.googlecode.dex2jar.ir.TypeClass;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.AssignStmt;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.UnopStmt;\nimport com.googlecode.dex2jar.ir.ts.TypeTransformer;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\n\npublic class TypeTransformerTest extends BaseTransformerTest<TypeTransformer> {\n    /**\n     * base test\n     */\n    @Test\n    public void test00Base() {\n        initMethod(true, \"Ljava/lang/Object;\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nString(\"123\")));\n        addStmt(nReturn(b));\n\n        transform();\n        Assert.assertEquals(\"\", \"L\", b.valueType.substring(0, 1));\n    }\n\n    @Test\n    public void test1Const() {\n        initMethod(true, \"F\");\n        Local b = addLocal(\"b\");\n\n        AssignStmt st1 = addStmt(nAssign(b, nInt(0)));\n        UnopStmt st3 = addStmt(nReturn(b));\n        transform();\n        Assert.assertEquals(\"\", b.valueType, \"F\");\n    }\n\n    @Test\n    public void test2byte() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nStaticField(\"La;\", \"z\", \"B\")));\n        addStmt(nVoidInvoke(nInvokeStatic(new Value[] { b }, \"La;\", \"y\", new String[] { \"I\" }, \"V\")));\n        addStmt(nAssign(nStaticField(\"La;\", \"z\", \"B\"), b));\n        addStmt(nReturnVoid());\n        transform();\n        // FIXME fix type detect\n        // Assert.assertEquals(\"\", \"I\", b.valueType);\n    }\n\n    @Test\n    public void test2char() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nInt(255)));\n        addStmt(nVoidInvoke(nInvokeStatic(new Value[] { b }, \"La;\", \"y\", new String[] { \"I\" }, \"V\")));\n        addStmt(nAssign(nStaticField(\"La;\", \"z\", \"C\"), b));\n        addStmt(nReturnVoid());\n        transform();\n        // FIXME fix type detect\n        // Assert.assertEquals(\"\", \"I\", b.valueType);\n    }\n\n    // @Ignore(\"type b to Int is ok to this context\")\n    @Test\n    public void test3() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nInt(456)));\n        LabelStmt L0 = newLabel();\n        addStmt(nIf(nEq(b, nInt(0), TypeClass.ZIFL.name), L0));\n        addStmt(L0);\n        addStmt(nReturnVoid());\n        transform();\n        Assert.assertEquals(\"\", \"I\", b.valueType);\n    }\n\n    @Test\n    public void test3Z() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nInt(1)));\n        LabelStmt L0 = newLabel();\n        addStmt(nIf(nEq(b, nInt(0), TypeClass.ZIFL.name), L0));\n        addStmt(L0);\n        addStmt(nReturnVoid());\n        transform();\n        // FIXME local should type to Z but I works as well\n        // Assert.assertEquals(\"\", \"Z\", b.valueType);\n    }\n\n    @Test\n    public void test2arrayF() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n\n        addStmt(nAssign(b, nNewMutiArray(\"F\", 1, new Value[]{nInt(2)})));\n        addStmt(nFillArrayData(b, nConstant(new int[]{5, 6})));\n        addStmt(nAssign(c, nArray(b, nInt(3), TypeClass.IF.name)));\n        addStmt(nReturnVoid());\n        transform();\n        Assert.assertEquals(\"\", b.valueType, \"[F\");\n    }\n\n    @Test\n    public void testDefaultZI() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n\n        addStmt(nAssign(b, nInt(5)));\n        addStmt(nAssign(c, nOr(b, nInt(6), TypeClass.ZI.name)));\n\n        addStmt(nReturnVoid());\n        transform();\n        Assert.assertEquals(\"I\", c.valueType);\n    }\n\n\n    @Test\n    public void testGithubIssue28() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nNewMutiArray(\"D\", 2, new Value[]{nInt(2), nInt(3)})));\n        addStmt(nAssign(nArray(nArray(b, nInt(5), TypeClass.OBJECT.name), nInt(1), TypeClass.JD.name), nLong(0)));\n        addStmt(nReturnVoid());\n        transform();\n        Assert.assertEquals(\"\", b.valueType, \"[[D\");\n    }\n\n    @Test\n    public void testGithubIssue28x() {\n        initMethod(true, \"V\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(b, nInt(0)));\n        addStmt(nAssign(nArray(nArray(b, nInt(5), TypeClass.OBJECT.name), nInt(1), TypeClass.JD.name), nLong(0)));\n        addStmt(nReturnVoid());\n        transform();\n        // this case is ok to fail as the NPE transformer cover this\n        // Assert.assertEquals(\"\", \"[[D\", b.valueType);\n    }\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/UnSSATransformerTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\n\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\nimport com.googlecode.dex2jar.ir.ts.UnSSATransformer;\n\npublic class UnSSATransformerTransformerTest extends BaseTransformerTest<UnSSATransformer> {\n\n    @Test\n    public void test00Base() {\n        initMethod(true, \"V\");\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local phi = addLocal(\"p\");\n        LabelStmt L1 = newLabel();\n        Stmt s1 = addStmt(nAssign(a, nString(\"123\")));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        Stmt s2 = addStmt(nAssign(b, nString(\"456\")));\n        addStmt(L1);\n        attachPhi(L1,nAssign(phi, nPhi(a, b)));\n        addStmt(nReturn(phi));\n        transform();\n        Assert.assertEquals(\"insert assign after s1\", ST.ASSIGN, s1.getNext().st);\n        Assert.assertEquals(\"insert assign after s1\", ST.ASSIGN, s2.getNext().st);\n        // Assert.assertEquals(\"local should index to 0\", 0, b._ls_index);\n    }\n\n    @Test\n    public void test01SSAProblem() {\n        initMethod(true, \"I\");\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local phi = addLocal(\"p\");\n        LabelStmt L0 = newLabel();\n        addStmt(nAssign(a, nInt(2)));\n        addStmt(L0);\n        attachPhi(L0, nAssign(phi, nPhi(a, b)));\n        Stmt stmt = addStmt(nAssign(b, niAdd(phi, nInt(0))));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L0));\n        addStmt(nReturn(phi));\n        transform();\n        Assert.assertTrue(\"a new local should introduced to solve the problem\", stmt.getPre() != L0);\n    }\n\n    @Test\n    public void test02_3branches() {\n        initMethod(true, \"I\");\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local c = addLocal(\"c\");\n        Local d = addLocal(\"d\");\n        Local phi = addLocal(\"p\");\n        LabelStmt L0 = newLabel();\n        LabelStmt L1 = newLabel();\n        addStmt(nAssign(a, nInt(2)));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        addStmt(nAssign(b, nInt(3)));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L0));\n        addStmt(nAssign(c, nInt(4)));\n        addStmt(nLock(c));\n        addStmt(nGoto(L1));\n        addStmt(L0);\n        addStmt(nAssign(d, nInt(5)));\n        addStmt(nLock(d));\n        addStmt(L1);\n        attachPhi(L1, nAssign(phi, nPhi(a, b)));\n        addStmt(nReturn(phi));\n        transform();\n    }\n\n    @Test\n    public void test04OneInPhi() {\n        initMethod(true, \"V\");\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local phi = addLocal(\"p\");\n        LabelStmt L1 = newLabel();\n        Stmt s1 = addStmt(nAssign(a, nString(\"123\")));\n        Stmt j = addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        Stmt s2 = addStmt(nAssign(b, nString(\"456\")));\n        addStmt(L1);\n        attachPhi(L1, nAssign(phi, nPhi(a)));\n        addStmt(nReturn(phi));\n        transform();\n        Assert.assertTrue(\"p=a should inserted\", j.getPre() != s1);\n\n    }\n\n    @Test\n    public void test05OneInPhiLoop() {\n        initMethod(true, \"V\");\n        Local a = addLocal(\"a\");\n        Local b = addLocal(\"b\");\n        Local phi = addLocal(\"p\");\n\n        Stmt s1 = addStmt(nAssign(a, nString(\"123\")));\n        LabelStmt L1 = newLabel();\n        addStmt(L1);\n        attachPhi(L1, nAssign(phi, nPhi(a)));\n        addStmt(nVoidInvoke(nInvokeStatic(new Value[] { phi }, \"LAAA;\", \"bMethod\",\n                new String[] { \"Ljava/lang/String;\" }, \"V\")));\n        addStmt(nAssign(b, nString(\"456\")));\n\n        // phi is still live here\n        Stmt s2 = addStmt(nVoidInvoke(nInvokeStatic(new Value[] { b }, \"LBBB;\", \"cMethod\",\n                new String[] { \"Ljava/lang/String;\" }, \"V\")));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        addStmt(nReturnVoid());\n        transform();\n\n        Assert.assertTrue(\"p=a should inserted\", s1.getPre() != L1);\n\n    }\n\n    @Test\n    public void test06TwoJump() {\n        initMethod(true, \"V\");\n        Local a1 = addLocal(\"a1\");\n        Local a2 = addLocal(\"a2\");\n        Local a = addLocal(\"a\");\n\n        Local b1 = addLocal(\"b1\");\n        Local b2 = addLocal(\"b2\");\n        Local b = addLocal(\"b\");\n\n        addStmt(nAssign(a1, nString(\"123\")));\n        addStmt(nAssign(b1, nString(\"123\")));\n        LabelStmt L1 = newLabel();\n        addStmt(L1);\n        attachPhi(L1, nAssign(a, nPhi(a1, a2)));\n        attachPhi(L1, nAssign(b, nPhi(b1, b2)));\n\n        addStmt(nAssign(a2, nString(\"456\")));\n\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n        addStmt(nAssign(b2, nString(\"456\")));\n        addStmt(nIf(niGt(nInt(100), nInt(0)), L1));\n\n        addStmt(nReturnVoid());\n        transform();\n        // Assert.assertTrue(\"must assign different index\", ls1._ls_index != ls2._ls_index);\n\n    }\n\n    @Test\n    public void test07PhiInHandler() {\n        initMethod(true, \"I\");\n        Local a1 = addLocal(\"a1\");\n        Local a2 = addLocal(\"a2\");\n        Local a = addLocal(\"a\");\n        Local ex = addLocal(\"ex\");\n        addStmt(Stmts.nAssign(a1, nInt(1)));\n        LabelStmt L0 = newLabel();\n        LabelStmt L2 = newLabel();\n        LabelStmt L3 = newLabel();\n        addStmt(L0);\n        addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[0], \"La;\", \"m\", new String[0], \"V\")));\n        addStmt(Stmts.nAssign(a2, nInt(2)));\n        addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[0], \"La;\", \"m\", new String[0], \"V\")));\n        addStmt(L2);\n        addStmt(Stmts.nReturn(a2));\n        addStmt(L3);\n        Stmt ref = addStmt(Stmts.nIdentity(ex, Exprs.nExceptionRef(\"Ljava/lang/Exception;\")));\n        attachPhi(L3, Stmts.nAssign(a, nPhi(a1, a2)));\n        addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[] { a1 }, \"La;\", \"m\", new String[] { \"I\" }, \"V\")));\n        addStmt(Stmts.nReturn(a));\n        method.traps.add(new Trap(L0, L2, new LabelStmt[] { L3 }, new String[] { \"Ljava/lang/Exception\" }));\n        transform();\n        Assert.assertTrue(\"the fix assign should insert after x=@ExceptionRef\", L3.getNext() == ref);\n    }\n\n}\n"
  },
  {
    "path": "dex-ir/src/test/java/com/googlecode/dex2jar/ir/test/ZeroTransformerTest.java",
    "content": "package com.googlecode.dex2jar.ir.test;\n\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport com.googlecode.dex2jar.ir.ts.RemoveConstantFromSSA;\nimport com.googlecode.dex2jar.ir.ts.ZeroTransformer;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInt;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeStatic;\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nPhi;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;\n\npublic class ZeroTransformerTest extends BaseTransformerTest<ZeroTransformer> {\n    @Test\n    public void t001() {\n\n        Local a = addLocal(\"a\");\n        Local c = addLocal(\"c\");\n        Local p = addLocal(\"p\");\n        Local q = addLocal(\"q\");\n\n        addStmt(nAssign(a, nInt(0)));\n        addStmt(nAssign(c, nInvokeStatic(new Value[0], \"La;\", \"a\", new String[0], \"I\")));\n        LabelStmt L1 = newLabel();\n        addStmt(L1);\n        Stmt sa = attachPhi(L1, nAssign(q, nPhi(a, c)));\n        Stmt sb = attachPhi(L1, nAssign(p, nPhi(a, c)));\n        addStmt(nReturn(p));\n        transform();\n        Assert.assertNotEquals(\"a is split to 2 local\", sb.getOp2().getOps()[0], sa.getOp2().getOps()[0]);\n        Assert.assertEquals(\"c is keep same\", sb.getOp2().getOps()[1], sa.getOp2().getOps()[1]);\n    }\n}\n"
  },
  {
    "path": "dex-reader/build.gradle",
    "content": "description = 'Dex Reader'\n\ndependencies {\n    compile project(':dex-reader-api')\n    testCompile (group: 'org.apache.commons', name: 'commons-compress', version:'1.4.1')\n}\n\n\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/reader/BaseDexFileReader.java",
    "content": "package com.googlecode.d2j.reader;\n\nimport com.googlecode.d2j.visitors.DexFileVisitor;\n\nimport java.util.List;\n\npublic interface BaseDexFileReader {\n\n    int getDexVersion();\n\n    void accept(DexFileVisitor dv);\n\n    List<String> getClassNames();\n\n    void accept(DexFileVisitor dv, int config);\n\n    void accept(DexFileVisitor dv, int classIdx, int config);\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/reader/DexFileReader.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.reader;\r\n\r\nimport java.io.*;\r\nimport java.nio.ByteBuffer;\r\nimport java.nio.ByteOrder;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.util.*;\r\n\r\nimport com.googlecode.d2j.*;\r\nimport com.googlecode.d2j.node.DexAnnotationNode;\r\nimport com.googlecode.d2j.util.Mutf8;\r\nimport com.googlecode.d2j.visitors.*;\r\n\r\nimport static com.googlecode.d2j.DexConstants.*;\r\n\r\n/**\r\n * Open and read a dex file.this is the entrance of dex-reader. to read a dex/odex, use the following code:\r\n * \r\n * <pre>\r\n * DexFileVisitor visitor = new xxxFileVisitor();\r\n * DexFileReader reader = new DexFileReader(dexFile);\r\n * reader.accept(visitor);\r\n * </pre>\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class DexFileReader implements BaseDexFileReader {\r\n    /**\r\n     * skip debug infos in dex file.\r\n     */\r\n    public static final int SKIP_DEBUG = 1;\r\n    /**\r\n     * skip code info in dex file, this indicate {@link #SKIP_DEBUG}\r\n     */\r\n    public static final int SKIP_CODE = 1 << 2;\r\n    /**\r\n     * skip annotation info in dex file.\r\n     */\r\n    public static final int SKIP_ANNOTATION = 1 << 3;\r\n    /**\r\n     * skip field constant in dex file.\r\n     */\r\n    public static final int SKIP_FIELD_CONSTANT = 1 << 4;\r\n    /**\r\n     * ingore read exception\r\n     */\r\n    public static final int IGNORE_READ_EXCEPTION = 1 << 5;\r\n    /**\r\n     * read all methods, even if they are glitch\r\n     */\r\n    public static final int KEEP_ALL_METHODS = 1 << 6;\r\n    /**\r\n     * keep clinit method when {@link #SKIP_DEBUG}\r\n     */\r\n    public static final int KEEP_CLINIT = 1 << 7;\r\n\r\n    /**\r\n     * keep clinit method when {@link #SKIP_DEBUG}\r\n     */\r\n    public static final int SKIP_EXCEPTION = 1 << 8;\r\n\r\n    // private static final int REVERSE_ENDIAN_CONSTANT = 0x78563412;\r\n\r\n    static final int DBG_END_SEQUENCE = 0x00;\r\n    static final int DBG_ADVANCE_PC = 0x01;\r\n    static final int DBG_ADVANCE_LINE = 0x02;\r\n    static final int DBG_START_LOCAL = 0x03;\r\n    static final int DBG_START_LOCAL_EXTENDED = 0x04;\r\n    static final int DBG_END_LOCAL = 0x05;\r\n    static final int DBG_RESTART_LOCAL = 0x06;\r\n    static final int DBG_SET_PROLOGUE_END = 0x07;\r\n    static final int DBG_SET_EPILOGUE_BEGIN = 0x08;\r\n    static final int DBG_SET_FILE = 0x09;\r\n    static final int DBG_FIRST_SPECIAL = 0x0a;\r\n    static final int DBG_LINE_BASE = -4;\r\n    static final int DBG_LINE_RANGE = 15;\r\n\r\n    private static final int ENDIAN_CONSTANT = 0x12345678;\r\n    private static final int VALUE_BYTE = 0x00;\r\n    private static final int VALUE_SHORT = 0x02;\r\n    private static final int VALUE_CHAR = 0x03;\r\n    private static final int VALUE_INT = 0x04;\r\n    private static final int VALUE_LONG = 0x06;\r\n    private static final int VALUE_FLOAT = 0x10;\r\n    private static final int VALUE_DOUBLE = 0x11;\r\n    private static final int VALUE_METHOD_TYPE = 0x15;\r\n    private static final int VALUE_METHOD_HANDLE = 0x16;\r\n    private static final int VALUE_STRING = 0x17;\r\n    private static final int VALUE_TYPE = 0x18;\r\n    private static final int VALUE_FIELD = 0x19;\r\n    private static final int VALUE_METHOD = 0x1a;\r\n    private static final int VALUE_ENUM = 0x1b;\r\n    private static final int VALUE_ARRAY = 0x1c;\r\n    private static final int VALUE_ANNOTATION = 0x1d;\r\n    private static final int VALUE_NULL = 0x1e;\r\n    private static final int VALUE_BOOLEAN = 0x1f;\r\n\r\n    private static final int TYPE_CALL_SITE_ID_ITEM = 0x0007;\r\n    private static final int TYPE_METHOD_HANDLE_ITEM = 0x0008;\r\n\r\n    final ByteBuffer annotationSetRefListIn;\r\n    final ByteBuffer annotationsDirectoryItemIn;\r\n    final ByteBuffer annotationSetItemIn;\r\n    final ByteBuffer annotationItemIn;\r\n    final ByteBuffer classDataIn;\r\n    final ByteBuffer codeItemIn;\r\n    final ByteBuffer encodedArrayItemIn;\r\n    final ByteBuffer stringIdIn;\r\n    final ByteBuffer typeIdIn;\r\n    final ByteBuffer protoIdIn;\r\n    final ByteBuffer fieldIdIn;\r\n    final ByteBuffer methoIdIn;\r\n    final ByteBuffer classDefIn;\r\n    final ByteBuffer typeListIn;\r\n    final ByteBuffer stringDataIn;\r\n    final ByteBuffer debugInfoIn;\r\n    final ByteBuffer callSiteIdIn;\r\n    final ByteBuffer methodHandleIdIn;\r\n    final int string_ids_size;\r\n    final int type_ids_size;\r\n    final int proto_ids_size;\r\n    final int field_ids_size;\r\n    final int method_ids_size;\r\n    final private int class_defs_size;\r\n    final int call_site_ids_size;\r\n    final int method_handle_ids_size;\r\n    final int dex_version;\r\n\r\n    /**\r\n     * read dex from a {@link ByteBuffer}.\r\n     * \r\n     * @param in\r\n     */\r\n    public DexFileReader(ByteBuffer in) {\r\n        in.position(0);\r\n        in = in.asReadOnlyBuffer().order(ByteOrder.BIG_ENDIAN);\r\n        int magic = in.getInt() & 0xFFFFFF00;\r\n\r\n        final int MAGIC_DEX = 0x6465780A & 0xFFFFFF00;// hex for 'dex ', ignore the 0A\r\n        final int MAGIC_ODEX = 0x6465790A & 0xFFFFFF00;// hex for 'dey ', ignore the 0A\r\n\r\n        if (magic == MAGIC_DEX) {\r\n            ;\r\n        } else if (magic == MAGIC_ODEX) {\r\n            throw new DexException(\"Not support odex\");\r\n        } else {\r\n            throw new DexException(\"not support magic.\");\r\n        }\r\n        int version = in.getInt() >> 8;\r\n        if (version < 0 || version < DEX_035) {\r\n            throw new DexException(\"not support version.\");\r\n        }\r\n        this.dex_version = version;\r\n        in.order(ByteOrder.LITTLE_ENDIAN);\r\n\r\n        // skip uint checksum\r\n        // and 20 bytes signature\r\n        // and uint file_size\r\n        // and uint header_size 0x70\r\n        skip(in, 4 + 20 + 4 + 4);\r\n\r\n        int endian_tag = in.getInt();\r\n        if (endian_tag != ENDIAN_CONSTANT) {\r\n            throw new DexException(\"not support endian_tag\");\r\n        }\r\n\r\n        // skip uint link_size\r\n        // and uint link_off\r\n        skip(in, 4 + 4);\r\n\r\n        int map_off = in.getInt();\r\n\r\n        string_ids_size = in.getInt();\r\n        int string_ids_off = in.getInt();\r\n        type_ids_size = in.getInt();\r\n        int type_ids_off = in.getInt();\r\n        proto_ids_size = in.getInt();\r\n        int proto_ids_off = in.getInt();\r\n        field_ids_size = in.getInt();\r\n        int field_ids_off = in.getInt();\r\n        method_ids_size = in.getInt();\r\n        int method_ids_off = in.getInt();\r\n        class_defs_size = in.getInt();\r\n        int class_defs_off = in.getInt();\r\n        // skip uint data_size data_off\r\n\r\n        int call_site_ids_off = 0;\r\n        int call_site_ids_size = 0;\r\n        int method_handle_ids_off = 0;\r\n        int method_handle_ids_size = 0;\r\n        if (dex_version > DEX_037) {\r\n            in.position(map_off);\r\n            int size = in.getInt();\r\n            for (int i = 0; i < size; i++) {\r\n                int type = in.getShort() & 0xFFFF;\r\n                in.getShort(); // unused;\r\n                int item_size = in.getInt();\r\n                int item_offset = in.getInt();\r\n                switch (type) {\r\n                case TYPE_CALL_SITE_ID_ITEM:\r\n                    call_site_ids_off = item_offset;\r\n                    call_site_ids_size = item_size;\r\n                    break;\r\n                case TYPE_METHOD_HANDLE_ITEM:\r\n                    method_handle_ids_off = item_offset;\r\n                    method_handle_ids_size = item_size;\r\n                    break;\r\n                default:\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        this.call_site_ids_size = call_site_ids_size;\r\n        this.method_handle_ids_size = method_handle_ids_size;\r\n\r\n        stringIdIn = slice(in, string_ids_off, string_ids_size * 4);\r\n        typeIdIn = slice(in, type_ids_off, type_ids_size * 4);\r\n        protoIdIn = slice(in, proto_ids_off, proto_ids_size * 12);\r\n        fieldIdIn = slice(in, field_ids_off, field_ids_size * 8);\r\n        methoIdIn = slice(in, method_ids_off, method_ids_size * 8);\r\n        classDefIn = slice(in, class_defs_off, class_defs_size * 32);\r\n        callSiteIdIn = slice(in, call_site_ids_off, call_site_ids_size * 4);\r\n        methodHandleIdIn = slice(in, method_handle_ids_off, method_handle_ids_size * 8);\r\n\r\n        in.position(0);\r\n        annotationsDirectoryItemIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        annotationSetItemIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        annotationItemIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        annotationSetRefListIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        classDataIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        codeItemIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        stringDataIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        encodedArrayItemIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        typeListIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        debugInfoIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n    }\r\n\r\n    /**\r\n     * \r\n     * @param data\r\n     *            the byte array of dex\r\n     * @return\r\n     */\r\n    public DexFileReader(byte[] data) {\r\n        this(ByteBuffer.wrap(data));\r\n    }\r\n\r\n    /**\r\n     * \r\n     * @param file\r\n     *            the dex file\r\n     * @throws IOException\r\n     */\r\n    public DexFileReader(File file) throws IOException {\r\n        this(file.toPath());\r\n    }\r\n\r\n    public DexFileReader(Path file) throws IOException {\r\n        this(Files.readAllBytes(file));\r\n    }\r\n\r\n    public DexFileReader(InputStream is) throws IOException {\r\n        this(toByteArray(is));\r\n    }\r\n\r\n    /**\r\n     * Reads a string index. String indicies are offset by 1, and a 0 value in the stream (-1 as returned by this\r\n     * method) means \"null\"\r\n     * \r\n     * @return index into file's string ids table, -1 means null\r\n     */\r\n    private static int readStringIndex(ByteBuffer bs) {\r\n        int offsetIndex = readULeb128i(bs);\r\n        return offsetIndex - 1;\r\n    }\r\n\r\n    private static byte[] toByteArray(InputStream is) throws IOException {\r\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\r\n        byte[] buff = new byte[1024];\r\n        for (int c = is.read(buff); c > 0; c = is.read(buff)) {\r\n            out.write(buff, 0, c);\r\n        }\r\n        return out.toByteArray();\r\n    }\r\n\r\n    private static ByteBuffer slice(ByteBuffer in, int offset, int length) {\r\n        in.position(offset);\r\n        ByteBuffer b = in.slice();\r\n        b.limit(length);\r\n        b.order(ByteOrder.LITTLE_ENDIAN);\r\n        return b;\r\n    }\r\n\r\n    private static void skip(ByteBuffer in, int bytes) {\r\n        in.position(in.position() + bytes);\r\n    }\r\n\r\n    public static void niceExceptionMessage(Throwable t, int deep) {\r\n        StringBuilder sb = new StringBuilder();\r\n        for (int i = 0; i < deep + 1; i++) {\r\n            sb.append(\".\");\r\n        }\r\n        sb.append(' ');\r\n        if (t instanceof DexException) {\r\n            sb.append(t.getMessage());\r\n            System.err.println(sb.toString());\r\n            if (t.getCause() != null) {\r\n                niceExceptionMessage(t.getCause(), deep + 1);\r\n            }\r\n        } else {\r\n            if (t != null) {\r\n                System.err.println(sb.append(\"ROOT cause:\").toString());\r\n                t.printStackTrace(System.err);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static long readIntBits(ByteBuffer in, int before) {\r\n        int length = ((before >> 5) & 0x7) + 1;\r\n        long value = 0;\r\n        for (int j = 0; j < length; j++) {\r\n            value |= ((long) (0xFF & in.get())) << (j * 8);\r\n        }\r\n        int shift = (8 - length) * 8;\r\n        return value << shift >> shift;\r\n    }\r\n\r\n    private static long readUIntBits(ByteBuffer in, int before) {\r\n        int length = ((before >> 5) & 0x7) + 1;\r\n        long value = 0;\r\n        for (int j = 0; j < length; j++) {\r\n            value |= ((long) (0xFF & in.get())) << (j * 8);\r\n        }\r\n        return value;\r\n    }\r\n\r\n    private static long readFloatBits(ByteBuffer in, int before) {\r\n        int bytes = ((before >> 5) & 0x7) + 1;\r\n        long result = 0L;\r\n        for (int i = 0; i < bytes; ++i) {\r\n            result |= ((long) (0xFF & in.get())) << (i * 8);\r\n        }\r\n        result <<= (8 - bytes) * 8;\r\n        return result;\r\n    }\r\n\r\n    static int sshort(byte[] data, int offset) {\r\n        return (data[offset + 1] << 8) | (0xFF & data[offset]);\r\n    }\r\n\r\n    static int ushort(byte[] data, int offset) {\r\n        return ((0xFF & data[offset + 1]) << 8) | (0xFF & data[offset]);\r\n    }\r\n\r\n    static int sint(byte[] data, int offset) {\r\n        return (data[offset + 3] << 24) | ((0xFF & data[offset + 2]) << 16) | ((0xFF & data[offset + 1]) << 8)\r\n                | ((0xFF & data[offset]));\r\n    }\r\n\r\n    static int uint(byte[] data, int offset) {\r\n        return sint(data, offset);\r\n    }\r\n\r\n    static void WARN(String fmt, Object... args) {\r\n        System.err.println(String.format(fmt, args));\r\n    }\r\n\r\n    static int ubyte(byte[] insns, int offset) {\r\n        return 0xFF & insns[offset];\r\n    }\r\n\r\n    static int sbyte(byte[] insns, int offset) {\r\n        return insns[offset];\r\n    }\r\n\r\n    private static void order(Map<Integer, DexLabel> labelsMap, int offset) {\r\n        if (!labelsMap.containsKey(offset)) {\r\n            labelsMap.put(offset, new DexLabel(offset));\r\n        }\r\n    }\r\n\r\n    public static int readULeb128i(ByteBuffer in) {\r\n        int value = 0;\r\n        int count = 0;\r\n        int b = in.get();\r\n        while ((b & 0x80) != 0) {\r\n            value |= (b & 0x7f) << count;\r\n            count += 7;\r\n            b = in.get();\r\n        }\r\n        value |= (b & 0x7f) << count;\r\n        return value;\r\n    }\r\n\r\n    public static int readLeb128i(ByteBuffer in) {\r\n        int bitpos = 0;\r\n        int vln = 0;\r\n        do {\r\n            int inp = in.get();\r\n            vln |= (inp & 0x7F) << bitpos;\r\n            bitpos += 7;\r\n            if ((inp & 0x80) == 0) {\r\n                break;\r\n            }\r\n        } while (true);\r\n        if (((1L << (bitpos - 1)) & vln) != 0) {\r\n            vln -= (1L << bitpos);\r\n        }\r\n        return vln;\r\n    }\r\n\r\n    private static void DEBUG_DEBUG(String fmt, Object... args) {\r\n        // System.out.println(String.format(fmt, args));\r\n    }\r\n\r\n    private void read_debug_info(int offset, int regSize, boolean isStatic, Method method,\r\n            Map<Integer, DexLabel> labelMap, DexDebugVisitor dcv) {\r\n        ByteBuffer in = debugInfoIn;\r\n        in.position(offset);\r\n        int address = 0;\r\n        int line = readULeb128i(in);\r\n        int szParams = readULeb128i(in);\r\n        LocalEntry lastEntryForReg[] = new LocalEntry[regSize];\r\n        int argsSize = 0;\r\n        for (String paramType : method.getParameterTypes()) {\r\n            if (paramType.equals(\"J\") || paramType.equals(\"D\")) {\r\n                argsSize += 2;\r\n            } else {\r\n                argsSize += 1;\r\n            }\r\n        }\r\n        int curReg = regSize - argsSize;\r\n        if (!isStatic) {\r\n            // Start off with implicit 'this' entry\r\n            LocalEntry thisEntry = new LocalEntry(\"this\", method.getOwner(), null);\r\n            lastEntryForReg[curReg - 1] = thisEntry;\r\n            // dcv.visitParameterName(curReg - 1, \"this\");\r\n            DEBUG_DEBUG(\"v%d :%s, %s\", curReg - 1, \"this\", method.getOwner());\r\n        }\r\n\r\n        String[] params = method.getParameterTypes();\r\n        for (int i = 0; i < szParams; i++) {\r\n            String paramType = params[i];\r\n            LocalEntry le;\r\n\r\n            int nameIdx = readStringIndex(in);\r\n            String name = getString(nameIdx);\r\n            le = new LocalEntry(name, paramType);\r\n            lastEntryForReg[curReg] = le;\r\n            if (name != null) {\r\n                dcv.visitParameterName(i, name);\r\n            }\r\n            DEBUG_DEBUG(\"v%d :%s, %s\", curReg, name, paramType);\r\n            curReg += 1;\r\n            if (paramType.equals(\"J\") || paramType.equals(\"D\")) {\r\n                curReg += 1;\r\n            }\r\n        }\r\n\r\n        for (;;) {\r\n            int opcode = in.get() & 0xff;\r\n\r\n            switch (opcode) {\r\n            case DBG_START_LOCAL: {\r\n                int reg = readULeb128i(in);\r\n                int nameIdx = readStringIndex(in);\r\n                int typeIdx = readStringIndex(in);\r\n                String name = getString(nameIdx);\r\n                String type = getType(typeIdx);\r\n                DEBUG_DEBUG(\"Start: v%d :%s, %s\", reg, name, type);\r\n                LocalEntry le = new LocalEntry(name, type);\r\n                lastEntryForReg[reg] = le;\r\n                order(labelMap, address);\r\n                dcv.visitStartLocal(reg, labelMap.get(address), name, type, null);\r\n            }\r\n                break;\r\n\r\n            case DBG_START_LOCAL_EXTENDED: {\r\n                int reg = readULeb128i(in);\r\n                int nameIdx = readStringIndex(in);\r\n                int typeIdx = readStringIndex(in);\r\n                int sigIdx = readStringIndex(in);\r\n                String name = getString(nameIdx);\r\n                String type = getType(typeIdx);\r\n                String signature = getString(sigIdx);\r\n                DEBUG_DEBUG(\"Start: v%d :%s, %s // %s\", reg, name, type, signature);\r\n                LocalEntry le = new LocalEntry(name, type, signature);\r\n                order(labelMap, address);\r\n                dcv.visitStartLocal(reg, labelMap.get(address), name, type, signature);\r\n                lastEntryForReg[reg] = le;\r\n            }\r\n                break;\r\n\r\n            case DBG_RESTART_LOCAL: {\r\n                int reg = readULeb128i(in);\r\n                LocalEntry le = lastEntryForReg[reg];\r\n                if (le == null) {\r\n                    throw new RuntimeException(\"Encountered RESTART_LOCAL on new v\" + reg);\r\n                }\r\n                if (le.signature == null) {\r\n                    DEBUG_DEBUG(\"Start: v%d :%s, %s\", reg, le.name, le.type);\r\n                } else {\r\n                    DEBUG_DEBUG(\"Start: v%d :%s, %s // %s\", reg, le.name, le.type, le.signature);\r\n                }\r\n                order(labelMap, address);\r\n                dcv.visitRestartLocal(reg, labelMap.get(address));\r\n            }\r\n                break;\r\n\r\n            case DBG_END_LOCAL: {\r\n                int reg = readULeb128i(in);\r\n                LocalEntry le = lastEntryForReg[reg];\r\n                if (le == null) {\r\n                    throw new RuntimeException(\"Encountered RESTART_LOCAL on new v\" + reg);\r\n                }\r\n                if (le.signature == null) {\r\n                    DEBUG_DEBUG(\"End: v%d :%s, %s\", reg, le.name, le.type);\r\n                } else {\r\n                    DEBUG_DEBUG(\"End: v%d :%s, %s // %s\", reg, le.name, le.type, le.signature);\r\n                }\r\n                order(labelMap, address);\r\n                dcv.visitEndLocal(reg, labelMap.get(address));\r\n            }\r\n                break;\r\n\r\n            case DBG_END_SEQUENCE:\r\n                // all done\r\n                return;\r\n\r\n            case DBG_ADVANCE_PC:\r\n                address += readULeb128i(in);\r\n                break;\r\n\r\n            case DBG_ADVANCE_LINE:\r\n                line += readLeb128i(in);\r\n                break;\r\n\r\n            case DBG_SET_PROLOGUE_END:\r\n                order(labelMap, address);\r\n                dcv.visitPrologue(labelMap.get(address));\r\n                break;\r\n            case DBG_SET_EPILOGUE_BEGIN:\r\n                order(labelMap, address);\r\n                dcv.visitEpiogue(labelMap.get(address));\r\n                break;\r\n            case DBG_SET_FILE:\r\n                // skip\r\n                break;\r\n\r\n            default:\r\n                if (opcode < DBG_FIRST_SPECIAL) {\r\n                    throw new RuntimeException(\"Invalid extended opcode encountered \" + opcode);\r\n                }\r\n\r\n                int adjopcode = opcode - DBG_FIRST_SPECIAL;\r\n\r\n                address += adjopcode / DBG_LINE_RANGE;\r\n                line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);\r\n\r\n                order(labelMap, address);\r\n                dcv.visitLineNumber(line, labelMap.get(address));\r\n                break;\r\n\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public int getDexVersion() {\r\n        return dex_version;\r\n    }\r\n\r\n    /**\r\n     * equals to {@link #accept(DexFileVisitor, int)} with 0 as config\r\n     * \r\n     * @param dv\r\n     */\r\n    @Override\r\n    public void accept(DexFileVisitor dv) {\r\n        this.accept(dv, 0);\r\n    }\r\n\r\n    @Override\r\n    public List<String> getClassNames() {\r\n        List<String> names = new ArrayList<>(class_defs_size);\r\n        ByteBuffer in = classDefIn;\r\n        for (int cid = 0; cid < class_defs_size; cid++) {\r\n            in.position(cid * 32);\r\n            String className = this.getType(in.getInt());\r\n            names.add(className);\r\n        }\r\n        return names;\r\n    }\r\n\r\n    /**\r\n     * Makes the given visitor visit the dex file.\r\n     * \r\n     * @param dv\r\n     *            visitor\r\n     * @param config\r\n     *            config flags, {@link #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_ANNOTATION},\r\n     *            {@link #SKIP_FIELD_CONSTANT}\r\n     */\r\n    @Override\r\n    public void accept(DexFileVisitor dv, int config) {\r\n        dv.visitDexFileVersion(this.dex_version);\r\n        for (int cid = 0; cid < class_defs_size; cid++) {\r\n            accept(dv, cid, config);\r\n        }\r\n        dv.visitEnd();\r\n    }\r\n\r\n    /**\r\n     * Makes the given visitor visit the dex file. Notice the\r\n     * {@link com.googlecode.d2j.visitors.DexFileVisitor#visitEnd()} is not called\r\n     * \r\n     * @param dv\r\n     *            visitor\r\n     * @param classIdx\r\n     *            index of class_def\r\n     * @param config\r\n     *            config flags, {@link #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_ANNOTATION},\r\n     *            {@link #SKIP_FIELD_CONSTANT}\r\n     */\r\n    @Override\r\n    public void accept(DexFileVisitor dv, int classIdx, int config) {\r\n        classDefIn.position(classIdx * 32);\r\n        int class_idx = classDefIn.getInt();\r\n        int access_flags = classDefIn.getInt();\r\n        int superclass_idx = classDefIn.getInt();\r\n        int interfaces_off = classDefIn.getInt();\r\n        int source_file_idx = classDefIn.getInt();\r\n        int annotations_off = classDefIn.getInt();\r\n        int class_data_off = classDefIn.getInt();\r\n        int static_values_off = classDefIn.getInt();\r\n\r\n        String className = getType(class_idx);\r\n        if(ignoreClass(className)) return;\r\n        String superClassName = getType(superclass_idx);\r\n        String[] interfaceNames = getTypeList(interfaces_off);\r\n        try {\r\n            DexClassVisitor dcv = dv.visit(access_flags, className, superClassName, interfaceNames);\r\n            if (dcv != null)// 不处理\r\n            {\r\n                acceptClass(dcv, source_file_idx, annotations_off, class_data_off, static_values_off, config);\r\n                dcv.visitEnd();\r\n            }\r\n        } catch (Exception ex) {\r\n            DexException dexException = new DexException(ex, \"Error process class: [%d]%s\", class_idx, className);\r\n            if (0 != (config & IGNORE_READ_EXCEPTION)) {\r\n                niceExceptionMessage(dexException, 0);\r\n            } else {\r\n                throw dexException;\r\n            }\r\n        }\r\n    }\r\n\r\n    public Boolean ignoreClass(String className){\r\n       return false;\r\n    }\r\n\r\n    private Object readEncodedValue(ByteBuffer in) {\r\n        int b = 0xFF & in.get();\r\n        int type = b & 0x1f;\r\n        switch (type) {\r\n        case VALUE_BYTE:\r\n            return new Byte((byte) readIntBits(in, b));\r\n\r\n        case VALUE_SHORT:\r\n            return new Short((short) readIntBits(in, b));\r\n\r\n        case VALUE_CHAR:\r\n            return new Character((char) readUIntBits(in, b));\r\n\r\n        case VALUE_INT:\r\n            return new Integer((int) readIntBits(in, b));\r\n\r\n        case VALUE_LONG:\r\n            return new Long(readIntBits(in, b));\r\n\r\n        case VALUE_FLOAT:\r\n            return Float.intBitsToFloat((int) (readFloatBits(in, b) >> 32));\r\n\r\n        case VALUE_DOUBLE:\r\n            return Double.longBitsToDouble(readFloatBits(in, b));\r\n        case VALUE_METHOD_TYPE:\r\n            return getProto((int) readUIntBits(in, b));\r\n        case VALUE_METHOD_HANDLE:\r\n            return getMethodHandle((int) readUIntBits(in, b));\r\n\r\n        case VALUE_STRING:\r\n            return getString((int) readUIntBits(in, b));\r\n\r\n        case VALUE_TYPE: {\r\n            int type_id = (int) readUIntBits(in, b);\r\n            return new DexType(getType(type_id));\r\n        }\r\n        case VALUE_FIELD: {\r\n            int field_id = (int) readUIntBits(in, b);\r\n            return getField(field_id);\r\n        }\r\n        case VALUE_METHOD: {\r\n            int method_id = (int) readUIntBits(in, b);\r\n            return getMethod(method_id);\r\n\r\n        }\r\n        case VALUE_ENUM: {\r\n            return getField((int) readUIntBits(in, b));\r\n        }\r\n        case VALUE_ARRAY: {\r\n            return read_encoded_array(in);\r\n        }\r\n        case VALUE_ANNOTATION: {\r\n            return read_encoded_annotation(in);\r\n        }\r\n        case VALUE_NULL:\r\n            return null;\r\n        case VALUE_BOOLEAN: {\r\n            return new Boolean(((b >> 5) & 0x3) != 0);\r\n        }\r\n        default:\r\n            throw new DexException(\"Not support yet.\");\r\n        }\r\n    }\r\n\r\n    private MethodHandle getMethodHandle(int i) {\r\n        methodHandleIdIn.position(i * 8);\r\n        int method_handle_type = methodHandleIdIn.getShort() & 0xFFFF;\r\n        methodHandleIdIn.getShort();//unused\r\n        int field_or_method_id = methodHandleIdIn.getShort() & 0xFFFF;\r\n\r\n        switch (method_handle_type) {\r\n        case MethodHandle.INSTANCE_GET:\r\n        case MethodHandle.INSTANCE_PUT:\r\n        case MethodHandle.STATIC_GET:\r\n        case MethodHandle.STATIC_PUT:\r\n            return new MethodHandle(method_handle_type, getField(field_or_method_id));\r\n\r\n        case MethodHandle.INVOKE_INSTANCE:\r\n        case MethodHandle.INVOKE_STATIC:\r\n        case MethodHandle.INVOKE_CONSTRUCTOR:\r\n        case MethodHandle.INVOKE_DIRECT:\r\n        case MethodHandle.INVOKE_INTERFACE:\r\n            return new MethodHandle(method_handle_type, getMethod(field_or_method_id));\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    private void acceptClass(DexClassVisitor dcv, int source_file_idx, int annotations_off, int class_data_off,\r\n            int static_values_off, int config) {\r\n        if ((config & SKIP_DEBUG) == 0) {\r\n            // 获取源文件\r\n            if (source_file_idx != -1) {\r\n                dcv.visitSource(this.getString(source_file_idx));\r\n            }\r\n        }\r\n\r\n        Map<Integer, Integer> fieldAnnotationPositions;\r\n        Map<Integer, Integer> methodAnnotationPositions;\r\n        Map<Integer, Integer> paramAnnotationPositions;\r\n        if ((config & SKIP_ANNOTATION) == 0) {\r\n            // 获取注解\r\n            fieldAnnotationPositions = new HashMap<Integer, Integer>();\r\n            methodAnnotationPositions = new HashMap<Integer, Integer>();\r\n            paramAnnotationPositions = new HashMap<Integer, Integer>();\r\n            if (annotations_off != 0) { // annotations_directory_item\r\n\r\n                annotationsDirectoryItemIn.position(annotations_off);\r\n\r\n                int class_annotations_off = annotationsDirectoryItemIn.getInt();\r\n                int field_annotation_size = annotationsDirectoryItemIn.getInt();\r\n                int method_annotation_size = annotationsDirectoryItemIn.getInt();\r\n                int parameter_annotation_size = annotationsDirectoryItemIn.getInt();\r\n\r\n                for (int i = 0; i < field_annotation_size; i++) {\r\n                    int field_idx = annotationsDirectoryItemIn.getInt();\r\n                    int field_annotations_offset = annotationsDirectoryItemIn.getInt();\r\n                    fieldAnnotationPositions.put(field_idx, field_annotations_offset);\r\n                }\r\n                for (int i = 0; i < method_annotation_size; i++) {\r\n                    int method_idx = annotationsDirectoryItemIn.getInt();\r\n                    int method_annotation_offset = annotationsDirectoryItemIn.getInt();\r\n                    methodAnnotationPositions.put(method_idx, method_annotation_offset);\r\n                }\r\n                for (int i = 0; i < parameter_annotation_size; i++) {\r\n                    int method_idx = annotationsDirectoryItemIn.getInt();\r\n                    int parameter_annotation_offset = annotationsDirectoryItemIn.getInt();\r\n                    paramAnnotationPositions.put(method_idx, parameter_annotation_offset);\r\n                }\r\n\r\n                if (class_annotations_off != 0) {\r\n                    try {\r\n                        read_annotation_set_item(class_annotations_off, dcv);\r\n                    } catch (Exception e) {\r\n                        throw new DexException(\"error on reading Annotation of class \", e);\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            fieldAnnotationPositions = null;\r\n            methodAnnotationPositions = null;\r\n            paramAnnotationPositions = null;\r\n        }\r\n\r\n        if (class_data_off != 0) {\r\n            ByteBuffer in = classDataIn;\r\n            in.position(class_data_off);\r\n\r\n            int static_fields = (int) readULeb128i(in);\r\n            int instance_fields = (int) readULeb128i(in);\r\n            int direct_methods = (int) readULeb128i(in);\r\n            int virtual_methods = (int) readULeb128i(in);\r\n            {\r\n                int lastIndex = 0;\r\n                {\r\n                    Object[] constant = null;\r\n                    if ((config & SKIP_FIELD_CONSTANT) == 0) {\r\n                        if (static_values_off != 0) {\r\n                            constant = read_encoded_array_item(static_values_off);\r\n                        }\r\n                    }\r\n                    for (int i = 0; i < static_fields; i++) {\r\n                        Object value = null;\r\n                        if (constant != null && i < constant.length) {\r\n                            value = constant[i];\r\n                        }\r\n                        lastIndex = acceptField(in, lastIndex, dcv, fieldAnnotationPositions, value, config);\r\n                    }\r\n                }\r\n                lastIndex = 0;\r\n                for (int i = 0; i < instance_fields; i++) {\r\n                    lastIndex = acceptField(in, lastIndex, dcv, fieldAnnotationPositions, null, config);\r\n                }\r\n                lastIndex = 0;\r\n                boolean firstMethod = true;\r\n                for (int i = 0; i < direct_methods; i++) {\r\n                    lastIndex = acceptMethod(in, lastIndex, dcv, methodAnnotationPositions, paramAnnotationPositions,\r\n                            config, firstMethod);\r\n                    firstMethod = false;\r\n                }\r\n                lastIndex = 0;\r\n                firstMethod = true;\r\n                for (int i = 0; i < virtual_methods; i++) {\r\n                    lastIndex = acceptMethod(in, lastIndex, dcv, methodAnnotationPositions, paramAnnotationPositions,\r\n                            config, firstMethod);\r\n                    firstMethod = false;\r\n                }\r\n            }\r\n\r\n        }\r\n    }\r\n\r\n    private Object[] read_encoded_array_item(int static_values_off) {\r\n        encodedArrayItemIn.position(static_values_off);\r\n        return read_encoded_array(encodedArrayItemIn);\r\n    }\r\n\r\n    private Object[] read_encoded_array(ByteBuffer in) {\r\n        int size = readULeb128i(in);\r\n        Object[] constant = new Object[size];\r\n        for (int i = 0; i < size; i++) {\r\n            constant[i] = readEncodedValue(in);\r\n        }\r\n        return constant;\r\n    }\r\n\r\n    private void read_annotation_set_item(int offset, DexAnnotationAble daa) { // annotation_set_item\r\n        ByteBuffer in = annotationSetItemIn;\r\n        in.position(offset);\r\n        int size = in.getInt();\r\n        for (int j = 0; j < size; j++) {\r\n            int annotation_off = in.getInt();\r\n            read_annotation_item(annotation_off, daa);\r\n        }\r\n    }\r\n\r\n    private void read_annotation_item(int annotation_off, DexAnnotationAble daa) {\r\n        ByteBuffer in = annotationItemIn;\r\n        in.position(annotation_off);\r\n        int visibility = 0xFF & in.get();\r\n        DexAnnotationNode annotation = read_encoded_annotation(in);\r\n        annotation.visibility = Visibility.values()[visibility];\r\n        annotation.accept(daa);\r\n    }\r\n\r\n    private DexAnnotationNode read_encoded_annotation(ByteBuffer in) {\r\n        int type_idx = readULeb128i(in);\r\n        int size = readULeb128i(in);\r\n        String _typeString = getType(type_idx);\r\n        DexAnnotationNode ann = new DexAnnotationNode(_typeString, Visibility.RUNTIME);\r\n        for (int i = 0; i < size; i++) {\r\n            int name_idx = readULeb128i(in);\r\n            String nameString = getString(name_idx);\r\n            Object value = readEncodedValue(in);\r\n            ann.items.add(new DexAnnotationNode.Item(nameString, value));\r\n        }\r\n        return ann;\r\n    }\r\n\r\n    private Field getField(int id) {\r\n        fieldIdIn.position(id * 8);\r\n        int owner_idx = 0xFFFF & fieldIdIn.getShort();\r\n        int type_idx = 0xFFFF & fieldIdIn.getShort();\r\n        int name_idx = fieldIdIn.getInt();\r\n        return new Field(getType(owner_idx), getString(name_idx), getType(type_idx));\r\n    }\r\n\r\n    private String[] getTypeList(int offset) {\r\n        if (offset == 0) {\r\n            return new String[0];\r\n        }\r\n        typeListIn.position(offset);\r\n        int size = typeListIn.getInt();\r\n        String[] types = new String[size];\r\n        for (int i = 0; i < size; i++) {\r\n            types[i] = getType(0xFFFF & typeListIn.getShort());\r\n        }\r\n        return types;\r\n    }\r\n\r\n    private Proto getProto(int proto_idx) {\r\n        String[] parameterTypes;\r\n        String returnType;\r\n\r\n        protoIdIn.position(proto_idx * 12 + 4); // move to position and skip shorty_idx\r\n\r\n        int return_type_idx = protoIdIn.getInt();\r\n        int parameters_off = protoIdIn.getInt();\r\n\r\n        returnType = getType(return_type_idx);\r\n\r\n        parameterTypes = getTypeList(parameters_off);\r\n        return new Proto(parameterTypes, returnType);\r\n    }\r\n\r\n    private Method getMethod(int id) {\r\n        methoIdIn.position(id * 8);\r\n        int owner_idx = 0xFFFF & methoIdIn.getShort();\r\n        int proto_idx = 0xFFFF & methoIdIn.getShort();\r\n        int name_idx = methoIdIn.getInt();\r\n        return new Method(getType(owner_idx), getString(name_idx), getProto(proto_idx));\r\n    }\r\n\r\n    private String getString(int id) {\r\n        if (id == -1) {\r\n            return null;\r\n        }\r\n        int offset = stringIdIn.getInt(id * 4);\r\n        stringDataIn.position(offset);\r\n        int length = readULeb128i(stringDataIn);\r\n        try {\r\n            StringBuilder buff = new StringBuilder((int) (length * 1.5));\r\n            return Mutf8.decode(stringDataIn, buff);\r\n        } catch (UTFDataFormatException e) {\r\n            throw new DexException(e, \"fail to load string %d@%08x\", id, offset);\r\n        }\r\n    }\r\n\r\n    private String getType(int id) {\r\n        if (id == -1) {\r\n            return null;\r\n        }\r\n        return getString(typeIdIn.getInt(id * 4));\r\n    }\r\n\r\n    private int acceptField(ByteBuffer in, int lastIndex, DexClassVisitor dcv,\r\n            Map<Integer, Integer> fieldAnnotationPositions, Object value, int config) {\r\n        int diff = (int) readULeb128i(in);\r\n        int field_access_flags = (int) readULeb128i(in);\r\n        int field_id = lastIndex + diff;\r\n        Field field = getField(field_id);\r\n        // //////////////////////////////////////////////////////////////\r\n        DexFieldVisitor dfv = dcv.visitField(field_access_flags, field, value);\r\n        if (dfv != null) {\r\n            if ((config & SKIP_ANNOTATION) == 0) {\r\n                Integer annotation_offset = fieldAnnotationPositions.get(field_id);\r\n                if (annotation_offset != null) {\r\n                    try {\r\n                        read_annotation_set_item(annotation_offset, dfv);\r\n                    } catch (Exception e) {\r\n                        throw new DexException(e, \"while accept annotation in field:%s.\", field.toString());\r\n                    }\r\n                }\r\n            }\r\n            dfv.visitEnd();\r\n        }\r\n        // //////////////////////////////////////////////////////////////\r\n        return field_id;\r\n    }\r\n\r\n    private int acceptMethod(ByteBuffer in, int lastIndex, DexClassVisitor cv, Map<Integer, Integer> methodAnnos,\r\n            Map<Integer, Integer> parameterAnnos, int config, boolean firstMethod) {\r\n        int offset = in.position();\r\n        int diff = (int) readULeb128i(in);\r\n        int method_access_flags = (int) readULeb128i(in);\r\n        int code_off = (int) readULeb128i(in);\r\n        int method_id = lastIndex + diff;\r\n        Method method = getMethod(method_id);\r\n\r\n        // issue 200, methods may have same signature, we only need to keep the first one\r\n        if (!firstMethod && diff == 0) { // detect a duplicated method\r\n            WARN(\"GLITCH: duplicated method %s @%08x\", method.toString(), offset);\r\n            if ((config & KEEP_ALL_METHODS) == 0) {\r\n                WARN(\"WARN: skip method %s @%08x\", method.toString(), offset);\r\n                return method_id;\r\n            }\r\n        }\r\n\r\n        // issue 195, a <clinit> or <init> but not marked as ACC_CONSTRUCTOR,\r\n        if (0 == (method_access_flags & DexConstants.ACC_CONSTRUCTOR)\r\n                && (method.getName().equals(\"<init>\") || method.getName().equals(\"<clinit>\"))) {\r\n            WARN(\"GLITCH: method %s @%08x not marked as ACC_CONSTRUCTOR\", method.toString(), offset);\r\n        }\r\n\r\n        try {\r\n            DexMethodVisitor dmv = cv.visitMethod(method_access_flags, method);\r\n            if (dmv != null) {\r\n                if ((config & SKIP_ANNOTATION) == 0) {\r\n                    Integer annotation_offset = methodAnnos.get(method_id);\r\n                    if (annotation_offset != null) {\r\n                        try {\r\n                            read_annotation_set_item(annotation_offset, dmv);\r\n                        } catch (Exception e) {\r\n                            throw new DexException(e, \"while accept annotation in method:%s.\", method.toString());\r\n                        }\r\n                    }\r\n                    Integer parameter_annotation_offset = parameterAnnos.get(method_id);\r\n                    if (parameter_annotation_offset != null) {\r\n                        try {\r\n                            read_annotation_set_ref_list(parameter_annotation_offset, dmv);\r\n                        } catch (Exception e) {\r\n                            throw new DexException(e, \"while accept parameter annotation in method:%s.\",\r\n                                    method.toString());\r\n                        }\r\n                    }\r\n                }\r\n                if (code_off != 0) {\r\n                    boolean keep = true;\r\n                    if (0 != (SKIP_CODE & config)) {\r\n                        keep = 0 != (KEEP_CLINIT & config) && method.getName().equals(\"<clinit>\");\r\n                    }\r\n                    if(keep) {\r\n                        DexCodeVisitor dcv = dmv.visitCode();\r\n                        if (dcv != null) {\r\n                            try {\r\n                                acceptCode(code_off, dcv, config, (method_access_flags & DexConstants.ACC_STATIC) != 0,\r\n                                        method);\r\n                            } catch (Exception e) {\r\n                                throw new DexException(e, \"while accept code in method:[%s] @%08x\", method.toString(),\r\n                                        code_off);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                dmv.visitEnd();\r\n            }\r\n        } catch (Exception e) {\r\n            throw new DexException(e, \"while accept method:[%s]\", method.toString());\r\n        }\r\n\r\n        return method_id;\r\n    }\r\n\r\n    private void read_annotation_set_ref_list(int parameter_annotation_offset, DexMethodVisitor dmv) {\r\n        ByteBuffer in = annotationSetRefListIn;\r\n        in.position(parameter_annotation_offset);\r\n\r\n        int size = in.getInt();\r\n        for (int j = 0; j < size; j++) {\r\n            int param_annotation_offset = in.getInt();\r\n            if (param_annotation_offset == 0) {\r\n                continue;\r\n            }\r\n            DexAnnotationAble dpav = dmv.visitParameterAnnotation(j);\r\n            try {\r\n                if (dpav != null) {\r\n                    read_annotation_set_item(param_annotation_offset, dpav);\r\n                }\r\n            } catch (Exception e) {\r\n                throw new DexException(e, \"while accept parameter annotation in parameter:[%d]\", j);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * the size of class in dex file\r\n     * \r\n     * @return class_defs_size\r\n     */\r\n    public final int getClassSize() {\r\n        return class_defs_size;\r\n    }\r\n\r\n    static class BadOpException extends RuntimeException{\r\n        public BadOpException(String fmt,Object ...args){\r\n            super(String.format(fmt,args));\r\n        }\r\n    }\r\n\r\n    private void findLabels(byte[] insns, BitSet nextBit, BitSet badOps, Map<Integer, DexLabel> labelsMap, Set<Integer> handlers,\r\n            Method method) {\r\n        Queue<Integer> q = new LinkedList<Integer>();\r\n        q.add(0);\r\n        q.addAll(handlers);\r\n        handlers.clear();\r\n        while (!q.isEmpty()) {\r\n            int offset = q.poll();\r\n            if (nextBit.get(offset)) {\r\n                continue;\r\n            } else {\r\n                nextBit.set(offset);\r\n            }\r\n            try {\r\n                travelInsn(labelsMap, q, insns, offset);\r\n            } catch (IndexOutOfBoundsException indexOutOfRange){\r\n                badOps.set(offset);\r\n                WARN(\"GLITCH: %04x %s | not enough space for reading instruction\", offset, method.toString());\r\n            } catch (BadOpException badOp){\r\n                badOps.set(offset);\r\n                WARN(\"GLITCH: %04x %s | %s\", offset, method.toString(), badOp.getMessage());\r\n            }\r\n        }\r\n    }\r\n\r\n    private void travelInsn(Map<Integer, DexLabel> labelsMap, Queue<Integer> q, byte[] insns, int offset) {\r\n        int u1offset = offset * 2;\r\n        if (u1offset >= insns.length) {\r\n            throw new IndexOutOfBoundsException();\r\n        }\r\n        int opcode = 0xFF & insns[u1offset];\r\n        Op op = null;\r\n        if (opcode < Op.ops.length) {\r\n            op = Op.ops[opcode];\r\n        }\r\n        if (op == null || op.format == null) {\r\n            throw new BadOpException(\"zero-width instruction op=0x%02x\", opcode);\r\n        }\r\n        int target;\r\n        boolean canContinue = true;\r\n        if (op.canBranch()) {\r\n            switch (op.format) {\r\n            case kFmt10t:\r\n                target = offset + insns[u1offset + 1];\r\n                if (target < 0 || target * 2 > insns.length ) {\r\n                    throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                }\r\n                q.add(target);\r\n                order(labelsMap, target);\r\n                break;\r\n            case kFmt20t:\r\n            case kFmt21t:\r\n                target = offset + sshort(insns, u1offset + 2);\r\n                if (target < 0 || target * 2 > insns.length ) {\r\n                    throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                }\r\n                q.add(target);\r\n                order(labelsMap, target);\r\n                break;\r\n            case kFmt22t:\r\n                target = offset + sshort(insns, u1offset + 2);\r\n\r\n                int u = ubyte(insns, u1offset + 1);\r\n                boolean cmpSameReg = (u & 0x0F) == ((u >> 4) & 0x0F);\r\n                boolean skipTarget = false;\r\n                if (cmpSameReg) {\r\n                    switch (op) {\r\n                    case IF_EQ:\r\n                    case IF_GE:\r\n                    case IF_LE:\r\n                        // means always jump, equals to goto\r\n                        canContinue = false;\r\n                        break;\r\n                    case IF_NE:\r\n                    case IF_GT:\r\n                    case IF_LT:\r\n                        // means always not jump\r\n                        skipTarget = true;\r\n                        break;\r\n                    default:\r\n                        break;\r\n                    }\r\n                }\r\n                if (!skipTarget) {\r\n                    if (target < 0 || target * 2 > insns.length ) {\r\n                        throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                    }\r\n                    q.add(target);\r\n                    order(labelsMap, target);\r\n                }\r\n                break;\r\n            case kFmt30t:\r\n            case kFmt31t:\r\n                target = offset + sint(insns, u1offset + 2);\r\n                if (target < 0 || target * 2 > insns.length ) {\r\n                    throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                }\r\n                q.add(target);\r\n                order(labelsMap, target);\r\n                break;\r\n            default:\r\n                break;\r\n            }\r\n        }\r\n        if (op.canSwitch()) {\r\n            order(labelsMap, offset + op.format.size);// default\r\n            int u1SwitchData = 2 * (offset + sint(insns, u1offset + 2));\r\n            if (u1SwitchData + 2 < insns.length) {\r\n\r\n                    switch (insns[u1SwitchData + 1]) {\r\n                        case 0x01: // packed-switch-data\r\n                        {\r\n                            int size = ushort(insns, u1SwitchData + 2);\r\n                            int b = u1SwitchData + 8;// targets\r\n                            for (int i = 0; i < size; i++) {\r\n                                target = offset + sint(insns, b + i * 4);\r\n                                if (target < 0 || target * 2 > insns.length ) {\r\n                                    throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                                }\r\n                                q.add(target);\r\n                                order(labelsMap, target);\r\n                            }\r\n                            break;\r\n                        }\r\n                        case 0x02:// sparse-switch-data\r\n                        {\r\n                            int size = ushort(insns, u1SwitchData + 2);\r\n                            int b = u1SwitchData + 4 + 4 * size;// targets\r\n                            for (int i = 0; i < size; i++) {\r\n                                target = offset + sint(insns, b + i * 4);\r\n                                if (target < 0 || target * 2 > insns.length ) {\r\n                                    throw new BadOpException(\"jump out of insns %s -> %04x\", op, target);\r\n                                }\r\n                                q.add(target);\r\n                                order(labelsMap, target);\r\n                            }\r\n                            break;\r\n                        }\r\n                        default:\r\n                            throw new BadOpException(\"bad payload for %s\", op);\r\n                    }\r\n            } else {\r\n                throw new BadOpException(\"bad payload offset for %s\", op);\r\n            }\r\n        }\r\n\r\n        if (canContinue) {\r\n            int idx = Integer.MAX_VALUE;\r\n            switch (op.indexType) {\r\n            case kIndexStringRef:\r\n                if (op.format == InstructionFormat.kFmt31c) {\r\n                    idx = uint(insns, u1offset + 2);\r\n                } else {// other\r\n                    idx = ushort(insns, u1offset + 2);\r\n                }\r\n                canContinue = idx >= 0 && idx < string_ids_size;\r\n                break;\r\n            case kIndexTypeRef:\r\n                idx = ushort(insns, u1offset + 2);\r\n                canContinue = idx < type_ids_size;\r\n                break;\r\n            case kIndexMethodRef:\r\n                idx = ushort(insns, u1offset + 2);\r\n                canContinue = idx < method_ids_size;\r\n                break;\r\n            case kIndexFieldRef:\r\n                idx = ushort(insns, u1offset + 2);\r\n                canContinue = idx < field_ids_size;\r\n                break;\r\n            case kIndexCallSiteRef:\r\n                idx = ushort(insns, u1offset + 2);\r\n                canContinue = idx < call_site_ids_size;\r\n                break;\r\n            case kIndexMethodAndProtoRef:\r\n                idx = ushort(insns, u1offset + 2);\r\n                int idx2 = ushort(insns, u1offset + 6);\r\n                canContinue = idx < method_ids_size && idx2 < proto_ids_size;\r\n                break;\r\n            default:\r\n            }\r\n            if (!canContinue) {\r\n                throw new BadOpException(\"index-out-of-range for %s index: %d\", op, idx);\r\n            }\r\n        }\r\n\r\n        if (canContinue && op.canContinue()) {\r\n            if (op == Op.NOP) {\r\n                switch (insns[u1offset + 1]) {\r\n                case 0x00:\r\n                    q.add(offset + op.format.size);\r\n                    break;\r\n                case 0x01: {\r\n                    int size = ushort(insns, u1offset + 2);\r\n                    q.add(offset + (size * 2) + 4);\r\n                    break;\r\n                }\r\n                case 0x02: {\r\n                    int size = ushort(insns, u1offset + 2);\r\n                    q.add(offset + (size * 4) + 2);\r\n                    break;\r\n                }\r\n                case 0x03: {\r\n                    int element_width = ushort(insns, u1offset + 2);\r\n                    int size = uint(insns, u1offset + 4);\r\n                    q.add(offset + (size * element_width + 1) / 2 + 4);\r\n                    break;\r\n                }\r\n                }\r\n            } else {\r\n                q.add(offset + op.format.size);\r\n            }\r\n        }\r\n    }\r\n\r\n    private void findTryCatch(ByteBuffer in, DexCodeVisitor dcv, int tries_size, int insn_size,\r\n            Map<Integer, DexLabel> labelsMap, Set<Integer> handlers) {\r\n        int encoded_catch_handler_list = in.position() + tries_size * 8;\r\n        ByteBuffer handlerIn = in.duplicate().order(ByteOrder.LITTLE_ENDIAN);\r\n        for (int i = 0; i < tries_size; i++) { // try_item\r\n            int start_addr = in.getInt();\r\n            int insn_count = 0xFFFF & in.getShort();\r\n            int handler_offset = 0xFFFF & in.getShort();\r\n            if (start_addr > insn_size) {\r\n                continue;\r\n            }\r\n            order(labelsMap, start_addr);\r\n            int end = start_addr + insn_count;\r\n            order(labelsMap, end);\r\n\r\n            handlerIn.position(encoded_catch_handler_list + handler_offset);// move to encoded_catch_handler\r\n\r\n            boolean catchAll = false;\r\n            int listSize = (int) readLeb128i(handlerIn);\r\n            int handlerCount = listSize;\r\n            if (listSize <= 0) {\r\n                listSize = -listSize;\r\n                handlerCount = listSize + 1;\r\n                catchAll = true;\r\n            }\r\n            DexLabel labels[] = new DexLabel[handlerCount];\r\n            String types[] = new String[handlerCount];\r\n            for (int k = 0; k < listSize; k++) {\r\n                int type_id = (int) readULeb128i(handlerIn);\r\n                int handler = (int) readULeb128i(handlerIn);\r\n                order(labelsMap, handler);\r\n                handlers.add(handler);\r\n                types[k] = getType(type_id);\r\n                labels[k] = labelsMap.get(handler);\r\n            }\r\n            if (catchAll) {\r\n                int handler = (int) readULeb128i(handlerIn);\r\n                order(labelsMap, handler);\r\n                handlers.add(handler);\r\n                labels[listSize] = labelsMap.get(handler);\r\n            }\r\n            dcv.visitTryCatch(labelsMap.get(start_addr), labelsMap.get(end), labels, types);\r\n        }\r\n    }\r\n\r\n    /* package */void acceptCode(int code_off, DexCodeVisitor dcv, int config, boolean isStatic, Method method) {\r\n        ByteBuffer in = codeItemIn;\r\n        in.position(code_off);\r\n        int registers_size = 0xFFFF & in.getShort();\r\n        in.getShort();// ins_size ushort\r\n        in.getShort();// outs_size ushort\r\n        int tries_size = 0xFFFF & in.getShort();\r\n        int debug_info_off = in.getInt();\r\n        int insns = in.getInt();\r\n\r\n        byte[] insnsArray = new byte[insns * 2];\r\n        in.get(insnsArray);\r\n        dcv.visitRegister(registers_size);\r\n        BitSet nextInsn = new BitSet();\r\n        Map<Integer, DexLabel> labelsMap = new TreeMap<Integer, DexLabel>();\r\n        Set<Integer> handlers = new HashSet<Integer>();\r\n        // 处理异常处理\r\n        if (tries_size > 0) {\r\n            if ((insns & 0x01) != 0) {// skip padding\r\n                in.getShort();\r\n            }\r\n            if (0 == (config & SKIP_EXCEPTION)) {\r\n                findTryCatch(in, dcv, tries_size, insns, labelsMap, handlers);\r\n            }\r\n        }\r\n        // 处理debug信息\r\n        if (debug_info_off != 0 && (0 == (config & SKIP_DEBUG))) {\r\n            DexDebugVisitor ddv = dcv.visitDebug();\r\n            if (ddv != null) {\r\n                read_debug_info(debug_info_off, registers_size, isStatic, method, labelsMap, ddv);\r\n                ddv.visitEnd();\r\n            }\r\n        }\r\n\r\n        BitSet badOps = new BitSet();\r\n        findLabels(insnsArray, nextInsn, badOps, labelsMap, handlers, method);\r\n        acceptInsn(insnsArray, dcv, nextInsn, badOps, labelsMap);\r\n        dcv.visitEnd();\r\n    }\r\n\r\n    // 处理指令\r\n    private void acceptInsn(byte[] insns, DexCodeVisitor dcv, BitSet nextInsn, BitSet badOps, Map<Integer, DexLabel> labelsMap) {\r\n        Iterator<Integer> labelOffsetIterator = labelsMap.keySet().iterator();\r\n        Integer nextLabelOffset = labelOffsetIterator.hasNext() ? labelOffsetIterator.next() : null;\r\n        Op[] values = Op.ops;\r\n        for (int offset = nextInsn.nextSetBit(0); offset >= 0; offset = nextInsn.nextSetBit(offset + 1)) {\r\n            // issue 65, a label may `inside` an instruction\r\n            // visit all label with offset <= currentOffset\r\n            while (nextLabelOffset != null) {\r\n                if (nextLabelOffset <= offset) {\r\n                    dcv.visitLabel(labelsMap.get(nextLabelOffset));\r\n                    nextLabelOffset = labelOffsetIterator.hasNext() ? labelOffsetIterator.next() : null;\r\n                } else {\r\n                    // the label is after this instruction\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if(badOps.get(offset)){\r\n                dcv.visitStmt0R(Op.BAD_OP);\r\n                continue;\r\n            }\r\n\r\n            int u1offset = offset * 2;\r\n            int opcode = 0xFF & insns[u1offset];\r\n\r\n            Op op = values[opcode];\r\n\r\n            int a, b, c, target;\r\n            switch (op.format) {\r\n            // case kFmt00x: break;\r\n            case kFmt10x:\r\n                dcv.visitStmt0R(op);\r\n                break;\r\n\r\n            case kFmt11x:\r\n                dcv.visitStmt1R(op, 0xFF & insns[u1offset + 1]);\r\n                break;\r\n            case kFmt12x:\r\n                a = ubyte(insns, u1offset + 1);\r\n                dcv.visitStmt2R(op, a & 0xF, a >> 4);\r\n                break;\r\n            // case kFmt20bc:break;\r\n            case kFmt10t:\r\n                target = offset + insns[u1offset + 1];\r\n                dcv.visitJumpStmt(op, -1, -1, labelsMap.get(target));\r\n                break;\r\n            case kFmt20t:\r\n                target = offset + sshort(insns, u1offset + 2);\r\n                dcv.visitJumpStmt(op, -1, -1, labelsMap.get(target));\r\n                break;\r\n            case kFmt21t:\r\n                target = offset + sshort(insns, u1offset + 2);\r\n                dcv.visitJumpStmt(op, ubyte(insns, u1offset + 1), -1, labelsMap.get(target));\r\n                break;\r\n            case kFmt22t:\r\n                target = offset + sshort(insns, u1offset + 2);\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = a & 0x0F;\r\n                c = a >> 4;\r\n                boolean ignore = false;\r\n                if (b == c) {\r\n                    switch (op) {\r\n                    case IF_EQ:\r\n                    case IF_GE:\r\n                    case IF_LE:\r\n                        // means always jump, equals to goto\r\n                        dcv.visitJumpStmt(Op.GOTO, 0, 0, labelsMap.get(target));\r\n                        ignore = true;\r\n                        break;\r\n                    case IF_NE:\r\n                    case IF_GT:\r\n                    case IF_LT:\r\n                        // means always not jump\r\n                        ignore = true;\r\n                        break;\r\n                    default:\r\n                        break;\r\n                    }\r\n                }\r\n                if (!ignore) {\r\n                    dcv.visitJumpStmt(op, b, c, labelsMap.get(target));\r\n                }\r\n                break;\r\n            case kFmt30t:\r\n                target = offset + sint(insns, u1offset + 2);\r\n                dcv.visitJumpStmt(op, -1, -1, labelsMap.get(target));\r\n                break;\r\n            case kFmt31t:\r\n                target = offset + sint(insns, u1offset + 2);\r\n                a = ubyte(insns, u1offset + 1);\r\n                int u1SwitchData = 2 * target;\r\n                if (op == Op.FILL_ARRAY_DATA) {\r\n                    int element_width = ushort(insns, u1SwitchData + 2);\r\n                    int size = uint(insns, u1SwitchData + 4);\r\n                    switch (element_width) {\r\n                    case 1: {\r\n                        byte[] data = new byte[size];\r\n                        System.arraycopy(insns, u1SwitchData + 8, data, 0, size);\r\n                        dcv.visitFillArrayDataStmt(op, a, data);\r\n                    }\r\n                        break;\r\n                    case 2: {\r\n                        short[] data = new short[size];\r\n                        for (int i = 0; i < size; i++) {\r\n                            data[i] = (short) sshort(insns, u1SwitchData + 8 + 2 * i);\r\n                        }\r\n                        dcv.visitFillArrayDataStmt(op, a, data);\r\n                    }\r\n                        break;\r\n                    case 4: {\r\n                        int[] data = new int[size];\r\n                        for (int i = 0; i < size; i++) {\r\n                            data[i] = sint(insns, u1SwitchData + 8 + 4 * i);\r\n                        }\r\n                        dcv.visitFillArrayDataStmt(op, a, data);\r\n                    }\r\n                        break;\r\n                    case 8: {\r\n                        long[] data = new long[size];\r\n                        for (int i = 0; i < size; i++) {\r\n                            int t = u1SwitchData + 8 + 8 * i;\r\n                            long z = 0;\r\n                            z |= ((long) ushort(insns, t + 0)) << 0;\r\n                            z |= ((long) ushort(insns, t + 2)) << 16;\r\n                            z |= ((long) ushort(insns, t + 4)) << 32;\r\n                            z |= ((long) ushort(insns, t + 6)) << 48;\r\n                            data[i] = z;\r\n                        }\r\n                        dcv.visitFillArrayDataStmt(op, a, data);\r\n                    }\r\n                        break;\r\n                    }\r\n                } else if (op == Op.SPARSE_SWITCH) {\r\n                    int size = sshort(insns, u1SwitchData + 2);\r\n                    int keys[] = new int[size];\r\n                    DexLabel labels[] = new DexLabel[size];\r\n                    int z = u1SwitchData + 4;\r\n                    for (int i = 0; i < size; i++) {\r\n                        keys[i] = sint(insns, z + i * 4);\r\n                    }\r\n                    z += size * 4;\r\n                    for (int i = 0; i < size; i++) {\r\n                        labels[i] = labelsMap.get(offset + sint(insns, z + i * 4));\r\n                    }\r\n                    dcv.visitSparseSwitchStmt(op, a, keys, labels);\r\n                } else {\r\n                    int size = sshort(insns, u1SwitchData + 2);\r\n                    int first_key = sint(insns, u1SwitchData + 4);\r\n                    DexLabel labels[] = new DexLabel[size];\r\n                    int z = u1SwitchData + 8;\r\n                    for (int i = 0; i < size; i++) {\r\n                        labels[i] = labelsMap.get(offset + sint(insns, z));\r\n                        z += 4;\r\n                    }\r\n                    dcv.visitPackedSwitchStmt(op, a, first_key, labels);\r\n                }\r\n                break;\r\n            case kFmt21c:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                switch (op.indexType) {\r\n                case kIndexStringRef:\r\n                    dcv.visitConstStmt(op, a, getString(b));\r\n                    break;\r\n                case kIndexFieldRef:\r\n                    dcv.visitFieldStmt(op, a, -1, getField(b));\r\n                    break;\r\n                case kIndexTypeRef:\r\n                    if (op == Op.CONST_CLASS) {\r\n                        dcv.visitConstStmt(op, a, new DexType(getType(b)));\r\n                    } else {\r\n                        dcv.visitTypeStmt(op, a, -1, getType(b));\r\n                    }\r\n                    break;\r\n                default:\r\n                    break;\r\n                }\r\n                break;\r\n            case kFmt22c:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                switch (op.indexType) {\r\n                case kIndexFieldRef:\r\n                    dcv.visitFieldStmt(op, a & 0xF, a >> 4, getField(b));\r\n                    break;\r\n                case kIndexTypeRef:\r\n                    dcv.visitTypeStmt(op, a & 0xF, a >> 4, getType(b));\r\n                    break;\r\n                default:\r\n                    break;\r\n                }\r\n                break;\r\n            case kFmt31c:\r\n                if (op.indexType == InstructionIndexType.kIndexStringRef) {\r\n                    a = ubyte(insns, u1offset + 1);\r\n                    b = uint(insns, u1offset + 2);\r\n                    dcv.visitConstStmt(op, a, getString(b));\r\n                }\r\n                break;\r\n            case kFmt35c: {\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                int dc = ubyte(insns, u1offset + 4); // DC\r\n                int fe = ubyte(insns, u1offset + 5); // FE\r\n\r\n                int regs[] = new int[a >> 4];\r\n                switch (a >> 4) {\r\n                case 5:\r\n                    regs[4] = a & 0xF;// G\r\n                case 4:\r\n                    regs[3] = 0xF & (fe >> 4);// F\r\n                case 3:\r\n                    regs[2] = 0xF & (fe >> 0);// E\r\n                case 2:\r\n                    regs[1] = 0xF & (dc >> 4);// D\r\n                case 1:\r\n                    regs[0] = 0xF & (dc >> 0);// C\r\n                }\r\n                if (op.indexType == InstructionIndexType.kIndexTypeRef) {\r\n                    dcv.visitFilledNewArrayStmt(op, regs, getType(b));\r\n                } else if (op.indexType == InstructionIndexType.kIndexCallSiteRef) {\r\n                    Object[] callsite = getCallSite(b);\r\n                    Object[] constArgs = Arrays.copyOfRange(callsite, 3, callsite.length);\r\n                    dcv.visitMethodStmt(op, regs, (String) callsite[1], (Proto) callsite[2], (MethodHandle) callsite[0], constArgs);\r\n                } else {\r\n                    dcv.visitMethodStmt(op, regs, getMethod(b));\r\n                }\r\n            }\r\n                break;\r\n            case kFmt3rc: {\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                c = ushort(insns, u1offset + 4);\r\n                int regs[] = new int[a];\r\n                for (int i = 0; i < a; i++) {\r\n                    regs[i] = c + i;\r\n                }\r\n                if (op.indexType == InstructionIndexType.kIndexTypeRef) {\r\n                    dcv.visitFilledNewArrayStmt(op, regs, getType(b));\r\n                } else if (op.indexType == InstructionIndexType.kIndexCallSiteRef) {\r\n                    Object[] callsite = getCallSite(b);\r\n                    Object[] constArgs = Arrays.copyOfRange(callsite, 3, callsite.length - 3);\r\n                    dcv.visitMethodStmt(op, regs, (String) callsite[1], (Proto) callsite[2], (MethodHandle) callsite[0], constArgs);\r\n                } else {\r\n                    dcv.visitMethodStmt(op, regs, getMethod(b));\r\n                }\r\n            }\r\n                break;\r\n            case kFmt45cc: {\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                int dc = ubyte(insns, u1offset + 4); // DC\r\n                int fe = ubyte(insns, u1offset + 5); // FE\r\n                int h = ushort(insns, u1offset + 6);\r\n\r\n                int regs[] = new int[a >> 4];\r\n                switch (a >> 4) {\r\n                case 5:\r\n                    regs[4] = a & 0xF;// G\r\n                case 4:\r\n                    regs[3] = 0xF & (fe >> 4);// F\r\n                case 3:\r\n                    regs[2] = 0xF & (fe >> 0);// E\r\n                case 2:\r\n                    regs[1] = 0xF & (dc >> 4);// D\r\n                case 1:\r\n                    regs[0] = 0xF & (dc >> 0);// C\r\n                }\r\n                dcv.visitMethodStmt(op, regs, getMethod(b), getProto(h));\r\n            }\r\n            break;\r\n            case kFmt4rcc: {\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                c = ushort(insns, u1offset + 4);\r\n                int h = ushort(insns, u1offset + 6);\r\n                int regs[] = new int[a];\r\n                for (int i = 0; i < a; i++) {\r\n                    regs[i] = c + i;\r\n                }\r\n                dcv.visitMethodStmt(op, regs, getMethod(b), getProto(h));\r\n            }\r\n            break;\r\n            case kFmt22x:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ushort(insns, u1offset + 2);\r\n                dcv.visitStmt2R(op, a, b);\r\n                break;\r\n            case kFmt23x:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ubyte(insns, u1offset + 2);\r\n                c = ubyte(insns, u1offset + 3);\r\n                dcv.visitStmt3R(op, a, b, c);\r\n                break;\r\n            case kFmt32x:\r\n                a = ushort(insns, u1offset + 2);\r\n                b = ushort(insns, u1offset + 4);\r\n                dcv.visitStmt2R(op, a, b);\r\n                break;\r\n            case kFmt11n:\r\n                a = insns[u1offset + 1];\r\n                dcv.visitConstStmt(op, a & 0xF, a >> 4);\r\n                break;\r\n            case kFmt21h:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = sshort(insns, u1offset + 2);\r\n                if (op == Op.CONST_HIGH16) {\r\n                    dcv.visitConstStmt(op, a, b << 16);\r\n                } else {\r\n                    dcv.visitConstStmt(op, a, ((long) b) << 48);\r\n                }\r\n                break;\r\n            case kFmt21s:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = sshort(insns, u1offset + 2);\r\n                if (op == Op.CONST_16) {\r\n                    dcv.visitConstStmt(op, a, b);\r\n                } else {\r\n                    dcv.visitConstStmt(op, a, (long) b);\r\n                }\r\n                break;\r\n            case kFmt22b:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = ubyte(insns, u1offset + 2);\r\n                c = sbyte(insns, u1offset + 3);\r\n                dcv.visitStmt2R1N(op, a, b, c);\r\n                break;\r\n            case kFmt22s:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = sshort(insns, u1offset + 2);\r\n                dcv.visitStmt2R1N(op, a & 0xF, a >> 4, b);\r\n                break;\r\n            // case kFmt22cs:break;\r\n            case kFmt31i:\r\n                a = ubyte(insns, u1offset + 1);\r\n                b = sint(insns, u1offset + 2);\r\n                if (op == Op.CONST) {\r\n                    dcv.visitConstStmt(op, a, b);\r\n                } else {\r\n                    dcv.visitConstStmt(op, a, (long) b);\r\n                }\r\n                break;\r\n            case kFmt51l:\r\n                a = ubyte(insns, u1offset + 1);\r\n                long z = 0;\r\n                z |= ((long) ushort(insns, u1offset + 2)) << 0;\r\n                z |= ((long) ushort(insns, u1offset + 4)) << 16;\r\n                z |= ((long) ushort(insns, u1offset + 6)) << 32;\r\n                z |= ((long) ushort(insns, u1offset + 8)) << 48;\r\n                dcv.visitConstStmt(op, a, z);\r\n                break;\r\n            }\r\n        }\r\n\r\n        while (nextLabelOffset != null) {\r\n            dcv.visitLabel(labelsMap.get(nextLabelOffset));\r\n            if (labelOffsetIterator.hasNext()) {\r\n                nextLabelOffset = labelOffsetIterator.next();\r\n            } else {\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    private Object[] getCallSite(int b) {\r\n        callSiteIdIn.position(b * 4);\r\n        int call_site_off = callSiteIdIn.getInt();\r\n\r\n        return read_encoded_array_item(call_site_off);\r\n    }\r\n\r\n    /**\r\n     * An entry in the resulting locals table\r\n     */\r\n    static private class LocalEntry {\r\n        public String name, type, signature;\r\n\r\n        private LocalEntry(String name, String type) {\r\n            this.name = name;\r\n            this.type = type;\r\n        }\r\n\r\n        private LocalEntry(String name, String type, String signature) {\r\n            this.name = name;\r\n            this.type = type;\r\n            this.signature = signature;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/reader/MultiDexFileReader.java",
    "content": "package com.googlecode.d2j.reader;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.util.zip.AccessBufByteArrayOutputStream;\nimport com.googlecode.d2j.util.zip.ZipEntry;\nimport com.googlecode.d2j.util.zip.ZipFile;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\npublic class MultiDexFileReader implements BaseDexFileReader {\n    final private List<DexFileReader> readers = new ArrayList<>();\n    final private List<Item> items = new ArrayList<>();\n\n    public MultiDexFileReader(Collection<DexFileReader> readers) {\n        this.readers.addAll(readers);\n        init();\n    }\n\n    private static byte[] toByteArray(InputStream is) throws IOException {\n        AccessBufByteArrayOutputStream out = new AccessBufByteArrayOutputStream();\n        byte[] buff = new byte[1024];\n        for (int c = is.read(buff); c > 0; c = is.read(buff)) {\n            out.write(buff, 0, c);\n        }\n        return out.getBuf();\n    }\n\n    public static BaseDexFileReader open(byte[] data) throws IOException {\n        if (data.length < 3) {\n            throw new IOException(\"File too small to be a dex/zip\");\n        }\n        if (\"dex\".equals(new String(data, 0, 3, StandardCharsets.ISO_8859_1))) {// dex\n            return new DexFileReader(data);\n        } else if (\"PK\".equals(new String(data, 0, 2, StandardCharsets.ISO_8859_1))) {// ZIP\n            TreeMap<String, DexFileReader> dexFileReaders = new TreeMap<>();\n            try (ZipFile zipFile = new ZipFile(data)) {\n                for (ZipEntry e : zipFile.entries()) {\n                    String entryName = e.getName();\n                    if (entryName.startsWith(\"classes\") && entryName.endsWith(\".dex\")) {\n                        if (!dexFileReaders.containsKey(entryName)) { // only the first one\n                            dexFileReaders.put(entryName, new DexFileReader(toByteArray(zipFile.getInputStream(e))));\n                        }\n                    }\n                }\n            }\n            if (dexFileReaders.size() == 0) {\n                throw new IOException(\"Can not find classes.dex in zip file\");\n            } else if (dexFileReaders.size() == 1) {\n                return dexFileReaders.firstEntry().getValue();\n            } else {\n                return new MultiDexFileReader(dexFileReaders.values());\n            }\n        }\n        throw new IOException(\"the src file not a .dex or zip file\");\n    }\n\n    void init() {\n        Set<String> classes = new HashSet<>();\n        for (DexFileReader reader : readers) {\n            List<String> classNames = reader.getClassNames();\n            for (int i = 0; i < classNames.size(); i++) {\n                String className = classNames.get(i);\n                if (classes.add(className)) {\n                    items.add(new Item(i, reader, className));\n                }\n            }\n        }\n    }\n\n    @Override\n    public int getDexVersion() {\n        int max = DexConstants.DEX_035;\n        for (DexFileReader r : readers) {\n            int v = r.getDexVersion();\n            if (v > max) {\n                max = v;\n            }\n        }\n        return max;\n    }\n\n    @Override\n    public void accept(DexFileVisitor dv) {\n        accept(dv, 0);\n    }\n\n    @Override\n    public List<String> getClassNames() {\n        return new AbstractList<String>() {\n            @Override\n            public String get(int index) {\n                return items.get(index).className;\n            }\n\n            @Override\n            public int size() {\n                return items.size();\n            }\n        };\n    }\n\n    @Override\n    public void accept(DexFileVisitor dv, int config) {\n        int size = items.size();\n        for (int i = 0; i < size; i++) {\n            accept(dv, i, config);\n        }\n    }\n\n    @Override\n    public void accept(DexFileVisitor dv, int classIdx, int config) {\n        Item item = items.get(classIdx);\n        item.reader.accept(dv, item.idx, config);\n    }\n\n    static class Item {\n        int idx;\n        DexFileReader reader;\n        String className;\n\n        public Item(int i, DexFileReader reader, String className) {\n            idx = i;\n            this.reader = reader;\n            this.className = className;\n        }\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/reader/zip/ZipUtil.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.d2j.reader.zip;\n\nimport com.googlecode.d2j.util.zip.AccessBufByteArrayOutputStream;\nimport com.googlecode.d2j.util.zip.ZipEntry;\nimport com.googlecode.d2j.util.zip.ZipFile;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\n/**\n * @author bob\n * \n */\npublic class ZipUtil {\n    public static byte[] toByteArray(InputStream is) throws IOException {\n        AccessBufByteArrayOutputStream out = new AccessBufByteArrayOutputStream();\n        byte[] buff = new byte[1024];\n        for (int c = is.read(buff); c > 0; c = is.read(buff)) {\n            out.write(buff, 0, c);\n        }\n        return out.getBuf();\n    }\n\n    /**\n     * read the dex file from file, if the file is a zip file, it will return the content of classes.dex in the zip\n     * file.\n     * \n     * @param file\n     * @return\n     * @throws IOException\n     */\n    public static byte[] readDex(File file) throws IOException {\n        return readDex(file.toPath());\n    }\n\n    public static byte[] readDex(Path file) throws IOException {\n        return readDex(Files.readAllBytes(file));\n    }\n\n    public static byte[] readDex(InputStream in) throws IOException {\n        return readDex(toByteArray(in));\n    }\n\n    /**\n     * read the dex file from byte array, if the byte array is a zip stream, it will return the content of classes.dex\n     * in the zip stream.\n     * \n     * @param data\n     * @return the content of classes.dex\n     * @throws IOException\n     */\n    public static byte[] readDex(byte[] data) throws IOException {\n        if (data.length < 3) {\n            throw new IOException(\"File too small to be a dex/zip\");\n        }\n        if (\"dex\".equals(new String(data, 0, 3, StandardCharsets.ISO_8859_1))) {// dex\n            return data;\n        } else if (\"PK\".equals(new String(data, 0, 2, StandardCharsets.ISO_8859_1))) {// ZIP\n            try (ZipFile zipFile = new ZipFile(data)) {\n                ZipEntry classes = zipFile.findFirstEntry(\"classes.dex\");\n                if (classes != null) {\n                    return toByteArray(zipFile.getInputStream(classes));\n                } else {\n                    throw new IOException(\"Can not find classes.dex in zip file\");\n                }\n            }\n        }\n        throw new IOException(\"the src file not a .dex or zip file\");\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/ASMifierAnnotationV.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.util;\r\n\r\nimport com.googlecode.d2j.DexConstants;\r\nimport com.googlecode.d2j.Visibility;\r\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class ASMifierAnnotationV extends DexAnnotationVisitor implements DexConstants {\r\n    ArrayOut out;\r\n    int i = 0;\r\n\r\n    public ASMifierAnnotationV(String objName, ArrayOut out, String name, Visibility visibility) {\r\n        this.out = out;\r\n        out.s(\"if(%s!=null){\", objName);\r\n        out.push();\r\n\r\n        out.s(\"DexAnnotationVisitor av%02d = %s.visitAnnotation(%s, Visibility.%s);\", i, objName, Escape.v(name),\r\n                visibility.name());\r\n        out.s(\"if(av%02d != null) {\", i);\r\n        out.push();\r\n    }\r\n\r\n    @Override\r\n    public void visit(String name, Object value) {\r\n        out.s(\"av%02d.visit(%s, %s);\", i, Escape.v(name), Escape.v(value));\r\n    }\r\n\r\n    @Override\r\n    public void visitEnum(String name, String desc, String value) {\r\n        out.s(\"av%02d.visitEnum(%s, %s, %s);\", i, Escape.v(name), Escape.v(desc), Escape.v(value));\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitAnnotation(String name, String desc) {\r\n        out.s(\"{\");\r\n        out.push();\r\n        int old = i;\r\n        int n = ++i;\r\n        out.s(\"DexAnnotationVisitor av%02d = av%02d.visitAnnotation(%s, %s);\", n, old, Escape.v(name), Escape.v(desc));\r\n        out.s(\"if(av%02d != null) {\", i);\r\n        out.push();\r\n        return this;\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitArray(String name) {\r\n        out.s(\"{\");\r\n        out.push();\r\n        int old = i;\r\n        int n = ++i;\r\n        out.s(\"DexAnnotationVisitor av%02d = av%02d.visitArray(%s);\", n, old, Escape.v(name));\r\n        out.s(\"if(av%02d != null) {\", i);\r\n        out.push();\r\n        return this;\r\n    }\r\n\r\n    @Override\r\n    public void visitEnd() {\r\n        out.s(\"av%02d.visitEnd();\", i);\r\n        i--;\r\n        out.pop();\r\n        out.s(\"}\");\r\n        out.pop();\r\n        out.s(\"}\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/ASMifierClassV.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.util;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Visibility;\r\nimport com.googlecode.d2j.visitors.DexAnnotationAble;\r\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class ASMifierClassV extends DexClassVisitor {\r\n    protected ArrayOut out = new ArrayOut();\r\n    private List<ArrayOut> methodOuts = new ArrayList<ArrayOut>();\r\n    private List<ArrayOut> fieldOuts = new ArrayList<ArrayOut>();\r\n\r\n    int fCount = 0;\r\n    int mCount = 0;\r\n\r\n    public ASMifierClassV(String pkgName, String javaClassName, int access_flags, String className, String superClass,\r\n            String[] interfaceNames) {\r\n        super();\r\n        out.s(\"package %s;\", pkgName);\r\n        out.s(\"import com.googlecode.d2j.*;\");\r\n        out.s(\"import com.googlecode.d2j.visitors.*;\");\r\n        out.s(\"import static com.googlecode.d2j.DexConstants.*;\");\r\n        out.s(\"import static com.googlecode.d2j.reader.Op.*;\");\r\n        out.s(\"public class %s {\", javaClassName);\r\n        out.push();\r\n        out.s(\"public static void accept(DexFileVisitor v) {\");\r\n        out.push();\r\n        out.s(\"DexClassVisitor cv=v.visit(%s,%s,%s,%s);\", Escape.classAcc(access_flags), Escape.v(className),\r\n                Escape.v(superClass), Escape.v(interfaceNames));\r\n        out.s(\"if(cv!=null) {\");\r\n        out.push();\r\n        out.s(\"accept(cv);\");\r\n        out.s(\"cv.visitEnd();\");\r\n        out.pop();\r\n        out.s(\"}\");\r\n        out.pop();\r\n        out.s(\"}\");\r\n        out.s(\"public static void accept(DexClassVisitor cv) {\");\r\n        out.push();\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n        return new ASMifierAnnotationV(\"cv\", out, name, visibility);\r\n    }\r\n\r\n    @Override\r\n    public void visitSource(String file) {\r\n        out.s(\"cv.visitSource(\\\"%s\\\");\", Utf8Utils.escapeString(file));\r\n    }\r\n\r\n    @Override\r\n    public DexFieldVisitor visitField(int accessFlags, Field field, Object value) {\r\n        String fieldName = String.format(\"f%03d_%s\", fCount++, field.getName());\r\n        out.s(\"%s(cv);\", fieldName);\r\n\r\n        final ArrayOut f = new ArrayOut();\r\n        fieldOuts.add(f);\r\n        f.s(\"public static void %s(DexClassVisitor cv) {\", fieldName);\r\n        f.push();\r\n        f.s(\"DexFieldVisitor fv=cv.visitField(%s, %s, %s);\", Escape.fieldAcc(accessFlags), Escape.v(field),\r\n                Escape.v(value));\r\n        f.s(\"if(fv != null) {\");\r\n        f.push();\r\n        return new DexFieldVisitor() {\r\n\r\n            @Override\r\n            public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n                return new ASMifierAnnotationV(\"fv\", f, name, visibility);\r\n            }\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                f.s(\"fv.visitEnd();\");\r\n                f.pop();\r\n                f.s(\"}\");\r\n                f.pop();\r\n                f.s(\"}\");\r\n            }\r\n        };\r\n    }\r\n\r\n    @Override\r\n    public DexMethodVisitor visitMethod(int accessFlags, Method method) {\r\n        String methodName = String.format(\"m%03d_%s\", mCount++, method.getName().replace('<', '_').replace('>', '_'));\r\n        out.s(\"%s(cv);\", methodName);\r\n\r\n        final ArrayOut m = new ArrayOut();\r\n        methodOuts.add(m);\r\n        m.s(\"public static void %s(DexClassVisitor cv) {\", methodName);\r\n        m.push();\r\n        m.s(\"DexMethodVisitor mv=cv.visitMethod(%s, %s);\", Escape.methodAcc(accessFlags), Escape.v(method));\r\n        m.s(\"if(mv != null) {\");\r\n        m.push();\r\n\r\n        return new DexMethodVisitor() {\r\n\r\n            @Override\r\n            public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n                return new ASMifierAnnotationV(\"mv\", m, name, visibility);\r\n            }\r\n\r\n            @Override\r\n            public DexAnnotationAble visitParameterAnnotation(final int index) {\r\n                m.s(\"DexAnnotationAble pv%02d = mv.visitParameterAnnotation(%s);\", index, index);\r\n                return new DexAnnotationAble() {\r\n\r\n                    @Override\r\n                    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n                        return new ASMifierAnnotationV(String.format(\"pv%02d\", index), m, name, visibility);\r\n                    }\r\n                };\r\n            }\r\n\r\n            @Override\r\n            public DexCodeVisitor visitCode() {\r\n                m.s(\"DexCodeVisitor code=mv.visitCode();\");\r\n                m.s(\"if(code != null) {\");\r\n                m.push();\r\n                return new ASMifierCodeV(m) {\r\n\r\n                    @Override\r\n                    public void visitEnd() {\r\n                        super.visitEnd();\r\n\r\n                        m.pop();\r\n                        m.s(\"}\");\r\n                    }\r\n                };\r\n            }\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                m.s(\"mv.visitEnd();\");\r\n                m.pop();\r\n                m.s(\"}\");\r\n                m.pop();\r\n                m.s(\"}\");\r\n            }\r\n\r\n        };\r\n    }\r\n\r\n    @Override\r\n    public void visitEnd() {\r\n        out.pop();\r\n        out.s(\"}\");\r\n        for (ArrayOut o : fieldOuts) {\r\n            out.array.addAll(o.array);\r\n            for (int i : o.is) {\r\n                out.is.add(out.i + i);\r\n            }\r\n        }\r\n        fieldOuts = null;\r\n        for (ArrayOut o : methodOuts) {\r\n            out.array.addAll(o.array);\r\n            for (int i : o.is) {\r\n                out.is.add(out.i + i);\r\n            }\r\n        }\r\n        methodOuts = null;\r\n        out.pop();\r\n        out.s(\"}\");\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/ASMifierCodeV.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.util;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\nimport com.googlecode.d2j.*;\r\nimport com.googlecode.d2j.reader.Op;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class ASMifierCodeV extends DexCodeVisitor implements DexConstants {\r\n    Out m;\r\n    Map<DexLabel, String> labelMap = new HashMap<>();\r\n\r\n    public ASMifierCodeV(Out m) {\r\n        this.m = m;\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R1N(Op op, int distReg, int srcReg, int content) {\r\n        m.s(\"code.visitStmt2R1N(%s,%s,%s,%s);\", op(op), distReg, srcReg, content);\r\n    }\r\n\r\n    @Override\r\n    public void visitRegister(int total) {\r\n        m.s(\"code.visitRegister(%s);\", total);\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt3R(Op op, int a, int b, int c) {\r\n        m.s(\"code.visitStmt3R(%s,%s,%s,%s);\", op(op), a, b, c);\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R(Op op, int a, int b) {\r\n        m.s(\"code.visitStmt2R(%s,%s,%s);\", op(op), a, b);\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt0R(Op op) {\r\n        m.s(\"code.visitStmt0R(%s);\", op(op));\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt1R(Op op, int reg) {\r\n        m.s(\"code.visitStmt1R(%s,%s);\", op(op), reg);\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitTypeStmt(Op op, int a, int b, String type) {\r\n        m.s(\"code.visitTypeStmt(%s,%s,%s,%s);\", op(op), a, b, Escape.v(type));\r\n    }\r\n\r\n    @Override\r\n    public void visitConstStmt(Op op, int toReg, Object value) {\r\n        if (value instanceof Integer) {\r\n            m.s(\"code.visitConstStmt(%s,%s,%s); // int: 0x%08x  float:%f\", op(op), toReg, Escape.v(value), value,\r\n                    Float.intBitsToFloat((Integer) value));\r\n        } else if (value instanceof Long) {\r\n            m.s(\"code.visitConstStmt(%s,%s,%s); // long: 0x%016x  double:%f\", op(op), toReg, Escape.v(value), value,\r\n                    Double.longBitsToDouble((Long) value));\r\n        } else {\r\n            m.s(\"code.visitConstStmt(%s,%s,%s);\", op(op), toReg, Escape.v(value));\r\n        }\r\n\r\n    }\r\n\r\n    @Override\r\n    public void visitFieldStmt(Op op, int fromOrToReg, int objReg, Field field) {\r\n        m.s(\"code.visitFieldStmt(%s,%s,%s,%s);\", op(op), fromOrToReg, objReg, Escape.v(field));\r\n    }\r\n\r\n    @Override\r\n    public void visitFilledNewArrayStmt(Op op, int[] args, String type) {\r\n        m.s(\"code.visitFilledNewArrayStmt(%s,%s,%s);\", op(op), Escape.v(args), Escape.v(type));\r\n    }\r\n\r\n    int i = 0;\r\n\r\n    public String v(DexLabel[] labels) {\r\n        StringBuilder sb = new StringBuilder(\"new DexLabel[]{\");\r\n        boolean first = true;\r\n        for (DexLabel dexLabel : labels) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(\",\");\r\n            }\r\n            sb.append(v(dexLabel));\r\n        }\r\n        return sb.append(\"}\").toString();\r\n    }\r\n\r\n    private Object v(DexLabel l) {\r\n        String name = labelMap.get(l);\r\n        if (name == null) {\r\n            name = \"L\" + i++;\r\n            m.s(\"DexLabel %s=new DexLabel();\", name);\r\n            labelMap.put(l, name);\r\n        }\r\n        return name;\r\n    }\r\n\r\n    String op(Op op) {\r\n        return op.name();\r\n    }\r\n\r\n    @Override\r\n    public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\r\n        m.s(\"code.visitJumpStmt(%s,%s,%s,%s);\", op(op), a, b, v(label));\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) {\r\n        m.s(\"code.visitMethodStmt(%s,%s,%s,%s,%s,%s);\", op(op), Escape.v(args), Escape.v(name), Escape.v(proto), Escape.v(bsm), Escape.v(bsmArgs));\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, Method bsm, Proto proto) {\r\n        m.s(\"code.visitMethodStmt(%s,%s,%s,%s);\", op(op), Escape.v(args), Escape.v(bsm), Escape.v(proto));\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, Method method) {\r\n        m.s(\"code.visitMethodStmt(%s,%s,%s);\", op(op), Escape.v(args), Escape.v(method));\r\n    }\r\n\r\n    @Override\r\n    public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {\r\n        m.s(\"code.visitSparseSwitchStmt(%s,%s,%s,%s);\", op(op), ra, Escape.v(cases), v(labels));\r\n    }\r\n\r\n    @Override\r\n    public void visitPackedSwitchStmt(Op op, int ra, int first_case, DexLabel[] labels) {\r\n        m.s(\"code.visitSparseSwitchStmt(%s,%s,%s,%s);\", op(op), ra, first_case, v(labels));\r\n    }\r\n\r\n    @Override\r\n    public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handlers, String[] types) {\r\n        m.s(\"code.visitTryCatch(%s,%s,%s,%s);\", v(start), v(end), v(handlers), Escape.v(types));\r\n    }\r\n\r\n    @Override\r\n    public void visitEnd() {\r\n        m.s(\"code.visitEnd();\");\r\n    }\r\n\r\n    @Override\r\n    public void visitLabel(DexLabel label) {\r\n        m.s(\"code.visitLabel(%s);\", v(label));\r\n    }\r\n\r\n    @Override\r\n    public void visitFillArrayDataStmt(Op op, int ra, Object array) {\r\n        // FIXME\r\n        super.visitFillArrayDataStmt(op, ra, array);\r\n    }\r\n\r\n    @Override\r\n    public DexDebugVisitor visitDebug() {\r\n        m.s(\"DexDebugVisitor ddv=new DexDebugVisitor(code.visitDebug());\");\r\n        return new DexDebugVisitor() {\r\n            @Override\r\n            public void visitParameterName(int reg, String name) {\r\n                m.s(\"ddv.visitParameterName(%d,%s);\", reg, Escape.v(name));\r\n            }\r\n\r\n            @Override\r\n            public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) {\r\n                m.s(\"ddv.visitStartLocal(%d,%s,%s,%s,%s);\", reg, v(label), Escape.v(name), Escape.v(type),\r\n                        Escape.v(signature));\r\n            }\r\n\r\n            @Override\r\n            public void visitLineNumber(int line, DexLabel label) {\r\n                m.s(\"ddv.visitLineNumber(%d,%s);\", line, v(label));\r\n            }\r\n\r\n            @Override\r\n            public void visitPrologue(DexLabel dexLabel) {\r\n                m.s(\"ddv.visitPrologue(%s);\", v(dexLabel));\r\n            }\r\n\r\n            @Override\r\n            public void visitEpiogue(DexLabel dexLabel) {\r\n                m.s(\"ddv.visitEpiogue(%s);\", v(dexLabel));\r\n            }\r\n\r\n            @Override\r\n            public void visitEndLocal(int reg, DexLabel label) {\r\n                m.s(\"ddv.visitEndLocal(%d,%s);\", reg, v(label));\r\n            }\r\n\r\n            @Override\r\n            public void visitSetFile(String file) {\r\n                m.s(\"ddv.visitSetFile(%s);\", Escape.v(file));\r\n            }\r\n\r\n            @Override\r\n            public void visitRestartLocal(int reg, DexLabel label) {\r\n                m.s(\"ddv.visitRestartLocal(%d,%s);\", reg, v(label));\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/ASMifierFileV.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.util;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.googlecode.d2j.reader.DexFileReader;\r\nimport com.googlecode.d2j.reader.zip.ZipUtil;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexFileVisitor;\r\n\r\n/**\r\n * similar with org.objectweb.asm.util.ASMifierClassVisitor\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n */\r\npublic class ASMifierFileV extends DexFileVisitor {\r\n\r\n    String pkgName = \"dex2jar.gen\";\r\n    Path dir;\r\n    ArrayOut file = new ArrayOut();\r\n    int i = 0;\r\n\r\n    public static void doData(byte[] data, Path destdir) throws IOException {\r\n        new DexFileReader(data).accept(new ASMifierFileV(destdir, null));\r\n    }\r\n\r\n    public static void doFile(Path srcDex) throws IOException {\r\n        String distName = srcDex.getFileName() + \"_asmifier\";\r\n        doFile(srcDex, srcDex.resolveSibling(distName));\r\n    }\r\n\r\n    public static void doFile(Path srcDex, Path dest) throws IOException {\r\n        doData(ZipUtil.readDex(srcDex), dest);\r\n    }\r\n\r\n    public static void main(String... args) throws IOException {\r\n        if (args.length < 1) {\r\n            System.out.println(\"ASMifier 1.dex 2.dex ... n.dex\");\r\n            return;\r\n        }\r\n        for (String s : args) {\r\n            System.out.println(\"asmifier \" + s);\r\n            doFile(new File(s).toPath());\r\n        }\r\n    }\r\n\r\n    public ASMifierFileV(Path dir, String pkgName) {\r\n        super();\r\n        if (dir == null) {\r\n            this.dir = new File(\".\").toPath();\r\n        } else {\r\n            this.dir = dir;\r\n        }\r\n        if (pkgName != null) {\r\n            this.pkgName = pkgName;\r\n        }\r\n        file.s(\"package %s;\", this.pkgName);\r\n        file.s(\"import com.googlecode.d2j.*;\");\r\n        file.s(\"import com.googlecode.dj2.visitors.*;\");\r\n        file.s(\"public class Main {\");\r\n        file.push();\r\n        file.s(\"public static void accept(DexFileVisitor v) {\");\r\n        file.push();\r\n\r\n    }\r\n\r\n    static void write(ArrayOut out, Path file) {\r\n        StringBuilder sb = new StringBuilder();\r\n        List<String> list = new ArrayList<String>(out.array.size());\r\n        for (int i = 0; i < out.array.size(); i++) {\r\n            sb.setLength(0);\r\n            int p = out.is.get(i);\r\n            for (int j = 0; j < p; j++) {\r\n                sb.append(\"    \");\r\n            }\r\n            sb.append(out.array.get(i));\r\n            list.add(sb.toString());\r\n        }\r\n        try {\r\n            Path parent = file.getParent();\r\n            if (parent != null && !Files.exists(parent)) {\r\n                Files.createDirectories(parent);\r\n            }\r\n            Files.write(file, list, StandardCharsets.UTF_8);\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\r\n        final String n = String.format(\"C%04d_\", i++)\r\n                + className.substring(1, className.length() - 1).replace('/', '_').replace('$', '_');\r\n        file.s(\"%s.accept(v);\", n);\r\n        return new ASMifierClassV(pkgName, n, access_flags, className, superClass, interfaceNames) {\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                super.visitEnd();\r\n                write(out, dir.resolve(pkgName.replace('.', '/') + '/' + n + \".java\"));\r\n            }\r\n\r\n        };\r\n    }\r\n\r\n    @Override\r\n    public void visitEnd() {\r\n        file.pop();\r\n        file.s(\"}\");\r\n        file.pop();\r\n        file.s(\"}\");\r\n        write(file, dir.resolve(pkgName.replace('.', '/') + \"/Main.java\"));\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/ArrayOut.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.util;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * @version $Rev$\n */\npublic class ArrayOut implements Out {\n\n    int i = 0;\n\n    public List<String> array = new ArrayList<String>();\n    public List<Integer> is = new ArrayList<Integer>();\n\n    @Override\n    public void push() {\n        i++;\n    }\n\n    @Override\n    public void s(String s) {\n        is.add(i);\n        array.add(s);\n    }\n\n    @Override\n    public void s(String format, Object... arg) {\n        s(String.format(format, arg));\n    }\n\n    @Override\n    public void pop() {\n        i--;\n    }\n\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/Escape.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.util;\r\n\r\nimport com.googlecode.d2j.*;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Escape implements DexConstants {\r\n\r\n    static boolean contain(int a, int b) {\r\n        return (a & b) != 0;\r\n    }\r\n\r\n    public static String classAcc(int acc) {\r\n        if (acc == 0) {\r\n            return \"0\";\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        if (contain(acc, ACC_PUBLIC)) {\r\n            sb.append(\"ACC_PUBLIC|\");\r\n        }\r\n        if (contain(acc, ACC_PRIVATE)) {\r\n            sb.append(\"ACC_PRIVATE|\");\r\n        }\r\n        if (contain(acc, ACC_PROTECTED)) {\r\n            sb.append(\"ACC_PROTECTED|\");\r\n        }\r\n        if (contain(acc, ACC_STATIC)) {\r\n            sb.append(\"ACC_STATIC|\");\r\n        }\r\n        if (contain(acc, ACC_FINAL)) {\r\n            sb.append(\"ACC_FINAL|\");\r\n        }\r\n        if (contain(acc, ACC_INTERFACE)) {\r\n            sb.append(\"ACC_INTERFACE|\");\r\n        }\r\n        if (contain(acc, ACC_ABSTRACT)) {\r\n            sb.append(\"ACC_ABSTRACT|\");\r\n        }\r\n        if (contain(acc, ACC_SYNTHETIC)) {\r\n            sb.append(\"ACC_SYNTHETIC|\");\r\n        }\r\n        if (contain(acc, ACC_ANNOTATION)) {\r\n            sb.append(\"ACC_ANNOTATION|\");\r\n        }\r\n        if (contain(acc, ACC_ENUM)) {\r\n            sb.append(\"ACC_ENUM|\");\r\n        }\r\n        if (sb.length() > 0) {\r\n            sb.setLength(sb.length() - 1);\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public static String methodAcc(int acc) {\r\n        if (acc == 0) {\r\n            return \"0\";\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        if (contain(acc, ACC_PUBLIC)) {\r\n            sb.append(\"ACC_PUBLIC|\");\r\n        }\r\n        if (contain(acc, ACC_PRIVATE)) {\r\n            sb.append(\"ACC_PRIVATE|\");\r\n        }\r\n        if (contain(acc, ACC_PROTECTED)) {\r\n            sb.append(\"ACC_PROTECTED|\");\r\n        }\r\n        if (contain(acc, ACC_STATIC)) {\r\n            sb.append(\"ACC_STATIC|\");\r\n        }\r\n        if (contain(acc, ACC_FINAL)) {\r\n            sb.append(\"ACC_FINAL|\");\r\n        }\r\n        if (contain(acc, ACC_BRIDGE)) {\r\n            sb.append(\"ACC_BRIDGE|\");\r\n        }\r\n        if (contain(acc, ACC_VARARGS)) {\r\n            sb.append(\"ACC_VARARGS|\");\r\n        }\r\n        if (contain(acc, ACC_NATIVE)) {\r\n            sb.append(\"ACC_NATIVE|\");\r\n        }\r\n        if (contain(acc, ACC_ABSTRACT)) {\r\n            sb.append(\"ACC_ABSTRACT|\");\r\n        }\r\n        if (contain(acc, ACC_STRICT)) {\r\n            sb.append(\"ACC_STRICT|\");\r\n        }\r\n        if (contain(acc, ACC_SYNTHETIC)) {\r\n            sb.append(\"ACC_SYNTHETIC|\");\r\n        }\r\n        if (contain(acc, ACC_CONSTRUCTOR)) {\r\n            sb.append(\"ACC_CONSTRUCTOR|\");\r\n        }\r\n        if (sb.length() > 0) {\r\n            sb.setLength(sb.length() - 1);\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public static String fieldAcc(int acc) {\r\n        if (acc == 0) {\r\n            return \"0\";\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        if (contain(acc, ACC_PUBLIC)) {\r\n            sb.append(\"ACC_PUBLIC|\");\r\n        }\r\n        if (contain(acc, ACC_PRIVATE)) {\r\n            sb.append(\"ACC_PRIVATE|\");\r\n        }\r\n        if (contain(acc, ACC_PROTECTED)) {\r\n            sb.append(\"ACC_PROTECTED|\");\r\n        }\r\n        if (contain(acc, ACC_STATIC)) {\r\n            sb.append(\"ACC_STATIC|\");\r\n        }\r\n        if (contain(acc, ACC_FINAL)) {\r\n            sb.append(\"ACC_FINAL|\");\r\n        }\r\n        if (contain(acc, ACC_VOLATILE)) {\r\n            sb.append(\"ACC_VOLATILE|\");\r\n        }\r\n        if (contain(acc, ACC_TRANSIENT)) {\r\n            sb.append(\"ACC_TRANSIENT|\");\r\n        }\r\n\r\n        if (contain(acc, ACC_SYNTHETIC)) {\r\n            sb.append(\"ACC_SYNTHETIC|\");\r\n        }\r\n        if (contain(acc, ACC_ENUM)) {\r\n            sb.append(\"ACC_ENUM|\");\r\n        }\r\n        if (sb.length() > 0) {\r\n            sb.setLength(sb.length() - 1);\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public static String v(Field f) {\r\n        return String.format(\"new Field(%s,%s,%s)\", v(f.getOwner()), v(f.getName()), v(f.getType()));\r\n    }\r\n\r\n    public static String v(Method m) {\r\n        return String.format(\"new Method(%s,%s,%s,%s)\", v(m.getOwner()), v(m.getName()), v(m.getParameterTypes()),\r\n                v(m.getReturnType()));\r\n    }\r\n    public static String v(Proto m) {\r\n        return String.format(\"new Proto(%s,%s)\", v(m.getParameterTypes()), v(m.getReturnType()));\r\n    }\r\n\r\n    public static String v(MethodHandle m) {\r\n        switch (m.getType()) {\r\n        case MethodHandle.INSTANCE_GET:\r\n            return String.format(\"new MethodHandle(MethodHandle.INSTANCE_GET,%s)\", v(m.getField()));\r\n        case MethodHandle.INSTANCE_PUT:\r\n            return String.format(\"new MethodHandle(MethodHandle.INSTANCE_PUT,%s)\", v(m.getField()));\r\n        case MethodHandle.STATIC_GET:\r\n            return String.format(\"new MethodHandle(MethodHandle.STATIC_GET,%s)\", v(m.getField()));\r\n        case MethodHandle.STATIC_PUT:\r\n            return String.format(\"new MethodHandle(MethodHandle.STATIC_PUT,%s)\", v(m.getField()));\r\n\r\n        case MethodHandle.INVOKE_INSTANCE:\r\n            return String.format(\"new MethodHandle(MethodHandle.INVOKE_INSTANCE,%s)\", v(m.getMethod()));\r\n        case MethodHandle.INVOKE_STATIC:\r\n            return String.format(\"new MethodHandle(MethodHandle.INVOKE_STATIC,%s)\", v(m.getMethod()));\r\n        case MethodHandle.INVOKE_CONSTRUCTOR:\r\n            return String.format(\"new MethodHandle(MethodHandle.INVOKE_CONSTRUCTOR,%s)\", v(m.getMethod()));\r\n        case MethodHandle.INVOKE_DIRECT:\r\n            return String.format(\"new MethodHandle(MethodHandle.INVOKE_DIRECT,%s)\", v(m.getMethod()));\r\n        case MethodHandle.INVOKE_INTERFACE:\r\n            return String.format(\"new MethodHandle(MethodHandle.INVOKE_INTERFACE,%s)\", v(m.getMethod()));\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    public static String v(String s) {\r\n        if (s == null) {\r\n            return \"null\";\r\n        }\r\n        return \"\\\"\" + Utf8Utils.escapeString(s) + \"\\\"\";\r\n    }\r\n\r\n    public static String v(DexType t) {\r\n        return \"new DexType(\" + v(t.desc) + \")\";\r\n\r\n    }\r\n\r\n    public static String v(int[] vs) {\r\n        StringBuilder sb = new StringBuilder(\"new int[]{ \");\r\n        boolean first = true;\r\n        for (int obj : vs) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(\",\");\r\n            }\r\n            sb.append(obj);\r\n        }\r\n        return sb.append(\"}\").toString();\r\n    }\r\n\r\n    public static String v(byte[] vs) {\r\n        StringBuilder sb = new StringBuilder(\"new byte[]{ \");\r\n        boolean first = true;\r\n        for (byte obj : vs) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(\",\");\r\n            }\r\n            sb.append(\"(byte)\").append(obj);\r\n        }\r\n        return sb.append(\"}\").toString();\r\n    }\r\n\r\n    public static String v(String[] vs) {\r\n        if (vs == null) {\r\n            return \"null\";\r\n        }\r\n        StringBuilder sb = new StringBuilder(\"new String[]{ \");\r\n        boolean first = true;\r\n        for (String obj : vs) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(\",\");\r\n            }\r\n            sb.append(v(obj));\r\n        }\r\n        return sb.append(\"}\").toString();\r\n    }\r\n\r\n    public static String v(Object[] vs) {\r\n        StringBuilder sb = new StringBuilder(\"new Object[]{ \");\r\n        boolean first = true;\r\n        for (Object obj : vs) {\r\n            if (first) {\r\n                first = false;\r\n            } else {\r\n                sb.append(\",\");\r\n            }\r\n            sb.append(v(obj));\r\n        }\r\n        return sb.append(\"}\").toString();\r\n    }\r\n\r\n    public static String v(Object obj) {\r\n        if (obj == null) {\r\n            return \"null\";\r\n        }\r\n        if (obj instanceof String) {\r\n            return v((String) obj);\r\n        }\r\n\r\n        if (obj instanceof DexType) {\r\n            return v((DexType) obj);\r\n        }\r\n\r\n        if (obj instanceof Method) {\r\n            return v((Method) obj);\r\n        }\r\n        if (obj instanceof Field) {\r\n            return v((Field) obj);\r\n        }\r\n        if (obj instanceof Proto) {\r\n            return v((Proto) obj);\r\n        }\r\n        if (obj instanceof MethodHandle) {\r\n            return v((MethodHandle) obj);\r\n        }\r\n\r\n        if (obj instanceof Integer) {\r\n            return \" Integer.valueOf(\" + obj + \")\";\r\n        }\r\n        if (obj instanceof Long) {\r\n            return \"Long.valueOf(\" + obj + \"L)\";\r\n        }\r\n        if (obj instanceof Float) {\r\n            return \"Float.valueOf(\" + obj + \"F)\";\r\n        }\r\n        if (obj instanceof Double) {\r\n            return \"Double.valueOf(\" + obj + \"D)\";\r\n        }\r\n        if (obj instanceof Short) {\r\n            return \"Short.valueOf((short)\" + obj + \")\";\r\n        }\r\n        if (obj instanceof Byte) {\r\n            return \"Byte.valueOf((byte)\" + obj + \")\";\r\n        }\r\n        if (obj instanceof Character) {\r\n            return \"Character.valueOf('\" + obj + \"')\";\r\n        }\r\n        if (obj instanceof Boolean) {\r\n            return \"Boolean.valueOf(\" + obj + \")\";\r\n        }\r\n        if (obj instanceof int[]) {\r\n            StringBuilder sb = new StringBuilder(\"new int[]{ \");\r\n            boolean first = true;\r\n            for (int i : (int[]) obj) {\r\n                if (first) {\r\n                    first = false;\r\n                } else {\r\n                    sb.append(\",\");\r\n                }\r\n                sb.append(i);\r\n            }\r\n            return sb.append(\"}\").toString();\r\n        }\r\n        if (obj instanceof short[]) {\r\n            StringBuilder sb = new StringBuilder(\"new short[]{ \");\r\n            boolean first = true;\r\n            for (int i : (short[]) obj) {\r\n                if (first) {\r\n                    first = false;\r\n                } else {\r\n                    sb.append(\",\");\r\n                }\r\n                sb.append(\"(short)\").append(i);\r\n            }\r\n            return sb.append(\"}\").toString();\r\n        }\r\n        if (obj instanceof long[]) {\r\n            StringBuilder sb = new StringBuilder(\"new long[]{ \");\r\n            boolean first = true;\r\n            for (long i : (long[]) obj) {\r\n                if (first) {\r\n                    first = false;\r\n                } else {\r\n                    sb.append(\",\");\r\n                }\r\n                sb.append(i).append(\"L\");\r\n            }\r\n            return sb.append(\"}\").toString();\r\n        }\r\n        if (obj instanceof float[]) {\r\n            StringBuilder sb = new StringBuilder(\"new float[]{ \");\r\n            boolean first = true;\r\n            for (float i : (float[]) obj) {\r\n                if (first) {\r\n                    first = false;\r\n                } else {\r\n                    sb.append(\",\");\r\n                }\r\n                sb.append(i).append(\"F\");\r\n            }\r\n            return sb.append(\"}\").toString();\r\n        }\r\n        return null;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.d2j.util;\n\nimport java.io.UTFDataFormatException;\nimport java.nio.ByteBuffer;\n\n/**\n * Modified UTF-8 as described in the dex file format spec.\n * \n * <p>\n * Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.\n */\npublic final class Mutf8 {\n    private Mutf8() {\n    }\n\n    /**\n     * Decodes bytes from {@code in} into {@code sb} until a delimiter 0x00 is encountered. Returns a new string\n     * containing the decoded characters.\n     */\n    public static String decode(ByteBuffer in, StringBuilder sb) throws UTFDataFormatException {\n        while (true) {\n            char a = (char) (in.get() & 0xff);\n            if (a == 0) {\n                return sb.toString();\n            }\n\n            if (a < '\\u0080') {\n                sb.append(a);\n            } else if ((a & 0xe0) == 0xc0) {\n                int b = in.get() & 0xff;\n                if ((b & 0xC0) != 0x80) {\n                    throw new UTFDataFormatException(\"bad second byte\");\n                }\n                sb.append((char) (((a & 0x1F) << 6) | (b & 0x3F)));\n            } else if ((a & 0xf0) == 0xe0) {\n                int b = in.get() & 0xff;\n                int c = in.get() & 0xff;\n                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {\n                    throw new UTFDataFormatException(\"bad second or third byte\");\n                }\n                sb.append((char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)));\n            } else {\n                throw new UTFDataFormatException(\"bad byte\");\n            }\n        }\n    }\n\n    /**\n     * Returns the number of bytes the modified UTF8 representation of 's' would take.\n     */\n    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {\n        long result = 0;\n        final int length = s.length();\n        for (int i = 0; i < length; ++i) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                ++result;\n            } else if (ch <= 2047) {\n                result += 2;\n            } else {\n                result += 3;\n            }\n            if (shortLength && result > 65535) {\n                throw new UTFDataFormatException(\"String more than 65535 UTF bytes long\");\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code dst}, starting at {@code offset}.\n     */\n    public static void encode(byte[] dst, int offset, String s) {\n        final int length = s.length();\n        for (int i = 0; i < length; i++) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                dst[offset++] = (byte) ch;\n            } else if (ch <= 2047) {\n                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            } else {\n                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));\n                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            }\n        }\n    }\n\n    /**\n     * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.\n     */\n    public static byte[] encode(String s) throws UTFDataFormatException {\n        int utfCount = (int) countBytes(s, true);\n        byte[] result = new byte[utfCount];\n        encode(result, 0, s);\n        return result;\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/Out.java",
    "content": "package com.googlecode.d2j.util;\n\npublic interface Out {\n    void push();\n\n    void s(String s);\n\n    void s(String format, Object... arg);\n\n    void pop();\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/Utf8Utils.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF 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 * As per the Apache license requirements, this file has been modified\n * from its original state.\n *\n * Such modifications are Copyright (C) 2010 Ben Gruver, and are released\n * under the original license\n */\n\npackage com.googlecode.d2j.util;\n\nimport java.io.IOException;\nimport java.io.Writer;\n\n/**\n * Constants of type <code>CONSTANT_Utf8_info</code>.\n */\npublic final class Utf8Utils {\n\n    /**\n     * Converts a string into its Java-style UTF-8 form. Java-style UTF-8 differs from normal UTF-8 in the handling of\n     * character '\\0' and surrogate pairs.\n     * \n     * @param string\n     *            non-null; the string to convert\n     * @return non-null; the UTF-8 bytes for it\n     */\n    public static byte[] stringToUtf8Bytes(String string) {\n        int len = string.length();\n        byte[] bytes = new byte[len * 3]; // Avoid having to reallocate.\n        int outAt = 0;\n\n        for (int i = 0; i < len; i++) {\n            char c = string.charAt(i);\n            if ((c != 0) && (c < 0x80)) {\n                bytes[outAt] = (byte) c;\n                outAt++;\n            } else if (c < 0x800) {\n                bytes[outAt] = (byte) (((c >> 6) & 0x1f) | 0xc0);\n                bytes[outAt + 1] = (byte) ((c & 0x3f) | 0x80);\n                outAt += 2;\n            } else {\n                bytes[outAt] = (byte) (((c >> 12) & 0x0f) | 0xe0);\n                bytes[outAt + 1] = (byte) (((c >> 6) & 0x3f) | 0x80);\n                bytes[outAt + 2] = (byte) ((c & 0x3f) | 0x80);\n                outAt += 3;\n            }\n        }\n\n        byte[] result = new byte[outAt];\n        System.arraycopy(bytes, 0, result, 0, outAt);\n        return result;\n    }\n\n    private static char[] tempBuffer = null;\n\n    /**\n     * Converts an array of UTF-8 bytes into a string.\n     * \n     * This method uses a global buffer to avoid having to allocate one every time, so it is *not* thread-safe\n     * \n     * @param bytes\n     *            non-null; the bytes to convert\n     * @param start\n     *            the start index of the utf8 string to convert\n     * @param length\n     *            the length of the utf8 string to convert, not including any null-terminator that might be present\n     * @return non-null; the converted string\n     */\n    public static String utf8BytesToString(byte[] bytes, int start, int length) {\n        if (tempBuffer == null || tempBuffer.length < length) {\n            tempBuffer = new char[length];\n        }\n        char[] chars = tempBuffer;\n        int outAt = 0;\n\n        for (int at = start; length > 0; /* at */) {\n            int v0 = bytes[at] & 0xFF;\n            char out;\n            switch (v0 >> 4) {\n            case 0x00:\n            case 0x01:\n            case 0x02:\n            case 0x03:\n            case 0x04:\n            case 0x05:\n            case 0x06:\n            case 0x07: {\n                // 0XXXXXXX -- single-byte encoding\n                length--;\n                if (v0 == 0) {\n                    // A single zero byte is illegal.\n                    return throwBadUtf8(v0, at);\n                }\n                out = (char) v0;\n                at++;\n                break;\n            }\n            case 0x0c:\n            case 0x0d: {\n                // 110XXXXX -- two-byte encoding\n                length -= 2;\n                if (length < 0) {\n                    return throwBadUtf8(v0, at);\n                }\n                int v1 = bytes[at + 1] & 0xFF;\n                if ((v1 & 0xc0) != 0x80) {\n                    return throwBadUtf8(v1, at + 1);\n                }\n                int value = ((v0 & 0x1f) << 6) | (v1 & 0x3f);\n                if ((value != 0) && (value < 0x80)) {\n                    /*\n                     * This should have been represented with one-byte encoding.\n                     */\n                    return throwBadUtf8(v1, at + 1);\n                }\n                out = (char) value;\n                at += 2;\n                break;\n            }\n            case 0x0e: {\n                // 1110XXXX -- three-byte encoding\n                length -= 3;\n                if (length < 0) {\n                    return throwBadUtf8(v0, at);\n                }\n                int v1 = bytes[at + 1] & 0xFF;\n                if ((v1 & 0xc0) != 0x80) {\n                    return throwBadUtf8(v1, at + 1);\n                }\n                int v2 = bytes[at + 2] & 0xFF;\n                if ((v1 & 0xc0) != 0x80) {\n                    return throwBadUtf8(v2, at + 2);\n                }\n                int value = ((v0 & 0x0f) << 12) | ((v1 & 0x3f) << 6) | (v2 & 0x3f);\n                if (value < 0x800) {\n                    /*\n                     * This should have been represented with one- or two-byte encoding.\n                     */\n                    return throwBadUtf8(v2, at + 2);\n                }\n                out = (char) value;\n                at += 3;\n                break;\n            }\n            default: {\n                // 10XXXXXX, 1111XXXX -- illegal\n                return throwBadUtf8(v0, at);\n            }\n            }\n            chars[outAt] = out;\n            outAt++;\n        }\n\n        return new String(chars, 0, outAt);\n    }\n\n    /**\n     * Helper for {@link #utf8BytesToString}, which throws the right exception for a bogus utf-8 byte.\n     * \n     * @param value\n     *            the byte value\n     * @param offset\n     *            the file offset\n     * @return never\n     * @throws IllegalArgumentException\n     *             always thrown\n     */\n    private static String throwBadUtf8(int value, int offset) {\n        throw new IllegalArgumentException(\"bad utf-8 byte \" + String.format(\"%02x\", value) + \" at offset \"\n                + String.format(\"%08x\", offset));\n    }\n\n    public static void writeEscapedChar(Writer writer, char c) throws IOException {\n        if ((c >= ' ') && (c < 0x7f)) {\n            if ((c == '\\'') || (c == '\\\"') || (c == '\\\\')) {\n                writer.write('\\\\');\n            }\n            writer.write(c);\n            return;\n        } else if (c <= 0x7f) {\n            switch (c) {\n            case '\\n':\n                writer.write(\"\\\\n\");\n                return;\n            case '\\r':\n                writer.write(\"\\\\r\");\n                return;\n            case '\\t':\n                writer.write(\"\\\\t\");\n                return;\n            }\n        }\n\n        writer.write(\"\\\\u\");\n        writer.write(Character.forDigit(c >> 12, 16));\n        writer.write(Character.forDigit((c >> 8) & 0x0f, 16));\n        writer.write(Character.forDigit((c >> 4) & 0x0f, 16));\n        writer.write(Character.forDigit(c & 0x0f, 16));\n\n    }\n\n    public static void writeEscapedString(Writer writer, String value) throws IOException {\n        for (int i = 0; i < value.length(); i++) {\n            char c = value.charAt(i);\n\n            if ((c >= ' ') && (c < 0x7f)) {\n                if ((c == '\\'') || (c == '\\\"') || (c == '\\\\')) {\n                    writer.write('\\\\');\n                }\n                writer.write(c);\n                continue;\n            } else if (c <= 0x7f) {\n                switch (c) {\n                case '\\n':\n                    writer.write(\"\\\\n\");\n                    continue;\n                case '\\r':\n                    writer.write(\"\\\\r\");\n                    continue;\n                case '\\t':\n                    writer.write(\"\\\\t\");\n                    continue;\n                }\n            }\n\n            writer.write(\"\\\\u\");\n            writer.write(Character.forDigit(c >> 12, 16));\n            writer.write(Character.forDigit((c >> 8) & 0x0f, 16));\n            writer.write(Character.forDigit((c >> 4) & 0x0f, 16));\n            writer.write(Character.forDigit(c & 0x0f, 16));\n        }\n    }\n\n    public static String escapeString(String value) {\n        int len = value.length();\n        StringBuilder sb = new StringBuilder(len * 3 / 2);\n\n        for (int i = 0; i < len; i++) {\n            char c = value.charAt(i);\n\n            if ((c >= ' ') && (c < 0x7f)) {\n                if ((c == '\\'') || (c == '\\\"') || (c == '\\\\')) {\n                    sb.append('\\\\');\n                }\n                sb.append(c);\n                continue;\n            } else if (c <= 0x7f) {\n                switch (c) {\n                case '\\n':\n                    sb.append(\"\\\\n\");\n                    continue;\n                case '\\r':\n                    sb.append(\"\\\\r\");\n                    continue;\n                case '\\t':\n                    sb.append(\"\\\\t\");\n                    continue;\n                }\n            }\n\n            sb.append(\"\\\\u\");\n            sb.append(Character.forDigit(c >> 12, 16));\n            sb.append(Character.forDigit((c >> 8) & 0x0f, 16));\n            sb.append(Character.forDigit((c >> 4) & 0x0f, 16));\n            sb.append(Character.forDigit(c & 0x0f, 16));\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/zip/AccessBufByteArrayOutputStream.java",
    "content": "package com.googlecode.d2j.util.zip;\n\nimport java.io.ByteArrayOutputStream;\n\npublic class AccessBufByteArrayOutputStream extends ByteArrayOutputStream {\n    public byte[] getBuf() {\n        return buf;\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/zip/AutoSTOREDZipOutputStream.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.util.zip;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.zip.*;\nimport java.util.zip.ZipEntry;\n\n/**\n * Auto calc size/crc for STORED\n */\npublic class AutoSTOREDZipOutputStream extends ZipOutputStream {\n    public AutoSTOREDZipOutputStream(OutputStream out) {\n        super(out);\n    }\n\n    private CRC32 crc = new CRC32();\n    private ZipEntry delayedEntry;\n    private AccessBufByteArrayOutputStream delayedOutputStream;\n\n    @Override\n    public void putNextEntry(ZipEntry e) throws IOException {\n        if (e.getMethod() != ZipEntry.STORED) {\n            super.putNextEntry(e);\n        } else {\n            delayedEntry = e;\n            if (delayedOutputStream == null) {\n                delayedOutputStream = new AccessBufByteArrayOutputStream();\n            }\n        }\n    }\n\n    @Override\n    public void closeEntry() throws IOException {\n        ZipEntry delayedEntry = this.delayedEntry;\n        if (delayedEntry != null) {\n            AccessBufByteArrayOutputStream delayedOutputStream = this.delayedOutputStream;\n            byte[] buf = delayedOutputStream.getBuf();\n            int size = delayedOutputStream.size();\n            delayedEntry.setSize(size);\n            delayedEntry.setCompressedSize(size);\n            crc.reset();\n            crc.update(buf, 0, size);\n            delayedEntry.setCrc(crc.getValue());\n            super.putNextEntry(delayedEntry);\n            super.write(buf, 0, size);\n            this.delayedEntry = null;\n            delayedOutputStream.reset();\n        }\n        super.closeEntry();\n    }\n\n    @Override\n    public synchronized void write(byte[] b, int off, int len) throws IOException {\n        if (delayedEntry != null) {\n            delayedOutputStream.write(b, off, len);\n        } else {\n            super.write(b, off, len);\n        }\n    }\n\n    @Override\n    public void write(int b) throws IOException {\n        if (delayedEntry != null) {\n            delayedOutputStream.write(b);\n        } else {\n            super.write(b);\n        }\n    }\n\n    @Override\n    public void write(byte[] b) throws IOException {\n        if (delayedEntry != null) {\n            delayedOutputStream.write(b);\n        } else {\n            super.write(b);\n        }\n    }\n\n    @Override\n    public void close() throws IOException {\n        delayedOutputStream = null;\n        super.close();\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipConstants.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.util.zip;\n\n/**\n * Do not add constants to this interface! It's implemented by the classes in this package whose names start \"Zip\", and\n * the constants are thereby public API.\n */\ninterface ZipConstants {\n\n    public static final long LOCSIG = 0x4034b50, EXTSIG = 0x8074b50, CENSIG = 0x2014b50, ENDSIG = 0x6054b50;\n\n    public static final int LOCHDR = 30, EXTHDR = 16, CENHDR = 46, ENDHDR = 22, LOCVER = 4, LOCFLG = 6, LOCHOW = 8,\n            LOCTIM = 10, LOCCRC = 14, LOCSIZ = 18, LOCLEN = 22, LOCNAM = 26, LOCEXT = 28, EXTCRC = 4, EXTSIZ = 8,\n            EXTLEN = 12, CENVEM = 4, CENVER = 6, CENFLG = 8, CENHOW = 10, CENTIM = 12, CENCRC = 16, CENSIZ = 20,\n            CENLEN = 24, CENNAM = 28, CENEXT = 30, CENCOM = 32, CENDSK = 34, CENATT = 36, CENATX = 38, CENOFF = 42,\n            ENDSUB = 8, ENDTOT = 10, ENDSIZ = 12, ENDOFF = 16, ENDCOM = 20;\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipEntry.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.util.zip;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Calendar;\nimport java.util.GregorianCalendar;\n\n/**\n * An entry within a zip file. An entry has attributes such as its name (which is actually a path) and the uncompressed\n * size of the corresponding data. An entry does not contain the data itself, but can be used as a key with\n * {@link java.util.zip.ZipFile#getInputStream}. The class documentation for {@link java.util.zip.ZipInputStream} and\n * {@link java.util.zip.ZipOutputStream} shows how {@code android.ZipEntry} is used in conjunction with those two\n * classes.\n */\npublic final class ZipEntry implements ZipConstants, Cloneable {\n    String name;\n    String comment;\n\n    long crc = -1; // Needs to be a long to distinguish -1 (\"not set\") from the 0xffffffff CRC32.\n\n    long compressedSize = -1;\n    long size = -1;\n\n    int compressionMethod = -1;\n    int time = -1;\n    int modDate = -1;\n\n    byte[] extra;\n\n    int nameLength = -1;\n    long localHeaderRelOffset = -1;\n\n    /**\n     * Zip entry state: Deflated.\n     */\n    public static final int DEFLATED = 8;\n\n    /**\n     * Zip entry state: Stored.\n     */\n    public static final int STORED = 0;\n\n    /**\n     * Returns the comment for this {@code android.ZipEntry}, or {@code null} if there is no comment. If we're reading a\n     * zip file using {@code ZipInputStream}, the comment is not available.\n     */\n    public String getComment() {\n        return comment;\n    }\n\n    /**\n     * Gets the compressed size of this {@code android.ZipEntry}.\n     * \n     * @return the compressed size, or -1 if the compressed size has not been set.\n     */\n    public long getCompressedSize() {\n        return compressedSize;\n    }\n\n    /**\n     * Gets the checksum for this {@code android.ZipEntry}.\n     * \n     * @return the checksum, or -1 if the checksum has not been set.\n     */\n    public long getCrc() {\n        return crc;\n    }\n\n    /**\n     * Gets the extra information for this {@code android.ZipEntry}.\n     * \n     * @return a byte array containing the extra information, or {@code null} if there is none.\n     */\n    public byte[] getExtra() {\n        return extra;\n    }\n\n    /**\n     * Gets the compression method for this {@code android.ZipEntry}.\n     * \n     * @return the compression method, either {@code DEFLATED}, {@code STORED} or -1 if the compression method has not\n     *         been set.\n     */\n    public int getMethod() {\n        return compressionMethod;\n    }\n\n    /**\n     * Gets the name of this {@code android.ZipEntry}.\n     * \n     * @return the entry name.\n     */\n    public String getName() {\n        return name;\n    }\n\n    /**\n     * Gets the uncompressed size of this {@code android.ZipEntry}.\n     * \n     * @return the uncompressed size, or {@code -1} if the size has not been set.\n     */\n    public long getSize() {\n        return size;\n    }\n\n    /**\n     * Gets the last modification time of this {@code android.ZipEntry}.\n     * \n     * @return the last modification time as the number of milliseconds since Jan. 1, 1970.\n     */\n    public long getTime() {\n        if (time != -1) {\n            GregorianCalendar cal = new GregorianCalendar();\n            cal.set(Calendar.MILLISECOND, 0);\n            cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1, modDate & 0x1f, (time >> 11) & 0x1f,\n                    (time >> 5) & 0x3f, (time & 0x1f) << 1);\n            return cal.getTime().getTime();\n        }\n        return -1;\n    }\n\n    /**\n     * Determine whether or not this {@code android.ZipEntry} is a directory.\n     * \n     * @return {@code true} when this {@code android.ZipEntry} is a directory, {@code false} otherwise.\n     */\n    public boolean isDirectory() {\n        return name.charAt(name.length() - 1) == '/';\n    }\n\n    /**\n     * Returns the string representation of this {@code android.ZipEntry}.\n     * \n     * @return the string representation of this {@code android.ZipEntry}.\n     */\n    @Override\n    public String toString() {\n        return name;\n    }\n\n    /**\n     * Returns a deep copy of this zip entry.\n     */\n    @Override\n    public Object clone() {\n        try {\n            ZipEntry result = (ZipEntry) super.clone();\n            result.extra = extra != null ? extra.clone() : null;\n            return result;\n        } catch (CloneNotSupportedException e) {\n            throw new AssertionError(e);\n        }\n    }\n\n    ZipEntry(ByteBuffer it0, boolean skipCommentsAndExtra) throws IOException {\n        ByteBuffer it = (ByteBuffer) it0.slice().order(ByteOrder.LITTLE_ENDIAN).limit(CENHDR);\n        ZipFile.skip(it0, CENHDR);\n        int sig = it.getInt();\n        if (sig != CENSIG) {\n            ZipFile.throwZipException(\"Central Directory Entry\", sig);\n        }\n\n        it.position(8);\n        int gpbf = it.getShort() & 0xffff;\n\n        compressionMethod = it.getShort() & 0xffff;\n        time = it.getShort() & 0xffff;\n        modDate = it.getShort() & 0xffff;\n\n        // These are 32-bit values in the file, but 64-bit fields in this object.\n        crc = ((long) it.getInt()) & 0xffffffffL;\n        compressedSize = ((long) it.getInt()) & 0xffffffffL;\n        size = ((long) it.getInt()) & 0xffffffffL;\n\n        nameLength = it.getShort() & 0xffff;\n        int extraLength = it.getShort() & 0xffff;\n        int commentByteCount = it.getShort() & 0xffff;\n\n        // This is a 32-bit value in the file, but a 64-bit field in this object.\n        it.position(42);\n        localHeaderRelOffset = ((long) it.getInt()) & 0xffffffffL;\n\n        byte[] nameBytes = new byte[nameLength];\n        it0.get(nameBytes);\n        // if (containsNulByte(nameBytes)) {\n        // throw new ZipException(\"Filename contains NUL byte: \" + Arrays.toString(nameBytes));\n        // }\n        name = new String(nameBytes, 0, nameBytes.length, StandardCharsets.UTF_8);\n\n        if (extraLength > 0) {\n            if (skipCommentsAndExtra) {\n                ZipFile.skip(it0, extraLength);\n            } else {\n                extra = new byte[extraLength];\n                it.get(extra);\n            }\n        }\n\n        // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is\n        // actually IBM-437.)\n        if (commentByteCount > 0) {\n            if (skipCommentsAndExtra) {\n                ZipFile.skip(it0, commentByteCount);\n            } else {\n                byte[] commentBytes = new byte[commentByteCount];\n                it0.get(commentBytes);\n                comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);\n            }\n        }\n    }\n\n    private static boolean containsNulByte(byte[] bytes) {\n        for (byte b : bytes) {\n            if (b == 0) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java",
    "content": "/**\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.util.zip;\n\nimport java.io.*;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.channels.FileChannel;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.zip.Inflater;\nimport java.util.zip.InflaterInputStream;\nimport java.util.zip.ZipException;\n\n/**\n * This is code is get from Android 4.4.2 intent to read as more zip as possible\n * \n * Ignore GPBF_ENCRYPTED_FLAG\n * \n * Allow duplicate ZipEntry\n * \n * Allow Nul byte in ZipEntry name\n * \n */\npublic class ZipFile implements AutoCloseable, ZipConstants {\n    /**\n     * General Purpose Bit Flags, Bit 0. If set, indicates that the file is encrypted.\n     */\n    static final int GPBF_ENCRYPTED_FLAG = 1 << 0;\n\n    /**\n     * General Purpose Bit Flags, Bit 3. If this bit is set, the fields crc-32, compressed size and uncompressed size\n     * are set to zero in the local header. The correct values are put in the data descriptor immediately following the\n     * compressed data. (Note: PKZIP version 2.04g for DOS only recognizes this bit for method 8 compression, newer\n     * versions of PKZIP recognize this bit for any compression method.)\n     */\n    static final int GPBF_DATA_DESCRIPTOR_FLAG = 1 << 3;\n\n    /**\n     * General Purpose Bit Flags, Bit 11. Language encoding flag (EFS). If this bit is set, the filename and comment\n     * fields for this file must be encoded using UTF-8.\n     */\n    static final int GPBF_UTF8_FLAG = 1 << 11;\n\n    /**\n     * Supported General Purpose Bit Flags Mask. Bit mask of bits not supported. Note: The only bit that we will enforce\n     * at this time is the encrypted bit. Although other bits are not supported, we must not enforce them as this could\n     * break some legitimate use cases (See http://b/8617715).\n     */\n    static final int GPBF_UNSUPPORTED_MASK = GPBF_ENCRYPTED_FLAG;\n\n    private List<ZipEntry> entries;\n\n    private String comment;\n    final ByteBuffer raf;\n    RandomAccessFile file;\n\n    public ZipFile(ByteBuffer in) throws IOException {\n        raf = in.asReadOnlyBuffer().order(ByteOrder.LITTLE_ENDIAN);\n        readCentralDir();\n    }\n\n    public ZipFile(File fd) throws IOException {\n        RandomAccessFile randomAccessFile = new RandomAccessFile(fd, \"r\");\n        file = randomAccessFile;\n        raf = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fd.length());\n        readCentralDir();\n    }\n\n    public ZipFile(byte[] data) throws IOException {\n        this(ByteBuffer.wrap(data));\n    }\n\n    public List<? extends ZipEntry> entries() {\n        return entries;\n    }\n\n    /**\n     * Returns this file's comment, or null if it doesn't have one. See {@link java.util.zip.ZipOutputStream#setComment}\n     * .\n     * \n     * @throws IllegalStateException\n     *             if this zip file has been closed.\n     * @since 1.7\n     */\n    public String getComment() {\n        return comment;\n    }\n\n    public ZipEntry findFirstEntry(String entryName) {\n        if (entryName == null) {\n            throw new NullPointerException(\"entryName == null\");\n        }\n\n        ZipEntry ze = findFirstEntry0(entryName);\n        if (ze == null) {\n            ze = findFirstEntry0(entryName + \"/\");\n        }\n        return ze;\n    }\n\n    private ZipEntry findFirstEntry0(String entryName) {\n        for (ZipEntry e : entries) {\n            if (e.getName().equals(entryName)) {\n                return e;\n            }\n        }\n        return null;\n    }\n\n    public long getEntryDataStart(ZipEntry entry) {\n        int fileNameLength = raf.getShort((int) (entry.localHeaderRelOffset + 26)) & 0xffff;\n        int extraFieldLength = raf.getShort((int) (entry.localHeaderRelOffset + 28)) & 0xffff;\n        return entry.localHeaderRelOffset + 30 + fileNameLength + extraFieldLength;\n    }\n\n    /**\n     * Returns an input stream on the data of the specified {@code android.ZipEntry}.\n     * \n     * @param entry\n     *            the android.ZipEntry.\n     * @return an input stream of the data contained in the {@code android.ZipEntry}.\n     * @throws java.io.IOException\n     *             if an {@code IOException} occurs.\n     * @throws IllegalStateException\n     *             if this zip file has been closed.\n     */\n    public InputStream getInputStream(ZipEntry entry) throws IOException {\n        long entryDataStart = getEntryDataStart(entry);\n        ByteBuffer is = (ByteBuffer) raf.duplicate().position((int) entryDataStart);\n\n        if (entry.compressionMethod == ZipEntry.STORED) {\n            final ByteBuffer buf = (ByteBuffer) is.slice().order(ByteOrder.LITTLE_ENDIAN).limit((int) entry.size);\n            return new ByteBufferBackedInputStream(buf);\n        } else {\n            final ByteBuffer buf = (ByteBuffer) is.slice().order(ByteOrder.LITTLE_ENDIAN)\n                    .limit((int) entry.compressedSize);\n            int bufSize = Math.max(1024, (int) Math.min(entry.getSize(), 65535L));\n            return new ZipInflaterInputStream(new ByteBufferBackedInputStream(buf), new Inflater(true), bufSize, entry);\n        }\n    }\n\n    static void skip(ByteBuffer is, int i) {\n        is.position(is.position() + i);\n    }\n\n    /**\n     * Returns the number of {@code ZipEntries} in this {@code android.ZipFile}.\n     * \n     * @return the number of entries in this file.\n     * @throws IllegalStateException\n     *             if this zip file has been closed.\n     */\n    public int size() {\n        return entries.size();\n    }\n\n    /**\n     * Find the central directory and read the contents.\n     * \n     * <p>\n     * The central directory can be followed by a variable-length comment field, so we have to scan through it\n     * backwards. The comment is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff itself, plus\n     * apparently sometimes people throw random junk on the end just for the fun of it.\n     * \n     * <p>\n     * This is all a little wobbly. If the wrong value ends up in the EOCD area, we're hosed. This appears to be the way\n     * that everybody handles it though, so we're in good company if this fails.\n     */\n    private void readCentralDir() throws IOException {\n        ByteBuffer raf = this.raf;\n        // Scan back, looking for the End Of Central Directory field. If the zip file doesn't\n        // have an overall comment (unrelated to any per-entry comments), we'll hit the EOCD\n        // on the first try.\n        // No need to synchronize raf here -- we only do this when we first open the zip file.\n        long scanOffset = raf.limit() - ENDHDR;\n        if (scanOffset < 0) {\n            throw new ZipException(\"File too short to be a zip file: \" + raf.limit());\n        }\n\n        // not check Magic\n        // raf.position(0);\n        // final int headerMagic = raf.getInt();\n        // if (headerMagic != LOCSIG) {\n        // throw new ZipException(\"Not a zip archive\");\n        // }\n\n        long stopOffset = scanOffset - 65536;\n        if (stopOffset < 0) {\n            stopOffset = 0;\n        }\n\n        while (true) {\n            raf.position((int) scanOffset);\n            if (raf.getInt() == ENDSIG) {\n                break;\n            }\n\n            scanOffset--;\n            if (scanOffset < stopOffset) {\n                throw new ZipException(\"End Of Central Directory signature not found\");\n            }\n        }\n\n        // Read the End Of Central Directory. ENDHDR includes the signature bytes,\n        // which we've already read.\n\n        // Pull out the information we need.\n        int diskNumber = raf.getShort() & 0xffff;\n        int diskWithCentralDir = raf.getShort() & 0xffff;\n        int numEntries = raf.getShort() & 0xffff;\n        int totalNumEntries = raf.getShort() & 0xffff;\n        skip(raf, 4); // Ignore centralDirSize.\n        long centralDirOffset = ((long) raf.getInt()) & 0xffffffffL;\n        int commentLength = raf.getShort() & 0xffff;\n\n        if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {\n            throw new ZipException(\"Spanned archives not supported\");\n        }\n        boolean skipCommentsAndExtra = true;\n\n        if (commentLength > 0) {\n            if (commentLength > raf.remaining()) {\n                System.err.println(\"WARN: the zip comment exceed the zip content\");\n            } else {\n                if (skipCommentsAndExtra) {\n                    skip(raf, commentLength);\n                } else {\n                    byte[] commentBytes = new byte[commentLength];\n                    raf.get(commentBytes);\n                    comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);\n                }\n            }\n        }\n\n        // Seek to the first CDE and read all entries.\n        // We have to do this now (from the constructor) rather than lazily because the\n        // public API doesn't allow us to throw IOException except from the constructor\n        // or from getInputStream.\n        ByteBuffer buf = (ByteBuffer) raf.duplicate().order(ByteOrder.LITTLE_ENDIAN).position((int) centralDirOffset);\n        entries = new ArrayList<>(numEntries);\n        for (int i = 0; i < numEntries; ++i) {\n            ZipEntry newEntry = new ZipEntry(buf, skipCommentsAndExtra);\n            if (newEntry.localHeaderRelOffset >= centralDirOffset) {\n                // Ignore the entry\n                // throw new ZipException(\"Local file header offset is after central directory\");\n            } else {\n                entries.add(newEntry);\n            }\n        }\n    }\n\n    static void throwZipException(String msg, int magic) throws ZipException {\n        final String hexString = String.format(\"0x%08x\", magic);\n        throw new ZipException(msg + \" signature not found; was \" + hexString);\n    }\n\n    @Override\n    public void close() throws IOException {\n        if(file!=null){\n            file.close();\n        }\n    }\n\n    static class ZipInflaterInputStream extends InflaterInputStream {\n        private final ZipEntry entry;\n        private long bytesRead = 0;\n\n        public ZipInflaterInputStream(InputStream is, Inflater inf, int bsize, ZipEntry entry) {\n            super(is, inf, bsize);\n            this.entry = entry;\n        }\n\n        @Override\n        public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {\n            final int i;\n            try {\n                i = super.read(buffer, byteOffset, byteCount);\n            } catch (IOException e) {\n                throw new IOException(\"Error reading data for \" + entry.getName() + \" near offset \" + bytesRead, e);\n            }\n            if (i == -1) {\n                if (entry.size != bytesRead) {\n                    throw new IOException(\"Size mismatch on inflated file: \" + bytesRead + \" vs \" + entry.size);\n                }\n            } else {\n                bytesRead += i;\n            }\n            return i;\n        }\n\n        @Override\n        public int available() throws IOException {\n            return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead);\n        }\n    }\n\n    private static class ByteBufferBackedInputStream extends InputStream {\n        private final ByteBuffer buf;\n\n        public ByteBufferBackedInputStream(ByteBuffer buf) {\n            this.buf = buf;\n        }\n\n        @Override\n        public int read() throws IOException {\n            if (!buf.hasRemaining()) {\n                return -1;\n            }\n            return buf.get() & 0xFF;\n        }\n\n        @Override\n        public int read(byte[] b, int off, int len) throws IOException {\n            if (!buf.hasRemaining()) {\n                return -1;\n            }\n            len = Math.min(len, buf.remaining());\n            buf.get(b, off, len);\n            return len;\n        }\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/test/java/com/googlecode/d2j/reader/test/AsmfierTest.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.d2j.reader.test;\n\nimport java.io.File;\n\nimport org.junit.Test;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.util.ASMifierFileV;\nimport com.googlecode.d2j.visitors.DexAnnotationAble;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\n/**\n * @author bob\n * \n */\npublic class AsmfierTest implements DexConstants {\n    @Test\n    public void test() {\n        ASMifierFileV fv = new ASMifierFileV(new File(\"target/asmftest\").toPath(), \"a.b\");\n        DexClassVisitor cv = fv.visit(ACC_PUBLIC, \"La/f;\", \"Ljava/lang/Object;\", null);\n        DexFieldVisitor f2v = cv.visitField(ACC_PUBLIC, new Field(\"La/f;\", \"abc\", \"I\"), null);\n        f2v.visitEnd();\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La/f;\", \"zz\", new String[0], \"I\"));\n\n        DexAnnotationAble pv = mv.visitParameterAnnotation(2);\n        DexAnnotationVisitor dav = pv.visitAnnotation(\"Leeeff;\", Visibility.BUILD);\n        dav.visitEnd();\n        DexCodeVisitor dcv = mv.visitCode();\n        dcv.visitConstStmt(Op.FILL_ARRAY_DATA, 0, new int[] { 1, 2, 3 });\n        dcv.visitStmt0R(Op.RETURN_VOID);\n        dcv.visitEnd();\n        mv.visitEnd();\n        cv.visitEnd();\n        fv.visitEnd();\n    }\n}\n"
  },
  {
    "path": "dex-reader/src/test/java/com/googlecode/d2j/reader/test/BadZipEntryFlagTest.java",
    "content": "package com.googlecode.d2j.reader.test;\n\nimport java.io.IOException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.d2j.util.zip.ZipFile;\nimport org.apache.commons.compress.archivers.zip.ZipArchiveEntry;\nimport org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;\nimport org.junit.Test;\n\n/**\n * Test case for issue 169\n * \n * @author bob\n * \n */\npublic class BadZipEntryFlagTest {\n    @Test\n    public void test1() throws IOException {\n        ZipArchiveInputStream zis = new ZipArchiveInputStream(BadZipEntryFlagTest.class.getResourceAsStream(\"/bad.zip\"));\n        for (ZipArchiveEntry e = zis.getNextZipEntry(); e != null; e = zis.getNextZipEntry()) {\n            e.getGeneralPurposeBit().useEncryption(false);\n            if (!e.isDirectory()) {\n                zis.read();\n                System.out.println(e.getName());\n            }\n        }\n    }\n\n    @Test\n    public void test0() throws IOException {\n        byte[] data = ZipUtil.toByteArray(BadZipEntryFlagTest.class.getResourceAsStream(\"/bad.zip\"));\n        try (ZipFile zip = new ZipFile(data)) {\n            for (com.googlecode.d2j.util.zip.ZipEntry e : zip.entries()) {\n                System.out.println(e);\n                if (!e.isDirectory()) {\n                    zip.getInputStream(e).read();\n                }\n            }\n        }\n    }\n\n    // @Ignore(\"the way to build bad zip\")\n    // @Test\n    // public void test2() throws IOException {\n    // ArchiveOutputStream zis = new ZipArchiveOutputStreamHack(new\n    // FileOutputStream(\"src/test/resources/bad.zip\"));\n    // ZipArchiveEntry entry = new ZipArchiveEntry(\"test.txt\");\n    // zis.putArchiveEntry(entry);\n    // zis.write(\"Test!\".getBytes(\"UTF-8\"));\n    // zis.closeArchiveEntry();\n    // zis.close();\n    // }\n\n}\n"
  },
  {
    "path": "dex-reader/src/test/java/com/googlecode/d2j/reader/test/SkipDupMethod.java",
    "content": "package com.googlecode.d2j.reader.test;\n\n\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\npublic class SkipDupMethod {\n    @Test\n    public void test() throws IOException {\n        InputStream is = SkipDupMethod.class.getClassLoader().getResourceAsStream(\"i200.dex\");\n        Assert.assertNotNull(is);\n        DexFileReader reader = new DexFileReader(is);\n        DexFileNode dfn1 = new DexFileNode();\n        reader.accept(dfn1, DexFileReader.KEEP_ALL_METHODS);\n        DexFileNode dfn2 = new DexFileNode();\n        reader.accept(dfn2, 0);\n        Assert.assertTrue(dfn1.clzs.get(0).methods.size() > dfn2.clzs.get(0).methods.size());\n\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/build.gradle",
    "content": "description = 'Dex Reader API'\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/DexConstants.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j;\r\n\r\n/**\r\n * constants in dex file\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic abstract interface DexConstants {\r\n\r\n    int ACC_PUBLIC = 0x0001; // class, field, method\r\n    int ACC_PRIVATE = 0x0002; // class, field, method\r\n    int ACC_PROTECTED = 0x0004; // class, field, method\r\n    int ACC_STATIC = 0x0008; // field, method\r\n    int ACC_FINAL = 0x0010; // class, field, method\r\n    // int ACC_SUPER = 0x0020; // class\r\n    int ACC_SYNCHRONIZED = 0x0020; // method\r\n    int ACC_VOLATILE = 0x0040; // field\r\n    int ACC_BRIDGE = 0x0040; // method\r\n    int ACC_VARARGS = 0x0080; // method\r\n    int ACC_TRANSIENT = 0x0080; // field\r\n    int ACC_NATIVE = 0x0100; // method\r\n    int ACC_INTERFACE = 0x0200; // class\r\n    int ACC_ABSTRACT = 0x0400; // class, method\r\n    int ACC_STRICT = 0x0800; // method\r\n    int ACC_SYNTHETIC = 0x1000; // class, field, method\r\n    int ACC_ANNOTATION = 0x2000; // class\r\n    int ACC_ENUM = 0x4000; // class(?) field inner\r\n    int ACC_CONSTRUCTOR = 0x10000;// constructor method (class or instance initializer)\r\n    int ACC_DECLARED_SYNCHRONIZED = 0x20000;\r\n\r\n    String ANNOTATION_DEFAULT_TYPE = \"Ldalvik/annotation/AnnotationDefault;\";\r\n    String ANNOTATION_SIGNATURE_TYPE = \"Ldalvik/annotation/Signature;\";\r\n    String ANNOTATION_THROWS_TYPE = \"Ldalvik/annotation/Throws;\";\r\n    String ANNOTATION_ENCLOSING_CLASS_TYPE = \"Ldalvik/annotation/EnclosingClass;\";\r\n    String ANNOTATION_ENCLOSING_METHOD_TYPE = \"Ldalvik/annotation/EnclosingMethod;\";\r\n    String ANNOTATION_INNER_CLASS_TYPE = \"Ldalvik/annotation/InnerClass;\";\r\n    String ANNOTATION_MEMBER_CLASSES_TYPE = \"Ldalvik/annotation/MemberClasses;\";\r\n\r\n    int DEX_035 = 0x00303335;\r\n    int DEX_036 = 0x00303336;\r\n    int DEX_037 = 0x00303337;\r\n    int DEX_038 = 0x00303338;\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/DexException.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j;\n\n/**\n * \n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * @version $Rev$\n */\npublic class DexException extends RuntimeException {\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    /**\n     * \n     */\n    public DexException() {\n    }\n\n    /**\n     * @param message\n     */\n    public DexException(String message) {\n        super(message);\n    }\n\n    /**\n     * @param cause\n     */\n    public DexException(Throwable cause) {\n        super(cause);\n    }\n\n    /**\n     * @param message\n     * @param cause\n     */\n    public DexException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    /**\n     * this is equals to\n     * \n     * <b> new DexException(String.format(messageFormat, args), cause); </b>\n     * \n     * @param cause\n     * @param messageFormat\n     * @param args\n     */\n    public DexException(Throwable cause, String messageFormat, Object... args) {\n        this(String.format(messageFormat, args), cause);\n    }\n\n    /**\n     * this is equals to\n     * \n     * <b> new DexException(String.format(messageFormat, args)); </b>\n     * \n     * @param messageFormat\n     * @param args\n     */\n    public DexException(String messageFormat, Object... args) {\n        this(String.format(messageFormat, args));\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/DexLabel.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j;\r\n\r\n/**\r\n * a light weight version of org.objectweb.asm.Label\r\n * \r\n * @author Panxiaobo\r\n * @version $Rev$\r\n */\r\npublic class DexLabel {\r\n    public String displayName;\r\n    private int offset = -1;\r\n\r\n    /**\r\n     * \r\n     * @param offset\r\n     *            the offset of the label\r\n     */\r\n    public DexLabel(int offset) {\r\n        super();\r\n        this.offset = offset;\r\n    }\r\n\r\n    public DexLabel() {\r\n        super();\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        if (displayName != null) {\r\n            return displayName;\r\n        }\r\n        if (offset >= 0) {\r\n            return String.format(\"L%04x\", offset);\r\n        }\r\n        return String.format(\"L%08x\", this.hashCode());\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/DexType.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j;\r\n\r\n/**\r\n * a light weight version of org.objectweb.asm.Type\r\n * \r\n * @author Panxiaobo\r\n * @version $Rev$\r\n * \r\n */\r\npublic class DexType {\r\n    public DexType(String desc) {\r\n        this.desc = desc;\r\n    }\r\n\r\n    /**\r\n     * type descriptor, in TypeDescriptor format\r\n     */\r\n    final public String desc;\r\n\r\n    @Override\r\n    public String toString() {\r\n        return desc;\r\n    }\r\n}"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/Field.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j;\r\n\r\n/**\r\n * represent a field_id_item in dex file format\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Field {\r\n    /**\r\n     * name of the field.\r\n     */\r\n    private String name;\r\n    /**\r\n     * owner class of the field, in TypeDescriptor format.\r\n     */\r\n    private String owner;\r\n    /**\r\n     * type of the field, in TypeDescriptor format.\r\n     */\r\n    private String type;\r\n\r\n    public Field(String owner, String name, String type) {\r\n        this.owner = owner;\r\n        this.type = type;\r\n        this.name = name;\r\n    }\r\n\r\n    /**\r\n     * @return the name\r\n     */\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * @return the owner\r\n     */\r\n    public String getOwner() {\r\n        return owner;\r\n    }\r\n\r\n    /**\r\n     * @return the type\r\n     */\r\n    public String getType() {\r\n        return type;\r\n    }\r\n\r\n    /*\r\n     * (non-Javadoc)\r\n     * \r\n     * @see java.lang.Object#toString()\r\n     */\r\n    @Override\r\n    public String toString() {\r\n        return this.getOwner() + \".\" + this.getName() + \" \" + this.getType();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/Method.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j;\r\n\r\nimport java.util.Arrays;\r\n\r\n/**\r\n * represent a method_id_item in dex file format\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Method {\r\n    /**\r\n     * name of the method.\r\n     */\r\n    private String name;\r\n    /**\r\n     * owner class of the method, in TypeDescriptor format.\r\n     */\r\n    private String owner;\r\n    /**\r\n     * parameter types of the method, in TypeDescriptor format.\r\n     */\r\n    private Proto proto;\r\n\r\n    public Proto getProto() {\r\n        return proto;\r\n    }\r\n\r\n    public Method(String owner, String name, String[] parameterTypes, String returnType) {\r\n        this.owner = owner;\r\n        this.name = name;\r\n        this.proto = new Proto(parameterTypes, returnType);\r\n    }\r\n    public Method(String owner, String name, Proto proto) {\r\n        this.owner = owner;\r\n        this.name = name;\r\n        this.proto = proto;\r\n    }\r\n    public String getDesc() {\r\n        return proto.getDesc();\r\n    }\r\n\r\n    /**\r\n     * @return the name\r\n     */\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * @return the owner\r\n     */\r\n    public String getOwner() {\r\n        return owner;\r\n    }\r\n\r\n    /**\r\n     * @return the parameterTypes\r\n     */\r\n    public String[] getParameterTypes() {\r\n        return proto.getParameterTypes();\r\n    }\r\n\r\n    public String getReturnType() {\r\n        return proto.getReturnType();\r\n    }\r\n\r\n    @Override\r\n    public boolean equals(Object o) {\r\n        if (this == o) return true;\r\n        if (o == null || getClass() != o.getClass()) return false;\r\n\r\n        Method method = (Method) o;\r\n\r\n        if (name != null ? !name.equals(method.name) : method.name != null) return false;\r\n        if (owner != null ? !owner.equals(method.owner) : method.owner != null) return false;\r\n        return proto.equals(method.proto);\r\n    }\r\n\r\n    @Override\r\n    public int hashCode() {\r\n        int result = name != null ? name.hashCode() : 0;\r\n        result = 31 * result + (owner != null ? owner.hashCode() : 0);\r\n        result = 31 * result + proto.hashCode();\r\n        return result;\r\n    }\r\n\r\n    /*\r\n         * (non-Javadoc)\r\n         *\r\n         * @see java.lang.Object#toString()\r\n         */\r\n    @Override\r\n    public String toString() {\r\n        return this.getOwner() + \".\" + this.getName() + this.getDesc();\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/MethodHandle.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j;\n\npublic class MethodHandle {\n    public static final int STATIC_PUT = 0x00;\n    public static final int STATIC_GET = 0x01;\n    public static final int INSTANCE_PUT = 0x02;\n    public static final int INSTANCE_GET = 0x03;\n    public static final int INVOKE_STATIC = 0x04;\n    public static final int INVOKE_INSTANCE = 0x05;\n    public static final int INVOKE_CONSTRUCTOR = 0x06;\n    public static final int INVOKE_DIRECT = 0x07;\n    public static final int INVOKE_INTERFACE = 0x08;\n\n    private int type;\n    private Field field;\n    private Method method;\n\n    public MethodHandle(int type, Field field) {\n        this.type = type;\n        this.field = field;\n    }\n\n    public MethodHandle(int type, Method method) {\n        this.type = type;\n        this.method = method;\n    }\n\n    public MethodHandle(int type, Field field, Method method) {\n        this.type = type;\n        this.field = field;\n        this.method = method;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        MethodHandle that = (MethodHandle) o;\n\n        if (type != that.type) return false;\n        if (field != null ? !field.equals(that.field) : that.field != null) return false;\n        return method != null ? method.equals(that.method) : that.method == null;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = type;\n        result = 31 * result + (field != null ? field.hashCode() : 0);\n        result = 31 * result + (method != null ? method.hashCode() : 0);\n        return result;\n    }\n\n    public int getType() {\n        return type;\n    }\n\n    public Field getField() {\n        return field;\n    }\n\n    public Method getMethod() {\n        return method;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/Proto.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j;\n\nimport java.util.Arrays;\n\npublic class Proto {\n    public Proto(String[] parameterTypes, String returnType) {\n        this.parameterTypes = parameterTypes;\n        this.returnType = returnType;\n    }\n\n    /**\n     * descriptor of the method, this will build after {@link #getDesc()}.\n     */\n    private String desc;\n    /**\n     * parameter types of the method, in TypeDescriptor format.\n     */\n    private String[] parameterTypes;\n\n    /**\n     * return type of the method, in TypeDescriptor format.\n     */\n    private String returnType;\n\n    /**\n     * @return the parameterTypes\n     */\n    public String[] getParameterTypes() {\n        return parameterTypes;\n    }\n\n    public String getReturnType() {\n        return returnType;\n    }\n\n    public String getDesc() {\n        if (desc == null) {\n            StringBuilder ps = new StringBuilder(\"(\");\n            if (parameterTypes != null) {\n                for (String t : parameterTypes) {\n                    ps.append(t);\n                }\n            }\n            ps.append(\")\").append(returnType);\n            desc = ps.toString();\n        }\n        return desc;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Proto proto = (Proto) o;\n\n        // Probably incorrect - comparing Object[] arrays with Arrays.equals\n        if (!Arrays.equals(parameterTypes, proto.parameterTypes)) return false;\n        return returnType != null ? returnType.equals(proto.returnType) : proto.returnType == null;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = Arrays.hashCode(parameterTypes);\n        result = 31 * result + (returnType != null ? returnType.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/Visibility.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j;\n\n/**\n * @author bob\n */\npublic enum Visibility {\n    BUILD(0), RUNTIME(1), SYSTEM(2);\n    public int value;\n\n    // int VISIBILITY_BUILD = 0;\n    // int VISIBILITY_RUNTIME = 1;\n    // int VISIBILITY_SYSTEM = 2;\n    Visibility(int v) {\n        this.value = v;\n    }\n\n    public String displayName() {\n        return name().toLowerCase();\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexAnnotationNode.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.node;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Visibility;\r\nimport com.googlecode.d2j.visitors.DexAnnotationAble;\r\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\r\n\r\n/**\r\n * \r\n * @author Bob Pan\r\n * \r\n */\r\npublic class DexAnnotationNode extends DexAnnotationVisitor {\r\n    private abstract static class AV extends DexAnnotationVisitor {\r\n        List<Object> objs = new ArrayList<Object>();\r\n\r\n        @Override\r\n        public void visit(String name, Object value) {\r\n            objs.add(value);\r\n        }\r\n\r\n        @Override\r\n        public DexAnnotationVisitor visitAnnotation(String name, String desc) {\r\n            DexAnnotationNode annotation = new DexAnnotationNode(desc, Visibility.RUNTIME);\r\n            objs.add(annotation);\r\n            return annotation;\r\n        }\r\n\r\n        @Override\r\n        public DexAnnotationVisitor visitArray(String name) {\r\n            return new AV() {\r\n\r\n                @Override\r\n                public void visitEnd() {\r\n                    AV.this.objs.add(this.objs.toArray());\r\n                    super.visitEnd();\r\n                }\r\n\r\n            };\r\n        }\r\n\r\n        @Override\r\n        public void visitEnd() {\r\n            objs = null;\r\n            super.visitEnd();\r\n        }\r\n\r\n        @Override\r\n        public void visitEnum(String name, String desc, String value) {\r\n            objs.add(new Field(null, value, desc));\r\n        }\r\n    }\r\n\r\n    public static class Item {\r\n        public String name;\r\n\r\n        public Object value;\r\n\r\n        public Item(String name, Object value) {\r\n            super();\r\n            this.name = name;\r\n            this.value = value;\r\n        }\r\n    }\r\n\r\n    public static void acceptAnnotationItem(DexAnnotationVisitor dav, String name, Object o) {\r\n        if (o instanceof Object[]) {\r\n            DexAnnotationVisitor arrayVisitor = dav.visitArray(name);\r\n            if (arrayVisitor != null) {\r\n                Object[] array = (Object[]) o;\r\n                for (Object e : array) {\r\n                    acceptAnnotationItem(arrayVisitor, null, e);\r\n                }\r\n                arrayVisitor.visitEnd();\r\n            }\r\n        } else if (o instanceof DexAnnotationNode) {\r\n            DexAnnotationNode ann = (DexAnnotationNode) o;\r\n            DexAnnotationVisitor av = dav.visitAnnotation(name, ann.type);\r\n            if (av != null) {\r\n                for (DexAnnotationNode.Item item : ann.items) {\r\n                    acceptAnnotationItem(av, item.name, item.value);\r\n                }\r\n                av.visitEnd();\r\n            }\r\n        } else if (o instanceof Field) {\r\n            Field f = (Field) o;\r\n            dav.visitEnum(name, f.getType(), f.getName());\r\n        } else {\r\n            dav.visit(name, o);\r\n        }\r\n    }\r\n\r\n    public List<Item> items = new ArrayList<Item>(5);\r\n\r\n    public String type;\r\n    public Visibility visibility;\r\n\r\n    public DexAnnotationNode(String type, Visibility visibility) {\r\n        super();\r\n        this.type = type;\r\n        this.visibility = visibility;\r\n    }\r\n\r\n    public void accept(DexAnnotationAble av) {\r\n        DexAnnotationVisitor av1 = av.visitAnnotation(type, visibility);\r\n        if (av1 != null) {\r\n            for (Item item : items) {\r\n                acceptAnnotationItem(av1, item.name, item.value);\r\n            }\r\n            av1.visitEnd();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visit(String name, Object value) {\r\n        items.add(new Item(name, value));\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitAnnotation(String name, String desc) {\r\n        DexAnnotationNode annotation = new DexAnnotationNode(desc, Visibility.RUNTIME);\r\n        items.add(new Item(name, annotation));\r\n        return annotation;\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitArray(final String name) {\r\n        return new AV() {\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                items.add(new Item(name, objs.toArray()));\r\n                super.visitEnd();\r\n            }\r\n        };\r\n    }\r\n\r\n    @Override\r\n    public void visitEnum(String name, String desc, String value) {\r\n        items.add(new Item(name, new Field(desc, value, desc)));\r\n    }\r\n}"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexClassNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\n/**\n * @author Bob Pan\n * \n */\npublic class DexClassNode extends DexClassVisitor {\n    public int access;\n    public List<DexAnnotationNode> anns;\n    public String className;\n    public List<DexFieldNode> fields;\n    public String[] interfaceNames;\n    public List<DexMethodNode> methods;\n    public String source;\n    public String superClass;\n\n    public DexClassNode(DexClassVisitor v, int access, String className, String superClass, String[] interfaceNames) {\n        super(v);\n        this.access = access;\n        this.className = className;\n        this.superClass = superClass;\n        this.interfaceNames = interfaceNames;\n    }\n\n    public DexClassNode(int access, String className, String superClass, String[] interfaceNames) {\n        super();\n        this.access = access;\n        this.className = className;\n        this.superClass = superClass;\n        this.interfaceNames = interfaceNames;\n    }\n\n    public void accept(DexClassVisitor dcv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                ann.accept(dcv);\n            }\n        }\n        if (methods != null) {\n            for (DexMethodNode m : methods) {\n                m.accept(dcv);\n            }\n        }\n        if (fields != null) {\n            for (DexFieldNode f : fields) {\n                f.accept(dcv);\n            }\n        }\n        if (source != null) {\n            dcv.visitSource(source);\n        }\n    }\n\n    public void accept(DexFileVisitor dfv) {\n        DexClassVisitor dcv = dfv.visit(access, className, superClass, interfaceNames);\n        if (dcv != null) {\n            accept(dcv);\n            dcv.visitEnd();\n        }\n    }\n\n    @Override\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\n        if (anns == null) {\n            anns = new ArrayList<DexAnnotationNode>(5);\n        }\n        DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);\n        anns.add(annotation);\n        return annotation;\n    }\n\n    @Override\n    public DexFieldVisitor visitField(int accessFlags, Field field, Object value) {\n        if (fields == null) {\n            fields = new ArrayList<DexFieldNode>();\n        }\n        DexFieldNode fieldNode = new DexFieldNode(accessFlags, field, value);\n        fields.add(fieldNode);\n        return fieldNode;\n    }\n\n    @Override\n    public DexMethodVisitor visitMethod(int accessFlags, Method method) {\n        if (methods == null) {\n            methods = new ArrayList<DexMethodNode>();\n        }\n        DexMethodNode methodNode = new DexMethodNode(accessFlags, method);\n        methods.add(methodNode);\n        return methodNode;\n    }\n\n    @Override\n    public void visitSource(String file) {\n        this.source = file;\n    }\n\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexCodeNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.*;\nimport com.googlecode.d2j.node.insn.*;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\npublic class DexCodeNode extends DexCodeVisitor {\n\n    public List<DexStmtNode> stmts = new ArrayList<DexStmtNode>();\n    public List<TryCatchNode> tryStmts = null;\n    public DexDebugNode debugNode;\n    public int totalRegister = -1;\n\n    public DexCodeNode() {\n        super();\n    }\n\n    public DexCodeNode(DexCodeVisitor visitor) {\n        super(visitor);\n    }\n\n    public void accept(DexCodeVisitor v) {\n        if (tryStmts != null) {\n            for (TryCatchNode n : tryStmts) {\n                n.accept(v);\n            }\n        }\n        if (debugNode != null) {\n            DexDebugVisitor ddv = v.visitDebug();\n            if (ddv != null) {\n                debugNode.accept(ddv);\n                ddv.visitEnd();\n            }\n        }\n        if (totalRegister >= 0) {\n            v.visitRegister(this.totalRegister);\n        }\n        for (DexStmtNode n : stmts) {\n            n.accept(v);\n        }\n    }\n\n    public void accept(DexMethodVisitor v) {\n        DexCodeVisitor cv = v.visitCode();\n        if (cv != null) {\n            accept(cv);\n            cv.visitEnd();\n        }\n    }\n\n    protected void add(DexStmtNode stmt) {\n        stmts.add(stmt);\n    }\n\n    @Override\n    public void visitConstStmt(final Op op, final int ra, final Object value) {\n        add(new ConstStmtNode(op, ra, value));\n    }\n\n    @Override\n    public void visitFillArrayDataStmt(final Op op, final int ra, final Object array) {\n        add(new FillArrayDataStmtNode(op, ra, array));\n    }\n\n    @Override\n    public void visitFieldStmt(final Op op, final int a, final int b, final Field field) {\n        add(new FieldStmtNode(op, a, b, field));\n    }\n\n    @Override\n    public void visitFilledNewArrayStmt(final Op op, final int[] args, final String type) {\n        add(new FilledNewArrayStmtNode(op, args, type));\n    }\n\n    @Override\n    public void visitJumpStmt(final Op op, final int a, final int b, final DexLabel label) {\n        add(new JumpStmtNode(op, a, b, label));\n    }\n\n    @Override\n    public void visitLabel(final DexLabel label) {\n        add(new DexLabelStmtNode(label));\n    }\n\n    @Override\n    public void visitMethodStmt(final Op op, final int[] args, final Method method) {\n        add(new MethodStmtNode(op, args, method));\n    }\n\n    @Override\n    public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) {\n        add(new MethodCustomStmtNode(op, args, name, proto, bsm, bsmArgs));\n    }\n\n    @Override\n    public void visitMethodStmt(Op op, int[] args, Method bsm, Proto proto) {\n        add(new MethodPolymorphicStmtNode(op, args, bsm, proto));\n    }\n\n    @Override\n    public void visitPackedSwitchStmt(final Op op, final int aA, final int first_case, final DexLabel[] labels) {\n        add(new PackedSwitchStmtNode(op, aA, first_case, labels));\n    }\n\n    @Override\n    public void visitRegister(final int total) {\n        this.totalRegister = total;\n    }\n\n    @Override\n    public void visitSparseSwitchStmt(final Op op, final int ra, final int[] cases, final DexLabel[] labels) {\n        add(new SparseSwitchStmtNode(op, ra, cases, labels));\n    }\n\n    @Override\n    public void visitStmt0R(final Op op) {\n        add(new Stmt0RNode(op));\n    }\n\n    @Override\n    public void visitStmt1R(final Op op, final int reg) {\n        add(new Stmt1RNode(op, reg));\n    }\n\n    @Override\n    public void visitStmt2R(final Op op, final int a, final int b) {\n        add(new Stmt2RNode(op, a, b));\n    }\n\n    @Override\n    public void visitStmt2R1N(final Op op, final int distReg, final int srcReg, final int content) {\n        add(new Stmt2R1NNode(op, distReg, srcReg, content));\n    }\n\n    @Override\n    public void visitStmt3R(final Op op, final int a, final int b, final int c) {\n        add(new Stmt3RNode(op, a, b, c));\n    }\n\n    @Override\n    public void visitTryCatch(final DexLabel start, final DexLabel end, final DexLabel[] handler, final String[] type) {\n        if (tryStmts == null) {\n            tryStmts = new ArrayList<>(3);\n        }\n        tryStmts.add(new TryCatchNode(start, end, handler, type));\n    }\n\n    @Override\n    public void visitTypeStmt(final Op op, final int a, final int b, final String type) {\n        add(new TypeStmtNode(op, a, b, type));\n    }\n\n    @Override\n    public DexDebugVisitor visitDebug() {\n        DexDebugNode dexDebugNode = new DexDebugNode();\n        this.debugNode = dexDebugNode;\n        return dexDebugNode;\n    }\n\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexDebugNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\n\npublic class DexDebugNode extends DexDebugVisitor {\n    public List<DexDebugOpNode> debugNodes = new ArrayList<>();\n    public List<String> parameterNames;\n    public String fineName;\n\n    protected void addDebug(DexDebugOpNode dexDebugNode) {\n        debugNodes.add(dexDebugNode);\n    }\n\n    @Override\n    public void visitSetFile(String file) {\n        this.fineName = file;\n    }\n\n    @Override\n    public void visitRestartLocal(int reg, DexLabel label) {\n        addDebug(new DexDebugOpNode.RestartLocal(label, reg));\n    }\n\n    @Override\n    public void visitParameterName(final int parameterIndex, final String name) {\n        if (parameterNames == null) {\n            parameterNames = new ArrayList<>();\n        }\n        while (parameterNames.size() <= parameterIndex) {\n            parameterNames.add(null);\n        }\n        parameterNames.set(parameterIndex, name);\n    }\n\n    @Override\n    public void visitLineNumber(final int line, final DexLabel label) {\n        addDebug(new DexDebugOpNode.LineNumber(label, line));\n    }\n\n    @Override\n    public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) {\n        addDebug(new DexDebugOpNode.StartLocalNode(label, reg, name, type, signature));\n    }\n\n    @Override\n    public void visitEndLocal(int reg, DexLabel label) {\n        addDebug(new DexDebugOpNode.EndLocal(label, reg));\n    }\n\n    public void accept(DexDebugVisitor v) {\n        if (parameterNames != null) {\n            for (int i = 0; i < parameterNames.size(); i++) {\n                String name = parameterNames.get(i);\n                if (name != null) {\n                    v.visitParameterName(i, name);\n                }\n            }\n        }\n        if (debugNodes != null) {\n            for (DexDebugOpNode n : debugNodes) {\n                n.accept(v);\n            }\n        }\n        if (fineName != null) {\n            v.visitSetFile(fineName);\n        }\n    }\n\n    @Override\n    public void visitPrologue(DexLabel dexLabel) {\n        addDebug(new DexDebugOpNode.Prologue(dexLabel));\n    }\n\n    @Override\n    public void visitEpiogue(DexLabel dexLabel) {\n        addDebug(new DexDebugOpNode.Epiogue(dexLabel));\n    }\n\n    public abstract static class DexDebugOpNode {\n        public DexLabel label;\n\n        protected DexDebugOpNode(DexLabel label) {\n            this.label = label;\n        }\n\n        public abstract void accept(DexDebugVisitor cv);\n\n        public static class StartLocalNode extends DexDebugOpNode {\n            public int reg;\n            public String name;\n            public String type;\n            public String signature;\n\n            public StartLocalNode(DexLabel label, int reg, String name, String type, String signature) {\n                super(label);\n                this.reg = reg;\n                this.name = name;\n                this.type = type;\n                this.signature = signature;\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitStartLocal(reg, label, name, type, signature);\n            }\n        }\n\n        public static class EndLocal extends DexDebugOpNode {\n            public int reg;\n\n            public EndLocal(DexLabel label, int reg) {\n                super(label);\n                this.reg = reg;\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitEndLocal(reg, label);\n            }\n        }\n\n        public static class Epiogue extends DexDebugOpNode {\n\n            public Epiogue(DexLabel label) {\n                super(label);\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitEpiogue(label);\n            }\n        }\n\n        public static class Prologue extends DexDebugOpNode {\n\n            public Prologue(DexLabel label) {\n                super(label);\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitPrologue(label);\n            }\n        }\n\n        public static class RestartLocal extends DexDebugOpNode {\n            public int reg;\n\n            public RestartLocal(DexLabel label, int reg) {\n                super(label);\n                this.reg = reg;\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitRestartLocal(reg, label);\n            }\n        }\n\n        public static class LineNumber extends DexDebugOpNode {\n            public int line;\n\n            public LineNumber(DexLabel label, int line) {\n                super(label);\n                this.line = line;\n            }\n\n            @Override\n            public void accept(DexDebugVisitor cv) {\n                cv.visitLineNumber(line, label);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexFieldNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\n\n/**\n * @author Bob Pan\n * \n */\npublic class DexFieldNode extends DexFieldVisitor {\n    public int access;\n    public List<DexAnnotationNode> anns;\n    public Object cst;\n    public Field field;\n\n    public DexFieldNode(DexFieldVisitor visitor, int access, Field field, Object cst) {\n        super(visitor);\n        this.access = access;\n        this.field = field;\n        this.cst = cst;\n    }\n\n    public DexFieldNode(int access, Field field, Object cst) {\n        super();\n        this.access = access;\n        this.field = field;\n        this.cst = cst;\n    }\n\n    public void accept(DexClassVisitor dcv) {\n        DexFieldVisitor fv = dcv.visitField(access, field, cst);\n        if (fv != null) {\n            accept(fv);\n            fv.visitEnd();\n        }\n    }\n\n    public void accept(DexFieldVisitor fv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                ann.accept(fv);\n            }\n        }\n    }\n\n    @Override\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\n        if (anns == null) {\n            anns = new ArrayList<DexAnnotationNode>(5);\n        }\n        DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);\n        anns.add(annotation);\n        return annotation;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexFileNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class DexFileNode extends DexFileVisitor {\n    public List<DexClassNode> clzs = new ArrayList<>();\n    public int dexVersion = DexConstants.DEX_035;\n\n    @Override\n    public void visitDexFileVersion(int version) {\n        this.dexVersion = version;\n        super.visitDexFileVersion(version);\n    }\n\n    @Override\n    public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\n        DexClassNode cn = new DexClassNode(access_flags, className, superClass, interfaceNames);\n        clzs.add(cn);\n        return cn;\n    }\n\n    public void accept(DexClassVisitor dcv) {\n        for (DexClassNode cn : clzs) {\n            cn.accept(dcv);\n        }\n    }\n\n    public void accept(DexFileVisitor dfv) {\n        for (DexClassNode cn : clzs) {\n            cn.accept(dfv);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/DexMethodNode.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.visitors.DexAnnotationAble;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\npublic class DexMethodNode extends DexMethodVisitor {\n    public int access;\n    public List<DexAnnotationNode> anns;\n    public DexCodeNode codeNode;\n    public Method method;\n    public List<DexAnnotationNode> parameterAnns[];\n\n    public DexMethodNode(DexMethodVisitor mv, int access, Method method) {\n        super(mv);\n        this.access = access;\n        this.method = method;\n    }\n\n    public DexMethodNode(int access, Method method) {\n        super();\n        this.access = access;\n        this.method = method;\n    }\n\n    public void accept(DexClassVisitor dcv) {\n        DexMethodVisitor mv = dcv.visitMethod(access, method);\n        if (mv != null) {\n            accept(mv);\n            mv.visitEnd();\n        }\n\n    }\n\n    public void accept(DexMethodVisitor mv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                ann.accept(mv);\n            }\n        }\n\n        if (parameterAnns != null) {\n            for (int i = 0; i < parameterAnns.length; i++) {\n                List<DexAnnotationNode> ps = parameterAnns[i];\n                if (ps != null) {\n                    DexAnnotationAble av = mv.visitParameterAnnotation(i);\n                    if (av != null) {\n                        for (DexAnnotationNode p : ps) {\n                            p.accept(av);\n                        }\n                    }\n                }\n            }\n        }\n        if (codeNode != null) {\n            codeNode.accept(mv);\n        }\n    }\n\n    @Override\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\n        if (anns == null) {\n            anns = new ArrayList<DexAnnotationNode>(5);\n        }\n        DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);\n        anns.add(annotation);\n        return annotation;\n    }\n\n    @Override\n    public DexCodeVisitor visitCode() {\n        DexCodeNode codeNode = new DexCodeNode(super.visitCode());\n        this.codeNode = codeNode;\n        return codeNode;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public DexAnnotationAble visitParameterAnnotation(final int index) {\n        if (parameterAnns == null) {\n            parameterAnns = new List[method.getParameterTypes().length];\n        }\n\n        return new DexAnnotationAble() {\n\n            @Override\n            public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\n                List<DexAnnotationNode> pas = parameterAnns[index];\n                if (pas == null) {\n                    pas = new ArrayList<DexAnnotationNode>(5);\n                    parameterAnns[index] = pas;\n                }\n                DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);\n                pas.add(annotation);\n                return annotation;\n            }\n        };\n    }\n\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/TryCatchNode.java",
    "content": "package com.googlecode.d2j.node;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class TryCatchNode {\n\n    public final DexLabel start;\n    public final DexLabel end;\n    public final DexLabel[] handler;\n    public final String[] type;\n\n    public TryCatchNode(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) {\n        this.start = start;\n        this.end = end;\n        this.handler = handler;\n        this.type = type;\n    }\n\n    public void accept(DexCodeVisitor cv) {\n        cv.visitTryCatch(start, end, handler, type);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/analysis/DvmFrame.java",
    "content": "package com.googlecode.d2j.node.analysis;\r\n\r\nimport com.googlecode.d2j.MethodHandle;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.d2j.node.insn.*;\r\nimport com.googlecode.d2j.reader.Op;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\npublic class DvmFrame<V> {\r\n    public V[] values;\r\n    public V tmp;\r\n\r\n    public DvmFrame(int totalRegister) {\r\n        values = (V[]) new Object[totalRegister];\r\n    }\r\n\r\n\r\n    public void setReg(int i, V v) {\r\n        if (i > values.length || i < 0) {\r\n            return;\r\n        }\r\n        values[i] = v;\r\n    }\r\n\r\n    public DvmFrame<V> init(DvmFrame<? extends V> src) {\r\n        this.tmp = src.tmp;\r\n        System.arraycopy(src.values, 0, this.values, 0, this.values.length);\r\n        return this;\r\n    }\r\n\r\n    public void execute(DexStmtNode insn, DvmInterpreter<V> interpreter) {\r\n        if (insn.op == null) {// label or others\r\n            return;\r\n        }\r\n        switch (insn.op) {\r\n            case CONST:\r\n            case CONST_4:\r\n            case CONST_16:\r\n            case CONST_HIGH16:\r\n            case CONST_WIDE:\r\n            case CONST_WIDE_16:\r\n            case CONST_WIDE_32:\r\n            case CONST_WIDE_HIGH16:\r\n            case CONST_STRING:\r\n            case CONST_STRING_JUMBO:\r\n            case CONST_CLASS:\r\n                setReg(((ConstStmtNode) insn).a, interpreter.newOperation(insn));\r\n                setTmp(null);\r\n                break;\r\n            case SGET:\r\n            case SGET_BOOLEAN:\r\n            case SGET_BYTE:\r\n            case SGET_CHAR:\r\n            case SGET_OBJECT:\r\n            case SGET_SHORT:\r\n            case SGET_WIDE:\r\n                setReg(((FieldStmtNode) insn).a, interpreter.newOperation(insn));\r\n                setTmp(null);\r\n                break;\r\n            case NEW_INSTANCE:\r\n                setReg(((TypeStmtNode) insn).a, interpreter.newOperation(insn));\r\n                setTmp(null);\r\n                break;\r\n            case MOVE:\r\n            case MOVE_16:\r\n            case MOVE_FROM16:\r\n            case MOVE_OBJECT:\r\n            case MOVE_OBJECT_16:\r\n            case MOVE_OBJECT_FROM16:\r\n            case MOVE_WIDE:\r\n            case MOVE_WIDE_FROM16:\r\n            case MOVE_WIDE_16:\r\n                Stmt2RNode stmt2RNode = (Stmt2RNode) insn;\r\n                setReg(stmt2RNode.a, interpreter.copyOperation(insn, getReg(stmt2RNode.b)));\r\n                setTmp(null);\r\n                break;\r\n            case MOVE_RESULT:\r\n            case MOVE_RESULT_WIDE:\r\n            case MOVE_RESULT_OBJECT:\r\n            case MOVE_EXCEPTION:\r\n                setReg(((Stmt1RNode) insn).a, interpreter.copyOperation(insn, getTmp()));\r\n                setTmp(null);\r\n                break;\r\n            case NOT_INT:\r\n            case NOT_LONG:\r\n            case NEG_DOUBLE:\r\n            case NEG_FLOAT:\r\n            case NEG_INT:\r\n            case NEG_LONG:\r\n            case INT_TO_BYTE:\r\n            case INT_TO_CHAR:\r\n            case INT_TO_DOUBLE:\r\n            case INT_TO_FLOAT:\r\n            case INT_TO_LONG:\r\n            case INT_TO_SHORT:\r\n            case FLOAT_TO_DOUBLE:\r\n            case FLOAT_TO_INT:\r\n            case FLOAT_TO_LONG:\r\n            case DOUBLE_TO_FLOAT:\r\n            case DOUBLE_TO_INT:\r\n            case DOUBLE_TO_LONG:\r\n            case LONG_TO_DOUBLE:\r\n            case LONG_TO_FLOAT:\r\n            case LONG_TO_INT:\r\n            case ARRAY_LENGTH:\r\n                Stmt2RNode stmt2RNode1 = (Stmt2RNode) insn;\r\n                setReg(stmt2RNode1.a, interpreter.unaryOperation(insn, getReg(stmt2RNode1.b)));\r\n                setTmp(null);\r\n                break;\r\n            case IF_EQZ:\r\n            case IF_GEZ:\r\n            case IF_GTZ:\r\n            case IF_LEZ:\r\n            case IF_LTZ:\r\n            case IF_NEZ:\r\n                interpreter.unaryOperation(insn, getReg(((JumpStmtNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case SPARSE_SWITCH:\r\n                interpreter.unaryOperation(insn, getReg(((SparseSwitchStmtNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case PACKED_SWITCH:\r\n                interpreter.unaryOperation(insn, getReg(((PackedSwitchStmtNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case SPUT:\r\n            case SPUT_BOOLEAN:\r\n            case SPUT_BYTE:\r\n            case SPUT_CHAR:\r\n            case SPUT_OBJECT:\r\n            case SPUT_SHORT:\r\n            case SPUT_WIDE:\r\n                interpreter.unaryOperation(insn, getReg(((FieldStmtNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case IGET:\r\n            case IGET_BOOLEAN:\r\n            case IGET_BYTE:\r\n            case IGET_CHAR:\r\n            case IGET_OBJECT:\r\n            case IGET_SHORT:\r\n            case IGET_WIDE:\r\n                FieldStmtNode fieldStmtNode = (FieldStmtNode) insn;\r\n                setReg(fieldStmtNode.a, interpreter.unaryOperation(insn, getReg(fieldStmtNode.b)));\r\n                setTmp(null);\r\n                break;\r\n            case NEW_ARRAY:\r\n            case INSTANCE_OF: {\r\n                TypeStmtNode typeStmtNode = (TypeStmtNode) insn;\r\n                setReg(typeStmtNode.a, interpreter.unaryOperation(insn, getReg(typeStmtNode.b)));\r\n                setTmp(null);\r\n            }\r\n            break;\r\n            case CHECK_CAST: {\r\n                TypeStmtNode typeStmtNode = (TypeStmtNode) insn;\r\n                setReg(typeStmtNode.a, interpreter.unaryOperation(insn, getReg(typeStmtNode.a)));\r\n                setTmp(null);\r\n            }\r\n            break;\r\n            case MONITOR_ENTER:\r\n            case MONITOR_EXIT:\r\n            case THROW:\r\n                interpreter.unaryOperation(insn, getReg(((Stmt1RNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case RETURN:\r\n            case RETURN_WIDE:\r\n            case RETURN_OBJECT:\r\n                interpreter.returnOperation(insn, getReg(((Stmt1RNode) insn).a));\r\n                setTmp(null);\r\n                break;\r\n            case AGET:\r\n            case AGET_BOOLEAN:\r\n            case AGET_BYTE:\r\n            case AGET_CHAR:\r\n            case AGET_OBJECT:\r\n            case AGET_SHORT:\r\n            case AGET_WIDE:\r\n            case CMP_LONG:\r\n            case CMPG_DOUBLE:\r\n            case CMPG_FLOAT:\r\n            case CMPL_DOUBLE:\r\n            case CMPL_FLOAT:\r\n            case ADD_DOUBLE:\r\n            case ADD_FLOAT:\r\n            case ADD_INT:\r\n            case ADD_LONG:\r\n            case SUB_DOUBLE:\r\n            case SUB_FLOAT:\r\n            case SUB_INT:\r\n            case SUB_LONG:\r\n            case MUL_DOUBLE:\r\n            case MUL_FLOAT:\r\n            case MUL_INT:\r\n            case MUL_LONG:\r\n            case DIV_DOUBLE:\r\n            case DIV_FLOAT:\r\n            case DIV_INT:\r\n            case DIV_LONG:\r\n            case REM_DOUBLE:\r\n            case REM_FLOAT:\r\n            case REM_INT:\r\n            case REM_LONG:\r\n            case AND_INT:\r\n            case AND_LONG:\r\n            case OR_INT:\r\n            case OR_LONG:\r\n            case XOR_INT:\r\n            case XOR_LONG:\r\n            case SHL_INT:\r\n            case SHL_LONG:\r\n            case SHR_INT:\r\n            case SHR_LONG:\r\n            case USHR_INT:\r\n            case USHR_LONG:\r\n                Stmt3RNode stmt3RNode = (Stmt3RNode) insn;\r\n                setReg(stmt3RNode.a, interpreter.binaryOperation(insn, getReg(stmt3RNode.b), getReg(stmt3RNode.c)));\r\n                setTmp(null);\r\n                break;\r\n            case IF_EQ:\r\n            case IF_GE:\r\n            case IF_GT:\r\n            case IF_LE:\r\n            case IF_LT:\r\n            case IF_NE:\r\n                JumpStmtNode jumpStmtNode = (JumpStmtNode) insn;\r\n                interpreter.binaryOperation(insn, getReg(jumpStmtNode.a), getReg(jumpStmtNode.b));\r\n                setTmp(null);\r\n                break;\r\n            case IPUT:\r\n            case IPUT_BOOLEAN:\r\n            case IPUT_BYTE:\r\n            case IPUT_CHAR:\r\n            case IPUT_OBJECT:\r\n            case IPUT_SHORT:\r\n            case IPUT_WIDE:\r\n                FieldStmtNode fieldStmtNode1 = (FieldStmtNode) insn;\r\n                interpreter.binaryOperation(insn, getReg(fieldStmtNode1.b), getReg(fieldStmtNode1.a));\r\n                setTmp(null);\r\n                break;\r\n            case APUT:\r\n            case APUT_BOOLEAN:\r\n            case APUT_BYTE:\r\n            case APUT_CHAR:\r\n            case APUT_OBJECT:\r\n            case APUT_SHORT:\r\n            case APUT_WIDE:\r\n                Stmt3RNode stmt3RNode1 = (Stmt3RNode) insn;\r\n                interpreter.ternaryOperation(insn, getReg(stmt3RNode1.b), getReg(stmt3RNode1.c), getReg(stmt3RNode1.a));\r\n                setTmp(null);\r\n                break;\r\n            case INVOKE_VIRTUAL_RANGE:\r\n            case INVOKE_VIRTUAL:\r\n            case INVOKE_SUPER_RANGE:\r\n            case INVOKE_DIRECT_RANGE:\r\n            case INVOKE_SUPER:\r\n            case INVOKE_DIRECT:\r\n            case INVOKE_STATIC_RANGE:\r\n            case INVOKE_STATIC:\r\n            case INVOKE_INTERFACE_RANGE:\r\n            case INVOKE_INTERFACE:\r\n            case INVOKE_CUSTOM:\r\n            case INVOKE_CUSTOM_RANGE:\r\n            case INVOKE_POLYMORPHIC:\r\n            case INVOKE_POLYMORPHIC_RANGE: {\r\n                int i = 0;\r\n                AbstractMethodStmtNode methodStmtNode = (AbstractMethodStmtNode) insn;\r\n                List<V> v;\r\n                Proto proto = methodStmtNode.getProto();\r\n                boolean isStatic = false;\r\n                if (insn.op == Op.INVOKE_STATIC || insn.op == Op.INVOKE_STATIC_RANGE) {\r\n                    isStatic = true;\r\n                } else if (insn.op == Op.INVOKE_CUSTOM || insn.op == Op.INVOKE_CUSTOM_RANGE) {\r\n                    isStatic = true;\r\n                }\r\n                if (isStatic) {\r\n                    v = new ArrayList<>(proto.getParameterTypes().length);\r\n                } else {\r\n                    v = new ArrayList<>(proto.getParameterTypes().length + 1);\r\n                    v.add(getReg(methodStmtNode.args[i++]));\r\n                }\r\n\r\n                for (String type : proto.getParameterTypes()) {\r\n                    v.add(getReg(methodStmtNode.args[i]));\r\n                    char t = type.charAt(0);\r\n                    if (t == 'J' || t == 'D') {\r\n                        i += 2;\r\n                    } else {\r\n                        i += 1;\r\n                    }\r\n                }\r\n                setTmp(interpreter.naryOperation(insn, v));\r\n            }\r\n            break;\r\n            case FILLED_NEW_ARRAY:\r\n            case FILLED_NEW_ARRAY_RANGE: {\r\n                FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;\r\n                List<V> v = new ArrayList<>(filledNewArrayStmtNode.args.length);\r\n                for (int i = 0; i < filledNewArrayStmtNode.args.length; i++) {\r\n                    v.add(getReg(filledNewArrayStmtNode.args[i]));\r\n                }\r\n                setTmp(interpreter.naryOperation(insn, v));\r\n            }\r\n            break;\r\n\r\n\r\n            case ADD_DOUBLE_2ADDR:\r\n            case ADD_FLOAT_2ADDR:\r\n            case ADD_INT_2ADDR:\r\n            case ADD_LONG_2ADDR:\r\n            case SUB_DOUBLE_2ADDR:\r\n            case SUB_FLOAT_2ADDR:\r\n            case SUB_INT_2ADDR:\r\n            case SUB_LONG_2ADDR:\r\n            case MUL_DOUBLE_2ADDR:\r\n            case MUL_FLOAT_2ADDR:\r\n            case MUL_INT_2ADDR:\r\n            case MUL_LONG_2ADDR:\r\n            case DIV_DOUBLE_2ADDR:\r\n            case DIV_FLOAT_2ADDR:\r\n            case DIV_INT_2ADDR:\r\n            case DIV_LONG_2ADDR:\r\n            case REM_DOUBLE_2ADDR:\r\n            case REM_FLOAT_2ADDR:\r\n            case REM_INT_2ADDR:\r\n            case REM_LONG_2ADDR:\r\n            case AND_INT_2ADDR:\r\n            case AND_LONG_2ADDR:\r\n            case OR_INT_2ADDR:\r\n            case OR_LONG_2ADDR:\r\n            case XOR_INT_2ADDR:\r\n            case XOR_LONG_2ADDR:\r\n            case SHL_INT_2ADDR:\r\n            case SHL_LONG_2ADDR:\r\n            case SHR_INT_2ADDR:\r\n            case SHR_LONG_2ADDR:\r\n            case USHR_INT_2ADDR:\r\n            case USHR_LONG_2ADDR:\r\n                Stmt2RNode stmt2RNode2 = (Stmt2RNode) insn;\r\n                setReg(stmt2RNode2.a, interpreter.binaryOperation(insn, getReg(stmt2RNode2.a), getReg(stmt2RNode2.b)));\r\n                setTmp(null);\r\n                break;\r\n            case ADD_INT_LIT16:\r\n            case ADD_INT_LIT8:\r\n            case RSUB_INT_LIT8:\r\n            case RSUB_INT:\r\n            case MUL_INT_LIT8:\r\n            case MUL_INT_LIT16:\r\n            case DIV_INT_LIT16:\r\n            case DIV_INT_LIT8:\r\n            case REM_INT_LIT16:\r\n            case REM_INT_LIT8:\r\n            case AND_INT_LIT16:\r\n            case AND_INT_LIT8:\r\n            case OR_INT_LIT16:\r\n            case OR_INT_LIT8:\r\n            case XOR_INT_LIT16:\r\n            case XOR_INT_LIT8:\r\n            case SHL_INT_LIT8:\r\n            case SHR_INT_LIT8:\r\n            case USHR_INT_LIT8:\r\n                Stmt2R1NNode stmt2R1NNode = (Stmt2R1NNode) insn;\r\n                setReg(stmt2R1NNode.distReg, interpreter.unaryOperation(insn, getReg(stmt2R1NNode.srcReg)));\r\n                setTmp(null);\r\n                break;\r\n            case FILL_ARRAY_DATA:\r\n                interpreter.unaryOperation(insn,getReg(((FillArrayDataStmtNode)insn).ra));\r\n                setTmp(null);\r\n                break;\r\n            case GOTO:\r\n            case GOTO_16:\r\n            case GOTO_32:\r\n            case RETURN_VOID:\r\n            case BAD_OP:\r\n                setTmp(null);\r\n                break;\r\n            default:\r\n                throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    public V getTmp() {\r\n        return tmp;\r\n    }\r\n\r\n    public void setTmp(V v) {\r\n        this.tmp = v;\r\n    }\r\n\r\n    public V getReg(int b) {\r\n        if (b > values.length || b < 0) {\r\n            return null;\r\n        }\r\n        return values[b];\r\n    }\r\n\r\n    public int getTotalRegisters() {\r\n        return values.length;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/analysis/DvmInterpreter.java",
    "content": "package com.googlecode.d2j.node.analysis;\r\n\r\nimport com.googlecode.d2j.node.insn.DexStmtNode;\r\n\r\nimport java.util.List;\r\n\r\npublic abstract class DvmInterpreter<V> {\r\n    \r\n    /**\r\n     * CONST*\r\n     * SGET*\r\n     * NEW\r\n     *\r\n     *\r\n     */\r\n    public abstract V newOperation(DexStmtNode insn) ;\r\n\r\n    /**\r\n     * MOVE*\r\n     */\r\n    public abstract V copyOperation(DexStmtNode insn, V value) ;\r\n\r\n    /**\r\n     * NEG*\r\n     * *_TO_*\r\n     * IF_*Z\r\n     * *SWITCH\r\n     * IGET*\r\n     * NEW_ARRAY\r\n     * MONITOR_*\r\n     * CHECK_CAST\r\n     * INSTANCEOF\r\n\r\n     */\r\n    public abstract V unaryOperation(DexStmtNode insn, V value);\r\n\r\n    /**\r\n     * AGET*\r\n     * IPUT*\r\n     *\r\n     */\r\n    public abstract V binaryOperation(DexStmtNode insn, V value1, V value2);\r\n\r\n    /**\r\n     * APUT\r\n     */\r\n    public abstract V ternaryOperation(DexStmtNode insn, V value1,\r\n                                       V value2, V value3) ;\r\n\r\n    /**\r\n     * INVOKE*\r\n     * MULTIANEWARRAY\r\n     * FilledNewArrayStmt\r\n     */\r\n    public abstract V naryOperation(DexStmtNode insn,\r\n                                    List<? extends V> values) ;\r\n\r\n    /**\r\n     * RETURN*\r\n     */\r\n    public abstract void returnOperation(DexStmtNode insn, V value);\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/AbstractMethodStmtNode.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.Proto;\nimport com.googlecode.d2j.reader.Op;\n\npublic abstract class AbstractMethodStmtNode extends DexStmtNode {\n    public final int[] args;\n\n    public AbstractMethodStmtNode(Op op, int[] args) {\n        super(op);\n        this.args = args;\n    }\n\n    public abstract Proto getProto();\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/BaseSwitchStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.reader.Op;\n\npublic abstract class BaseSwitchStmtNode extends DexStmtNode {\n\n    public final int a;\n    public final DexLabel[] labels;\n\n    protected BaseSwitchStmtNode(Op op, int a, DexLabel[] labels) {\n        super(op);\n        this.a = a;\n        this.labels = labels;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/ConstStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\n\npublic class ConstStmtNode extends DexStmtNode {\n    public final int a;\n    public final Object value;\n\n    public ConstStmtNode(Op op, int a, Object value) {\n        super(op);\n        this.a = a;\n        this.value = value;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitConstStmt(op, a, value);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/DexLabelStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class DexLabelStmtNode extends DexStmtNode {\n    public DexLabel label;\n\n    public DexLabelStmtNode(DexLabel label) {\n        super(null);\n        this.label = label;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitLabel(label);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/DexStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\n\npublic abstract class DexStmtNode {\n    public final Op op;\n\n    public int __index;\n\n    protected DexStmtNode(Op op) {\n        this.op = op;\n    }\n\n    public abstract void accept(DexCodeVisitor cv);\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/FieldStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class FieldStmtNode extends DexStmtNode {\n\n    public final int a;\n    public final int b;\n    public final Field field;\n\n    public FieldStmtNode(Op op, int a, int b, Field field) {\n        super(op);\n        this.a = a;\n        this.b = b;\n        this.field = field;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitFieldStmt(op, a, b, field);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/FillArrayDataStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class FillArrayDataStmtNode extends DexStmtNode {\n\n    public final int ra;\n    public final Object array;\n\n    public FillArrayDataStmtNode(Op op, int ra, Object array) {\n        super(op);\n        this.ra = ra;\n        this.array = array;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitFillArrayDataStmt(op, ra, array);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/FilledNewArrayStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class FilledNewArrayStmtNode extends DexStmtNode {\n\n    public final int[] args;\n    public final String type;\n\n    public FilledNewArrayStmtNode(Op op, int[] args, String type) {\n        super(op);\n        this.args = args;\n        this.type = type;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitFilledNewArrayStmt(op, args, type);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/JumpStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class JumpStmtNode extends DexStmtNode {\n    public final int a;\n    public final int b;\n    public final DexLabel label;\n\n    public JumpStmtNode(Op op, int a, int b, DexLabel label) {\n        super(op);\n        this.a = a;\n        this.b = b;\n        this.label = label;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitJumpStmt(op, a, b, label);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/MethodCustomStmtNode.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.MethodHandle;\nimport com.googlecode.d2j.Proto;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class MethodCustomStmtNode extends AbstractMethodStmtNode {\n    public final String name;\n    public final Proto proto;\n    public final MethodHandle bsm;\n    public final Object[] bsmArgs;\n\n    public MethodCustomStmtNode(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object[] bsmArgs) {\n        super(op, args);\n        this.proto = proto;\n        this.name = name;\n        this.bsm = bsm;\n        this.bsmArgs = bsmArgs;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitMethodStmt(op, args, name, proto, bsm, bsmArgs);\n    }\n\n    @Override\n    public Proto getProto() {\n        return proto;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/MethodPolymorphicStmtNode.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Proto;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class MethodPolymorphicStmtNode extends AbstractMethodStmtNode {\n    public final Method method;\n    public final Proto proto;\n\n    public MethodPolymorphicStmtNode(Op op, int[] args, Method method, Proto proto) {\n        super(op, args);\n        this.method = method;\n        this.proto = proto;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitMethodStmt(op, args, method, proto);\n    }\n\n    @Override\n    public Proto getProto() {\n        return proto;\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/MethodStmtNode.java",
    "content": "/*\n * Copyright (c) 2009-2017 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Proto;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class MethodStmtNode extends AbstractMethodStmtNode {\n    public final Method method;\n\n    public MethodStmtNode(Op op, int[] args, Method method) {\n        super(op, args);\n        this.method = method;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitMethodStmt(op, args, method);\n    }\n\n    @Override\n    public Proto getProto() {\n        return method.getProto();\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/PackedSwitchStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class PackedSwitchStmtNode extends BaseSwitchStmtNode {\n\n    public final int first_case;\n\n    public PackedSwitchStmtNode(Op op, int a, int first_case, DexLabel[] labels) {\n        super(op, a,labels);\n        this.first_case = first_case;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitPackedSwitchStmt(op, a, first_case, labels);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/SparseSwitchStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class SparseSwitchStmtNode extends BaseSwitchStmtNode {\n\n    public final int[] cases;\n\n    public SparseSwitchStmtNode(Op op, int a, int[] cases, DexLabel[] labels) {\n        super(op, a, labels);\n        this.cases = cases;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitSparseSwitchStmt(op, a, cases, labels);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/Stmt0RNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class Stmt0RNode extends DexStmtNode {\n    public Stmt0RNode(Op op) {\n        super(op);\n    }\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitStmt0R(op);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/Stmt1RNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class Stmt1RNode extends DexStmtNode {\n\n    public final int a;\n\n    public Stmt1RNode(Op op, int a) {\n        super(op);\n        this.a = a;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitStmt1R(op, a);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/Stmt2R1NNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class Stmt2R1NNode extends DexStmtNode {\n\n    public final int distReg;\n    public final int srcReg;\n    public final int content;\n\n    public Stmt2R1NNode(Op op, int distReg, int srcReg, int content) {\n        super(op);\n        this.distReg = distReg;\n        this.srcReg = srcReg;\n        this.content = content;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitStmt2R1N(op, distReg, srcReg, content);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/Stmt2RNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class Stmt2RNode extends DexStmtNode {\n    public final int a;\n    public final int b;\n\n    public Stmt2RNode(Op op, int a, int b) {\n        super(op);\n        this.a = a;\n        this.b = b;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitStmt2R(op, a, b);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/Stmt3RNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class Stmt3RNode extends DexStmtNode {\n    public final int a;\n    public final int b;\n    public final int c;\n\n    public Stmt3RNode(Op op, int a, int b, int c) {\n        super(op);\n        this.a = a;\n        this.b = b;\n        this.c = c;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitStmt3R(op, a, b, c);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/node/insn/TypeStmtNode.java",
    "content": "package com.googlecode.d2j.node.insn;\n\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\npublic class TypeStmtNode extends DexStmtNode {\n\n    public final int a;\n    public final int b;\n    public final String type;\n\n    public TypeStmtNode(Op op, int a, int b, String type) {\n        super(op);\n        this.a = a;\n        this.b = b;\n        this.type = type;\n    }\n\n    @Override\n    public void accept(DexCodeVisitor cv) {\n        cv.visitTypeStmt(op, a, b, type);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/reader/CFG.java",
    "content": "package com.googlecode.d2j.reader;\n\npublic interface CFG {\n    public static final int kInstrCanBranch = 1; // conditional or unconditional branch\n    public static final int kInstrCanContinue = 1 << 1; // flow can continue to next statement\n    public static final int kInstrCanSwitch = 1 << 2; // switch\n    public static final int kInstrCanThrow = 1 << 3; // could cause an exception to be thrown\n    public static final int kInstrCanReturn = 1 << 4; // returns, no additional statements\n    public static final int kInstrInvoke = 1 << 5; // a flavor of invoke\n\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/reader/InstructionFormat.java",
    "content": "package com.googlecode.d2j.reader;\n\npublic enum InstructionFormat {\n    // kFmt00x(0), // unknown format (also used for \"breakpoint\" opcode)\n    kFmt10x(1), // op\n    kFmt12x(1), // op vA, vB\n    kFmt11n(1), // op vA, #+B\n    kFmt11x(1), // op vAA\n    kFmt10t(1), // op +AA\n    // kFmt20bc(2), // [opt] op AA, thing@BBBB\n    kFmt20t(2), // op +AAAA\n    kFmt22x(2), // op vAA, vBBBB\n    kFmt21t(2), // op vAA, +BBBB\n    kFmt21s(2), // op vAA, #+BBBB\n    kFmt21h(2), // op vAA, #+BBBB00000[00000000]\n    kFmt21c(2), // op vAA, thing@BBBB\n    kFmt23x(2), // op vAA, vBB, vCC\n    kFmt22b(2), // op vAA, vBB, #+CC\n    kFmt22t(2), // op vA, vB, +CCCC\n    kFmt22s(2), // op vA, vB, #+CCCC\n    kFmt22c(2), // op vA, vB, thing@CCCC\n    // kFmt22cs(2), // [opt] op vA, vB, field offset CCCC\n    kFmt30t(3), // op +AAAAAAAA\n    kFmt32x(3), // op vAAAA, vBBBB\n    kFmt31i(3), // op vAA, #+BBBBBBBB\n    kFmt31t(3), // op vAA, +BBBBBBBB\n    kFmt31c(3), // op vAA, string@BBBBBBBB\n    kFmt35c(3), // op {vC,vD,vE,vF,vG}, thing@BBBB\n    // kFmt35ms(3), // [opt] invoke-virtual+super\n    kFmt3rc(3), // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB\n    // kFmt3rms(3), // [opt] invoke-virtual+super/range\n    kFmt45cc(4), // op {vC,vD,vE,vF,vG}, meth@BBBB, proto@HHHH\n    kFmt4rcc(4), // op {vCCCC .. vNNNNN}, meth@BBBB, proto@HHHH\n    kFmt51l(5), // op vAA, #+BBBBBBBBBBBBBBBB\n    // kFmt35mi(3), // [opt] inline invoke\n    // kFmt3rmi(3), // [opt] inline invoke/range\n\n    ;\n    public int size;\n\n    InstructionFormat(int size) {\n        this.size = size;\n    }\n};\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/reader/InstructionIndexType.java",
    "content": "package com.googlecode.d2j.reader;\n\n/* package */enum InstructionIndexType {\n    kIndexUnknown, //\n    kIndexNone, // has no index\n    kIndexVaries, // \"It depends.\" Used for throw-verification-error\n    kIndexTypeRef, // type reference index\n    kIndexStringRef, // string reference index\n    kIndexMethodRef, // method reference index\n    kIndexFieldRef, // field reference index\n    kIndexInlineMethod, // inline method index (for inline linked methods)\n    kIndexVtableOffset, // vtable offset (for static linked methods)\n    kIndexFieldOffset, // field offset (for static linked fields)\n    kIndexMethodAndProtoRef, // 038,\n    kIndexCallSiteRef, // 038,\n};"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/reader/Op.java",
    "content": "package com.googlecode.d2j.reader;\n\nimport static com.googlecode.d2j.reader.InstructionFormat.*;\nimport static com.googlecode.d2j.reader.InstructionIndexType.*;\n\npublic enum Op implements CFG {\n    NOP(0x00, \"nop\", kFmt10x, kIndexNone, kInstrCanContinue, false), //\n    MOVE(0x01, \"move\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_FROM16(0x02, \"move/from16\", kFmt22x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_16(0x03, \"move/16\", kFmt32x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_WIDE(0x04, \"move-wide\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_WIDE_FROM16(0x05, \"move-wide/from16\", kFmt22x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_WIDE_16(0x06, \"move-wide/16\", kFmt32x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_OBJECT(0x07, \"move-object\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_OBJECT_FROM16(0x08, \"move-object/from16\", kFmt22x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_OBJECT_16(0x09, \"move-object/16\", kFmt32x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_RESULT(0x0a, \"move-result\", kFmt11x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_RESULT_WIDE(0x0b, \"move-result-wide\", kFmt11x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_RESULT_OBJECT(0x0c, \"move-result-object\", kFmt11x, kIndexNone, kInstrCanContinue, true), //\n    MOVE_EXCEPTION(0x0d, \"move-exception\", kFmt11x, kIndexNone, kInstrCanContinue, true), //\n    RETURN_VOID(0x0e, \"return-void\", kFmt10x, kIndexNone, kInstrCanReturn, false), //\n    RETURN(0x0f, \"return\", kFmt11x, kIndexNone, kInstrCanReturn, false), //\n    RETURN_WIDE(0x10, \"return-wide\", kFmt11x, kIndexNone, kInstrCanReturn, false), //\n    RETURN_OBJECT(0x11, \"return-object\", kFmt11x, kIndexNone, kInstrCanReturn, false), //\n    CONST_4(0x12, \"const/4\", kFmt11n, kIndexNone, kInstrCanContinue, true), //\n    CONST_16(0x13, \"const/16\", kFmt21s, kIndexNone, kInstrCanContinue, true), //\n    CONST(0x14, \"const\", kFmt31i, kIndexNone, kInstrCanContinue, true), //\n    CONST_HIGH16(0x15, \"const/high16\", kFmt21h, kIndexNone, kInstrCanContinue, true), //\n    CONST_WIDE_16(0x16, \"const-wide/16\", kFmt21s, kIndexNone, kInstrCanContinue, true), //\n    CONST_WIDE_32(0x17, \"const-wide/32\", kFmt31i, kIndexNone, kInstrCanContinue, true), //\n    CONST_WIDE(0x18, \"const-wide\", kFmt51l, kIndexNone, kInstrCanContinue, true), //\n    CONST_WIDE_HIGH16(0x19, \"const-wide/high16\", kFmt21h, kIndexNone, kInstrCanContinue, true), //\n    CONST_STRING(0x1a, \"const-string\", kFmt21c, kIndexStringRef, kInstrCanContinue | kInstrCanThrow, true), //\n    CONST_STRING_JUMBO(0x1b, \"const-string/jumbo\", kFmt31c, kIndexStringRef, kInstrCanContinue | kInstrCanThrow, true), //\n    CONST_CLASS(0x1c, \"const-class\", kFmt21c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    MONITOR_ENTER(0x1d, \"monitor-enter\", kFmt11x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    MONITOR_EXIT(0x1e, \"monitor-exit\", kFmt11x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    CHECK_CAST(0x1f, \"check-cast\", kFmt21c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    INSTANCE_OF(0x20, \"instance-of\", kFmt22c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    ARRAY_LENGTH(0x21, \"array-length\", kFmt12x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    NEW_INSTANCE(0x22, \"new-instance\", kFmt21c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    NEW_ARRAY(0x23, \"new-array\", kFmt22c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    FILLED_NEW_ARRAY(0x24, \"filled-new-array\", kFmt35c, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow, true), //\n    FILLED_NEW_ARRAY_RANGE(0x25, \"filled-new-array/range\", kFmt3rc, kIndexTypeRef, kInstrCanContinue | kInstrCanThrow,\n            true), //\n    FILL_ARRAY_DATA(0x26, \"fill-array-data\", kFmt31t, kIndexNone, kInstrCanContinue, false), //\n    THROW(0x27, \"throw\", kFmt11x, kIndexNone, kInstrCanThrow, false), //\n    GOTO(0x28, \"goto\", kFmt10t, kIndexNone, kInstrCanBranch, false), //\n    GOTO_16(0x29, \"goto/16\", kFmt20t, kIndexNone, kInstrCanBranch, false), //\n    GOTO_32(0x2a, \"goto/32\", kFmt30t, kIndexNone, kInstrCanBranch, false), //\n    PACKED_SWITCH(0x2b, \"packed-switch\", kFmt31t, kIndexNone, kInstrCanContinue | kInstrCanSwitch, false), //\n    SPARSE_SWITCH(0x2c, \"sparse-switch\", kFmt31t, kIndexNone, kInstrCanContinue | kInstrCanSwitch, false), //\n    CMPL_FLOAT(0x2d, \"cmpl-float\", kFmt23x, kIndexNone, kInstrCanContinue, false), //\n    CMPG_FLOAT(0x2e, \"cmpg-float\", kFmt23x, kIndexNone, kInstrCanContinue, false), //\n    CMPL_DOUBLE(0x2f, \"cmpl-double\", kFmt23x, kIndexNone, kInstrCanContinue, false), //\n    CMPG_DOUBLE(0x30, \"cmpg-double\", kFmt23x, kIndexNone, kInstrCanContinue, false), //\n    CMP_LONG(0x31, \"cmp-long\", kFmt23x, kIndexNone, kInstrCanContinue, false), //\n    IF_EQ(0x32, \"if-eq\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_NE(0x33, \"if-ne\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_LT(0x34, \"if-lt\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_GE(0x35, \"if-ge\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_GT(0x36, \"if-gt\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_LE(0x37, \"if-le\", kFmt22t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_EQZ(0x38, \"if-eqz\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_NEZ(0x39, \"if-nez\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_LTZ(0x3a, \"if-ltz\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_GEZ(0x3b, \"if-gez\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_GTZ(0x3c, \"if-gtz\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n    IF_LEZ(0x3d, \"if-lez\", kFmt21t, kIndexNone, kInstrCanBranch | kInstrCanContinue, false), //\n//    UNUSED_3E(0x3e, \"unused-3e\", null, kIndexUnknown, 0, false), //\n//    UNUSED_3F(0x3f, \"unused-3f\", null, kIndexUnknown, 0, false), //\n//    UNUSED_40(0x40, \"unused-40\", null, kIndexUnknown, 0, false), //\n//    UNUSED_41(0x41, \"unused-41\", null, kIndexUnknown, 0, false), //\n//    UNUSED_42(0x42, \"unused-42\", null, kIndexUnknown, 0, false), //\n//    UNUSED_43(0x43, \"unused-43\", null, kIndexUnknown, 0, false), //\n    AGET(0x44, \"aget\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_WIDE(0x45, \"aget-wide\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_OBJECT(0x46, \"aget-object\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_BOOLEAN(0x47, \"aget-boolean\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_BYTE(0x48, \"aget-byte\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_CHAR(0x49, \"aget-char\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AGET_SHORT(0x4a, \"aget-short\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    APUT(0x4b, \"aput\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_WIDE(0x4c, \"aput-wide\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_OBJECT(0x4d, \"aput-object\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_BOOLEAN(0x4e, \"aput-boolean\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_BYTE(0x4f, \"aput-byte\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_CHAR(0x50, \"aput-char\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    APUT_SHORT(0x51, \"aput-short\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, false), //\n    IGET(0x52, \"iget\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_WIDE(0x53, \"iget-wide\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_OBJECT(0x54, \"iget-object\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_BOOLEAN(0x55, \"iget-boolean\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_BYTE(0x56, \"iget-byte\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_CHAR(0x57, \"iget-char\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IGET_SHORT(0x58, \"iget-short\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    IPUT(0x59, \"iput\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_WIDE(0x5a, \"iput-wide\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_OBJECT(0x5b, \"iput-object\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_BOOLEAN(0x5c, \"iput-boolean\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_BYTE(0x5d, \"iput-byte\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_CHAR(0x5e, \"iput-char\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    IPUT_SHORT(0x5f, \"iput-short\", kFmt22c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SGET(0x60, \"sget\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_WIDE(0x61, \"sget-wide\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_OBJECT(0x62, \"sget-object\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_BOOLEAN(0x63, \"sget-boolean\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_BYTE(0x64, \"sget-byte\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_CHAR(0x65, \"sget-char\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SGET_SHORT(0x66, \"sget-short\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, true), //\n    SPUT(0x67, \"sput\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_WIDE(0x68, \"sput-wide\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_OBJECT(0x69, \"sput-object\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_BOOLEAN(0x6a, \"sput-boolean\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_BYTE(0x6b, \"sput-byte\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_CHAR(0x6c, \"sput-char\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    SPUT_SHORT(0x6d, \"sput-short\", kFmt21c, kIndexFieldRef, kInstrCanContinue | kInstrCanThrow, false), //\n    INVOKE_VIRTUAL(0x6e, \"invoke-virtual\", kFmt35c, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow | kInstrInvoke,\n            true), //\n\n    /**\n     *  Behavior changed in 037, interface method is allowed\n     */\n    INVOKE_SUPER(0x6f, \"invoke-super\", kFmt35c, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow | kInstrInvoke,\n            true), //\n    INVOKE_DIRECT(0x70, \"invoke-direct\", kFmt35c, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow | kInstrInvoke,\n            true), //\n    INVOKE_STATIC(0x71, \"invoke-static\", kFmt35c, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow | kInstrInvoke,\n            true), //\n    INVOKE_INTERFACE(0x72, \"invoke-interface\", kFmt35c, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n//    UNUSED_73(0x73, \"unused-73\", null, kIndexUnknown, 0, false), //\n    INVOKE_VIRTUAL_RANGE(0x74, \"invoke-virtual/range\", kFmt3rc, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_SUPER_RANGE(0x75, \"invoke-super/range\", kFmt3rc, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_DIRECT_RANGE(0x76, \"invoke-direct/range\", kFmt3rc, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_STATIC_RANGE(0x77, \"invoke-static/range\", kFmt3rc, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_INTERFACE_RANGE(0x78, \"invoke-interface/range\", kFmt3rc, kIndexMethodRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n//    UNUSED_79(0x79, \"unused-79\", null, kIndexUnknown, 0, false), //\n//    UNUSED_7A(0x7a, \"unused-7a\", null, kIndexUnknown, 0, false), //\n    NEG_INT(0x7b, \"neg-int\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    NOT_INT(0x7c, \"not-int\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    NEG_LONG(0x7d, \"neg-long\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    NOT_LONG(0x7e, \"not-long\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    NEG_FLOAT(0x7f, \"neg-float\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    NEG_DOUBLE(0x80, \"neg-double\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_LONG(0x81, \"int-to-long\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_FLOAT(0x82, \"int-to-float\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_DOUBLE(0x83, \"int-to-double\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    LONG_TO_INT(0x84, \"long-to-int\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    LONG_TO_FLOAT(0x85, \"long-to-float\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    LONG_TO_DOUBLE(0x86, \"long-to-double\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    FLOAT_TO_INT(0x87, \"float-to-int\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    FLOAT_TO_LONG(0x88, \"float-to-long\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    FLOAT_TO_DOUBLE(0x89, \"float-to-double\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DOUBLE_TO_INT(0x8a, \"double-to-int\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DOUBLE_TO_LONG(0x8b, \"double-to-long\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DOUBLE_TO_FLOAT(0x8c, \"double-to-float\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_BYTE(0x8d, \"int-to-byte\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_CHAR(0x8e, \"int-to-char\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    INT_TO_SHORT(0x8f, \"int-to-short\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    ADD_INT(0x90, \"add-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SUB_INT(0x91, \"sub-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    MUL_INT(0x92, \"mul-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    DIV_INT(0x93, \"div-int\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_INT(0x94, \"rem-int\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_INT(0x95, \"and-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    OR_INT(0x96, \"or-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    XOR_INT(0x97, \"xor-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SHL_INT(0x98, \"shl-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SHR_INT(0x99, \"shr-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    USHR_INT(0x9a, \"ushr-int\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    ADD_LONG(0x9b, \"add-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SUB_LONG(0x9c, \"sub-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    MUL_LONG(0x9d, \"mul-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    DIV_LONG(0x9e, \"div-long\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_LONG(0x9f, \"rem-long\", kFmt23x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_LONG(0xa0, \"and-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    OR_LONG(0xa1, \"or-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    XOR_LONG(0xa2, \"xor-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SHL_LONG(0xa3, \"shl-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SHR_LONG(0xa4, \"shr-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    USHR_LONG(0xa5, \"ushr-long\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    ADD_FLOAT(0xa6, \"add-float\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SUB_FLOAT(0xa7, \"sub-float\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    MUL_FLOAT(0xa8, \"mul-float\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    DIV_FLOAT(0xa9, \"div-float\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    REM_FLOAT(0xaa, \"rem-float\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    ADD_DOUBLE(0xab, \"add-double\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    SUB_DOUBLE(0xac, \"sub-double\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    MUL_DOUBLE(0xad, \"mul-double\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    DIV_DOUBLE(0xae, \"div-double\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    REM_DOUBLE(0xaf, \"rem-double\", kFmt23x, kIndexNone, kInstrCanContinue, true), //\n    ADD_INT_2ADDR(0xb0, \"add-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SUB_INT_2ADDR(0xb1, \"sub-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MUL_INT_2ADDR(0xb2, \"mul-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DIV_INT_2ADDR(0xb3, \"div-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_INT_2ADDR(0xb4, \"rem-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_INT_2ADDR(0xb5, \"and-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    OR_INT_2ADDR(0xb6, \"or-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    XOR_INT_2ADDR(0xb7, \"xor-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SHL_INT_2ADDR(0xb8, \"shl-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SHR_INT_2ADDR(0xb9, \"shr-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    USHR_INT_2ADDR(0xba, \"ushr-int/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    ADD_LONG_2ADDR(0xbb, \"add-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SUB_LONG_2ADDR(0xbc, \"sub-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MUL_LONG_2ADDR(0xbd, \"mul-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DIV_LONG_2ADDR(0xbe, \"div-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_LONG_2ADDR(0xbf, \"rem-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_LONG_2ADDR(0xc0, \"and-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    OR_LONG_2ADDR(0xc1, \"or-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    XOR_LONG_2ADDR(0xc2, \"xor-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SHL_LONG_2ADDR(0xc3, \"shl-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SHR_LONG_2ADDR(0xc4, \"shr-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    USHR_LONG_2ADDR(0xc5, \"ushr-long/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    ADD_FLOAT_2ADDR(0xc6, \"add-float/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SUB_FLOAT_2ADDR(0xc7, \"sub-float/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MUL_FLOAT_2ADDR(0xc8, \"mul-float/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DIV_FLOAT_2ADDR(0xc9, \"div-float/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    REM_FLOAT_2ADDR(0xca, \"rem-float/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    ADD_DOUBLE_2ADDR(0xcb, \"add-double/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    SUB_DOUBLE_2ADDR(0xcc, \"sub-double/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    MUL_DOUBLE_2ADDR(0xcd, \"mul-double/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    DIV_DOUBLE_2ADDR(0xce, \"div-double/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    REM_DOUBLE_2ADDR(0xcf, \"rem-double/2addr\", kFmt12x, kIndexNone, kInstrCanContinue, true), //\n    ADD_INT_LIT16(0xd0, \"add-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    RSUB_INT(0xd1, \"rsub-int\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    MUL_INT_LIT16(0xd2, \"mul-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    DIV_INT_LIT16(0xd3, \"div-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_INT_LIT16(0xd4, \"rem-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_INT_LIT16(0xd5, \"and-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    OR_INT_LIT16(0xd6, \"or-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    XOR_INT_LIT16(0xd7, \"xor-int/lit16\", kFmt22s, kIndexNone, kInstrCanContinue, true), //\n    ADD_INT_LIT8(0xd8, \"add-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    RSUB_INT_LIT8(0xd9, \"rsub-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    MUL_INT_LIT8(0xda, \"mul-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    DIV_INT_LIT8(0xdb, \"div-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    REM_INT_LIT8(0xdc, \"rem-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue | kInstrCanThrow, true), //\n    AND_INT_LIT8(0xdd, \"and-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    OR_INT_LIT8(0xde, \"or-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    XOR_INT_LIT8(0xdf, \"xor-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    SHL_INT_LIT8(0xe0, \"shl-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    SHR_INT_LIT8(0xe1, \"shr-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    USHR_INT_LIT8(0xe2, \"ushr-int/lit8\", kFmt22b, kIndexNone, kInstrCanContinue, true), //\n    INVOKE_POLYMORPHIC(0xfa, \"invoke-polymorphic\", kFmt45cc, kIndexMethodAndProtoRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_POLYMORPHIC_RANGE(0xfb, \"invoke-polymorphic/range\", kFmt4rcc, kIndexMethodAndProtoRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_CUSTOM(0xfc, \"invoke-custom\", kFmt35c, kIndexCallSiteRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    INVOKE_CUSTOM_RANGE(0xfd, \"invoke-custom/range\", kFmt3rc, kIndexCallSiteRef, kInstrCanContinue | kInstrCanThrow\n            | kInstrInvoke, true), //\n    BAD_OP(-1, \"bad-opcode\", null, kIndexNone, 0, false), //\n    ;\n    public int opcode;\n    public InstructionFormat format;\n    /* package */InstructionIndexType indexType;\n    /* package */int flags;\n    public String displayName;\n    public final static Op ops[] = new Op[256];\n    public boolean changeFrame;\n    static {\n        Op[] ops = Op.ops;\n        for (Op op : Op.values()) {\n            if (op.opcode >= 0) {\n                ops[op.opcode] = op;\n            }\n        }\n    }\n\n    public boolean canBranch() {\n        return 0 != (flags & kInstrCanBranch);\n    }\n\n    public boolean canContinue() {\n        return 0 != (flags & kInstrCanContinue);\n    }\n\n    public boolean canReturn() {\n        return 0 != (flags & kInstrCanReturn);\n    }\n\n    public boolean canSwitch() {\n        return 0 != (flags & kInstrCanSwitch);\n    }\n\n    public boolean canThrow() {\n        return 0 != (flags & kInstrCanThrow);\n    }\n\n    Op(int op, String displayName, InstructionFormat fmt, InstructionIndexType indexType, int flags, boolean changeFrame) {\n        this.opcode = op;\n        this.displayName = displayName;\n        this.format = fmt;\n        this.indexType = indexType;\n        this.flags = flags;\n    }\n\n    public String toString() {\n        return displayName;\n    }\n}"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexAnnotationAble.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\nimport com.googlecode.d2j.Visibility;\r\n\r\n/**\r\n * 用于访问注解\r\n * \r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic interface DexAnnotationAble {\r\n\r\n    /**\r\n     * 访问注解\r\n     * \r\n     * @param name\r\n     *            注解名\r\n     * @param visibility\r\n     *            是否运行时可见\r\n     * @return\r\n     */\r\n    DexAnnotationVisitor visitAnnotation(String name, Visibility visibility);\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexAnnotationVisitor.java",
    "content": "/***\r\n * ASM: a very small and fast Java bytecode manipulation framework\r\n * Copyright (c) 2000-2007 INRIA, France Telecom\r\n * All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without\r\n * modification, are permitted provided that the following conditions\r\n * are met:\r\n * 1. Redistributions of source code must retain the above copyright\r\n *    notice, this list of conditions and the following disclaimer.\r\n * 2. Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimer in the\r\n *    documentation and/or other materials provided with the distribution.\r\n * 3. Neither the name of the copyright holders nor the names of its\r\n *    contributors may be used to endorse or promote products derived from\r\n *    this software without specific prior written permission.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\r\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\nimport com.googlecode.d2j.DexType;\r\n\r\n/**\r\n * A visitor to visit a Java annotation. The methods of this interface must be called in the following order: (\r\n * <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt>)* <tt>visitEnd</tt>.\r\n * \r\n * @author Eric Bruneton\r\n * @author Eugene Kuleshov\r\n */\r\npublic class DexAnnotationVisitor {\r\n    protected DexAnnotationVisitor visitor;\r\n\r\n    public DexAnnotationVisitor() {\r\n        super();\r\n    }\r\n\r\n    public DexAnnotationVisitor(DexAnnotationVisitor visitor) {\r\n        super();\r\n        this.visitor = visitor;\r\n    }\r\n\r\n    /**\r\n     * Visits a primitive value of the annotation.\r\n     * \r\n     * @param name\r\n     *            the value name.\r\n     * @param value\r\n     *            the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},\r\n     *            {@link Integer}, {@link Long}, {@link Float}, {@link Double}, {@link String} or {@link DexType}.\r\n     */\r\n    public void visit(String name, Object value) {\r\n        if (visitor != null) {\r\n            visitor.visit(name, value);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Visits an enumeration value of the annotation.\r\n     * \r\n     * @param name\r\n     *            the value name.\r\n     * @param desc\r\n     *            the class descriptor of the enumeration class.\r\n     * @param value\r\n     *            the actual enumeration value.\r\n     */\r\n    public void visitEnum(String name, String desc, String value) {\r\n        if (this.visitor != null) {\r\n            visitor.visitEnum(name, desc, value);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Visits a nested annotation value of the annotation.\r\n     * \r\n     * @param name\r\n     *            the value name.\r\n     * @param desc\r\n     *            the class descriptor of the nested annotation class.\r\n     * @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this visitor is not interested\r\n     *         in visiting this nested annotation. <i>The nested annotation value must be fully visited before calling\r\n     *         other methods on this annotation visitor</i>.\r\n     */\r\n    public DexAnnotationVisitor visitAnnotation(String name, String desc) {\r\n        if (this.visitor != null) {\r\n            return this.visitor.visitAnnotation(name, desc);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public DexAnnotationVisitor visitArray(String name) {\r\n        if (visitor != null) {\r\n            return visitor.visitArray(name);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Visits the end of the annotation.\r\n     */\r\n    public void visitEnd() {\r\n        if (this.visitor != null) {\r\n            visitor.visitEnd();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexClassVisitor.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Visibility;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n */\r\npublic class DexClassVisitor implements DexAnnotationAble {\r\n    protected DexClassVisitor visitor;\r\n\r\n    public DexClassVisitor() {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @param dcv\r\n     */\r\n    public DexClassVisitor(DexClassVisitor dcv) {\r\n        super();\r\n        this.visitor = dcv;\r\n    }\r\n\r\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitAnnotation(name, visibility);\r\n    }\r\n\r\n    public void visitEnd() {\r\n        if (visitor == null) {\r\n            return;\r\n        }\r\n        visitor.visitEnd();\r\n    }\r\n\r\n    public DexFieldVisitor visitField(int accessFlags, Field field, Object value) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitField(accessFlags, field, value);\r\n    }\r\n\r\n    public DexMethodVisitor visitMethod(int accessFlags, Method method) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitMethod(accessFlags, method);\r\n    }\r\n\r\n    public void visitSource(String file) {\r\n        if (visitor == null) {\r\n            return;\r\n        }\r\n        visitor.visitSource(file);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexCodeVisitor.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\nimport com.googlecode.d2j.*;\r\nimport com.googlecode.d2j.reader.Op;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class DexCodeVisitor {\r\n    protected DexCodeVisitor visitor;\r\n\r\n    public DexCodeVisitor() {\r\n        super();\r\n    }\r\n\r\n    public DexCodeVisitor(DexCodeVisitor visitor) {\r\n        super();\r\n        this.visitor = visitor;\r\n    }\r\n\r\n    public void visitRegister(int total) {\r\n        if (visitor != null) {\r\n            visitor.visitRegister(total);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_X_INT_LIT8\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param distReg\r\n     * @param srcReg\r\n     * @param content\r\n     */\r\n    public void visitStmt2R1N(Op op, int distReg, int srcReg, int content) {\r\n        if (visitor != null) {\r\n            visitor.visitStmt2R1N(op, distReg, srcReg, content);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * \r\n     * OP_ADD\r\n     * OP_SUB\r\n     * OP_MUL\r\n     * OP_DIV\r\n     * OP_REM\r\n     * OP_AND\r\n     * OP_OR\r\n     * OP_XOR\r\n     * OP_SHL\r\n     * OP_SHR\r\n     * OP_USHR\r\n     * OP_CMPL\r\n     * OP_CMPG\r\n     * OP_CMP\r\n     * OP_AGETX\r\n     * OP_APUTX\r\n     * </pre>\r\n     * \r\n     */\r\n    public void visitStmt3R(Op op, int a, int b, int c) {\r\n        if (visitor != null) {\r\n            visitor.visitStmt3R(op, a, b, c);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_INSTANCE_OF\r\n     * OP_NEW_ARRAY\r\n     * OP_CHECK_CAST\r\n     * OP_NEW_INSTANCE\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param a\r\n     * @param b\r\n     * @param type\r\n     */\r\n    public void visitTypeStmt(Op op, int a, int b, String type) {\r\n        if (visitor != null) {\r\n            visitor.visitTypeStmt(op, a, b, type);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * CONST * CONST_WIDE * CONST_STRING * CONST_CLASS *\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param ra\r\n     * @param value\r\n     *            int/long/type\r\n     */\r\n    public void visitConstStmt(Op op, int ra, Object value) {\r\n        if (visitor != null) {\r\n            visitor.visitConstStmt(op, ra, value);\r\n        }\r\n    }\r\n\r\n    public void visitFillArrayDataStmt(Op op, int ra, Object array) {\r\n        if (visitor != null) {\r\n            visitor.visitFillArrayDataStmt(op, ra, array);\r\n        }\r\n    }\r\n\r\n    public void visitEnd() {\r\n        if (visitor != null) {\r\n            visitor.visitEnd();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_IGETX a,b field\r\n     * OP_IPUTX a,b field\r\n     * OP_SGETX a field\r\n     * OP_SPUTX a field\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param a\r\n     * @param b\r\n     * @param field\r\n     */\r\n    public void visitFieldStmt(Op op, int a, int b, Field field) {\r\n        if (visitor != null) {\r\n            visitor.visitFieldStmt(op, a, b, field);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_FILLED_NEW_ARRAY\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param args\r\n     * @param type\r\n     */\r\n    public void visitFilledNewArrayStmt(Op op, int[] args, String type) {\r\n        if (visitor != null) {\r\n            visitor.visitFilledNewArrayStmt(op, args, type);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_IF_EQ\r\n     * OP_IF_NE\r\n     * OP_IF_LT\r\n     * OP_IF_GE\r\n     * OP_IF_GT\r\n     * OP_IF_LE\r\n     * OP_GOTO\r\n     * OP_IF_EQZ\r\n     * OP_IF_NEZ\r\n     * OP_IF_LTZ\r\n     * OP_IF_GEZ\r\n     * OP_IF_GTZ\r\n     * OP_IF_LEZ\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param a\r\n     * @param b\r\n     * @param label\r\n     */\r\n    public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\r\n        if (visitor != null) {\r\n            visitor.visitJumpStmt(op, a, b, label);\r\n        }\r\n    }\r\n\r\n    public void visitLabel(DexLabel label) {\r\n        if (visitor != null) {\r\n            visitor.visitLabel(label);\r\n        }\r\n    }\r\n\r\n    public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {\r\n        if (visitor != null) {\r\n            visitor.visitSparseSwitchStmt(op, ra, cases, labels);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_INVOKE_VIRTUAL\r\n     * OP_INVOKE_SUPER\r\n     * OP_INVOKE_DIRECT\r\n     * OP_INVOKE_STATIC\r\n     * OP_INVOKE_INTERFACE\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param args\r\n     * @param method\r\n     */\r\n    public void visitMethodStmt(Op op, int[] args, Method method) {\r\n        if (visitor != null) {\r\n            visitor.visitMethodStmt(op, args, method);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_INVOKE_CUSTOM\r\n     * </pre>\r\n     */\r\n    public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) {\r\n        if (visitor != null) {\r\n            visitor.visitMethodStmt(op, args, name, proto, bsm, bsmArgs);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_INVOKE_POLYMORPHIC\r\n     * </pre>\r\n     *\r\n     */\r\n    public void visitMethodStmt(Op op, int[] args, Method bsm, Proto proto) {\r\n        if (visitor != null) {\r\n            visitor.visitMethodStmt(op, args, bsm, proto);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_MOVE*\r\n     * a = a X b\r\n     * OP_ARRAY_LENGTH\r\n     * a=Xb\r\n     * X_TO_Y\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param a\r\n     * @param b\r\n     */\r\n    public void visitStmt2R(Op op, int a, int b) {\r\n        if (visitor != null) {\r\n            visitor.visitStmt2R(op, a, b);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * \r\n     * {@link Op#RETURN_VOID} {@link Op#NOP} {@link Op#BAD_OP}\r\n     * \r\n     * @param op\r\n     */\r\n    public void visitStmt0R(Op op) {\r\n        if (visitor != null) {\r\n            visitor.visitStmt0R(op);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * <pre>\r\n     * OP_RETURN_X\r\n     * OP_THROW_X\r\n     * OP_MONITOR_ENTER\r\n     * OP_MONITOR_EXIT\r\n     * OP_MOVE_RESULT_X\r\n     * OP_MOVE_EXCEPTION_X\r\n     * </pre>\r\n     * \r\n     * @param op\r\n     * @param reg\r\n     */\r\n    public void visitStmt1R(Op op, int reg) {\r\n        if (visitor != null) {\r\n            visitor.visitStmt1R(op, reg);\r\n        }\r\n    }\r\n\r\n    public void visitPackedSwitchStmt(Op op, int aA, int first_case, DexLabel[] labels) {\r\n        if (visitor != null) {\r\n            visitor.visitPackedSwitchStmt(op, aA, first_case, labels);\r\n        }\r\n    }\r\n\r\n    public void visitTryCatch(DexLabel start, DexLabel end, DexLabel handler[], String type[]) {\r\n        if (visitor != null) {\r\n            visitor.visitTryCatch(start, end, handler, type);\r\n        }\r\n    }\r\n\r\n    public DexDebugVisitor visitDebug() {\r\n        if (visitor != null) {\r\n            return visitor.visitDebug();\r\n        }\r\n        return null;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexDebugVisitor.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.visitors;\n\nimport com.googlecode.d2j.DexLabel;\n\npublic class DexDebugVisitor {\n    protected DexDebugVisitor visitor;\n\n    public DexDebugVisitor() {\n    }\n\n    public DexDebugVisitor(DexDebugVisitor visitor) {\n        this.visitor = visitor;\n    }\n\n    /**\n     * \n     * @param parameterIndex\n     *            start with the first index of DexMethod.getParameterTypes(), no 'this'\n     * @param name\n     */\n    public void visitParameterName(int parameterIndex, String name) {\n        if (visitor != null) {\n            visitor.visitParameterName(parameterIndex, name);\n        }\n    }\n\n    public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) {\n        if (visitor != null) {\n            visitor.visitStartLocal(reg, label, name, type, signature);\n        }\n    }\n\n    public void visitLineNumber(int line, DexLabel label) {\n        if (visitor != null) {\n            visitor.visitLineNumber(line, label);\n        }\n    }\n\n    public void visitEndLocal(int reg, DexLabel label) {\n        if (visitor != null) {\n            visitor.visitEndLocal(reg, label);\n        }\n    }\n\n    public void visitSetFile(String file) {\n        if (visitor != null) {\n            visitor.visitSetFile(file);\n        }\n    }\n\n    public void visitPrologue(DexLabel dexLabel) {\n        if (visitor != null) {\n            visitor.visitPrologue(dexLabel);\n        }\n    }\n\n    public void visitEpiogue(DexLabel dexLabel) {\n        if (visitor != null) {\n            visitor.visitEpiogue(dexLabel);\n        }\n    }\n\n    public void visitRestartLocal(int reg, DexLabel label) {\n        if (visitor != null) {\n            visitor.visitRestartLocal(reg, label);\n        }\n    }\n\n    public void visitEnd() {\n        if (visitor != null) {\n            visitor.visitEnd();\n        }\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexFieldVisitor.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.d2j.visitors;\n\nimport com.googlecode.d2j.Visibility;\n\n/**\n * @author bob\n * \n */\npublic class DexFieldVisitor implements DexAnnotationAble {\n    protected DexFieldVisitor visitor;\n\n    public DexFieldVisitor(DexFieldVisitor visitor) {\n        super();\n        this.visitor = visitor;\n    }\n\n    public DexFieldVisitor() {\n    }\n\n    public void visitEnd() {\n        if (visitor == null) {\n            return;\n        }\n        visitor.visitEnd();\n    }\n\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\n        if (visitor == null) {\n            return null;\n        }\n        return visitor.visitAnnotation(name, visibility);\n    }\n}\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexFileVisitor.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class DexFileVisitor {\r\n    protected DexFileVisitor visitor;\r\n\r\n    public DexFileVisitor() {\r\n        super();\r\n    }\r\n\r\n    public DexFileVisitor(DexFileVisitor visitor) {\r\n        super();\r\n        this.visitor = visitor;\r\n    }\r\n\r\n    public void visitDexFileVersion(int version) {\r\n        if (visitor != null) {\r\n            visitor.visitDexFileVersion(version);\r\n        }\r\n    }\r\n\r\n    public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visit(access_flags, className, superClass, interfaceNames);\r\n    }\r\n\r\n    public void visitEnd() {\r\n        if (visitor == null) {\r\n            return;\r\n        }\r\n        visitor.visitEnd();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-reader-api/src/main/java/com/googlecode/d2j/visitors/DexMethodVisitor.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.visitors;\r\n\r\nimport com.googlecode.d2j.Visibility;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class DexMethodVisitor implements DexAnnotationAble {\r\n    protected DexMethodVisitor visitor;\r\n\r\n    public DexMethodVisitor() {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @param mv\r\n     */\r\n    public DexMethodVisitor(DexMethodVisitor mv) {\r\n        super();\r\n        this.visitor = mv;\r\n    }\r\n\r\n    public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitAnnotation(name, visibility);\r\n    }\r\n\r\n    public DexCodeVisitor visitCode() {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitCode();\r\n    }\r\n\r\n    public void visitEnd() {\r\n        if (visitor == null) {\r\n            return;\r\n        }\r\n        visitor.visitEnd();\r\n    }\r\n\r\n    public DexAnnotationAble visitParameterAnnotation(int index) {\r\n        if (visitor == null) {\r\n            return null;\r\n        }\r\n        return visitor.visitParameterAnnotation(index);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-tools/build.gradle",
    "content": "description = 'Dex Tools'\napply plugin:'application'\n\nmainClassName=\"com.googlecode.dex2jar.tools.BaseCmd\"\n\ndependencies {\n  compile project(':dex-translator')\n  compile project(':d2j-smali')\n  compile project(':d2j-jasmin')\n  compile project(':dex-writer')\n  compile project(':d2j-base-cmd')\n}\n\ntask bin_gen(type: JavaExec) {\n    dependsOn jar\n    classpath sourceSets.main.runtimeClasspath\n    ext.binDir=\"$buildDir/generated-sources/bin\"\n    outputs.dir file(ext.binDir)\n    main='com.googlecode.dex2jar.bin_gen.BinGen'\n    args=[\"$projectDir/src/main/bin_gen\",\"$ext.binDir\"]\n}\napplicationDistribution.from(bin_gen)\n//applicationDistribution.from('src/main/jars') {\n//  into(\"lib\")\n//}\napplicationDistribution.from('open-source-license.txt') {\n  into(\"lib\")\n}\napplicationDistribution.from(\"$parent.rootDir\") {\n  include(\"NOTICE.txt\")\n  include(\"LICENSE.txt\")\n}\n\nstartScripts.dependsOn bin_gen\n\nartifacts.archives distZip\n\n"
  },
  {
    "path": "dex-tools/open-source-license.txt",
    "content": "==== dx-*.jar\nApache 2.0 http://www.apache.org/licenses/LICENSE-2.0.html\n\n\n==== antlr-*.jar\n[The BSD License]\nCopyright (c) 2003-2007, Terence Parr\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n* Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright\n  notice, this list of conditions and the following disclaimer in\n  the documentation and/or other materials provided with the\n  distribution.\n* Neither the name of the author nor the names of its contributors\n  may be used to endorse or promote products derived from this\n  software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\nFOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\nCOPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\n\n==== asm-*.jar\n\n ASM: a very small and fast Java bytecode manipulation framework\n Copyright (c) 2000-2005 INRIA, France Telecom\n All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions\n are met:\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n 3. Neither the name of the copyright holders nor the names of its\n    contributors may be used to endorse or promote products derived from\n    this software without specific prior written permission.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n THE POSSIBILITY OF SUCH DAMAGE.\n\n"
  },
  {
    "path": "dex-tools/src/main/assemble/package.xml",
    "content": "<assembly\r\n    xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0\"\r\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd\">\r\n    <id>distribution</id>\r\n    <formats>\r\n        <format>zip</format>\r\n    </formats>\r\n\r\n    <fileSets>\r\n        <fileSet>\r\n            <directory>target/bin/</directory>\r\n            <includes>\r\n                <include>*.sh</include>\r\n                <include>*.bat</include>\r\n            </includes>\r\n            <outputDirectory>/</outputDirectory>\r\n        </fileSet>\r\n    </fileSets>\r\n    <files>\r\n        <file>\r\n            <source>../LICENSE.txt</source>\r\n            <fileMode>664</fileMode>\r\n            <outputDirectory>/</outputDirectory>\r\n        </file>\r\n        <file>\r\n            <source>../NOTICE.txt</source>\r\n            <fileMode>664</fileMode>\r\n            <outputDirectory>/</outputDirectory>\r\n        </file>\r\n        <file>\r\n            <source>open-source-license.txt</source>\r\n            <fileMode>664</fileMode>\r\n            <outputDirectory>/lib</outputDirectory>\r\n        </file>\r\n    </files>\r\n    <dependencySets>\r\n        <dependencySet>\r\n            <outputDirectory>/lib</outputDirectory>\r\n            <scope>runtime</scope>\r\n        </dependencySet>\r\n    </dependencySets>\r\n</assembly>\r\n"
  },
  {
    "path": "dex-tools/src/main/bin_gen/bat_template",
    "content": "@echo off\r\n\r\nREM\r\nREM dex2jar - Tools to work with android .dex and java .class files\r\nREM Copyright (c) 2009-2013 Panxiaobo\r\nREM \r\nREM Licensed under the Apache License, Version 2.0 (the \"License\");\r\nREM you may not use this file except in compliance with the License.\r\nREM You may obtain a copy of the License at\r\nREM \r\nREM      http://www.apache.org/licenses/LICENSE-2.0\r\nREM \r\nREM Unless required by applicable law or agreed to in writing, software\r\nREM distributed under the License is distributed on an \"AS IS\" BASIS,\r\nREM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nREM See the License for the specific language governing permissions and\r\nREM limitations under the License.\r\nREM\r\n\r\nREM call d2j_invoke.bat to setup java environment\r\n@\"%~dp0d2j_invoke.bat\" __@class_name@__ %*\r\n"
  },
  {
    "path": "dex-tools/src/main/bin_gen/class.cfg",
    "content": "\n# from dex-reader\n#d2j-dex-asmifier=com.googlecode.dex2jar.util.ASMifierFileV\n#d2j-dex-dump=com.googlecode.dex2jar.util.Dump\n\n# from dex-tool\nd2j-dex2jar=com.googlecode.dex2jar.tools.Dex2jarCmd\nd2j-jar2dex=com.googlecode.dex2jar.tools.Jar2Dex\nd2j-asm-verify=com.googlecode.dex2jar.tools.AsmVerify\nd2j-jar2jasmin=com.googlecode.d2j.jasmin.Jar2JasminCmd\nd2j-jasmin2jar=com.googlecode.d2j.jasmin.Jasmin2JarCmd\n\nd2j-apk-sign=com.googlecode.dex2jar.tools.ApkSign\n\n#d2j-init-deobf=com.googlecode.dex2jar.tools.DeObfInitCmd\n#d2j-jar-remap=com.googlecode.dex2jar.tools.JarRemap\nd2j-jar-access=com.googlecode.dex2jar.tools.JarAccessCmd\nd2j-decrypt-string=com.googlecode.dex2jar.tools.DecryptStringCmd\nd2j-smali=com.googlecode.d2j.smali.SmaliCmd\nd2j-baksmali=com.googlecode.d2j.smali.BaksmaliCmd\nd2j-dex2smali=com.googlecode.d2j.smali.BaksmaliCmd\n#d2j-dex-remap=com.googlecode.dex2jar.tools.DexRemapCmd\n\n\nd2j-dex-recompute-checksum=com.googlecode.dex2jar.tools.DexRecomputeChecksum\nd2j-std-apk=com.googlecode.dex2jar.tools.StdApkCmd\n\nd2j-dex-weaver=com.googlecode.dex2jar.tools.DexWeaverCmd\nd2j-jar-weaver=com.googlecode.dex2jar.tools.JarWeaverCmd\n\nd2j-class-version-switch=com.googlecode.dex2jar.tools.ClassVersionSwitch\n\n#EOF\n"
  },
  {
    "path": "dex-tools/src/main/bin_gen/d2j_invoke.bat",
    "content": "@echo off\r\nREM better invocation scripts for windows from lanchon, release in public domain. thanks!\r\nREM https://code.google.com/p/dex2jar/issues/detail?id=192\r\n\r\nsetlocal enabledelayedexpansion\r\n\r\nset LIB=%~dp0lib\r\n\r\nset CP=\r\nfor %%X in (\"%LIB%\"\\*.jar) do (\r\n    set CP=!CP!%%X;\r\n)\r\n\r\njava -Xms512m -Xmx1024m -cp \"%CP%\" %*\r\n"
  },
  {
    "path": "dex-tools/src/main/bin_gen/d2j_invoke.sh",
    "content": "#!/bin/sh\n\n#\n# dex2jar - Tools to work with android .dex and java .class files\n# Copyright (c) 2009-2013 Panxiaobo\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#      http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF 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# copy from $Tomcat/bin/startup.sh\n# resolve links - $0 may be a softlink\nPRG=\"$0\"\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\nPRGDIR=`dirname \"$PRG\"`\n#\n\n_classpath=\".\"\nif [ `uname -a | grep -i -c cygwin` -ne 0 ]; then # Cygwin, translate the path\n    for k in \"$PRGDIR\"/lib/*.jar\n    do\n        _classpath=\"${_classpath};`cygpath -w ${k}`\"\n    done\nelse\n    for k in \"$PRGDIR\"/lib/*.jar\n    do\n        _classpath=\"${_classpath}:${k}\"\n    done\nfi\n\njava -Xms512m -Xmx1024m -classpath \"${_classpath}\" \"$@\"\n"
  },
  {
    "path": "dex-tools/src/main/bin_gen/sh_template",
    "content": "#!/bin/sh\n\n#\n# dex2jar - Tools to work with android .dex and java .class files\n# Copyright (c) 2009-2013 Panxiaobo\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#      http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF 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# copy from $Tomcat/bin/startup.sh\n# resolve links - $0 may be a softlink\nPRG=\"$0\"\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\nPRGDIR=`dirname \"$PRG\"`\n#\n\n_classpath=\".\"\nif [ `uname -a | grep -i -c cygwin` -ne 0 ]; then # Cygwin, translate the path\n    for k in \"$PRGDIR\"/lib/*.jar\n    do\n        _classpath=\"${_classpath};`cygpath -w ${k}`\"\n    done\nelse\n    for k in \"$PRGDIR\"/lib/*.jar\n    do\n        _classpath=\"${_classpath}:${k}\"\n    done\nfi\n\njava -Xms512m -Xmx1024m -classpath \"${_classpath}\" \"__@class_name@__\" \"$@\"\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java",
    "content": "/*\r\n * Copyright (C) 2008 The Android Open Source Project\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.googlecode.d2j.signapk;\r\n\r\nimport java.io.File;\r\nimport java.io.FileOutputStream;\r\nimport java.io.FilterOutputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.OutputStream;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.security.DigestOutputStream;\r\nimport java.security.GeneralSecurityException;\r\nimport java.security.MessageDigest;\r\nimport java.security.PrivateKey;\r\nimport java.security.Signature;\r\nimport java.security.SignatureException;\r\nimport java.util.ArrayList;\r\nimport java.util.Collections;\r\nimport java.util.Enumeration;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.TreeMap;\r\nimport java.util.jar.Attributes;\r\nimport java.util.jar.JarEntry;\r\nimport java.util.jar.JarFile;\r\nimport java.util.jar.JarOutputStream;\r\nimport java.util.jar.Manifest;\r\nimport java.util.regex.Pattern;\r\n\r\npublic abstract class AbstractJarSign {\r\n    /** Write to another stream and also feed it to the Signature object. */\r\n    private static class SignatureOutputStream extends FilterOutputStream {\r\n        private int mCount;\r\n        private Signature mSignature;\r\n\r\n        public SignatureOutputStream(OutputStream out, Signature sig) {\r\n            super(out);\r\n            mSignature = sig;\r\n            mCount = 0;\r\n        }\r\n\r\n        public int size() {\r\n            return mCount;\r\n        }\r\n\r\n        @Override\r\n        public void write(byte[] b) throws IOException {\r\n            try {\r\n                mSignature.update(b, 0, b.length);\r\n            } catch (SignatureException e) {\r\n                throw new IOException(\"SignatureException: \" + e);\r\n            }\r\n            out.write(b);\r\n            mCount += b.length;\r\n        }\r\n\r\n        @Override\r\n        public void write(byte[] b, int off, int len) throws IOException {\r\n            try {\r\n                mSignature.update(b, off, len);\r\n            } catch (SignatureException e) {\r\n                throw new IOException(\"SignatureException: \" + e);\r\n            }\r\n            out.write(b, off, len);\r\n            mCount += len;\r\n        }\r\n\r\n        @Override\r\n        public void write(int b) throws IOException {\r\n            try {\r\n                mSignature.update((byte) b);\r\n            } catch (SignatureException e) {\r\n                throw new IOException(\"SignatureException: \" + e);\r\n            }\r\n            out.write(b);\r\n            mCount++;\r\n        }\r\n    }\r\n\r\n    // Files matching this pattern are not copied to the output.\r\n    private static Pattern stripPattern = Pattern.compile(\"^META-INF/(.*)[.](SF|RSA|DSA)$\");\r\n    private static final byte[] EOL = \"\\r\\n\".getBytes(StandardCharsets.UTF_8);\r\n    private static final byte[] COL = \": \".getBytes(StandardCharsets.UTF_8);\r\n    private static final byte[] NAMES = \"Name: \".getBytes(StandardCharsets.UTF_8);\r\n\r\n    /**\r\n     * Copy all the files in a manifest from input to output. We set the\r\n     * modification times in the output to a fixed time, so as to reduce\r\n     * variation in the output file and make incremental OTAs more efficient.\r\n     */\r\n    private static void copyFiles(Manifest manifest, JarFile in, JarOutputStream out, long timestamp)\r\n            throws IOException {\r\n        byte[] buffer = new byte[4096];\r\n        int num;\r\n\r\n        Map<String, Attributes> entries = manifest.getEntries();\r\n        List<String> names = new ArrayList<>(entries.keySet());\r\n        Collections.sort(names);\r\n        for (String name : names) {\r\n            JarEntry inEntry = in.getJarEntry(name);\r\n            JarEntry outEntry = null;\r\n            if (inEntry.getMethod() == JarEntry.STORED) {\r\n                // Preserve the STORED method of the input entry.\r\n                outEntry = new JarEntry(inEntry);\r\n            } else {\r\n                // Create a new entry so that the compressed len is recomputed.\r\n                outEntry = new JarEntry(name);\r\n            }\r\n            outEntry.setTime(timestamp);\r\n            out.putNextEntry(outEntry);\r\n\r\n            InputStream data = in.getInputStream(inEntry);\r\n            while ((num = data.read(buffer)) > 0) {\r\n                out.write(buffer, 0, num);\r\n            }\r\n            out.flush();\r\n        }\r\n    }\r\n\r\n    final protected String digestAlg;\r\n\r\n    final protected PrivateKey privateKey;\r\n\r\n    public AbstractJarSign(PrivateKey privateKey) {\r\n        this(privateKey, \"SHA1\", \"SHA1withRSA\");\r\n    }\r\n\r\n    public AbstractJarSign(PrivateKey privateKey, String digestAlg, String signAlg) {\r\n        super();\r\n\r\n        this.privateKey = privateKey;\r\n        this.digestAlg = digestAlg;\r\n        this.signAlg = signAlg;\r\n    }\r\n\r\n    final protected String signAlg;\r\n\r\n    /** Add the SHA1 of every file to the manifest, creating it if necessary. */\r\n    private Manifest addDigestsToManifest(JarFile jar) throws IOException, GeneralSecurityException {\r\n        Manifest input = jar.getManifest();\r\n        Manifest output = new Manifest();\r\n        Attributes main = output.getMainAttributes();\r\n        if (input != null) {\r\n            main.putAll(input.getMainAttributes());\r\n        }\r\n        main.putValue(\"Manifest-Version\", \"1.0\");\r\n        main.putValue(\"Created-By\", \"1.6.0_21 (d2j-\" + AbstractJarSign.class.getPackage().getImplementationVersion() + \")\");\r\n\r\n        MessageDigest md = MessageDigest.getInstance(digestAlg);\r\n        byte[] buffer = new byte[4096];\r\n        int num;\r\n\r\n        // We sort the input entries by name, and add them to the\r\n        // output manifest in sorted order. We expect that the output\r\n        // map will be deterministic.\r\n\r\n        TreeMap<String, JarEntry> byName = new TreeMap<String, JarEntry>();\r\n\r\n        for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {\r\n            JarEntry entry = e.nextElement();\r\n            byName.put(entry.getName(), entry);\r\n        }\r\n\r\n        String digName = digestAlg + \"-Digest\";\r\n        for (JarEntry entry : byName.values()) {\r\n            String name = entry.getName();\r\n            if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) && !stripPattern.matcher(name).matches()) {\r\n                InputStream data = jar.getInputStream(entry);\r\n                while ((num = data.read(buffer)) > 0) {\r\n                    md.update(buffer, 0, num);\r\n                }\r\n\r\n                Attributes attr = null;\r\n                if (input != null) {\r\n                    attr = input.getAttributes(name);\r\n                }\r\n                attr = attr != null ? new Attributes(attr) : new Attributes();\r\n                attr.putValue(digName, encodeBase64(md.digest()));\r\n                output.getEntries().put(name, attr);\r\n            }\r\n        }\r\n\r\n        return output;\r\n    }\r\n\r\n    protected String encodeBase64(byte[] data) {\r\n       return Base64.encodeToString(data, Base64.NO_WRAP);\r\n    }\r\n\r\n    public void sign(File in, File out) throws IOException, GeneralSecurityException {\r\n\r\n        JarFile inputJar = null;\r\n        JarOutputStream outputJar = null;\r\n        FileOutputStream outputFile = null;\r\n\r\n        try {\r\n\r\n            // Assume the certificate is valid for at least an hour.\r\n            long timestamp = System.currentTimeMillis();\r\n\r\n            inputJar = new JarFile(in, false); // Don't verify.\r\n\r\n            OutputStream outputStream = outputFile = new FileOutputStream(out);\r\n            outputJar = new JarOutputStream(outputStream);\r\n            outputJar.setLevel(9);\r\n\r\n            JarEntry je;\r\n\r\n            // MANIFEST.MF\r\n            Manifest manifest = addDigestsToManifest(inputJar);\r\n            je = new JarEntry(JarFile.MANIFEST_NAME);\r\n            je.setTime(timestamp);\r\n            outputJar.putNextEntry(je);\r\n            manifest.write(outputJar);\r\n\r\n            // CERT.SF\r\n            Signature signature = Signature.getInstance(signAlg);\r\n            signature.initSign(privateKey);\r\n            je = new JarEntry(\"META-INF/CERT.SF\");\r\n            je.setTime(timestamp);\r\n            outputJar.putNextEntry(je);\r\n            writeSignatureFile(manifest, new SignatureOutputStream(outputJar, signature));\r\n\r\n            int i = digestAlg.toLowerCase().indexOf(\"with\");\r\n            String ext;\r\n            if (i > 0) {\r\n                ext = digestAlg.substring(i + 4);\r\n            } else {\r\n                ext = \"RSA\";\r\n            }\r\n            // CERT.RSA\r\n            je = new JarEntry(\"META-INF/CERT.\" + ext);\r\n            je.setTime(timestamp);\r\n            outputJar.putNextEntry(je);\r\n\r\n            writeSignatureBlock(signature.sign(), outputJar);\r\n\r\n            // Everything else\r\n            copyFiles(manifest, inputJar, outputJar, timestamp);\r\n\r\n            outputJar.close();\r\n            outputJar = null;\r\n            outputStream.flush();\r\n\r\n        } finally {\r\n            try {\r\n                if (inputJar != null) {\r\n                    inputJar.close();\r\n                }\r\n                if (outputFile != null) {\r\n                    outputFile.close();\r\n                }\r\n            } catch (IOException e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n    }\r\n\r\n    /** Write a .RSA file with a digital signature. */\r\n    protected abstract void writeSignatureBlock(byte[] signature, OutputStream out) throws IOException;\r\n\r\n    /** Write a .SF file with a digest of the specified manifest. */\r\n    private void writeSignatureFile(Manifest manifest, SignatureOutputStream out) throws IOException,\r\n            GeneralSecurityException {\r\n        Manifest sf = new Manifest();\r\n        Attributes main = sf.getMainAttributes();\r\n        main.putValue(\"Signature-Version\", \"1.0\");\r\n        main.putValue(\"Created-By\", \"1.6.0_21 (d2j-\" + AbstractJarSign.class.getPackage().getImplementationVersion() + \")\");\r\n\r\n        MessageDigest md = MessageDigest.getInstance(digestAlg);\r\n        DigestOutputStream print = new DigestOutputStream(new OutputStream() {\r\n\r\n            @Override\r\n            public void write(byte[] b) throws IOException {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void write(byte[] b, int off, int len) throws IOException {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void write(int b) throws IOException {\r\n\r\n            }\r\n        }, md);\r\n\r\n        // Digest of the entire manifest\r\n        manifest.write(print);\r\n        print.flush();\r\n        main.putValue(digestAlg + \"-Digest-Manifest\", encodeBase64(md.digest()));\r\n\r\n        // digest main attribute\r\n        Manifest m2 = new Manifest();\r\n        m2.getMainAttributes().putAll(manifest.getMainAttributes());\r\n        m2.write(print);\r\n        main.putValue(digestAlg + \"-Digest-Manifest-Main-Attributes\", encodeBase64(md.digest()));\r\n\r\n        String digName = digestAlg + \"-Digest\";\r\n        Map<String, Attributes> entries = manifest.getEntries();\r\n\r\n        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {\r\n            // Digest of the manifest stanza for this entry.\r\n            print.write(NAMES);\r\n            print.write(entry.getKey().getBytes(StandardCharsets.UTF_8));\r\n            print.write(EOL);\r\n            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {\r\n                print.write(att.getKey().toString().getBytes(StandardCharsets.UTF_8));\r\n                print.write(COL);\r\n                print.write(att.getKey().toString().getBytes(StandardCharsets.UTF_8));\r\n                print.write(EOL);\r\n            }\r\n            print.write(EOL);\r\n            print.flush();\r\n\r\n            Attributes sfAttr = new Attributes();\r\n            sfAttr.putValue(digName, encodeBase64(md.digest()));\r\n            sf.getEntries().put(entry.getKey(), sfAttr);\r\n        }\r\n\r\n        sf.write(out);\r\n\r\n        // A bug in the java.util.jar implementation of Android platforms\r\n        // up to version 1.6 will cause a spurious IOException to be thrown\r\n        // if the length of the signature file is a multiple of 1024 bytes.\r\n        // As a workaround, add an extra CRLF in this case.\r\n        if ((out.size() % 1024) == 0) {\r\n            out.write(EOL);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.signapk;\nimport java.io.UnsupportedEncodingException;\n\n/**\n * Utilities for encoding and decoding the Base64 representation of\n * binary data.  See RFCs <a\n * href=\"http://www.ietf.org/rfc/rfc2045.txt\">2045</a> and <a\n * href=\"http://www.ietf.org/rfc/rfc3548.txt\">3548</a>.\n */\npublic class Base64 {\n    /**\n     * Default values for encoder/decoder flags.\n     */\n    public static final int DEFAULT = 0;\n\n    /**\n     * Encoder flag bit to omit the padding '=' characters at the end\n     * of the output (if any).\n     */\n    public static final int NO_PADDING = 1;\n\n    /**\n     * Encoder flag bit to omit all line terminators (i.e., the output\n     * will be on one long line).\n     */\n    public static final int NO_WRAP = 2;\n\n    /**\n     * Encoder flag bit to indicate lines should be terminated with a\n     * CRLF pair instead of just an LF.  Has no effect if {@code\n     * NO_WRAP} is specified as well.\n     */\n    public static final int CRLF = 4;\n\n    /**\n     * Encoder/decoder flag bit to indicate using the \"URL and\n     * filename safe\" variant of Base64 (see RFC 3548 section 4) where\n     * {@code -} and {@code _} are used in place of {@code +} and\n     * {@code /}.\n     */\n    public static final int URL_SAFE = 8;\n\n    /**\n     * Flag to pass to {@link Base64OutputStream} to indicate that it\n     * should not close the output stream it is wrapping when it\n     * itself is closed.\n     */\n    public static final int NO_CLOSE = 16;\n\n    //  --------------------------------------------------------\n    //  shared code\n    //  --------------------------------------------------------\n\n    /* package */ static abstract class Coder {\n        public byte[] output;\n        public int op;\n\n        /**\n         * Encode/decode another block of input data.  this.output is\n         * provided by the caller, and must be big enough to hold all\n         * the coded data.  On exit, this.opwill be set to the length\n         * of the coded data.\n         *\n         * @param finish true if this is the final call to process for\n         *        this object.  Will finalize the coder state and\n         *        include any final bytes in the output.\n         *\n         * @return true if the input so far is good; false if some\n         *         error has been detected in the input stream..\n         */\n        public abstract boolean process(byte[] input, int offset, int len, boolean finish);\n\n        /**\n         * @return the maximum number of bytes a call to process()\n         * could produce for the given number of input bytes.  This may\n         * be an overestimate.\n         */\n        public abstract int maxOutputSize(int len);\n    }\n\n    //  --------------------------------------------------------\n    //  decoding\n    //  --------------------------------------------------------\n\n    /**\n     * Decode the Base64-encoded data in input and return the data in\n     * a new byte array.\n     *\n     * <p>The padding '=' characters at the end are considered optional, but\n     * if any are present, there must be the correct number of them.\n     *\n     * @param str    the input String to decode, which is converted to\n     *               bytes using the default charset\n     * @param flags  controls certain features of the decoded output.\n     *               Pass {@code DEFAULT} to decode standard Base64.\n     *\n     * @throws IllegalArgumentException if the input contains\n     * incorrect padding\n     */\n    public static byte[] decode(String str, int flags) {\n        return decode(str.getBytes(), flags);\n    }\n\n    /**\n     * Decode the Base64-encoded data in input and return the data in\n     * a new byte array.\n     *\n     * <p>The padding '=' characters at the end are considered optional, but\n     * if any are present, there must be the correct number of them.\n     *\n     * @param input the input array to decode\n     * @param flags  controls certain features of the decoded output.\n     *               Pass {@code DEFAULT} to decode standard Base64.\n     *\n     * @throws IllegalArgumentException if the input contains\n     * incorrect padding\n     */\n    public static byte[] decode(byte[] input, int flags) {\n        return decode(input, 0, input.length, flags);\n    }\n\n    /**\n     * Decode the Base64-encoded data in input and return the data in\n     * a new byte array.\n     *\n     * <p>The padding '=' characters at the end are considered optional, but\n     * if any are present, there must be the correct number of them.\n     *\n     * @param input  the data to decode\n     * @param offset the position within the input array at which to start\n     * @param len    the number of bytes of input to decode\n     * @param flags  controls certain features of the decoded output.\n     *               Pass {@code DEFAULT} to decode standard Base64.\n     *\n     * @throws IllegalArgumentException if the input contains\n     * incorrect padding\n     */\n    public static byte[] decode(byte[] input, int offset, int len, int flags) {\n        // Allocate space for the most data the input could represent.\n        // (It could contain less if it contains whitespace, etc.)\n        Decoder decoder = new Decoder(flags, new byte[len*3/4]);\n\n        if (!decoder.process(input, offset, len, true)) {\n            throw new IllegalArgumentException(\"bad base-64\");\n        }\n\n        // Maybe we got lucky and allocated exactly enough output space.\n        if (decoder.op == decoder.output.length) {\n            return decoder.output;\n        }\n\n        // Need to shorten the array, so allocate a new one of the\n        // right size and copy.\n        byte[] temp = new byte[decoder.op];\n        System.arraycopy(decoder.output, 0, temp, 0, decoder.op);\n        return temp;\n    }\n\n    /* package */ static class Decoder extends Coder {\n        /**\n         * Lookup table for turning bytes into their position in the\n         * Base64 alphabet.\n         */\n        private static final int DECODE[] = {\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,\n            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,\n            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,\n            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,\n            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n        };\n\n        /**\n         * Decode lookup table for the \"web safe\" variant (RFC 3548\n         * sec. 4) where - and _ replace + and /.\n         */\n        private static final int DECODE_WEBSAFE[] = {\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,\n            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,\n            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,\n            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,\n            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n        };\n\n        /** Non-data values in the DECODE arrays. */\n        private static final int SKIP = -1;\n        private static final int EQUALS = -2;\n\n        /**\n         * States 0-3 are reading through the next input tuple.\n         * State 4 is having read one '=' and expecting exactly\n         * one more.\n         * State 5 is expecting no more data or padding characters\n         * in the input.\n         * State 6 is the error state; an error has been detected\n         * in the input and no future input can \"fix\" it.\n         */\n        private int state;   // state number (0 to 6)\n        private int value;\n\n        final private int[] alphabet;\n\n        public Decoder(int flags, byte[] output) {\n            this.output = output;\n\n            alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;\n            state = 0;\n            value = 0;\n        }\n\n        /**\n         * @return an overestimate for the number of bytes {@code\n         * len} bytes could decode to.\n         */\n        public int maxOutputSize(int len) {\n            return len * 3/4 + 10;\n        }\n\n        /**\n         * Decode another block of input data.\n         *\n         * @return true if the state machine is still healthy.  false if\n         *         bad base-64 data has been detected in the input stream.\n         */\n        public boolean process(byte[] input, int offset, int len, boolean finish) {\n            if (this.state == 6) return false;\n\n            int p = offset;\n            len += offset;\n\n            // Using local variables makes the decoder about 12%\n            // faster than if we manipulate the member variables in\n            // the loop.  (Even alphabet makes a measurable\n            // difference, which is somewhat surprising to me since\n            // the member variable is final.)\n            int state = this.state;\n            int value = this.value;\n            int op = 0;\n            final byte[] output = this.output;\n            final int[] alphabet = this.alphabet;\n\n            while (p < len) {\n                // Try the fast path:  we're starting a new tuple and the\n                // next four bytes of the input stream are all data\n                // bytes.  This corresponds to going through states\n                // 0-1-2-3-0.  We expect to use this method for most of\n                // the data.\n                //\n                // If any of the next four bytes of input are non-data\n                // (whitespace, etc.), value will end up negative.  (All\n                // the non-data values in decode are small negative\n                // numbers, so shifting any of them up and or'ing them\n                // together will result in a value with its top bit set.)\n                //\n                // You can remove this whole block and the output should\n                // be the same, just slower.\n                if (state == 0) {\n                    while (p+4 <= len &&\n                           (value = ((alphabet[input[p] & 0xff] << 18) |\n                                     (alphabet[input[p+1] & 0xff] << 12) |\n                                     (alphabet[input[p+2] & 0xff] << 6) |\n                                     (alphabet[input[p+3] & 0xff]))) >= 0) {\n                        output[op+2] = (byte) value;\n                        output[op+1] = (byte) (value >> 8);\n                        output[op] = (byte) (value >> 16);\n                        op += 3;\n                        p += 4;\n                    }\n                    if (p >= len) break;\n                }\n\n                // The fast path isn't available -- either we've read a\n                // partial tuple, or the next four input bytes aren't all\n                // data, or whatever.  Fall back to the slower state\n                // machine implementation.\n\n                int d = alphabet[input[p++] & 0xff];\n\n                switch (state) {\n                case 0:\n                    if (d >= 0) {\n                        value = d;\n                        ++state;\n                    } else if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n\n                case 1:\n                    if (d >= 0) {\n                        value = (value << 6) | d;\n                        ++state;\n                    } else if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n\n                case 2:\n                    if (d >= 0) {\n                        value = (value << 6) | d;\n                        ++state;\n                    } else if (d == EQUALS) {\n                        // Emit the last (partial) output tuple;\n                        // expect exactly one more padding character.\n                        output[op++] = (byte) (value >> 4);\n                        state = 4;\n                    } else if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n\n                case 3:\n                    if (d >= 0) {\n                        // Emit the output triple and return to state 0.\n                        value = (value << 6) | d;\n                        output[op+2] = (byte) value;\n                        output[op+1] = (byte) (value >> 8);\n                        output[op] = (byte) (value >> 16);\n                        op += 3;\n                        state = 0;\n                    } else if (d == EQUALS) {\n                        // Emit the last (partial) output tuple;\n                        // expect no further data or padding characters.\n                        output[op+1] = (byte) (value >> 2);\n                        output[op] = (byte) (value >> 10);\n                        op += 2;\n                        state = 5;\n                    } else if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n\n                case 4:\n                    if (d == EQUALS) {\n                        ++state;\n                    } else if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n\n                case 5:\n                    if (d != SKIP) {\n                        this.state = 6;\n                        return false;\n                    }\n                    break;\n                }\n            }\n\n            if (!finish) {\n                // We're out of input, but a future call could provide\n                // more.\n                this.state = state;\n                this.value = value;\n                this.op = op;\n                return true;\n            }\n\n            // Done reading input.  Now figure out where we are left in\n            // the state machine and finish up.\n\n            switch (state) {\n            case 0:\n                // Output length is a multiple of three.  Fine.\n                break;\n            case 1:\n                // Read one extra input byte, which isn't enough to\n                // make another output byte.  Illegal.\n                this.state = 6;\n                return false;\n            case 2:\n                // Read two extra input bytes, enough to emit 1 more\n                // output byte.  Fine.\n                output[op++] = (byte) (value >> 4);\n                break;\n            case 3:\n                // Read three extra input bytes, enough to emit 2 more\n                // output bytes.  Fine.\n                output[op++] = (byte) (value >> 10);\n                output[op++] = (byte) (value >> 2);\n                break;\n            case 4:\n                // Read one padding '=' when we expected 2.  Illegal.\n                this.state = 6;\n                return false;\n            case 5:\n                // Read all the padding '='s we expected and no more.\n                // Fine.\n                break;\n            }\n\n            this.state = state;\n            this.op = op;\n            return true;\n        }\n    }\n\n    //  --------------------------------------------------------\n    //  encoding\n    //  --------------------------------------------------------\n\n    /**\n     * Base64-encode the given data and return a newly allocated\n     * String with the result.\n     *\n     * @param input  the data to encode\n     * @param flags  controls certain features of the encoded output.\n     *               Passing {@code DEFAULT} results in output that\n     *               adheres to RFC 2045.\n     */\n    public static String encodeToString(byte[] input, int flags) {\n        try {\n            return new String(encode(input, flags), \"US-ASCII\");\n        } catch (UnsupportedEncodingException e) {\n            // US-ASCII is guaranteed to be available.\n            throw new AssertionError(e);\n        }\n    }\n\n    /**\n     * Base64-encode the given data and return a newly allocated\n     * String with the result.\n     *\n     * @param input  the data to encode\n     * @param offset the position within the input array at which to\n     *               start\n     * @param len    the number of bytes of input to encode\n     * @param flags  controls certain features of the encoded output.\n     *               Passing {@code DEFAULT} results in output that\n     *               adheres to RFC 2045.\n     */\n    public static String encodeToString(byte[] input, int offset, int len, int flags) {\n        try {\n            return new String(encode(input, offset, len, flags), \"US-ASCII\");\n        } catch (UnsupportedEncodingException e) {\n            // US-ASCII is guaranteed to be available.\n            throw new AssertionError(e);\n        }\n    }\n\n    /**\n     * Base64-encode the given data and return a newly allocated\n     * byte[] with the result.\n     *\n     * @param input  the data to encode\n     * @param flags  controls certain features of the encoded output.\n     *               Passing {@code DEFAULT} results in output that\n     *               adheres to RFC 2045.\n     */\n    public static byte[] encode(byte[] input, int flags) {\n        return encode(input, 0, input.length, flags);\n    }\n\n    /**\n     * Base64-encode the given data and return a newly allocated\n     * byte[] with the result.\n     *\n     * @param input  the data to encode\n     * @param offset the position within the input array at which to\n     *               start\n     * @param len    the number of bytes of input to encode\n     * @param flags  controls certain features of the encoded output.\n     *               Passing {@code DEFAULT} results in output that\n     *               adheres to RFC 2045.\n     */\n    public static byte[] encode(byte[] input, int offset, int len, int flags) {\n        Encoder encoder = new Encoder(flags, null);\n\n        // Compute the exact length of the array we will produce.\n        int output_len = len / 3 * 4;\n\n        // Account for the tail of the data and the padding bytes, if any.\n        if (encoder.do_padding) {\n            if (len % 3 > 0) {\n                output_len += 4;\n            }\n        } else {\n            switch (len % 3) {\n                case 0: break;\n                case 1: output_len += 2; break;\n                case 2: output_len += 3; break;\n            }\n        }\n\n        // Account for the newlines, if any.\n        if (encoder.do_newline && len > 0) {\n            output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *\n                (encoder.do_cr ? 2 : 1);\n        }\n\n        encoder.output = new byte[output_len];\n        encoder.process(input, offset, len, true);\n\n        assert encoder.op == output_len;\n\n        return encoder.output;\n    }\n\n    /* package */ static class Encoder extends Coder {\n        /**\n         * Emit a new line every this many output tuples.  Corresponds to\n         * a 76-character line length (the maximum allowable according to\n         * <a href=\"http://www.ietf.org/rfc/rfc2045.txt\">RFC 2045</a>).\n         */\n        public static final int LINE_GROUPS = 19;\n\n        /**\n         * Lookup table for turning Base64 alphabet positions (6 bits)\n         * into output bytes.\n         */\n        private static final byte ENCODE[] = {\n            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\n            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',\n            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',\n            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',\n        };\n\n        /**\n         * Lookup table for turning Base64 alphabet positions (6 bits)\n         * into output bytes.\n         */\n        private static final byte ENCODE_WEBSAFE[] = {\n            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\n            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',\n            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',\n            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',\n        };\n\n        final private byte[] tail;\n        /* package */ int tailLen;\n        private int count;\n\n        final public boolean do_padding;\n        final public boolean do_newline;\n        final public boolean do_cr;\n        final private byte[] alphabet;\n\n        public Encoder(int flags, byte[] output) {\n            this.output = output;\n\n            do_padding = (flags & NO_PADDING) == 0;\n            do_newline = (flags & NO_WRAP) == 0;\n            do_cr = (flags & CRLF) != 0;\n            alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;\n\n            tail = new byte[2];\n            tailLen = 0;\n\n            count = do_newline ? LINE_GROUPS : -1;\n        }\n\n        /**\n         * @return an overestimate for the number of bytes {@code\n         * len} bytes could encode to.\n         */\n        public int maxOutputSize(int len) {\n            return len * 8/5 + 10;\n        }\n\n        public boolean process(byte[] input, int offset, int len, boolean finish) {\n            // Using local variables makes the encoder about 9% faster.\n            final byte[] alphabet = this.alphabet;\n            final byte[] output = this.output;\n            int op = 0;\n            int count = this.count;\n\n            int p = offset;\n            len += offset;\n            int v = -1;\n\n            // First we need to concatenate the tail of the previous call\n            // with any input bytes available now and see if we can empty\n            // the tail.\n\n            switch (tailLen) {\n                case 0:\n                    // There was no tail.\n                    break;\n\n                case 1:\n                    if (p+2 <= len) {\n                        // A 1-byte tail with at least 2 bytes of\n                        // input available now.\n                        v = ((tail[0] & 0xff) << 16) |\n                            ((input[p++] & 0xff) << 8) |\n                            (input[p++] & 0xff);\n                        tailLen = 0;\n                    };\n                    break;\n\n                case 2:\n                    if (p+1 <= len) {\n                        // A 2-byte tail with at least 1 byte of input.\n                        v = ((tail[0] & 0xff) << 16) |\n                            ((tail[1] & 0xff) << 8) |\n                            (input[p++] & 0xff);\n                        tailLen = 0;\n                    }\n                    break;\n            }\n\n            if (v != -1) {\n                output[op++] = alphabet[(v >> 18) & 0x3f];\n                output[op++] = alphabet[(v >> 12) & 0x3f];\n                output[op++] = alphabet[(v >> 6) & 0x3f];\n                output[op++] = alphabet[v & 0x3f];\n                if (--count == 0) {\n                    if (do_cr) output[op++] = '\\r';\n                    output[op++] = '\\n';\n                    count = LINE_GROUPS;\n                }\n            }\n\n            // At this point either there is no tail, or there are fewer\n            // than 3 bytes of input available.\n\n            // The main loop, turning 3 input bytes into 4 output bytes on\n            // each iteration.\n            while (p+3 <= len) {\n                v = ((input[p] & 0xff) << 16) |\n                    ((input[p+1] & 0xff) << 8) |\n                    (input[p+2] & 0xff);\n                output[op] = alphabet[(v >> 18) & 0x3f];\n                output[op+1] = alphabet[(v >> 12) & 0x3f];\n                output[op+2] = alphabet[(v >> 6) & 0x3f];\n                output[op+3] = alphabet[v & 0x3f];\n                p += 3;\n                op += 4;\n                if (--count == 0) {\n                    if (do_cr) output[op++] = '\\r';\n                    output[op++] = '\\n';\n                    count = LINE_GROUPS;\n                }\n            }\n\n            if (finish) {\n                // Finish up the tail of the input.  Note that we need to\n                // consume any bytes in tail before any bytes\n                // remaining in input; there should be at most two bytes\n                // total.\n\n                if (p-tailLen == len-1) {\n                    int t = 0;\n                    v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;\n                    tailLen -= t;\n                    output[op++] = alphabet[(v >> 6) & 0x3f];\n                    output[op++] = alphabet[v & 0x3f];\n                    if (do_padding) {\n                        output[op++] = '=';\n                        output[op++] = '=';\n                    }\n                    if (do_newline) {\n                        if (do_cr) output[op++] = '\\r';\n                        output[op++] = '\\n';\n                    }\n                } else if (p-tailLen == len-2) {\n                    int t = 0;\n                    v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |\n                        (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);\n                    tailLen -= t;\n                    output[op++] = alphabet[(v >> 12) & 0x3f];\n                    output[op++] = alphabet[(v >> 6) & 0x3f];\n                    output[op++] = alphabet[v & 0x3f];\n                    if (do_padding) {\n                        output[op++] = '=';\n                    }\n                    if (do_newline) {\n                        if (do_cr) output[op++] = '\\r';\n                        output[op++] = '\\n';\n                    }\n                } else if (do_newline && op > 0 && count != LINE_GROUPS) {\n                    if (do_cr) output[op++] = '\\r';\n                    output[op++] = '\\n';\n                }\n\n                assert tailLen == 0;\n                assert p == len;\n            } else {\n                // Save the leftovers in tail to be consumed on the next\n                // call to encodeInternal.\n\n                if (p == len-1) {\n                    tail[tailLen++] = input[p];\n                } else if (p == len-2) {\n                    tail[tailLen++] = input[p];\n                    tail[tailLen++] = input[p+1];\n                }\n            }\n\n            this.op = op;\n            this.count = count;\n\n            return true;\n        }\n    }\n\n    private Base64() { }   // don't instantiate\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/signapk/SunJarSignImpl.java",
    "content": "package com.googlecode.d2j.signapk;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.PrivateKey;\nimport java.security.cert.X509Certificate;\n\nimport sun.security.pkcs.ContentInfo;\nimport sun.security.pkcs.PKCS7;\nimport sun.security.pkcs.SignerInfo;\nimport sun.security.x509.AlgorithmId;\nimport sun.security.x509.X500Name;\n\npublic class SunJarSignImpl extends AbstractJarSign {\n    final protected X509Certificate cert;\n\n    public SunJarSignImpl(X509Certificate cert, PrivateKey privateKey) {\n        super(privateKey);\n        this.cert = cert;\n    }\n\n    /** Write a .RSA file with a digital signature. */\n    @SuppressWarnings(\"all\")\n    protected void writeSignatureBlock(byte[] signature, OutputStream out) throws IOException {\n        try {\n            SignerInfo signerInfo = new SignerInfo(new X500Name(cert.getIssuerX500Principal().getName()),\n                    cert.getSerialNumber(), AlgorithmId.get(digestAlg), AlgorithmId.get(\"RSA\"), signature);\n\n            PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { AlgorithmId.get(digestAlg) }, new ContentInfo(\n                    ContentInfo.DATA_OID, null), new X509Certificate[] { cert }, new SignerInfo[] { signerInfo });\n\n            pkcs7.encodeSignedData(out);\n        } catch (NoSuchAlgorithmException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/signapk/TinySignImpl.java",
    "content": "package com.googlecode.d2j.signapk;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.security.KeyFactory;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.PrivateKey;\nimport java.security.spec.InvalidKeySpecException;\nimport java.security.spec.PKCS8EncodedKeySpec;\n\n/**\n * get from\n * https://code.google.com/p/tiny-sign/source/browse/src/main/java/pxb/android\n * /tinysign/TinySign.java\n * \n * @author bob\n * \n */\npublic final class TinySignImpl extends AbstractJarSign {\n\n    private static PrivateKey buildPrivateKey() {\n\n        PrivateKey privateKey;\n        try {\n            privateKey = KeyFactory.getInstance(\"RSA\").generatePrivate(\n                    new PKCS8EncodedKeySpec(Base64.decode(sPrivateKey,0)));\n        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {\n            throw new RuntimeException(e);\n        }\n        return privateKey;\n    }\n\n    public TinySignImpl() {\n        super(buildPrivateKey(), \"SHA1\", \"SHA1withRSA\");\n    }\n\n    private static final String sPrivateKey = \"MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J+tOnSgtsQIDAQABAkEAihag5u3Qhds9BsViIUmqhZebhr8vUuqZR8cuTo1GnbSoOHIPbAgD3J8TDbC/CVqae8NrgwLp325Pem1Tuof/0QIhAN1hqft1K307bsljgw3iYKopGVZBHRXsjRnNL4edV9QrAiEAu4F+XtS1wohGLz5QtfuMFsQNo4l31mCjt6WpBDmSi5MCIQCB++YijxmJ3mueM5+vd0vqnVcTHghF5y6yB5fwuKHpIQIgInnS1Hjj2prX3MPmby+LOHxfzZvvDtnCAHhTNVWonkUCIQCvV8l+SpL6Vh1nQ/2EKFJo2dbZB3wKG/BEYsFkPFbn9w==\";\n    private static final String sSigPrefix = \"MIIB5gYJKoZIhvcNAQcCoIIB1zCCAdMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCATYwggEyMIHdoAMCAQICBCunMokwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAxMEVGVzdDAeFw0xMjA0MjIwODQ1NDdaFw0xMzA0MjIwODQ1NDdaMA8xDTALBgNVBAMTBFRlc3QwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J+tOnSgtsQIDAQABoyEwHzAdBgNVHQ4EFgQUVL2yOinUwpARE1tOPxc1bf4WrTgwDQYJKoZIhvcNAQELBQADQQAnj/eZwhqwb2tgSYNvgRo5bBNNCpJbQ4alEeP/MLSIWf2nZpAix8T3oS9X2affQtAgctPATcKQaiH2B4L7FKlVMXoweAIBATAXMA8xDTALBgNVBAMTBFRlc3QCBCunMokwCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAARA\";\n\n\n    @Override\n    protected void writeSignatureBlock(byte[] signature, OutputStream out) throws IOException {\n        out.write(Base64.decode(sSigPrefix, 0));\n        out.write(signature);\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/BaseWeaver.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2015 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.tools.jar;\n\nimport org.objectweb.asm.Type;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\n\n\npublic class BaseWeaver {\n    protected String invocationInterfaceDesc = \"Lcom/googlecode/d2j/tools/jar/MethodInvocation;\";\n    protected String invocationTypePrefix = \"d2j/gen/MI_\";\n\n    protected static final String DEFAULT_RET_TYPE = \"L888;\";\n    protected static final String DEFAULT_DESC = \"(L;)\" + DEFAULT_RET_TYPE;\n    protected List<Callback> callbacks = new ArrayList<Callback>();\n    protected int currentInvocationIdx = 0;\n    protected int seqIndex = 1;\n    protected MtdInfo key = new MtdInfo();\n    protected Set<String> ignores = new HashSet<String>();\n    protected Map<String, String> clzDescMap = new HashMap<String, String>();\n    protected Map<MtdInfo, MtdInfo> mtdMap = new HashMap<MtdInfo, MtdInfo>();\n    protected Map<MtdInfo, MtdInfo> defMap = new HashMap<MtdInfo, MtdInfo>();\n\n    protected String buildMethodAName(String oldName) {\n        return String.format(\"%s_A%03d\", oldName, seqIndex++);\n    }\n\n    protected String buildCallbackMethodName(String oldName) {\n        return String.format(\"%s_CB%03d\", oldName, seqIndex++);\n    }\n\n    protected MtdInfo findDefinedTargetMethod(String owner, String name, String desc) {\n        return findTargetMethod0(defMap, owner, name, desc);\n    }\n\n    protected MtdInfo findTargetMethod(String owner, String name, String desc) {\n        return findTargetMethod0(mtdMap, owner, name, desc);\n    }\n\n    protected MtdInfo findTargetMethod0(Map<MtdInfo, MtdInfo> map, String owner, String name, String desc) {\n        MtdInfo v = map.get(buildKey(owner, name, desc));\n        if (v != null) {\n            return v;\n        }\n\n        // try with default ret\n        key.desc = Type.getMethodDescriptor(Type.getType(DEFAULT_RET_TYPE), Type.getArgumentTypes(desc));\n        v = map.get(key);\n        if (v != null) {\n            return v;\n        }\n        // try with default desc\n        key.desc = DEFAULT_DESC;\n        v = map.get(key);\n        if (v != null) {\n            return v;\n        }\n        if (!name.equals(\"*\")) {\n            return findTargetMethod0(map, owner, \"*\", desc);\n        }\n        return v;\n    }\n\n    protected MtdInfo buildKey(String owner, String name, String desc) {\n        key.name = name;\n        key.owner = owner;\n        key.desc = desc;\n        return key;\n    }\n\n    public BaseWeaver withConfig(Path is) throws IOException {\n        return withConfig(Files.readAllLines(is, StandardCharsets.UTF_8));\n    }\n\n    public BaseWeaver withConfig(InputStream is) throws IOException {\n        try (BufferedReader r = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {\n            List<String> list = new ArrayList<>();\n            for (String ln = r.readLine(); ln != null; ln = r.readLine()) {\n                list.add(ln);\n            }\n            return withConfig(list);\n        }\n    }\n\n    public BaseWeaver withConfig(List<String> lines) {\n        for (String ln : lines) {\n            withConfig(ln);\n        }\n        return this;\n    }\n\n    public void withConfig(String ln) {\n        if (\"\".equals(ln) || ln.startsWith(\"#\")) {\n            return;\n        }\n        switch (Character.toLowerCase(ln.charAt(0))) {\n            case 'i':\n                ignores.add(ln.substring(2));\n                break;\n            case 'c':\n                int index = ln.lastIndexOf('=');\n                if (index > 0) {\n                    String key = toInternal(ln.substring(2, index));\n                    String value = toInternal(ln.substring(index + 1));\n                    clzDescMap.put(key, value);\n                    ignores.add(value);\n                }\n                break;\n            case 'r':\n                index = ln.lastIndexOf('=');\n                if (index > 0) {\n                    String key = ln.substring(2, index);\n                    String value = ln.substring(index + 1);\n                    MtdInfo mi = buildMethodInfo(key);\n\n                    index = value.indexOf('.');\n                    MtdInfo mtdValue = new MtdInfo();\n                    mtdValue.owner = value.substring(0, index);\n\n                    int index2 = value.indexOf('(', index);\n                    mtdValue.name = value.substring(index + 1, index2);\n                    mtdValue.desc = value.substring(index2);\n\n                    mtdMap.put(mi, mtdValue);\n\n                }\n                break;\n            case 'd':\n                index = ln.lastIndexOf('=');\n                if (index > 0) {\n                    String key = ln.substring(2, index);\n                    String value = ln.substring(index + 1);\n                    MtdInfo mi = buildMethodInfo(key);\n\n                    index = value.indexOf('.');\n                    MtdInfo mtdValue = new MtdInfo();\n                    mtdValue.owner = value.substring(0, index);\n\n                    int index2 = value.indexOf('(', index);\n                    mtdValue.name = value.substring(index + 1, index2);\n                    mtdValue.desc = value.substring(index2);\n\n                    defMap.put(mi, mtdValue);\n                }\n                break;\n\n            case 'o':\n                setInvocationInterfaceDesc(ln.substring(2));\n                break;\n            case 'p':\n                invocationTypePrefix = ln.substring(2);\n                break;\n        }\n    }\n\n    public void setInvocationInterfaceDesc(String invocationInterfaceDesc) {\n        this.invocationInterfaceDesc = invocationInterfaceDesc;\n    }\n\n    protected static String toInternal(String key) {\n        if (key.endsWith(\";\")) {\n            key = key.substring(1, key.length() - 1);\n        }\n        return key;\n    }\n\n    protected MtdInfo buildMethodInfo(String value) {\n        int index = value.indexOf('.');\n        MtdInfo mtdValue = new MtdInfo();\n        mtdValue.owner = value.substring(0, index);\n        int index2 = value.indexOf('(', index);\n        if (index2 >= 0) {\n            mtdValue.name = value.substring(index + 1, index2);\n            int index3 = value.indexOf(')');\n            if (index3 == value.length() - 1) {\n                mtdValue.desc = value.substring(index2) + DEFAULT_RET_TYPE;\n            } else {\n                mtdValue.desc = value.substring(index2);\n            }\n        } else {\n            mtdValue.name = value.substring(index + 1);\n            mtdValue.desc = DEFAULT_DESC;\n        }\n        return mtdValue;\n    }\n\n    // internal name\n    public String getCurrentInvocationName() {\n        return String.format(\"%s_%03d\", invocationTypePrefix, currentInvocationIdx);\n    }\n\n    protected void nextInvocationName() {\n        currentInvocationIdx++;\n        callbacks.clear();\n    }\n\n    public static class Callback {\n        int idx;\n        Object callback;\n        Object target;\n        boolean isSpecial;\n        boolean isStatic;\n    }\n\n    public static class MtdInfo {\n        public String desc;\n        public String name;\n        public String owner;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o)\n                return true;\n            if (o == null || getClass() != o.getClass())\n                return false;\n\n            MtdInfo mtdInfo = (MtdInfo) o;\n\n            if (!desc.equals(mtdInfo.desc))\n                return false;\n            if (!name.equals(mtdInfo.name))\n                return false;\n            if (!owner.equals(mtdInfo.owner))\n                return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = desc.hashCode();\n            result = 31 * result + name.hashCode();\n            result = 31 * result + owner.hashCode();\n            return result;\n        }\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ClassInfo.java",
    "content": "package com.googlecode.d2j.tools.jar;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\npublic class ClassInfo {\n\n    final public String name;\n    public List<MemberInfo> members = new ArrayList<MemberInfo>(5);\n    public Set<String> parent = new HashSet<String>();\n\n    public ClassInfo(String name) {\n        this.name = name;\n    }\n\n    public boolean equals(Object o) {\n        return name.equals(((ClassInfo) o).name);\n    }\n\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    public String toString() {\n        return name;\n    }\n\n    public static class MemberInfo {\n        public int access;\n        public String desc;\n        public String name;\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/DexWeaver.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2015 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.tools.jar;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.node.DexCodeNode;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.objectweb.asm.Type;\n\nimport java.lang.reflect.Modifier;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * only implement sub set of InvocationWeaver\n * 2. Replace method A to another method B, parameter of B must be MethodInvocation\n * 3. Replace Methods Implementations\n */\npublic class DexWeaver extends BaseWeaver {\n    interface CB {\n        String getKey(Method mtd);\n    }\n\n    public String buildInvocationClz(DexFileVisitor dfv) {\n        String typeName = getCurrentInvocationName();\n        String typeNameDesc = \"L\" + typeName + \";\";\n        DexClassVisitor dcv = dfv.visit(DexConstants.ACC_PUBLIC, typeNameDesc, \"Ljava/lang/Object;\", new String[]{\n                invocationInterfaceDesc});\n\n        dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL,\n                new Field(typeNameDesc, \"thiz\", \"Ljava/lang/Object;\"), null).visitEnd();\n        dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, \"args\", \"[Ljava/lang/Object;\"), null)\n                .visitEnd();\n        dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, \"idx\", \"I\"), null)\n                .visitEnd();\n\n\n        {\n            DexMethodVisitor mv = dcv\n                    .visitMethod(DexConstants.ACC_PUBLIC | DexConstants.ACC_CONSTRUCTOR, new Method(typeNameDesc, \"<init>\", new String[]{\n                            \"Ljava/lang/Object;\", \"[Ljava/lang/Object;\", \"I\"}, \"V\"));\n            DexCodeVisitor codeVisitor = mv.visitCode();\n            codeVisitor.visitRegister(4);\n            codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 1, 0, new Field(typeNameDesc, \"thiz\", \"Ljava/lang/Object;\"));\n            codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 2, 0, new Field(typeNameDesc, \"args\", \"[Ljava/lang/Object;\"));\n            codeVisitor.visitFieldStmt(Op.IPUT, 3, 0, new Field(typeNameDesc, \"idx\", \"I\"));\n            codeVisitor.visitStmt0R(Op.RETURN_VOID);\n            codeVisitor.visitEnd();\n            mv.visitEnd();\n        }\n        {\n            genSwitchMethod(dcv, typeNameDesc, \"getMethodOwner\", new CB() {\n                @Override\n                public String getKey(Method mtd) {\n                    return toInternal(mtd.getOwner());\n                }\n            });\n            genSwitchMethod(dcv, typeNameDesc, \"getMethodName\", new CB() {\n                @Override\n                public String getKey(Method mtd) {\n                    return mtd.getName();\n                }\n            });\n            genSwitchMethod(dcv, typeNameDesc, \"getMethodDesc\", new CB() {\n                @Override\n                public String getKey(Method mtd) {\n                    return mtd.getDesc();\n                }\n            });\n        }\n\n        {\n            DexMethodVisitor mv = dcv\n                    .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, \"getArguments\", new String[0], \"[Ljava/lang/Object;\"));\n            DexCodeVisitor code = mv.visitCode();\n            code.visitRegister(2);\n            code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, \"args\", \"[Ljava/lang/Object;\"));\n            code.visitStmt1R(Op.RETURN_OBJECT, 0);\n\n            code.visitEnd();\n            mv.visitEnd();\n        }\n\n        {\n            DexMethodVisitor mv = dcv\n                    .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, \"getThis\", new String[0], \"Ljava/lang/Object;\"));\n            DexCodeVisitor code = mv.visitCode();\n            code.visitRegister(2);\n            code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, \"thiz\", \"Ljava/lang/Object;\"));\n            code.visitStmt1R(Op.RETURN_OBJECT, 0);\n            code.visitEnd();\n            mv.visitEnd();\n        }\n        {\n            DexMethodVisitor mv = dcv\n                    .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, \"proceed\", new String[0], \"Ljava/lang/Object;\"));\n            DexCodeVisitor code = mv.visitCode();\n            code.visitRegister(4);\n\n\n            code.visitFieldStmt(Op.IGET, 0, 3, new Field(typeNameDesc, \"thiz\", \"Ljava/lang/Object;\"));\n            code.visitFieldStmt(Op.IGET, 1, 3, new Field(typeNameDesc, \"args\", \"[Ljava/lang/Object;\"));\n            code.visitFieldStmt(Op.IGET, 2, 3, new Field(typeNameDesc, \"idx\", \"I\"));\n\n            DexLabel labels[] = new DexLabel[callbacks.size()];\n            for (int i = 0; i < labels.length; i++) {\n                labels[i] = new DexLabel();\n            }\n            code.visitPackedSwitchStmt(Op.PACKED_SWITCH, 2, 0, labels);\n            code.visitTypeStmt(Op.NEW_INSTANCE, 0, 0, \"Ljava/lang/RuntimeException;\");\n            code.visitConstStmt(Op.CONST_STRING, 1, \"invalid idx\");\n            code.visitMethodStmt(Op.INVOKE_DIRECT, new int[]{0,\n                    1}, new Method(\"Ljava/lang/RuntimeException;\", \"<init>\", new String[]{\"Ljava/lang/String;\"}, \"V\"));\n            code.visitStmt1R(Op.THROW, 0);\n\n            for (int i = 0; i < labels.length; i++) {\n                code.visitLabel(labels[i]);\n                Callback callback = callbacks.get(i);\n                Method mCallback = (Method) callback.callback;\n                if (callback.isStatic) {\n                    code.visitMethodStmt(Op.INVOKE_STATIC, new int[]{1}, mCallback);\n                } else if (callback.isSpecial) {\n                    code.visitTypeStmt(Op.CHECK_CAST, 0, -1, mCallback.getOwner());\n                    code.visitMethodStmt(Op.INVOKE_VIRTUAL, new int[]{0, 1}, mCallback);\n                } else {\n                    code.visitMethodStmt(Op.INVOKE_STATIC, new int[]{0, 1}, mCallback);\n                }\n                code.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);\n                code.visitStmt1R(Op.RETURN_OBJECT, 0);\n            }\n\n            code.visitEnd();\n            mv.visitEnd();\n        }\n\n        dcv.visitEnd();\n        return typeName;\n    }\n\n    private void genSwitchMethod(DexClassVisitor dcv, String typeNameDesc, String methodName, CB callback) {\n        DexMethodVisitor dmv = dcv\n                .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, methodName, new String[0], \"Ljava/lang/String;\"));\n        DexCodeVisitor code = dmv.visitCode();\n        code.visitRegister(3);\n        code.visitFieldStmt(Op.IGET, 0, 2, new Field(typeNameDesc, \"idx\", \"I\"));\n\n        DexLabel labels[] = new DexLabel[callbacks.size()];\n\n        Map<String, DexLabel> strMap = new TreeMap<>();\n        for (int i = 0; i < labels.length; i++) {\n            Callback cb = callbacks.get(i);\n            String key = callback.getKey((Method) cb.target);\n            DexLabel label = strMap.get(key);\n            if (label == null) {\n                label = new DexLabel();\n                strMap.put(key, label);\n            }\n            labels[i] = label;\n        }\n        code.visitPackedSwitchStmt(Op.PACKED_SWITCH, 0, 0, labels);\n        code.visitTypeStmt(Op.NEW_INSTANCE, 0, 0, \"Ljava/lang/RuntimeException;\");\n        code.visitConstStmt(Op.CONST_STRING, 1, \"invalid idx\");\n        code.visitMethodStmt(Op.INVOKE_DIRECT, new int[]{0,\n                1}, new Method(\"Ljava/lang/RuntimeException;\", \"<init>\", new String[]{\"Ljava/lang/String;\"}, \"V\"));\n        code.visitStmt1R(Op.THROW, 0);\n\n        for (Map.Entry<String, DexLabel> e : strMap.entrySet()) {\n            code.visitLabel(e.getValue());\n            code.visitConstStmt(Op.CONST_STRING, 0, e.getKey());\n            code.visitStmt1R(Op.RETURN_OBJECT, 0);\n        }\n        code.visitEnd();\n        dmv.visitEnd();\n    }\n\n    public DexFileVisitor wrap(DexFileVisitor dcv) {\n        return dcv == null ? null : new DexFileVisitor(dcv) {\n            @Override\n            public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\n                return wrap(className, super.visit(access_flags, className, superClass, interfaceNames));\n            }\n        };\n    }\n\n    public DexClassVisitor wrap(final String classNameDesc, final DexClassVisitor dcv) {\n\n        return dcv == null ? null : new DexClassVisitor(dcv) {\n            Map<MtdInfo, Method> cache = new HashMap<>();\n\n            @Override\n            public DexMethodVisitor visitMethod(final int accessFlags, Method method) {\n                final DexMethodVisitor dmv = superVisitDexMethod(accessFlags, method);\n                final MtdInfo mapTo = findDefinedTargetMethod(method.getOwner(), method.getName(), method.getDesc());\n                if (mapTo != null) {\n                    final Method t = new Method(\n                            method.getOwner(), buildMethodAName(method.getName()), method.getParameterTypes(), method\n                            .getReturnType()\n                    );\n                    final Method src = method;\n                    return new DexMethodNode(accessFlags, method) {\n                        @Override\n                        public void visitEnd() {\n                            super.visitEnd();\n                            DexCodeNode code = this.codeNode;\n                            this.codeNode = null;\n                            accept(dmv);\n                            Op opcode;\n                            if (Modifier.isStatic(access)) {\n                                opcode = Op.INVOKE_STATIC_RANGE;\n                            } else {\n                                opcode = Op.INVOKE_VIRTUAL_RANGE;\n                            }\n                            generateMtdACode(opcode, t, mapTo, dmv, src);\n\n                            int newAccess = (access & ~(DexConstants.ACC_PRIVATE | DexConstants.ACC_PROTECTED)) | DexConstants.ACC_PUBLIC; // make sure public\n                            code.accept(wrap(superVisitDexMethod(newAccess, t), dcv));\n                        }\n                    };\n                } else {\n                    return wrap(dmv, dcv);\n                }\n            }\n\n            private DexMethodVisitor wrap(DexMethodVisitor dmv, final DexClassVisitor classVisitor) {\n                return dmv == null ? null : new DexMethodVisitor(dmv) {\n                    @Override\n                    public DexCodeVisitor visitCode() {\n                        return wrap(super.visitCode(), classVisitor);\n                    }\n                };\n            }\n\n            private DexCodeVisitor wrap(DexCodeVisitor dcv, final DexClassVisitor classVisitor) {\n                return dcv == null ? null : new DexCodeVisitor(dcv) {\n                    @Override\n                    public void visitMethodStmt(Op op, int[] args, Method method) {\n                        MtdInfo mapTo = findTargetMethod(method.getOwner(), method.getName(), method.getDesc());\n                        if (mapTo != null) {\n\n                            Method methodA = cache.get(buildKey(method.getOwner(), method.getName(), method.getDesc()));\n                            if (methodA == null) {\n                                if (isStatic(op)) {\n                                    methodA = new Method(classNameDesc, buildMethodAName(method.getName()), method\n                                            .getParameterTypes(), method.getReturnType());\n                                } else {\n                                    methodA = new Method(classNameDesc, buildMethodAName(method.getName()), join(method\n                                            .getOwner(), method.getParameterTypes()), method.getReturnType());\n                                }\n                                DexMethodVisitor dmv = classVisitor\n                                        .visitMethod(DexConstants.ACC_PRIVATE | DexConstants.ACC_STATIC, methodA);\n                                generateMtdACode(op, method, mapTo, dmv, method);\n                                dmv.visitEnd();\n                                cache.put(buildKey(method.getOwner(), method.getName(), method.getDesc()), methodA);\n                            }\n                            super.visitMethodStmt(isRange(op) ? Op.INVOKE_STATIC_RANGE : Op.INVOKE_STATIC, args, methodA);\n                        } else {\n                            super.visitMethodStmt(op, args, method);\n                        }\n                    }\n                };\n            }\n\n            private void generateMtdACode(Op opcode, Method t, MtdInfo mapTo, DexMethodVisitor dmv, Method src) {\n\n                DexCodeVisitor dcv = dmv.visitCode();\n                int countArge = countArgs(t);\n                boolean haveThis = haveThis(opcode);\n\n                int registers = 4 + (haveThis ? 1 : 0) + countArge;\n                dcv.visitRegister(registers);\n                int argStart = 4;\n                if (haveThis) {\n                    dcv.visitStmt2R(Op.MOVE_OBJECT, 0, argStart);\n                    argStart++;\n                } else {\n                    dcv.visitConstStmt(Op.CONST_4, 0, 0);\n                }\n                if (t.getParameterTypes().length == 0) {\n                    dcv.visitConstStmt(Op.CONST_4, 1, 0);\n                } else {\n                    dcv.visitConstStmt(Op.CONST, 1, t.getParameterTypes().length);\n                    dcv.visitTypeStmt(Op.NEW_ARRAY, 1, 1, \"[Ljava/lang/Object;\");\n                    for (int i = 0; i < t.getParameterTypes().length; i++) {\n                        char type = t.getParameterTypes()[i].charAt(0);\n                        dcv.visitConstStmt(Op.CONST, 2, i);\n                        box(type, argStart, 3, dcv);\n                        dcv.visitStmt3R(Op.APUT_OBJECT, 3, 1, 2);\n                        if (type == 'J' || type == 'D') {\n                            argStart += 2;\n                        } else {\n                            argStart += 1;\n                        }\n                    }\n                }\n                int nextIdx = callbacks.size();\n                dcv.visitConstStmt(Op.CONST, 2, nextIdx);\n                String miTypeDesc = \"L\" + getCurrentInvocationName() + \";\";\n                dcv.visitTypeStmt(Op.NEW_INSTANCE, 3, 0, miTypeDesc);\n                dcv.visitMethodStmt(Op.INVOKE_DIRECT, new int[]{3, 0, 1,\n                        2}, new Method(miTypeDesc, \"<init>\", new String[]{\n                        \"Ljava/lang/Object;\", \"[Ljava/lang/Object;\", \"I\"\n                }, \"V\"));\n                Method call = build(mapTo);\n                dcv.visitMethodStmt(Op.INVOKE_STATIC, new int[]{3}, call);\n                if (!\"V\".equals(t.getReturnType())) {\n                    switch (call.getReturnType().charAt(0)) {\n                        case '[':\n                        case 'L':\n                            dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);\n                            break;\n                        case 'J':\n                        case 'D':\n                            dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);\n                            break;\n                        default:\n                            dcv.visitStmt1R(Op.MOVE_RESULT, 0);\n                            break;\n                    }\n                    unbox(t.getReturnType(), 0, dcv);\n                    switch (t.getReturnType().charAt(0)) {\n                        case '[':\n                        case 'L':\n                            dcv.visitStmt1R(Op.RETURN_OBJECT, 0);\n                            break;\n                        case 'J':\n                        case 'D':\n                            dcv.visitStmt1R(Op.RETURN_WIDE, 0);\n                            break;\n                        default:\n                            dcv.visitStmt1R(Op.RETURN, 0);\n                            break;\n                    }\n                } else {\n                    dcv.visitStmt0R(Op.RETURN_VOID);\n                }\n\n                Callback cb = new Callback();\n                cb.idx = nextIdx;\n                cb.callback = newMethodCallback(opcode, t);\n                cb.target = src;\n                cb.isSpecial = isSuper(opcode);\n                cb.isStatic = isStatic(opcode);\n                callbacks.add(cb);\n            }\n\n            private Method newMethodCallback(Op opcode, Method t) {\n                boolean isStatic = !haveThis(opcode);\n                boolean isSuper = isSuper(opcode);\n                Method m;\n                if (isSuper || isStatic) {\n                    m = new Method(t.getOwner(), buildCallbackMethodName(t.getName()), new String[]{\n                            \"[Ljava/lang/Object;\"\n                    }, \"Ljava/lang/Object;\");\n                } else {\n                    m = new Method(t.getOwner(), buildCallbackMethodName(t.getName()), new String[]{\n                            \"Ljava/lang/Object;\", \"[Ljava/lang/Object;\"\n                    }, \"Ljava/lang/Object;\");\n                }\n\n                DexMethodVisitor dmv = superVisitDexMethod(\n                        DexConstants.ACC_PUBLIC | (isSuper ? 0 : DexConstants.ACC_STATIC), m);\n                DexCodeVisitor dcv = dmv.visitCode();\n                int totalRegs;\n                int argStart;\n                if (isStatic) {\n                    totalRegs = 1 + countArgs(t) + 1;\n                    argStart = totalRegs - 1;\n                } else {\n                    totalRegs = 1 + countArgs(t) + 2;\n                    argStart = totalRegs - 2;\n                }\n                dcv.visitRegister(totalRegs);\n                int args[] = new int[countArgs(t) + (isStatic ? 0 : 1)];\n                int args_index = 0;\n                int i = 1;\n                if (!isStatic) {\n                    if (i != argStart) {\n                        dcv.visitStmt2R(Op.MOVE_OBJECT, i, argStart);\n                    }\n                    if(!isSuper) {\n                        dcv.visitTypeStmt(Op.CHECK_CAST, i, -1, t.getOwner());\n                    }\n                    args[args_index++] = i;\n                    i++;\n                    argStart++;\n                }\n\n                String[] parameterTypes = t.getParameterTypes();\n                for (int i1 = 0; i1 < parameterTypes.length; i1++) {\n                    String argType = parameterTypes[i1];\n                    dcv.visitConstStmt(Op.CONST, 0, i1);\n                    dcv.visitStmt3R(Op.AGET_OBJECT, i, argStart, 0);\n                    unbox(argType, i, dcv);\n                    args[args_index++] = i;\n                    if (argType.charAt(0) == 'J' || argType.charAt(0) == 'D') {\n                        args[args_index++] = i + 1;\n                        i += 2;\n                    } else {\n                        i += 1;\n                    }\n                }\n\n                dcv.visitMethodStmt(opcode, args, t);\n                if (\"V\".equals(t.getReturnType())) {\n                    dcv.visitConstStmt(Op.CONST, 0, 0);\n                } else {\n                    switch (t.getReturnType().charAt(0)) {\n                        case '[':\n                        case 'L':\n                            dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);\n                            break;\n                        case 'J':\n                        case 'D':\n                            dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);\n                            break;\n                        default:\n                            dcv.visitStmt1R(Op.MOVE_RESULT, 0);\n                            break;\n                    }\n                    box(t.getReturnType().charAt(0), 0, 0, dcv);\n                }\n                dcv.visitStmt1R(Op.RETURN_OBJECT, 0);\n\n                return m;\n            }\n\n            private DexMethodVisitor superVisitDexMethod(int accessFlags, Method method) {\n                return super.visitMethod(accessFlags, method);\n            }\n        };\n    }\n\n    private String[] join(String a, String[] b) {\n        String joined[] = new String[b.length + 1];\n        joined[0] = a;\n        System.arraycopy(b, 0, joined, 1, b.length);\n        return joined;\n    }\n\n    private boolean isStatic(Op op) {\n        return op == Op.INVOKE_STATIC || op == Op.INVOKE_STATIC_RANGE;\n    }\n\n    private boolean isRange(Op op) {\n        switch (op) {\n            case INVOKE_STATIC_RANGE:\n            case INVOKE_DIRECT_RANGE:\n            case INVOKE_INTERFACE_RANGE:\n            case INVOKE_SUPER_RANGE:\n            case INVOKE_VIRTUAL_RANGE:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    private void unbox(String argType, int i, DexCodeVisitor dcv) {\n        switch (argType.charAt(0)) {\n            case '[':\n            case 'L':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, argType);\n                break;\n            case 'Z':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Boolean;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Boolean;\", \"booleanValue\", new String[]{}, \"Z\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'B':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Byte;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Byte;\", \"byteValue\", new String[]{}, \"B\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'S':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Short;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Short;\", \"shortValue\", new String[]{}, \"S\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'C':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Character;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Character;\", \"charValue\", new String[]{}, \"C\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'I':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Integer;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Integer;\", \"intValue\", new String[]{}, \"I\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'F':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Float;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Float;\", \"floatValue\", new String[]{}, \"F\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT, i);\n                break;\n            case 'D':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Double;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Double;\", \"doubleValue\", new String[]{}, \"D\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);\n                break;\n            case 'J':\n                dcv.visitTypeStmt(Op.CHECK_CAST, i, i, \"Ljava/lang/Long;\");\n                dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{\n                        i}, new Method(\"Ljava/lang/Long;\", \"longValue\", new String[]{}, \"J\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);\n                break;\n        }\n    }\n\n    private boolean isSuper(Op opcode) {\n        return opcode == Op.INVOKE_SUPER || opcode == Op.INVOKE_SUPER_RANGE;\n    }\n\n    private Method build(MtdInfo mapTo) {\n        Type[] ts = Type.getArgumentTypes(mapTo.desc);\n        String ss[] = new String[ts.length];\n        for (int i = 0; i < ss.length; i++) {\n            ss[i] = ts[i].getDescriptor();\n        }\n        return new Method(mapTo.owner, mapTo.name, ss, Type.getReturnType(mapTo.desc).getDescriptor());\n    }\n\n    private void box(char type, int from, int to, DexCodeVisitor dcv) {\n        switch (type) {\n            case 'L':\n            case '[':\n                dcv.visitStmt2R(Op.MOVE_OBJECT, from, to);\n                break;\n            case 'Z':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Boolean;\", \"valueOf\", new String[]{\"Z\"}, \"Ljava/lang/Boolean;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'B':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Byte;\", \"valueOf\", new String[]{\"B\"}, \"Ljava/lang/Byte;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'S':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Short;\", \"valueOf\", new String[]{\"S\"}, \"Ljava/lang/Short;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'C':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Character;\", \"valueOf\", new String[]{\n                        \"C\"}, \"Ljava/lang/Character;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'I':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Integer;\", \"valueOf\", new String[]{\"I\"}, \"Ljava/lang/Integer;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'F':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from}, new Method(\"Ljava/lang/Float;\", \"valueOf\", new String[]{\"F\"}, \"Ljava/lang/Float;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'D':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from, from + 1}, new Method(\"Ljava/lang/Double;\", \"valueOf\", new String[]{\n                        \"D\"}, \"Ljava/lang/Double;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n            case 'J':\n                dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{\n                        from, from + 1}, new Method(\"Ljava/lang/Long;\", \"valueOf\", new String[]{\n                        \"J\"}, \"Ljava/lang/Long;\"));\n                dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);\n                break;\n        }\n    }\n\n    private boolean haveThis(Op opcode) {\n        return opcode != Op.INVOKE_STATIC && opcode != Op.INVOKE_STATIC_RANGE;\n    }\n\n    static int countArgs(Method t) {\n        int i = 0;\n        for (String arg : t.getParameterTypes()) {\n            char type = arg.charAt(0);\n            if (type == 'J' || type == 'D') {\n                i += 2;\n            } else {\n                i += 1;\n            }\n        }\n        return i;\n    }\n\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InitOut.java",
    "content": "package com.googlecode.d2j.tools.jar;\r\n\r\nimport com.googlecode.dex2jar.tools.BaseCmd;\r\nimport org.objectweb.asm.ClassReader;\r\nimport org.objectweb.asm.ClassVisitor;\r\nimport org.objectweb.asm.FieldVisitor;\r\nimport org.objectweb.asm.MethodVisitor;\r\nimport org.objectweb.asm.tree.*;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.FileSystem;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.util.*;\r\n\r\nimport static com.googlecode.d2j.util.AccUtils.*;\r\nimport static org.objectweb.asm.Opcodes.*;\r\n\r\npublic class InitOut {\r\n    private static Set<String> keywords = new HashSet<String>(Arrays.asList(\"abstract\", \"continue\", \"for\", \"new\",\r\n            \"switch\", \"assert\", \"default\", \"goto\", \"package\", \"synchronized\", \"boolean\", \"do\", \"if\", \"private\", \"this\",\r\n            \"break\", \"double\", \"implements\", \"protected\", \"throw\", \"byte\", \"else\", \"import\", \"public\", \"throws\",\r\n            \"case\", \"enum\", \"instanceof\", \"return\", \"transient\", \"catch\", \"extends\", \"int\", \"short\", \"try\", \"char\",\r\n            \"final\", \"interface\", \"static\", \"void\", \"class\", \"finally\", \"long\", \"strictfp\", \"volatile\", \"const\",\r\n            \"float\", \"native\", \"super\", \"while\"));\r\n    private int clzIndex = 0;\r\n    private Set<String> clzMap = new TreeSet<String>();\r\n    private Set<String> clzSet = new TreeSet<String>();\r\n    private Path from;\r\n    private int maxLength = 40;\r\n    private Set<String> memberMap = new TreeSet<String>();\r\n    private int minLength = 2;\r\n    private int pkgIndex = 0;\r\n    private Set<String> pkgMap = new TreeSet<String>();\r\n    private Set<String> pkgSet = new TreeSet<String>();\r\n    private boolean initEnumNames = false;\r\n    private boolean initSourceNames = false;\r\n    private boolean initAssertionNames = false;\r\n\r\n    public InitOut initEnumNames() {\r\n        this.initEnumNames = true;\r\n        return this;\r\n    }\r\n\r\n    public InitOut initSourceNames() {\r\n        this.initSourceNames = true;\r\n        return this;\r\n    }\r\n\r\n    public InitOut initAssertionNames() {\r\n        this.initAssertionNames = true;\r\n        return this;\r\n    }\r\n\r\n    private void doClass0(String clz) {\r\n        if (clzSet.contains(clz)) {\r\n            return;\r\n        }\r\n        clzSet.add(clz);\r\n\r\n        int index = clz.lastIndexOf('$');\r\n        if (index > 0) {\r\n            doClass0(clz.substring(0, index));\r\n            String cName = clz.substring(index + 1);\r\n            try {\r\n                Integer.parseInt(cName);\r\n            } catch (Exception ex) {\r\n                if (shouldRename(cName)) {\r\n                    clzMap.add(String.format(\"c %s=CI%03d%s\", clz, clzIndex++, short4LongName(cName)));\r\n                }\r\n            }\r\n        } else {\r\n            index = clz.lastIndexOf('/');\r\n            if (index > 0) {\r\n                doPkg(clz.substring(0, index));\r\n                String cName = clz.substring(index + 1);\r\n                if (shouldRename(cName)) {\r\n                    clzMap.add(String.format(\"c %s=C%03d%s\", clz, clzIndex++, short4LongName(cName)));\r\n                }\r\n            } else {\r\n                if (shouldRename(clz)) {\r\n                    clzMap.add(String.format(\"c %s=CI_%03d%s\", clz, clzIndex++, short4LongName(clz)));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private String short4LongName(String name) {\r\n        if (name.length() > maxLength) {\r\n            return \"x\" + Integer.toHexString(name.hashCode());\r\n        } else {\r\n            return name;\r\n        }\r\n    }\r\n\r\n    private void doMember(String owner, MemberInfo member, final int x) {\r\n        // TODO use suggested name\r\n        if (x > 0 || shouldRename(member.name)) {\r\n            if (member.desc.indexOf('(') >= 0) {\r\n                StringBuilder sb = new StringBuilder();\r\n                sb.append(isStatic(member.access) ? \"M\" : \"m\");\r\n                if (isPrivate(member.access)) {\r\n                    sb.append(\"p\");\r\n                } else if (isPublic(member.access)) {\r\n                    sb.append(\"P\");\r\n                }\r\n                if (x > 0) {\r\n                    sb.append(x);\r\n                }\r\n                sb.append(short4LongName(member.name));\r\n                if (x > 0) {\r\n                    memberMap.add(\"m \" + owner + \".\" + member.name + member.desc + \"=\" + sb.toString());\r\n                } else {\r\n                    memberMap.add(\"m \" + owner + \".\" + member.name\r\n                            + member.desc.substring(0, member.desc.indexOf(')') + 1) + \"=\" + sb.toString());\r\n                }\r\n            } else {\r\n                StringBuilder sb = new StringBuilder();\r\n                sb.append(isStatic(member.access) ? \"F\" : \"f\");\r\n                if (isPrivate(member.access)) {\r\n                    sb.append(\"p\");\r\n                } else if (isPublic(member.access)) {\r\n                    sb.append(\"P\");\r\n                }\r\n                if (x > 0) {\r\n                    sb.append(x);\r\n                }\r\n                sb.append(short4LongName(member.name));\r\n                if (x > 0) {\r\n                    memberMap.add(\"m \" + owner + \".\" + member.name + \"[\" + member.desc + \"]\" + \"=\" + sb.toString());\r\n                } else {\r\n                    memberMap.add(\"m \" + owner + \".\" + member.name + \"=\" + sb.toString());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private List<ClassInfo> collect(Path file) throws IOException {\r\n        final List<ClassInfo> clzList = new ArrayList<ClassInfo>();\r\n        final ClassVisitor collectVisitor = new ClassVisitor(ASM4) {\r\n            private static final String ASSERTION_DISABLED_FIELD_NAME = \"$assertionsDisabled\";\r\n            private static final String ENUM_VALUES_FIELD_NAME = \"ENUM$VALUES\";\r\n            ClassInfo clz;\r\n            boolean isEnum = false;\r\n            Map<String, String> enumFieldMap = new HashMap<String, String>();\r\n\r\n            @Override\r\n            public void visitSource(String source, String debug) {\r\n                if (initSourceNames && !clz.name.contains(\"$\") && source.endsWith(\".java\")) {\r\n                    clz.suggestName = source.substring(0, source.length() - 5);\r\n                }\r\n            }\r\n\r\n            @Override\r\n            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\r\n                clz.addMethod(access, name, desc);\r\n                if (initEnumNames && isEnum && name.equals(\"<clinit>\")) {\r\n                    final String thisDesc = \"L\" + clz.name + \";\";\r\n                    return new MethodNode(ASM4, access, name, desc, signature, exceptions) {\r\n                        @Override\r\n                        public void visitEnd() {\r\n                            if (this.instructions != null) {\r\n                                int status = 0;\r\n                                String eFieldName = null;\r\n                                for (AbstractInsnNode p = this.instructions.getFirst(); p != null; p = p.getNext()) {\r\n                                    //looking for  NEW,DUP,LDC,PUTSTATUS\r\n\r\n                                    if (status == 0) {  // init\r\n                                        if (p.getOpcode() == NEW) {\r\n                                            TypeInsnNode ti = (TypeInsnNode) p;\r\n                                            if (thisDesc.equals(ti.desc)) {\r\n                                                status = 1;\r\n                                            }\r\n                                        }\r\n                                    } else if (status == 1) {  // find NEW\r\n                                        if (p.getOpcode() == DUP) {\r\n                                            status = 2;\r\n                                        } else {\r\n                                            status = 0;\r\n                                        }\r\n                                    } else if (status == 2) {  //find DUP\r\n                                        if (p.getOpcode() == LDC) {\r\n                                            LdcInsnNode ldc = (LdcInsnNode) p;\r\n                                            if (ldc.cst instanceof String) {\r\n                                                eFieldName = (String) ldc.cst;\r\n                                                status = 3;\r\n                                            } else {\r\n                                                status = 0;\r\n                                            }\r\n                                        } else {\r\n                                            status = 0;\r\n                                        }\r\n                                    } else if (status == 3) {  //find LDC\r\n                                        if (p.getOpcode() == PUTSTATIC) {\r\n                                            FieldInsnNode fin = (FieldInsnNode) p;\r\n                                            if (fin.owner.equals(thisDesc) && fin.desc.equals(thisDesc)) {\r\n                                                if (!fin.name.equals(eFieldName)) {\r\n                                                    enumFieldMap.put(fin.name, eFieldName);\r\n                                                }\r\n                                                eFieldName = null;\r\n                                                status = 0;\r\n                                            }\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    };\r\n                }\r\n                return null;\r\n            }\r\n\r\n            @Override\r\n            public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {\r\n                MemberInfo mi = clz.addField(access, name, desc);\r\n                if (initEnumNames && isEnum\r\n                        && isPrivate(access) && isFinal(access) && isSynthetic(access)\r\n                        && !ENUM_VALUES_FIELD_NAME.equals(name)\r\n                        && (\"[L\" + clz.name + \";\").equals(desc)) {\r\n                    mi.suggestName = ENUM_VALUES_FIELD_NAME;\r\n                }\r\n                if (initAssertionNames && isSynthetic(access) && isStatic(access)\r\n                        && !isPrivate(access) && !isPublic(access) && !isProtected(access)\r\n                        && desc.equals(\"Z\") && !ASSERTION_DISABLED_FIELD_NAME.equals(name)) {\r\n                    mi.suggestName = ASSERTION_DISABLED_FIELD_NAME;\r\n                }\r\n\r\n                return null;\r\n            }\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                if (initEnumNames) {\r\n                    final String thisDesc = \"L\" + clz.name + \";\";\r\n                    for (Map.Entry<String, String> e : enumFieldMap.entrySet()) {\r\n                        String name = e.getKey();\r\n                        String suggestName = e.getValue();\r\n                        for (MemberInfo mi : clz.fields) {\r\n                            if (isFinal(mi.access) && isStatic(mi.access)\r\n                                    && mi.name.equals(name) && mi.desc.equals(thisDesc)) {\r\n                                mi.suggestName = suggestName;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                clzList.add(clz);\r\n                clz = null;\r\n                isEnum = false;\r\n                enumFieldMap.clear();\r\n            }\r\n\r\n            @Override\r\n            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {\r\n                this.clz = new ClassInfo(name);\r\n                isEnum = isEnum(access);\r\n            }\r\n        };\r\n\r\n      try(FileSystem fs = BaseCmd.openZip(file)) {\r\n          BaseCmd.walkJarOrDir(fs.getPath(\"/\"), new BaseCmd.FileVisitorX() {\r\n              @Override\r\n              public void visitFile(Path file, String relative) throws IOException {\r\n                  if (relative.endsWith(\".class\")) {\r\n                      byte data[] = Files.readAllBytes(file);\r\n                      new ClassReader(data).accept(collectVisitor, ClassReader.EXPAND_FRAMES);\r\n                  }\r\n              }\r\n          });\r\n      }\r\n        return clzList;\r\n    }\r\n\r\n    private void doPkg(String pkg) {\r\n        if (pkgSet.contains(pkg)) {\r\n            return;\r\n        }\r\n        pkgSet.add(pkg);\r\n        int index = pkg.lastIndexOf('/');\r\n        if (index > 0) {\r\n            doPkg(pkg.substring(0, index));\r\n            String cName = pkg.substring(index + 1);\r\n            if (shouldRename(cName)) {\r\n                pkgMap.add(String.format(\"p %s=p%02d%s\", pkg, pkgIndex++, short4LongName(cName)));\r\n            }\r\n        } else {\r\n            if (shouldRename(pkg)) {\r\n                pkgMap.add(String.format(\"p %s=p%02d%s\", pkg, pkgIndex++, short4LongName(pkg)));\r\n            }\r\n        }\r\n    }\r\n\r\n    public InitOut from(Path from) {\r\n        this.from = from;\r\n        return this;\r\n    }\r\n\r\n    public InitOut maxLength(int m) {\r\n        this.maxLength = m;\r\n        return this;\r\n    }\r\n\r\n    public InitOut minLength(int m) {\r\n        this.minLength = m;\r\n        return this;\r\n    }\r\n\r\n    private boolean shouldRename(String s) {\r\n        return s.length() > maxLength || s.length() < minLength || keywords.contains(s);\r\n    }\r\n\r\n    public void to(Path config) throws IOException {\r\n        List<ClassInfo> classInfoList = collect(from);\r\n        transform(classInfoList);\r\n        List<String> list = new ArrayList<String>();\r\n        list.addAll(pkgMap);\r\n        list.addAll(clzMap);\r\n        list.addAll(memberMap);\r\n        Files.write(config,list, StandardCharsets.UTF_8);\r\n    }\r\n\r\n    private void transformerMember(String owner, List<MemberInfo> members) {\r\n        Iterator<MemberInfo> it = members.iterator();\r\n        if (it.hasNext()) {\r\n            MemberInfo current = it.next();\r\n            while (true) {\r\n                if (it.hasNext()) {\r\n                    MemberInfo next = it.next();\r\n                    if (current.name.equals(next.name)) {\r\n                        int x = 1;\r\n                        doMember(owner, current, x++);\r\n                        doMember(owner, next, x++);\r\n                        while (it.hasNext()) {\r\n                            next = it.next();\r\n                            if (current.name.equals(next.name)) {\r\n                                doMember(owner, next, x++);\r\n                            } else {\r\n                                current = next;\r\n                                break;\r\n                            }\r\n                        }\r\n                    } else {\r\n                        doMember(owner, current, 0);\r\n                        current = next;\r\n                    }\r\n                } else {\r\n                    doMember(owner, current, 0);\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private void transform(List<ClassInfo> classInfoList) {\r\n        MemberInfoComparator comparator = new MemberInfoComparator();\r\n        for (ClassInfo ci : classInfoList) {\r\n            doClass0(ci.name);\r\n            Collections.sort(ci.fields, comparator);\r\n            transformerMember(ci.name, ci.fields);\r\n            Collections.sort(ci.methods, comparator);\r\n            transformerMember(ci.name, ci.methods);\r\n        }\r\n\r\n    }\r\n\r\n    static private class ClassInfo {\r\n\r\n        final public String name;\r\n        public List<MemberInfo> fields = new ArrayList<MemberInfo>(5);\r\n        public List<MemberInfo> methods = new ArrayList<MemberInfo>(5);\r\n        public String suggestName;\r\n\r\n        public ClassInfo(String name) {\r\n            this.name = name;\r\n        }\r\n\r\n        public MemberInfo addField(int access, String name, String type) {\r\n            MemberInfo mi = new MemberInfo(access, name, type);\r\n            fields.add(mi);\r\n            return mi;\r\n        }\r\n\r\n        public MemberInfo addMethod(int access, String name, String desc) {\r\n            MemberInfo mi = new MemberInfo(access, name, desc);\r\n            methods.add(mi);\r\n            return mi;\r\n        }\r\n\r\n        public String toString() {\r\n            return name;\r\n        }\r\n    }\r\n\r\n    private static class MemberInfo {\r\n        public int access;\r\n        public String desc;\r\n        public String name;\r\n        public String suggestName;\r\n\r\n        public MemberInfo(int access, String name, String desc) {\r\n            this.name = name;\r\n            this.access = access;\r\n            this.desc = desc;\r\n        }\r\n    }\r\n\r\n    private static class MemberInfoComparator implements Comparator<MemberInfo> {\r\n        @Override\r\n        public int compare(MemberInfo memberInfo, MemberInfo memberInfo2) {\r\n            int x = memberInfo.name.compareTo(memberInfo2.name);\r\n            if (x != 0) {\r\n                return x;\r\n            }\r\n            return memberInfo.desc.compareTo(memberInfo2.desc);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2015 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.tools.jar;\n\nimport com.googlecode.dex2jar.tools.BaseCmd;\nimport org.objectweb.asm.*;\nimport org.objectweb.asm.commons.Remapper;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\nimport org.objectweb.asm.tree.InsnList;\nimport org.objectweb.asm.tree.LocalVariableNode;\nimport org.objectweb.asm.tree.MethodNode;\nimport org.objectweb.asm.tree.TryCatchBlockNode;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Modifier;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.jar.Attributes.Name;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\n\n/**\n * 1. Replace class A to another class B, include superclass, new for\n * <p/>\n * <pre>\n *     class Test1 extends A ...\n *     class Test2 implements A ...\n *     void amethod(A a) ...\n * </pre>\n * <p/>\n * after\n * <p/>\n * <pre>\n *     class Test1 extends B ...\n *     class Test2 extends B ...\n *     void amethod(B a) ...\n * </pre>\n * <p/>\n * 2. Replace method A to another method B, method B must be public static, and in either 'public static RET b(ARGs)' or\n * 'public RET b(Invocation inv)' RET: same return type with method A or Object ARGs: if method A is static, ARGs is\n * same with method A, if method A is non-static the ARGs is 'thiz, arguments in methodA'\n * <p/>\n * <pre>\n * public int a() {\n *     Test t = new Test();\n *     return t.test(1, 2);\n * }\n * </pre>\n * <p/>\n * after\n * <p/>\n * <pre>\n *     // direct replace\n *     public int a(){\n *         Test t=new Test();\n *         return B(t,1,2);\n *     }\n *     // or by MethodInvocation\n *     public int a(){\n *         Test t=new Test();\n *         return test_$$$_A_(t,1,2)\n *     }\n *     // the replaced invoke method\n *     public static int test$$$_A_(Test t, int a, int b){\n *         MethodInvocation i=new MethodInvocation(t, new Object[]{a.b})\n *         return B(i).intValue();\n *     }\n *     // the callback if MethodInvocation.proceed() is invoked\n *     public static Object test$$$$_callback(Test t, Object[]args) {\n *        return box(t.test(args[0].intValue(),args[1].intValue()));\n *     }\n * </pre>\n * <p/>\n * 3. Replace Methods Implementations\n * <p/>\n * <pre>\n * public int test() {\n *         ...\n * }\n * </pre>\n * <p/>\n * after\n * <p/>\n * <pre>\n *     public int test(){\n *          MethodInvocation i=new MethodInvocation(t, new Object[]{a.b})\n *          return B(i).intValue();\n *     }\n *     public int org_test(){\n *         ...\n *     }\n * </pre>\n */\npublic class InvocationWeaver extends BaseWeaver implements Opcodes {\n    private static final Type OBJECT_TYPE = Type.getType(Object.class);\n    private Remapper remapper = new Remapper() {\n\n        @Override\n        public String mapDesc(String desc) {\n            if (desc.length() == 1) {\n                return desc;\n            }\n            String nDesc = clzDescMap.get(desc);\n            return nDesc == null ? desc : nDesc;\n        }\n    };\n\n    static private void box(Type arg, MethodVisitor mv) {\n        switch (arg.getSort()) {\n            case Type.OBJECT:\n            case Type.ARRAY:\n                return;\n            case Type.INT:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Integer\", \"valueOf\", \"(I)Ljava/lang/Integer;\");\n                break;\n            case Type.LONG:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Long\", \"valueOf\", \"(J)Ljava/lang/Long;\");\n                break;\n            case Type.FLOAT:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Floag\", \"valueOf\", \"(F)Ljava/lang/Floag;\");\n                break;\n            case Type.DOUBLE:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Double\", \"valueOf\", \"(D)Ljava/lang/Double;\");\n                break;\n            case Type.SHORT:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Short\", \"valueOf\", \"(S)Ljava/lang/Short;\");\n                break;\n            case Type.CHAR:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Character\", \"valueOf\", \"(C)Ljava/lang/Character;\");\n                break;\n            case Type.BOOLEAN:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Boolean\", \"valueOf\", \"(Z)Ljava/lang/Boolean;\");\n                break;\n            case Type.BYTE:\n                mv.visitMethodInsn(INVOKESTATIC, \"java/lang/Byte\", \"valueOf\", \"(B)Ljava/lang/Byte;\");\n                break;\n            case Type.VOID:\n                mv.visitInsn(ACONST_NULL);\n                break;\n        }\n    }\n\n    static private void unBox(Type orgRet, Type nRet, MethodVisitor mv) {\n        if (orgRet.equals(nRet)) {\n            return;\n        }\n        if (orgRet.getSort() == Type.VOID) {\n            mv.visitInsn(nRet.getSize() == 1 ? POP : POP2);\n        }\n        if (nRet.getSort() != Type.OBJECT) {\n            throw new RuntimeException(\"invalid ret type:\" + nRet);\n        }\n        switch (orgRet.getSort()) {\n            case Type.OBJECT:\n            case Type.ARRAY:\n                mv.visitTypeInsn(CHECKCAST, orgRet.getInternalName());\n                break;\n            case Type.INT:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"intValue\", \"()I\");\n                break;\n            case Type.FLOAT:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"floatValue\", \"()F\");\n                break;\n            case Type.LONG:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"longValue\", \"()J\");\n                break;\n            case Type.DOUBLE:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"doubleValue\", \"()D\");\n                break;\n            case Type.BYTE:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"byteValue\", \"()B\");\n                break;\n            case Type.SHORT:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Number\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Number\", \"shortValue\", \"()S\");\n                break;\n            case Type.CHAR:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Character\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Character\", \"charValue\", \"()C\");\n                break;\n            case Type.BOOLEAN:\n                mv.visitTypeInsn(CHECKCAST, \"java/lang/Boolean\");\n                mv.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Boolean\", \"booleanValue\", \"()Z\");\n                break;\n        }\n    }\n\n    public byte[] wave0(byte[] data) throws IOException {\n        final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n        wave0(data, cw);\n        return cw.toByteArray();\n    }\n\n    public void wave0(byte[] data, final ClassVisitor cv) throws IOException {\n        new ClassReader(data).accept(wrapper(cv), ClassReader.EXPAND_FRAMES);\n    }\n\n    public ClassVisitor wrapper(final ClassVisitor cv) {\n        return new RemappingClassAdapter(cv, remapper) {\n            Map<MtdInfo, MtdInfo> toCreate = new HashMap<MtdInfo, MtdInfo>();\n            String clzName;\n\n            private MtdInfo newMethodA(int opcode, MtdInfo t, MtdInfo mapTo) {\n                MtdInfo n = toCreate.get(t);\n                if (n != null) {\n                    return n;\n                }\n                n = new MtdInfo();\n                n.owner = t.owner;\n                n.name = buildMethodAName(t.name);\n                boolean hasThis = opcode != INVOKESTATIC;\n\n                if (hasThis) {\n                    Type[] args = Type.getArgumentTypes(t.desc);\n                    Type ret = Type.getReturnType(t.desc);\n                    List<Type> ts = new ArrayList<>(args.length + 1);\n                    ts.add(Type.getType(t.owner));\n                    ts.addAll(Arrays.asList(args));\n                    n.desc = Type.getMethodDescriptor(ret, ts.toArray(new Type[ts.size()]));\n                } else {\n                    n.desc = t.desc;\n                }\n\n                toCreate.put(t, n);\n                MethodVisitor mv = cv.visitMethod(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC, n.name, n.desc, null, null);\n                mv.visitCode();\n                genMethodACode(opcode, t, mapTo, mv, t);\n\n                return n;\n            }\n\n            private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor mv, MtdInfo src) {\n                boolean hasThis = opcode != INVOKESTATIC;\n                Type[] args = Type.getArgumentTypes(t.desc);\n                Type ret = Type.getReturnType(t.desc);\n\n\n                final int start;\n                mv.visitTypeInsn(NEW, getCurrentInvocationName());\n                mv.visitInsn(DUP);\n                if (hasThis) {\n                    mv.visitVarInsn(ALOAD, 0);\n                    start = 1;\n                } else {\n                    mv.visitInsn(ACONST_NULL);\n                    start = 0;\n                }\n                if (args.length == 0) {\n                    mv.visitInsn(ACONST_NULL);\n                } else {\n                    mv.visitLdcInsn(args.length);\n                    mv.visitTypeInsn(ANEWARRAY, \"java/lang/Object\");\n                    for (int i = 0; i < args.length; i++) {\n                        mv.visitInsn(DUP);\n                        mv.visitLdcInsn(i);\n                        mv.visitVarInsn(args[i].getOpcode(ILOAD), i + start);\n                        box(args[i], mv);\n                        mv.visitInsn(AASTORE);\n                    }\n                }\n                int nextIdx = callbacks.size();\n                mv.visitLdcInsn(nextIdx);\n                mv.visitMethodInsn(INVOKESPECIAL, getCurrentInvocationName(), \"<init>\",\n                        \"(Ljava/lang/Object;[Ljava/lang/Object;I)V\");\n\n                mv.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);\n                unBox(ret, Type.getReturnType(mapTo.desc), mv);\n                mv.visitInsn(ret.getOpcode(IRETURN));\n                mv.visitMaxs(-1, -1);\n                mv.visitEnd();\n\n                Callback cb = new Callback();\n                cb.idx = nextIdx;\n                cb.callback = newMethodCallback(opcode, t);\n                cb.target = src;\n                cb.isSpecial = opcode == INVOKESPECIAL;\n                cb.isStatic = opcode == INVOKESTATIC;\n                callbacks.add(cb);\n            }\n\n            private MtdInfo newMethodCallback(int opcode, MtdInfo t) {\n                MtdInfo n = new MtdInfo();\n                n.owner = \"L\" + className + \";\";\n                n.name = buildCallbackMethodName(t.name) ;\n                if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {\n                    n.desc = \"([Ljava/lang/Object;)Ljava/lang/Object;\";\n                } else {\n                    n.desc = \"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\";\n                }\n                MethodVisitor mv = cv.visitMethod(opcode == INVOKESPECIAL ? ACC_PUBLIC : ACC_PUBLIC\n                        | ACC_STATIC, n.name, n.desc, null, null);\n                mv.visitCode();\n                int start;\n                if (opcode != INVOKESTATIC) {\n                    mv.visitVarInsn(ALOAD, 0);\n                    if (opcode != INVOKESPECIAL) {\n                        mv.visitTypeInsn(CHECKCAST, toInternal(t.owner));\n                    }\n                    start = 1;\n                } else {\n                    start = 0;\n                }\n                Type[] args = Type.getArgumentTypes(t.desc);\n\n                for (int i = 0; i < args.length; i++) {\n                    mv.visitVarInsn(ALOAD, start);\n                    mv.visitLdcInsn(i);\n                    mv.visitInsn(AALOAD);\n                    unBox(args[i], OBJECT_TYPE, mv);\n                }\n                mv.visitMethodInsn(opcode, toInternal(t.owner), t.name, t.desc);\n                Type ret = Type.getReturnType(t.desc);\n                box(ret, mv);\n                mv.visitInsn(ARETURN);\n                mv.visitMaxs(-1, -1);\n                mv.visitEnd();\n                return n;\n            }\n\n            @Override\n            public void visit(int version, int access, String name, String signature, String superName,\n                              String[] interfaces) {\n                super.visit(version, access, name, signature, superName, interfaces);\n                clzName = name;\n            }\n\n            public MethodVisitor visitMethod(int access, final String name, String desc, String signature,\n                                             String[] exceptions) {\n\n                final MethodVisitor superMv = superMethodVisitor(access, name, desc, signature, exceptions);\n                final MtdInfo mapTo = findDefinedTargetMethod(\"L\" + clzName + \";\", name, desc);\n                if (mapTo != null) {\n                    final MtdInfo t1 = new MtdInfo();\n                    t1.owner = \"L\" + clzName + \";\";\n                    t1.name = buildMethodAName(name) ;\n                    t1.desc = desc;\n                    final MtdInfo t = t1;\n                    final MtdInfo src = new MtdInfo();\n                    src.owner = t.owner;\n                    src.name = name;\n                    src.desc = desc;\n                    return new MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) {\n                        @Override\n                        public void visitEnd() {\n\n                            InsnList instructions = this.instructions;\n                            List<TryCatchBlockNode> tryCatchBlocks = this.tryCatchBlocks;\n                            List<LocalVariableNode> localVariables = this.localVariables;\n\n                            this.instructions = new InsnList();\n                            this.tryCatchBlocks = new ArrayList<>();\n                            this.localVariables = new ArrayList<>();\n                            this.maxLocals = -1;\n                            this.maxStack = -1;\n                            accept(superMv);\n                            int opcode;\n                            if (Modifier.isStatic(access)) {\n                                opcode = Opcodes.INVOKESTATIC;\n                            } else {\n                                opcode = Opcodes.INVOKEVIRTUAL;\n                            }\n                            genMethodACode(opcode, t, mapTo, superMv, src);\n\n                            int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC; // make sure public\n                            MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t.name, desc, null, null));\n                            if(rmv!=null) {\n                                rmv.visitCode();\n                                int n, i;\n                                n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();\n\n                                for (i = 0; i < n; ++i) {\n                                    tryCatchBlocks.get(i).accept(rmv);\n                                }\n                                instructions.accept(rmv);\n                                n = localVariables == null ? 0 : localVariables.size();\n\n                                for (i = 0; i < n; ++i) {\n                                    localVariables.get(i).accept(rmv);\n                                }\n                                rmv.visitMaxs(-1, -1);\n                                rmv.visitEnd();\n                            }\n                        }\n                    };\n                } else {\n                    return wrap(superMv);\n                }\n            }\n\n            private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {\n                return super.visitMethod(access, name, desc, signature, exceptions);\n            }\n\n            MethodVisitor wrap(MethodVisitor mv){\n                return  mv==null?null: new ReplaceMethodVisitor(mv);\n            }\n            class ReplaceMethodVisitor extends MethodVisitor {\n                public ReplaceMethodVisitor(MethodVisitor mv) {\n                    super(Opcodes.ASM4, mv);\n                }\n\n                @Override\n                public void visitMethodInsn(int opcode, String owner, String name, String desc) {\n                    MtdInfo mapTo = findTargetMethod(\"L\" + owner + \";\", name, desc);\n                    if (mapTo != null) {\n                        boolean isStatic = opcode == INVOKESTATIC;\n                        Type orgRet = Type.getReturnType(desc);\n                        Type orgArgs[] = Type.getArgumentTypes(desc);\n                        Type nRet = Type.getReturnType(mapTo.desc);\n                        Type nArgs[] = Type.getArgumentTypes(mapTo.desc);\n                        if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {\n                            throw new RuntimeException(\"can't cast \" + nRet + \" to \" + orgRet);\n                        }\n\n                        if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {\n                            MtdInfo t = new MtdInfo();\n                            t.owner = \"L\" + owner + \";\";\n                            t.name = name;\n                            t.desc = desc;\n                            MtdInfo n = newMethodA(opcode, t, mapTo);\n                            super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc);\n                        } else { // simple replace\n                            // checking for invalid replace\n                            if (isStatic) {\n                                if (!Arrays.deepEquals(orgArgs, nArgs)) {\n                                    throw new RuntimeException(\"arguments not equal: \" + owner + \".\" + name + desc\n                                            + \" <> \" + mapTo.owner + \".\" + mapTo.name + mapTo.desc);\n                                }\n                            } else {\n                                if (nArgs.length != orgArgs.length + 1) {\n                                    throw new RuntimeException(\"arguments not equal: \" + owner + \".\" + name + desc\n                                            + \" <> \" + mapTo.owner + \".\" + mapTo.name + mapTo.desc);\n                                }\n                                if (orgArgs.length > 0) {\n                                    for (int i = 0; i < orgArgs.length; i++) {\n                                        if (!orgArgs[i].equals(nArgs[i + 1])) {\n                                            throw new RuntimeException(\"arguments not equal: \" + owner + \".\" + name\n                                                    + desc + \" <> \" + mapTo.owner + \".\" + mapTo.name + mapTo.desc);\n                                        }\n                                    }\n                                }\n                            }\n                            // replace it!\n                            super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);\n                            unBox(orgRet, nRet, this.mv);\n                        }\n\n                    } else {\n                        super.visitMethodInsn(opcode, owner, name, desc);\n                    }\n                }\n            }\n\n        };\n    }\n\n    public void wave(Path from, final Path to) throws IOException {\n\n        BaseCmd.walkJarOrDir(from, new BaseCmd.FileVisitorX() {\n            @Override\n            public void visitFile(Path file, String relative) throws IOException {\n                String name = relative;\n                Path targetPath = to.resolve(relative);\n                BaseCmd.createParentDirectories(targetPath);\n                if (name.endsWith(\".class\")) {\n                    String clzName = name.substring(0, name.length() - \".class\".length());\n                    if (ignores.contains(clzName)) {\n                        Files.copy(file, targetPath);\n                    } else {\n                        byte[] out = wave0(Files.readAllBytes(file));\n                        Files.write(targetPath, out);\n                    }\n                } else {\n                    if (name.startsWith(\"META-INF/\")) {\n                        if (name.equals(JarFile.MANIFEST_NAME)) {\n                            try (InputStream in = Files.newInputStream(file)) {\n                                Manifest mf = new Manifest(in);\n                                mf.getMainAttributes().put(new Name(\"X-NOTICE\"), \"Modified\");\n                                mf.getEntries().clear();\n\n                                ByteArrayOutputStream baos = new ByteArrayOutputStream();\n                                mf.write(baos);\n                                baos.flush();\n                                Files.write(targetPath, baos.toByteArray());\n                            }\n                        } else if (name.endsWith(\".DSA\") || name.endsWith(\".RSA\") || name.endsWith(\".SF\")\n                                || name.endsWith(\".ECDSA\")) {\n                            // ignored\n                        } else {\n                            Files.copy(file, targetPath);\n                        }\n                    } else {\n                        Files.copy(file, targetPath);\n                    }\n                }\n            }\n        });\n\n        if (callbacks.size() > 0) {\n            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n            String type = buildInvocationClz(cw);\n            byte[] data = cw.toByteArray();\n            Path target = to.resolve(type + \".class\");\n            BaseCmd.createParentDirectories(target);\n            Files.write(target, data);\n            nextInvocationName();\n        }\n\n    }\n\n    public String buildInvocationClz(ClassVisitor cw) {\n        String typeName = getCurrentInvocationName();\n        cw.visit(V1_6, ACC_PUBLIC, typeName, null, \"java/lang/Object\", new String[]{\n                toInternal(invocationInterfaceDesc)});\n        cw.visitField(ACC_PRIVATE | ACC_FINAL, \"thiz\", \"Ljava/lang/Object;\", null, null).visitEnd();\n        cw.visitField(ACC_PRIVATE | ACC_FINAL, \"args\", \"[Ljava/lang/Object;\", null, null).visitEnd();\n        cw.visitField(ACC_PRIVATE | ACC_FINAL, \"idx\", \"I\", null, null).visitEnd();\n        {\n            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, \"<init>\", \"(Ljava/lang/Object;[Ljava/lang/Object;I)V\", null,\n                    null);\n            mv.visitCode();\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitMethodInsn(INVOKESPECIAL, \"java/lang/Object\", \"<init>\", \"()V\");\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitVarInsn(ALOAD, 1);\n            mv.visitFieldInsn(PUTFIELD, typeName, \"thiz\", \"Ljava/lang/Object;\");\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitVarInsn(ALOAD, 2);\n            mv.visitFieldInsn(PUTFIELD, typeName, \"args\", \"[Ljava/lang/Object;\");\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitVarInsn(ILOAD, 3);\n            mv.visitFieldInsn(PUTFIELD, typeName, \"idx\", \"I\");\n            mv.visitInsn(RETURN);\n            mv.visitMaxs(-1, -1);\n            mv.visitEnd();\n        }\n        {\n            genSwitchMethod(cw, typeName, \"getMethodOwner\", new CB() {\n                @Override\n                public String getKey(MtdInfo mtd) {\n                    return toInternal(mtd.owner);\n                }\n            });\n            genSwitchMethod(cw, typeName, \"getMethodName\", new CB() {\n                @Override\n                public String getKey(MtdInfo mtd) {\n                    return mtd.name;\n                }\n            });\n            genSwitchMethod(cw, typeName, \"getMethodDesc\", new CB() {\n                @Override\n                public String getKey(MtdInfo mtd) {\n                    return mtd.desc;\n                }\n            });\n        }\n        {\n            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, \"getArguments\", \"()[Ljava/lang/Object;\", null, null);\n            mv.visitCode();\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitFieldInsn(GETFIELD, typeName, \"args\", \"[Ljava/lang/Object;\");\n            mv.visitInsn(ARETURN);\n            mv.visitMaxs(-1, -1);\n            mv.visitEnd();\n        }\n\n        {\n            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, \"getThis\", \"()Ljava/lang/Object;\", null, null);\n            mv.visitCode();\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitFieldInsn(GETFIELD, typeName, \"thiz\", \"Ljava/lang/Object;\");\n            mv.visitInsn(ARETURN);\n            mv.visitMaxs(-1, -1);\n            mv.visitEnd();\n        }\n\n        {\n            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, \"proceed\", \"()Ljava/lang/Object;\", null,\n                    new String[]{\"java/lang/Throwable\"});\n            mv.visitCode();\n            mv.visitVarInsn(ALOAD, 0);\n            mv.visitFieldInsn(GETFIELD, typeName, \"idx\", \"I\");\n            Label def = new Label();\n            Label[] labels = new Label[callbacks.size()];\n            for (int i = 0; i < labels.length; i++) {\n                labels[i] = new Label();\n            }\n            mv.visitTableSwitchInsn(0, callbacks.size() - 1, def, labels);\n\n            for (int i = 0; i < labels.length; i++) {\n                mv.visitLabel(labels[i]);\n                Callback cb = callbacks.get(i);\n                MtdInfo m = (MtdInfo) cb.callback;\n                if (cb.isStatic) {\n                    mv.visitVarInsn(ALOAD, 0);\n                    mv.visitFieldInsn(GETFIELD, typeName, \"args\", \"[Ljava/lang/Object;\");\n                    mv.visitMethodInsn(INVOKESTATIC, toInternal(m.owner), m.name, m.desc);\n                } else if (cb.isSpecial) {\n                    mv.visitVarInsn(ALOAD, 0);\n                    mv.visitFieldInsn(GETFIELD, typeName, \"thiz\", \"Ljava/lang/Object;\");\n                    mv.visitTypeInsn(CHECKCAST, toInternal(m.owner));\n                    mv.visitVarInsn(ALOAD, 0);\n                    mv.visitFieldInsn(GETFIELD, typeName, \"args\", \"[Ljava/lang/Object;\");\n                    mv.visitMethodInsn(INVOKEVIRTUAL, toInternal(m.owner), m.name, m.desc);\n                } else {\n                    mv.visitVarInsn(ALOAD, 0);\n                    mv.visitFieldInsn(GETFIELD, typeName, \"thiz\", \"Ljava/lang/Object;\");\n                    mv.visitVarInsn(ALOAD, 0);\n                    mv.visitFieldInsn(GETFIELD, typeName, \"args\", \"[Ljava/lang/Object;\");\n                    mv.visitMethodInsn(INVOKESTATIC, toInternal(m.owner), m.name, m.desc);\n                }\n                Type ret = Type.getReturnType(m.desc);\n                box(ret, mv);\n                mv.visitInsn(ret.getOpcode(IRETURN));\n            }\n            mv.visitLabel(def);\n            mv.visitTypeInsn(NEW, \"java/lang/RuntimeException\");\n            mv.visitInsn(DUP);\n            mv.visitLdcInsn(\"invalid idx\");\n            mv.visitMethodInsn(INVOKESPECIAL, \"java/lang/RuntimeException\", \"<init>\", \"(Ljava/lang/String;)V\");\n            mv.visitInsn(ATHROW);\n            mv.visitMaxs(-1, -1);\n            mv.visitEnd();\n        }\n        return typeName;\n    }\n\n    interface CB {\n        String getKey(MtdInfo mtd);\n    }\n\n    private void genSwitchMethod(ClassVisitor cw, String typeName, String methodName, CB callback) {\n        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, \"()Ljava/lang/String;\", null, null);\n        mv.visitCode();\n        mv.visitVarInsn(ALOAD, 0);\n        mv.visitFieldInsn(GETFIELD, typeName, \"idx\", \"I\");\n        Label def = new Label();\n        Label[] labels = new Label[callbacks.size()];\n\n        Map<String, Label> strMap = new TreeMap<>();\n        for (int i = 0; i < labels.length; i++) {\n            Callback cb = callbacks.get(i);\n            String key = callback.getKey((MtdInfo) cb.target);\n            Label label = strMap.get(key);\n            if (label == null) {\n                label = new Label();\n                strMap.put(key, label);\n            }\n            labels[i] = label;\n        }\n\n        mv.visitTableSwitchInsn(0, callbacks.size() - 1, def, labels);\n\n        for (Map.Entry<String, Label> e : strMap.entrySet()) {\n            mv.visitLabel(e.getValue());\n            mv.visitLdcInsn(e.getKey());\n            mv.visitInsn(ARETURN);\n        }\n        mv.visitLabel(def);\n        mv.visitTypeInsn(NEW, \"java/lang/RuntimeException\");\n        mv.visitInsn(DUP);\n        mv.visitLdcInsn(\"invalid idx\");\n        mv.visitMethodInsn(INVOKESPECIAL, \"java/lang/RuntimeException\", \"<init>\", \"(Ljava/lang/String;)V\");\n        mv.visitInsn(ATHROW);\n        mv.visitMaxs(-1, -1);\n        mv.visitEnd();\n    }\n\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ScanBridgeAdapter.java",
    "content": "package com.googlecode.d2j.tools.jar;\n\nimport com.googlecode.d2j.tools.jar.ClassInfo.MemberInfo;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static com.googlecode.d2j.util.AccUtils.isBridge;\nimport static com.googlecode.d2j.util.AccUtils.isSynthetic;\n\npublic class ScanBridgeAdapter extends ClassVisitor implements Opcodes {\n\n    private Map<String, MemberInfo> bridge = new HashMap<String, MemberInfo>();\n\n    public ScanBridgeAdapter(ClassVisitor cv) {\n        super(ASM4, cv);\n    }\n\n    // private String currentName;\n    //\n    // @Override\n    // public void visit(int version, int access, String name, String signature,\n    // String superName, String[] interfaces) {\n    // super.visit(version, access, name, signature, superName, interfaces);\n    // this.currentName = name;\n    // }\n\n    public Map<String, MemberInfo> getBridge() {\n        return Collections.unmodifiableMap(bridge);\n    }\n\n    @Override\n    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\n        MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);\n        if (isBridge(access) && isSynthetic(access)) {\n            if (mv == null) {\n                mv = new MethodVisitor(ASM4) {\n                };\n            }\n            final MemberInfo member = new MemberInfo();\n            member.access = access;\n            member.desc = desc;\n            member.name = name;\n            mv = new MethodVisitor(ASM4, mv) {\n\n                @Override\n                public void visitMethodInsn(int opcode, String owner, String name, String desc) {\n                    super.visitMethodInsn(opcode, owner, name, desc);\n                    if (!name.equals(member.name)) {\n                        bridge.put(owner + '.' + name + desc.substring(0, desc.lastIndexOf(')') + 1), member);\n                    }\n                }\n            };\n        }\n        return mv;\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/tools/jar/WebApp.java",
    "content": "package com.googlecode.d2j.tools.jar;\r\n\r\nimport com.googlecode.dex2jar.tools.BaseCmd;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.FileVisitResult;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.nio.file.SimpleFileVisitor;\r\nimport java.nio.file.attribute.BasicFileAttributes;\r\nimport java.util.HashSet;\r\nimport java.util.Set;\r\n\r\npublic class WebApp {\r\n\r\n    /**\r\n     * @param args\r\n     * @throws IOException\r\n     */\r\n    public static void main(String[] args) throws IOException {\r\n        if (args.length < 2) {\r\n            System.out.println(\"webapp pathToWebApp config [ignoreJarConfig]\");\r\n            return;\r\n        }\r\n\r\n        File webApp = new File(args[0]);\r\n        File config = new File(args[1]);\r\n        Path jarIgnore = args.length > 2 ? new File(args[2]).toPath() : null;\r\n\r\n        Path clz = new File(webApp, \"WEB-INF/classes\").toPath();\r\n        Path tmpClz = new File(webApp, \"WEB-INF/tmp-classes\").toPath();\r\n        final InvocationWeaver ro = (InvocationWeaver) new InvocationWeaver().withConfig(config.toPath());\r\n        Files.deleteIfExists(tmpClz);\r\n        copyDirectory(clz, tmpClz);\r\n\r\n        System.out.println(\"InvocationWeaver from [\" + tmpClz + \"] to [\" + clz + \"]\");\r\n        ro.wave(tmpClz, clz);\r\n        Files.deleteIfExists(tmpClz);\r\n\r\n        final File lib = new File(webApp, \"WEB-INF/lib\");\r\n        Path tmpLib = new File(webApp, \"WEB-INF/Nlib\").toPath();\r\n\r\n        final Set<String> ignores = new HashSet<String>();\r\n        if (jarIgnore != null && Files.exists(jarIgnore)) {\r\n            ignores.addAll(Files.readAllLines(jarIgnore, StandardCharsets.UTF_8));\r\n        } else {\r\n            System.out.println(\"ignoreJarConfig ignored\");\r\n        }\r\n\r\n        Files.deleteIfExists(tmpLib);\r\n        copyDirectory(lib.toPath(), tmpLib);\r\n\r\n        Files.walkFileTree(tmpLib, new SimpleFileVisitor<Path>() {\r\n            @Override\r\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r\n                if (file.getFileName().toString().endsWith(\".jar\")) {\r\n                    final String s = file.getFileName().toString();\r\n                    boolean ignore = false;\r\n                    for (String i : ignores) {\r\n                        if (s.startsWith(i)) {\r\n                            ignore = true;\r\n                            break;\r\n                        }\r\n                    }\r\n                    if (!ignore) {\r\n                        Path nJar = new File(lib, s).toPath();\r\n                        System.out.println(\"InvocationWeaver from [\" + file + \"] to [\" + nJar + \"]\");\r\n                        ro.wave(file, nJar);\r\n                    }\r\n                }\r\n                return super.visitFile(file, attrs);\r\n            }\r\n        });\r\n        Files.deleteIfExists(tmpLib);\r\n    }\r\n\r\n    private static void copyDirectory(final Path clz, final Path tmpClz) throws IOException {\r\n        Files.walkFileTree(clz, new SimpleFileVisitor<Path>() {\r\n            @Override\r\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r\n                Path n = clz.relativize(file);\r\n                Path target = tmpClz.resolve(n);\r\n                BaseCmd.createParentDirectories(target);\r\n                Files.copy(file, target);\r\n                return super.visitFile(file, attrs);\r\n            }\r\n        });\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/d2j/util/AccUtils.java",
    "content": "package com.googlecode.d2j.util;\n\nimport org.objectweb.asm.Opcodes;\n\npublic class AccUtils {\n    public static boolean isBridge(int acc) {\n        return (acc & Opcodes.ACC_BRIDGE) != 0;\n    }\n\n    public static boolean isEnum(int acc) {\n        return (acc & Opcodes.ACC_ENUM) != 0;\n    }\n\n    public static boolean isFinal(int acc) {\n        return (acc & Opcodes.ACC_FINAL) != 0;\n    }\n\n    public static boolean isPrivate(int acc) {\n        return (acc & Opcodes.ACC_PRIVATE) != 0;\n    }\n\n    public static boolean isProtected(int acc) {\n        return (acc & Opcodes.ACC_PROTECTED) != 0;\n    }\n\n    public static boolean isPublic(int acc) {\n        return (acc & Opcodes.ACC_PUBLIC) != 0;\n    }\n\n    public static boolean isStatic(int acc) {\n        return (acc & Opcodes.ACC_STATIC) != 0;\n    }\n\n    public static boolean isSynthetic(int acc) {\n        return (acc & Opcodes.ACC_SYNTHETIC) != 0;\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/bin_gen/BinGen.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.bin_gen;\n\nimport com.googlecode.dex2jar.tools.BaseCmd;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.*;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.nio.file.attribute.PosixFilePermissions;\nimport java.util.Properties;\n\npublic class BinGen {\n\n    /**\n     * @param args\n     * @throws IOException\n     */\n    public static void main(String[] args) throws IOException {\n        if (args.length < 2) {\n            System.err.println(\"bin-gen cfg-dir out-dir\");\n            return;\n        }\n        final Path cfg = new File(args[0]).toPath();\n        final Path out = new File(args[1]).toPath();\n        Properties p = new Properties();\n        try (InputStream is = Files.newInputStream(cfg.resolve(\"class.cfg\"))) {\n            p.load(is);\n        }\n\n        String bat = new String(Files.readAllBytes(cfg.resolve(\"bat_template\")), StandardCharsets.UTF_8);\n\n        String sh = new String(Files.readAllBytes(cfg.resolve(\"sh_template\")), StandardCharsets.UTF_8);\n\n        Files.walkFileTree(cfg, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                String fileName = file.getFileName().toString();\n                if (fileName.endsWith(\".sh\") || fileName.endsWith(\".bat\")) {\n                    Path f = out.resolve(cfg.relativize(file));\n                    BaseCmd.createParentDirectories(f);\n                    Files.copy(file, f, StandardCopyOption.REPLACE_EXISTING);\n                    if (fileName.endsWith(\".sh\")) {\n                        setExec(f);\n                    }\n                }\n                return super.visitFile(file, attrs);\n            }\n        });\n\n        for (Object key : p.keySet()) {\n            String name = key.toString();\n            Path path = out.resolve(key.toString() + \".sh\");\n            BaseCmd.createParentDirectories(path);\n            try (BufferedWriter bw = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE,\n                    StandardOpenOption.WRITE)) {\n                String s = sh.replaceAll(\"__@class_name@__\", p.getProperty(name));\n                bw.append(s);\n            }\n\n            setExec(path);\n\n            path = out.resolve(key.toString() + \".bat\");\n            BaseCmd.createParentDirectories(path);\n            try (BufferedWriter bw = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE,\n                    StandardOpenOption.WRITE)) {\n                String s = bat.replaceAll(\"__@class_name@__\", p.getProperty(name));\n                bw.append(s);\n            }\n        }\n    }\n\n    private static void setExec(Path path) {\n        try {\n            path.toFile().setExecutable(true);\n            Files.setPosixFilePermissions(path, PosixFilePermissions.fromString(\"rwxr-xr-x\"));\n        } catch (Exception ex) {\n            // ignored\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/ApkSign.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.security.KeyFactory;\nimport java.security.PrivateKey;\nimport java.security.cert.CertificateFactory;\nimport java.security.cert.X509Certificate;\nimport java.security.spec.PKCS8EncodedKeySpec;\n\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.d2j.signapk.AbstractJarSign;\nimport com.googlecode.d2j.signapk.SunJarSignImpl;\nimport com.googlecode.d2j.signapk.TinySignImpl;\n\n@BaseCmd.Syntax(cmd = \"d2j-apk-sign\", syntax = \"[options] <apk>\", desc = \"Sign an android apk file use a test certificate.\")\npublic class ApkSign extends BaseCmd {\n    public static void main(String... args) {\n        new ApkSign().doMain(args);\n    }\n\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .apk file, default is $current_dir/[apk-name]-signed.apk\", argName = \"out-apk-file\")\n    private Path output;\n    @Opt(opt = \"t\", longOpt = \"tiny\", hasArg = false, description = \"use tiny sign\")\n    private boolean tiny = false;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length != 1) {\n            usage();\n            return;\n        }\n\n        Path apkIn = new File(remainingArgs[0]).toPath();\n        if (!Files.exists(apkIn)) {\n            System.err.println(apkIn + \" is not exists\");\n            usage();\n            return;\n        }\n\n        if (output == null) {\n            if (Files.isDirectory(apkIn)) {\n                output = new File(apkIn.getFileName() + \"-signed.apk\").toPath();\n            } else {\n                output = new File(getBaseName(apkIn.getFileName().toString()) + \"-signed.apk\").toPath();\n            }\n        }\n\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            usage();\n            return;\n        }\n        Path tmp = null;\n        try {\n            final Path realJar;\n            if (Files.isDirectory(apkIn)) {\n                realJar = Files.createTempFile(\"d2j\", \".jar\");\n                tmp = realJar;\n                System.out.println(\"zipping \" + apkIn + \" -> \" + realJar);\n                try (FileSystem fs = createZip(realJar)) {\n                    final Path outRoot = fs.getPath(\"/\");\n                    walkJarOrDir(apkIn, new FileVisitorX() {\n                        @Override\n                        public void visitFile(Path file, String relative) throws IOException {\n                            Path target = outRoot.resolve(relative);\n                            createParentDirectories(target);\n                            Files.copy(file, target);\n                        }\n                    });\n                }\n            } else {\n                realJar = apkIn;\n            }\n\n            AbstractJarSign signer;\n\n            if (tiny) {\n                signer = new TinySignImpl();\n            } else {\n                try {\n                    CertificateFactory certificateFactory = CertificateFactory.getInstance(\"X.509\");\n                    X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(ApkSign.class\n                            .getResourceAsStream(\"ApkSign.cer\"));\n                    KeyFactory rSAKeyFactory = KeyFactory.getInstance(\"RSA\");\n                    PrivateKey privateKey = rSAKeyFactory.generatePrivate(new PKCS8EncodedKeySpec(ZipUtil\n                            .toByteArray(ApkSign.class.getResourceAsStream(\"ApkSign.private\"))));\n\n                    signer = new SunJarSignImpl(cert, privateKey);\n                } catch (Exception cnfe) {\n                    signer = new TinySignImpl();\n                }\n            }\n            signer.sign(apkIn.toFile(), output.toFile());\n\n            System.out.println(\"sign \" + realJar + \" -> \" + output);\n        } finally {\n            if (tmp != null) {\n                Files.deleteIfExists(tmp);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/AsmVerify.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.lang.reflect.Field;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.tree.ClassNode;\nimport org.objectweb.asm.tree.MethodNode;\nimport org.objectweb.asm.tree.TryCatchBlockNode;\nimport org.objectweb.asm.tree.analysis.Analyzer;\nimport org.objectweb.asm.tree.analysis.BasicValue;\nimport org.objectweb.asm.tree.analysis.BasicVerifier;\nimport org.objectweb.asm.tree.analysis.Frame;\nimport org.objectweb.asm.util.CheckClassAdapter;\nimport org.objectweb.asm.util.Printer;\nimport org.objectweb.asm.util.Textifier;\nimport org.objectweb.asm.util.TraceMethodVisitor;\n\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\n\n@Syntax(cmd = \"d2j-asm-verify\", syntax = \"[options] <jar0> [jar1 ... jarN]\", desc = \"Verify .class in jar\")\npublic class AsmVerify extends BaseCmd {\n\n    private static String getShortName(final String name) {\n        int n = name.lastIndexOf('/');\n        return n == -1 ? name : \"o\";\n    }\n\n    public static void main(String... args) {\n        new AsmVerify().doMain(args);\n    }\n\n    static Field buf;\n    static {\n        try {\n            buf = Printer.class.getDeclaredField(\"buf\");\n        } catch (NoSuchFieldException | SecurityException e) {\n            e.printStackTrace();\n        }\n        buf.setAccessible(true);\n    }\n\n    static void printAnalyzerResult(MethodNode method, Analyzer a, final PrintWriter pw)\n            throws IllegalArgumentException {\n        Frame[] frames = a.getFrames();\n        Textifier t = new Textifier();\n        TraceMethodVisitor mv = new TraceMethodVisitor(t);\n        String format = \"%05d %-\" + (method.maxStack + method.maxLocals + 6) + \"s|%s\";\n        for (int j = 0; j < method.instructions.size(); ++j) {\n            method.instructions.get(j).accept(mv);\n\n            StringBuffer s = new StringBuffer();\n            Frame f = frames[j];\n            if (f == null) {\n                s.append('?');\n            } else {\n                for (int k = 0; k < f.getLocals(); ++k) {\n                    s.append(getShortName(f.getLocal(k).toString()));\n                }\n                s.append(\" : \");\n                for (int k = 0; k < f.getStackSize(); ++k) {\n                    s.append(getShortName(f.getStack(k).toString()));\n                }\n            }\n            try {\n                pw.printf(format, j, s, buf.get(t)); // mv.text.get(j));\n            } catch (IllegalAccessException e) {\n                e.printStackTrace();\n            }\n        }\n        for (TryCatchBlockNode tryCatchBlockNode: method.tryCatchBlocks) {\n            tryCatchBlockNode.accept(mv);\n            try {\n                pw.print(\" \" + buf.get(t));\n            } catch (IllegalAccessException e) {\n                e.printStackTrace();\n            }\n        }\n        pw.println();\n        pw.flush();\n    }\n\n    @Opt(opt = \"d\", longOpt = \"detail\", hasArg = false, description = \"Print detail error message\")\n    boolean detail = false;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length < 1) {\n            usage();\n            return;\n        }\n\n        List<Path> files = new ArrayList<>();\n        for (String fn : remainingArgs) {\n            Path file = new File(fn).toPath();\n            if (!Files.exists(file)) {\n                System.err.println(fn + \" is not exists\");\n                usage();\n                return;\n            }\n            files.add(file);\n        }\n\n        for (Path file : files) {\n            System.out.println(\"verify \" + file);\n            walkJarOrDir(file, new FileVisitorX() {\n                @Override\n                public void visitFile(Path file, String relative) throws IOException {\n                    if (file.getFileName().toString().endsWith(\".class\")) {\n                        ClassReader cr = new ClassReader(Files.readAllBytes(file));\n                        ClassNode cn = new ClassNode();\n                        cr.accept(new CheckClassAdapter(cn, false),\n                                ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);\n                        for (MethodNode method : cn.methods) {\n                            BasicVerifier verifier = new BasicVerifier();\n                            Analyzer<BasicValue> a = new Analyzer<>(verifier);\n                            try {\n                                a.analyze(cn.name, method);\n                            } catch (Exception ex) {\n                                System.err.println(\"Error verify method \" + cr.getClassName() + \".\" + method.name + \" \"\n                                        + method.desc);\n                                if (detail) {\n                                    ex.printStackTrace(System.err);\n                                    printAnalyzerResult(method, a, new PrintWriter(new OutputStreamWriter(System.err, StandardCharsets.UTF_8)));\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/BaksmaliBaseDexExceptionHandler.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.dex.BaseDexExceptionHandler;\nimport com.googlecode.d2j.dex.Dex2jar;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.smali.BaksmaliDumper;\nimport com.googlecode.d2j.smali.Smali;\nimport com.googlecode.dex2jar.ir.ET;\nimport org.objectweb.asm.MethodVisitor;\n\nimport java.io.BufferedWriter;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.text.SimpleDateFormat;\nimport java.util.*;\nimport java.util.zip.GZIPOutputStream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\npublic class BaksmaliBaseDexExceptionHandler extends BaseDexExceptionHandler {\n    public static final String REPORT_MESSAGE = \"Please report this file to one of following link if possible (any one).\\n\" + //\n            \"    https://sourceforge.net/p/dex2jar/tickets/\\n\" + //\n            \"    https://bitbucket.org/pxb1988/dex2jar/issues\\n\" + //\n            \"    https://github.com/pxb1988/dex2jar/issues\\n\" + //\n            \"    dex2jar@googlegroups.com\";\n\n    private Map<DexMethodNode, Exception> exceptionMap = new HashMap<>();\n    private List<Exception> fileExceptions = new ArrayList<>();\n\n    public boolean hasException() {\n        return exceptionMap.size() > 0 || fileExceptions.size() > 0;\n    }\n\n    @Override\n    public void handleFileException(Exception e) {\n        super.handleFileException(e);\n        fileExceptions.add(e);\n    }\n\n    @Override\n    public void handleMethodTranslateException(Method method, DexMethodNode methodNode, MethodVisitor mv, Exception e) {\n        super.handleMethodTranslateException(method, methodNode, mv, e);\n        exceptionMap.put(methodNode, e);\n    }\n\n    public static String getVersionString() {\n        List<String> vs = new ArrayList<>();\n        doAddVersion(vs, \"dex-reader\", DexFileReader.class);\n        doAddVersion(vs, \"dex-reader-api\", Method.class);\n        doAddVersion(vs, \"dex-ir\", ET.class);\n        doAddVersion(vs, \"d2j-smali\", Smali.class);\n        doAddVersion(vs, \"d2j-base-cmd\", BaseCmd.class);\n        doAddVersion(vs, \"dex-tools\", Dex2jarCmd.class);\n        doAddVersion(vs, \"dex-translator\", Dex2jar.class);\n        return vs.toString();\n    }\n\n    private static void doAddVersion(List<String> vs, String pkg, Class<?> clz) {\n        try {\n            vs.add(pkg + \"-\" + clz.getPackage().getImplementationVersion());\n        } catch (Exception ignore) {\n            // ignored\n        }\n    }\n\n    public void dump(Path exFile, String[] originalArgs) {\n        String fileName = exFile.getFileName().toString().toLowerCase();\n        try {\n            if (fileName.endsWith(\".zip\")) {\n                dumpZip(exFile, originalArgs);\n            } else if (fileName.endsWith(\".gz\")) {\n                dumGZip(exFile, originalArgs);\n            } else {\n                dumpTxt(exFile, originalArgs);\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void dumpTxt(Path exFile, String[] originalArgs) throws IOException {\n        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files\n                .newOutputStream(exFile), StandardCharsets.UTF_8))) {\n            dumpTxt0(writer, originalArgs);\n        }\n    }\n\n    private void dumGZip(Path exFile, String[] originalArgs) throws IOException {\n        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(Files\n                .newOutputStream(exFile)), StandardCharsets.UTF_8))) {\n            dumpTxt0(writer, originalArgs);\n        }\n    }\n\n    private void dumpTxt0(BufferedWriter writer, String[] originalArgs) throws IOException {\n        dumpSummary(originalArgs, writer);\n        int i = 0;\n        for (Map.Entry<DexMethodNode, Exception> e : exceptionMap.entrySet()) {\n            DexMethodNode dexMethodNode = e.getKey();\n            Exception ex = e.getValue();\n            writer.newLine();\n            writer.write(\"================= \" + i++ + \" ===================\");\n            writer.newLine();\n            dumpMethod(writer, dexMethodNode, ex);\n        }\n    }\n\n    public void dumpZip(Path exFile, String[] originalArgs) throws IOException {\n        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(exFile))) {\n            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zos, StandardCharsets.UTF_8));\n\n            zos.putNextEntry(new ZipEntry(\"summary.txt\"));\n            dumpTxt0(writer, originalArgs);\n            zos.closeEntry();\n            zos.flush();\n        }\n    }\n\n    // dump each method\n    private void dumpMethod(BufferedWriter writer, DexMethodNode dexMethodNode, Exception ex) throws IOException {\n        writer.append(dexMethodNode.method.toString());\n        writer.newLine();\n        writer.flush();\n        ex.printStackTrace(new PrintWriter(writer, true));\n        writer.newLine();\n        new BaksmaliDumper().baksmaliMethod(dexMethodNode, writer);\n        writer.flush();\n    }\n\n    // dump summary: timestamp, version, cmdline\n    private void dumpSummary(String[] originalArgs, BufferedWriter writer) throws IOException {\n        writer.write(\"#This file is generated by dex2jar\");\n        writer.newLine();\n        writer.write(REPORT_MESSAGE);\n        writer.newLine();\n        writer.newLine();\n        if (fileExceptions.size() > 0) {\n            writer.append(String.format(\"There are %d fails.\", fileExceptions.size()));\n            writer.newLine();\n        }\n        if (exceptionMap.size() > 0) {\n            writer.append(String.format(\"There are %d methods fail to translate.\", exceptionMap.size()));\n            writer.newLine();\n        }\n        SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss z\");\n        sdf.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        writer.append(sdf.format(new Date()));\n        writer.newLine();\n        writer.append(\"version: \");\n        writer.append(getVersionString());\n        writer.newLine();\n        writer.append(\"cmdline: \");\n        writer.append(Arrays.asList(originalArgs).toString());\n        writer.newLine();\n\n        writer.append(\"env:\");\n        writer.newLine();\n        Properties properties = System.getProperties();\n        for (String key : properties.stringPropertyNames()) {\n            if (key.startsWith(\"java.\") && !key.toLowerCase().contains(\"pass\")) {\n                writer.append(key).append(\": \").append(properties.getProperty(key));\n                writer.newLine();\n            }\n        }\n        PrintWriter p = new PrintWriter(writer, true);\n        for (Exception ex : fileExceptions) {\n            ex.printStackTrace(p);\n        }\n        writer.flush();\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java",
    "content": "package com.googlecode.dex2jar.tools;\r\n\r\n\r\nimport org.objectweb.asm.ClassReader;\r\nimport org.objectweb.asm.ClassVisitor;\r\nimport org.objectweb.asm.ClassWriter;\r\nimport org.objectweb.asm.Opcodes;\r\n\r\nimport java.io.File;\r\nimport java.io.FileOutputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.util.Enumeration;\r\nimport java.util.zip.ZipEntry;\r\nimport java.util.zip.ZipFile;\r\nimport java.util.zip.ZipOutputStream;\r\n\r\npublic class ClassVersionSwitch {\r\n    static final int jVersions[] = new int[]{\r\n            0,\r\n            Opcodes.V1_1,\r\n            Opcodes.V1_2,\r\n            Opcodes.V1_3,\r\n            Opcodes.V1_4,\r\n            Opcodes.V1_5,\r\n            Opcodes.V1_6,\r\n            Opcodes.V1_7,\r\n            52,\r\n            53,\r\n    };\r\n\r\n    public static void main(String... args) throws IOException {\r\n        if (args.length < 3) {\r\n            System.out.println(\"Usage: clz-version-switch version old.jar new.jar\");\r\n            System.exit(1);\r\n        }\r\n        int version = Integer.parseInt(args[0]);\r\n        if (version < 1 || version > 9) {\r\n            throw new RuntimeException(\"version not support yet!\");\r\n        }\r\n        File old = new File(args[1]);\r\n        File n = new File(args[2]);\r\n        byte[] buff = new byte[1024 * 50];\r\n        final int jVersion = jVersions[version];\r\n        try (ZipFile zip = new ZipFile(old); ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(n));) {\r\n\r\n            for (Enumeration<? extends ZipEntry> e = zip.entries(); e.hasMoreElements(); ) {\r\n                ZipEntry zipEntry = e.nextElement();\r\n                zos.putNextEntry(new ZipEntry(zipEntry.getName()));\r\n                if (!zipEntry.isDirectory()) {\r\n                    try (InputStream is = zip.getInputStream(zipEntry)) {\r\n                        if (zipEntry.getName().endsWith(\".class\")) {\r\n                            ClassReader cr = new ClassReader(is);\r\n                            ClassWriter cw = new ClassWriter(0);\r\n                            ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, cw) {\r\n                                @Override\r\n                                public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {\r\n                                    super.visit(jVersion, access, name, signature, superName, interfaces);\r\n                                }\r\n                            };\r\n                            cr.accept(cv, ClassReader.EXPAND_FRAMES|ClassReader.SKIP_FRAMES);\r\n                            zos.write(cw.toByteArray());\r\n                        } else {\r\n                            for (int c = is.read(buff); c > 0; c = is.read(buff)) {\r\n                                zos.write(buff, 0, c);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                }\r\n                zos.closeEntry();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/DeObfInitCmd.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.tools;\r\n\r\nimport com.googlecode.d2j.tools.jar.InitOut;\r\n\r\nimport java.io.File;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\n\r\npublic class DeObfInitCmd extends BaseCmd {\r\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\r\n    private boolean forceOverwrite = false;\r\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .jar file, default is $current_dir/[file-name]-deobf-init.txt\", argName = \"out-file\")\r\n    private Path output;\r\n    @Opt(opt = \"min\", longOpt = \"min-length\", description = \"do the rename if the length < MIN, default is 2\", argName = \"MIN\")\r\n    private int min = 2;\r\n    @Opt(opt = \"max\", longOpt = \"max-length\", description = \"do the rename if the length > MIN, default is 40\", argName = \"MAX\")\r\n    private int max = 40;\r\n\r\n    public DeObfInitCmd() {\r\n        super(\"d2j-init-deobf [options] <jar>\", \"generate an init config file for deObfuscate a jar\");\r\n    }\r\n\r\n    public static void main(String... args) {\r\n        new DeObfInitCmd().doMain(args);\r\n    }\r\n\r\n    @Override\r\n    protected void doCommandLine() throws Exception {\r\n        if (remainingArgs.length != 1) {\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        Path jar = new File(remainingArgs[0]).toPath();\r\n        if (!Files.exists(jar)) {\r\n            System.err.println(jar + \" is not exists\");\r\n            usage();\r\n            return;\r\n        }\r\n        if (output == null) {\r\n            if (Files.isDirectory(jar)) {\r\n                output = new File(jar.getFileName().toString() + \"-deobf-init.txt\").toPath();\r\n            } else {\r\n                output = new File(getBaseName(jar.getFileName().toString()) + \"-deobf-init.txt\").toPath();\r\n            }\r\n        }\r\n\r\n        if (Files.exists(output) && !forceOverwrite) {\r\n            System.err.println(output + \" exists, use --force to overwrite\");\r\n            usage();\r\n            return;\r\n        }\r\n        System.out.println(\"generate \" + jar + \" -> \" + output);\r\n        new InitOut().from(jar).maxLength(max).minLength(min).to(output);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/DecryptStringCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport com.googlecode.d2j.converter.IR2JConverter;\nimport com.googlecode.d2j.converter.J2IRConverter;\nimport com.googlecode.d2j.util.Escape;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.StmtTraveler;\nimport com.googlecode.dex2jar.ir.expr.*;\nimport com.googlecode.dex2jar.ir.ts.*;\nimport com.googlecode.dex2jar.ir.ts.array.FillArrayTransformer;\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.Type;\nimport org.objectweb.asm.tree.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\n\n@Syntax(cmd = \"d2j-decrypt-string\", syntax = \"[options] <jar>\", desc = \"Decrypt in class file\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/DecryptStrings\\nhttps://bitbucket.org/pxb1988/dex2jar/wiki/DecryptStrings\")\npublic class DecryptStringCmd extends BaseCmd {\n    public static void main(String... args) {\n        new DecryptStringCmd().doMain(args);\n    }\n\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output of .jar files, default is $current_dir/[jar-name]-decrypted.jar\", argName = \"out\")\n    private Path output;\n    @Opt(opt = \"m\", longOpt = \"methods\", description = \"a file contain a list of methods, each line like: La/b;->decrypt(III)Ljava/lang/String;\", argName = \"cfg\")\n    private Path method;\n    @Opt(opt = \"mo\", longOpt = \"decrypt-method-owner\", description = \"the owner of the method which can decrypt the stings, example: java.lang.String\", argName = \"owner\")\n    private String methodOwner;\n    @Opt(opt = \"mn\", longOpt = \"decrypt-method-name\", description = \"the owner of the method which can decrypt the stings, the method's signature must be static (parameter-type)Ljava/lang/String;. Please use -pt,--parameter-type to set the argument descrypt.\", argName = \"name\")\n    private String methodName;\n    @Opt(opt = \"cp\", longOpt = \"classpath\", description = \"add extra lib to classpath\", argName = \"cp\")\n    private String classpath;\n    //extended parameter option: e.g. '-t int,byte,string' to specify a routine such as decryptionRoutine(int a, byte b, String c)\n    @Opt(opt = \"t\", longOpt = \"arg-types\", description = \"comma-separated list of types:boolean,byte,short,char,int,long,float,double,string. Default is string\", argName = \"type\")\n    private String parameterJTypes;\n    @Opt(opt = \"pd\", longOpt = \"parameters-descriptor\", description = \"the descriptor for the method which can decrypt the stings, example1: Ljava/lang/String; example2: III, default is Ljava/lang/String;\", argName = \"type\")\n    private String parametersDescriptor;\n    @Opt(opt = \"d\", longOpt = \"delete\", hasArg = false, description = \"delete the method which can decrypt the stings\")\n    private boolean deleteMethod = false;\n    @Opt(opt = \"da\", longOpt = \"deep-analyze\", hasArg = false, description = \"use dex2jar IR to static analyze and find more values like byte[]\")\n    private boolean deepAnalyze = false;\n    @Opt(opt = \"v\", longOpt = \"verbose\", hasArg = false, description = \"show more on output\")\n    private boolean verbose = false;\n\n    static class MethodConfig {\n        Method jmethod;\n        /**\n         * in java/lang/String format\n         */\n        String owner;\n        String name;\n        String desc;\n\n        @Override\n        public int hashCode() {\n            final int prime = 31;\n            int result = 1;\n            result = prime * result + ((desc == null) ? 0 : desc.hashCode());\n            result = prime * result + ((name == null) ? 0 : name.hashCode());\n            result = prime * result + ((owner == null) ? 0 : owner.hashCode());\n            return result;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj)\n                return true;\n            if (obj == null)\n                return false;\n            if (getClass() != obj.getClass())\n                return false;\n            MethodConfig other = (MethodConfig) obj;\n            if (desc == null) {\n                if (other.desc != null)\n                    return false;\n            } else if (!desc.equals(other.desc))\n                return false;\n            if (name == null) {\n                if (other.name != null)\n                    return false;\n            } else if (!name.equals(other.name))\n                return false;\n            if (owner == null) {\n                if (other.owner != null)\n                    return false;\n            } else if (!owner.equals(other.owner))\n                return false;\n            return true;\n        }\n    }\n\n    MethodConfig build(String line) {\n        int idx = line.indexOf(\"->\");\n        if (idx < 0) {\n            throw new RuntimeException(\"Can't read line:\" + line);\n        }\n        String owner = line.substring(0, idx);\n\n        if (owner.startsWith(\"L\") && owner.endsWith(\";\")) {\n            owner = owner.substring(1, owner.length() - 1);\n        }\n\n        int idx2 = line.indexOf('(', idx);\n        if (idx2 < 0) {\n            throw new RuntimeException(\"Can't read line:\" + line);\n        }\n\n        String name = line.substring(idx + 2, idx2);\n\n        String desc = line.substring(idx2);\n        if (desc.endsWith(\")\")) {\n            desc = desc + \"Ljava/lang/String;\";\n        }\n\n        MethodConfig config = new MethodConfig();\n        config.owner = owner;\n        config.desc = desc;\n        config.name = name;\n        return config;\n\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length == 0) {\n            throw new HelpException(\"One <jar> file is required\");\n        } else if (remainingArgs.length > 1) {\n            throw new HelpException(\"Only one <jar> file is required, But we found \" + remainingArgs.length);\n        }\n\n        final Path jar = new File(remainingArgs[0]).toPath();\n        if (!Files.exists(jar)) {\n            System.err.println(jar + \" is not exists\");\n            return;\n        }\n        if (output == null) {\n            if (Files.isDirectory(jar)) {\n                output = new File(jar.getFileName() + \"-decrypted.jar\").toPath();\n            } else {\n                output = new File(getBaseName(jar.getFileName().toString()) + \"-decrypted.jar\").toPath();\n            }\n        }\n\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            return;\n        }\n\n        System.err.println(jar + \" -> \" + output);\n\n        List<MethodConfig> methodConfigs = collectMethodConfigs();\n        if (methodConfigs == null || methodConfigs.size() == 0) {\n            System.err.println(\"No method selected !\");\n            return;\n        }\n\n        final Map<MethodConfig, MethodConfig> map = loadMethods(jar, methodConfigs);\n        try (FileSystem outputFileSystem = createZip(output)) {\n            final Path outputBase = outputFileSystem.getPath(\"/\");\n            walkJarOrDir(jar, new FileVisitorX() {\n                @Override\n                public void visitFile(Path file, String relative) throws IOException {\n                    if (file.getFileName().toString().endsWith(\".class\")) {\n                        Path dist1 = outputBase.resolve(relative);\n                        createParentDirectories(dist1);\n                        byte[] data = Files.readAllBytes(file);\n                        ClassNode cn = readClassNode(data);\n\n                        if (decrypt(cn, map)) {\n                            byte[] data2 = toByteArray(cn);\n                            Files.write(dist1, data2);\n                        } else {\n                            Files.write(dist1, data);\n                        }\n                    } else {\n                        Path dist1 = outputBase.resolve(relative);\n                        createParentDirectories(dist1);\n                        Files.copy(file, dist1);\n                    }\n                }\n            });\n        }\n    }\n\n    private byte[] toByteArray(ClassNode cn) {\n        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n        cn.accept(cw);\n        return cw.toByteArray();\n    }\n\n    private ClassNode readClassNode(byte[] data) {\n        ClassReader cr = new ClassReader(data);\n        ClassNode cn = new ClassNode();\n        cr.accept(cn, ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);\n        return cn;\n    }\n\n    private boolean decrypt(ClassNode cn, Map<MethodConfig, MethodConfig> map) {\n        if (deepAnalyze) {\n            return decryptByIr(cn, map);\n        } else {\n            return decryptByStack(cn, map);\n        }\n    }\n\n    private boolean decryptByIr(ClassNode cn, Map<MethodConfig, MethodConfig> map) {\n        MethodConfig key = this.key;\n        boolean changed = false;\n        for (Iterator<MethodNode> it = cn.methods.iterator(); it.hasNext(); ) {\n            MethodNode m = it.next();\n            if (m.instructions == null) {\n                continue;\n            }\n            key.owner = cn.name;\n            key.name = m.name;\n            key.desc = m.desc;\n            if (map.containsKey(key)) {\n                if (deleteMethod) {\n                    it.remove();\n                }\n                continue;\n            }\n\n\n            if (false && verbose) {\n                System.out.println();\n                System.out.println(\"===============\");\n                System.out.println(\"on method \" + cn.name + \";->\" + m.name + m.desc);\n            }\n\n            boolean find = false;\n            // search for the decrypt method\n            for (AbstractInsnNode p = m.instructions.getFirst(); p != null; p = p.getNext()) {\n                if (p.getOpcode() == Opcodes.INVOKESTATIC) {\n                    MethodInsnNode mn = (MethodInsnNode) p;\n                    key.owner = mn.owner;\n                    key.name = mn.name;\n                    key.desc = mn.desc;\n                    MethodConfig config = map.get(key);\n                    if (config != null) {\n                        find = true;\n                    }\n                }\n            }\n            if (find) {\n                try {\n                    // copy m to m2 for cleanup debug info\n                    MethodNode m2 = new MethodNode();\n                    m2.tryCatchBlocks = new ArrayList<>();\n                    m2.name = m.name;\n                    m2.access = m.access;\n                    m2.desc = m.desc;\n                    m.accept(m2);\n                    cleanDebug(m2);\n                    // convert m2 to ir\n                    IrMethod irMethod = J2IRConverter.convert(cn.name, m2);\n                    // opt and decrypt\n                    optAndDecrypt(irMethod, map);\n\n                    // convert ir to m3\n                    MethodNode m3 = new MethodNode();\n                    m3.tryCatchBlocks = new ArrayList<>();\n                    new IR2JConverter(true).convert(irMethod, m3);\n\n                    // copy back m3 to m\n                    m.maxLocals = -1;\n                    m.maxLocals = -1;\n                    m.instructions = m3.instructions;\n                    m.tryCatchBlocks = m3.tryCatchBlocks;\n                    m.localVariables = null;\n                    changed = true;\n                } catch (Exception ex) {\n                    if(verbose) {\n                        ex.printStackTrace();\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    MethodConfig key = new MethodConfig();\n\n    private boolean decryptByStack(ClassNode cn, Map<MethodConfig, MethodConfig> map) {\n        MethodConfig key = this.key;\n        boolean changed = false;\n        for (Iterator<MethodNode> it = cn.methods.iterator(); it.hasNext(); ) {\n            MethodNode m = it.next();\n            if (m.instructions == null) {\n                continue;\n            }\n            key.owner = cn.name;\n            key.name = m.name;\n            key.desc = m.desc;\n            if (map.containsKey(key)) {\n                if (deleteMethod) {\n                    it.remove();\n                }\n                continue;\n            }\n\n            if (false && verbose) {\n                System.out.println();\n                System.out.println(\"===============\");\n                System.out.println(\"on method \" + cn.name + \";->\" + m.name + m.desc);\n            }\n\n            AbstractInsnNode p = m.instructions.getFirst();\n            while (p != null) {\n                if (p.getOpcode() == Opcodes.INVOKESTATIC) {\n                    MethodInsnNode mn = (MethodInsnNode) p;\n                    key.owner = mn.owner;\n                    key.name = mn.name;\n                    key.desc = mn.desc;\n                    MethodConfig config = map.get(key);\n                    if (config != null) {\n                        //here we are, given that the decryption method is successfully recognised\n                        Method jmethod = config.jmethod;\n                        try {\n                            int pSize = jmethod.getParameterTypes().length;\n                            // arguments' list. each parameter's value is retrieved by reading bytecode backwards, starting from the INVOKESTATIC statement\n                            Object[] as = readArgumentValues(mn, jmethod, pSize);\n                            if (verbose) {\n                                System.out.println(\" > calling \" + jmethod + \" with arguments \" + v(as));\n                            }\n                            //decryption routine invocation\n                            String newValue = (String) jmethod.invoke(null, as);\n                            if (verbose) {\n                                System.out.println(\"  -> \" + Escape.v(newValue));\n                            }\n                            //LDC statement generation\n                            LdcInsnNode nLdc = new LdcInsnNode(newValue);\n                            //insertion of the decrypted string's LDC statement, after INVOKESTATIC statement\n                            m.instructions.insert(mn, nLdc);\n                            //removal of INVOKESTATIC and previous push statements\n                            removeInsts(m, mn, pSize);\n                            p = nLdc;\n                            changed = true;\n                        } catch (InvocationTargetException ex){\n                            if(verbose){\n                                ex.getTargetException().printStackTrace();\n                            }\n                        } catch (Exception ex) {\n                            if (verbose) {\n                                ex.printStackTrace();\n                            }\n                        }\n                    }\n                }\n                p = p.getNext();\n            }\n        }\n        return changed;\n    }\n\n    protected final CleanLabel T_cleanLabel = new CleanLabel();\n    protected final Ir2JRegAssignTransformer T_ir2jRegAssign = new Ir2JRegAssignTransformer();\n    protected final NewTransformer T_new = new NewTransformer();\n    protected final RemoveConstantFromSSA T_removeConst = new RemoveConstantFromSSA();\n    protected final RemoveLocalFromSSA T_removeLocal = new RemoveLocalFromSSA();\n    protected final ExceptionHandlerTrim T_trimEx = new ExceptionHandlerTrim();\n    protected final TypeTransformer T_type = new TypeTransformer();\n    protected final DeadCodeTransformer T_deadCode = new DeadCodeTransformer();\n    protected final FillArrayTransformer T_fillArray = new FillArrayTransformer();\n    protected final AggTransformer T_agg = new AggTransformer();\n    protected final UnSSATransformer T_unssa = new UnSSATransformer();\n    protected final ZeroTransformer T_zero = new ZeroTransformer();\n    protected final VoidInvokeTransformer T_voidInvoke = new VoidInvokeTransformer();\n    protected final NpeTransformer T_npe = new NpeTransformer();\n\n    public void optAndDecrypt(IrMethod irMethod, final Map<MethodConfig, MethodConfig> map) {\n        T_deadCode.transform(irMethod);\n        T_cleanLabel.transform(irMethod);\n        T_removeLocal.transform(irMethod);\n        T_removeConst.transform(irMethod);\n        T_zero.transform(irMethod);\n        if (T_npe.transformReportChanged(irMethod)) {\n            T_deadCode.transform(irMethod);\n            T_removeLocal.transform(irMethod);\n            T_removeConst.transform(irMethod);\n        }\n        T_new.transform(irMethod);\n        T_fillArray.transform(irMethod);\n        T_agg.transform(irMethod);\n        T_voidInvoke.transform(irMethod);\n\n        new StmtTraveler() {\n            @Override\n            public Value travel(Value op) {\n                op = super.travel(op);\n                if (op.vt == Value.VT.INVOKE_STATIC) {\n                    InvokeExpr ie = (InvokeExpr) op;\n                    MethodConfig key = DecryptStringCmd.this.key;\n                    key.owner = ie.getOwner().substring(1, ie.getOwner().length() - 1);\n                    key.name = ie.getName();\n                    key.desc = buildMethodDesc(ie.getArgs(), ie.getRet());\n\n                    MethodConfig c = map.get(key);\n                    if (c != null) {\n                        try {\n                            Method jmethod = c.jmethod;\n                            if (ie.getArgs().length != jmethod.getParameterTypes().length) {\n                                throw new RuntimeException();\n                            }\n\n                            Object args[] = new Object[ie.getArgs().length];\n                            for (int i = 0; i < args.length; i++) {\n                                args[i] = convertIr2Jobj(ie.getOps()[i], ie.getArgs()[i]);\n                            }\n                            if (verbose) {\n                                System.out.println(\" > calling \" + jmethod + \" with arguments \" + v(args));\n                            }\n                            String str = (String) jmethod.invoke(null, args);\n                            if (verbose) {\n                                System.out.println(\"  -> \" + Escape.v(str));\n                            }\n                            return Exprs.nString(str);\n                        } catch (Exception e) {\n                            e.printStackTrace();\n                        }\n\n                    }\n                }\n                return op;\n            }\n        }.travel(irMethod.stmts);\n\n        T_type.transform(irMethod);\n        T_unssa.transform(irMethod);\n        T_trimEx.transform(irMethod);\n        T_ir2jRegAssign.transform(irMethod);\n    }\n\n    public static String v(Object[] vs) {\n        StringBuilder sb = new StringBuilder(\"[\");\n        boolean first = true;\n        for (Object obj : vs) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\",\");\n            }\n            if(obj instanceof String) {\n                sb.append(Escape.v(obj));\n            }else {\n                sb.append(obj);\n            }\n        }\n        return sb.append(\"]\").toString();\n    }\n\n    private Object convertIr2Jobj(Value value, String type) {\n        if (value instanceof Constant) {\n            if (Constant.Null.equals(((Constant) value).value)) {\n                return null;\n            }\n        }\n        switch (type) {\n            case \"Z\": {\n                Object obj = ((Constant) value).value;\n                return obj instanceof Boolean ? obj : ((Number) obj).intValue() != 0;\n            }\n            case \"B\": {\n                Object obj = ((Constant) value).value;\n                return ((Number) obj).byteValue();\n            }\n            case \"S\": {\n                Object obj = ((Constant) value).value;\n                return ((Number) obj).shortValue();\n            }\n            case \"C\": {\n                Object obj = ((Constant) value).value;\n                return obj instanceof Character ? obj : (char) ((Number) obj).intValue();\n            }\n            case \"I\": {\n                Object obj = ((Constant) value).value;\n                return ((Number) obj).intValue();\n            }\n            case \"J\": {\n                Object obj = ((Constant) value).value;\n                return ((Number) obj).longValue();\n            }\n            case \"F\": {\n                Object obj = ((Constant) value).value;\n                return obj instanceof Float ? obj : Float.intBitsToFloat(((Number) obj).intValue());\n            }\n            case \"D\": {\n                Object obj = ((Constant) value).value;\n                return obj instanceof Double ? obj : Double.longBitsToDouble(((Number) obj).longValue());\n            }\n            case \"Ljava/lang/String;\":\n                return (String) ((Constant) value).value;\n            case \"[Z\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof boolean[]) {\n                        return obj;\n                    } else {\n\n                        boolean[] b = new boolean[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = ((Number) Array.get(obj, i)).intValue() != 0;\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    boolean b[] = new boolean[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        if (obj instanceof Boolean) {\n                            b[i] = ((Boolean) obj).booleanValue();\n                        } else {\n                            b[i] = ((Number) obj).intValue() != 0;\n                        }\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[B\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof byte[]) {\n                        return obj;\n                    } else {\n                        byte[] b = new byte[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = ((Number) Array.get(obj, i)).byteValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    byte b[] = new byte[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = ((Number) obj).byteValue();\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[S\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof short[]) {\n                        return obj;\n                    } else {\n                        short[] b = new short[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = ((Number) Array.get(obj, i)).shortValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    short b[] = new short[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = ((Number) obj).shortValue();\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[C\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof char[]) {\n                        return obj;\n                    } else {\n                        char[] b = new char[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = (char) ((Number) Array.get(obj, i)).intValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    char b[] = new char[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = obj instanceof Character ? ((Character) obj).charValue() : (char) ((Number) obj).intValue();\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[I\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof int[]) {\n                        return obj;\n                    } else {\n                        int[] b = new int[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = ((Number) Array.get(obj, i)).intValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    int b[] = new int[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = ((Number) obj).intValue();\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[J\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof long[]) {\n                        return obj;\n                    } else {\n                        long[] b = new long[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = ((Number) Array.get(obj, i)).longValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    long b[] = new long[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = ((Number) obj).longValue();\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[F\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof float[]) {\n                        return obj;\n                    } else {\n                        float[] b = new float[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = (char) ((Number) Array.get(obj, i)).intValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    float b[] = new float[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = obj instanceof Float ? ((Float) obj).floatValue() : Float.intBitsToFloat(((Number) obj).intValue());\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[D\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof double[]) {\n                        return obj;\n                    } else {\n                        double[] b = new double[Array.getLength(obj)];\n                        for (int i = 0; i < b.length; i++) {\n                            b[i] = (char) ((Number) Array.get(obj, i)).intValue();\n                        }\n                        return b;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    double b[] = new double[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        b[i] = obj instanceof Double ? ((Double) obj).doubleValue() : Double.longBitsToDouble(((Number) obj).longValue());\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n            case \"[Ljava/lang/String;\":\n                if (value instanceof Constant) {\n                    Object obj = ((Constant) value).value;\n                    if (obj instanceof String[]) {\n                        return obj;\n                    }\n                } else if (value instanceof FilledArrayExpr) {\n                    String b[] = new String[value.getOps().length];\n                    for (int i = 0; i < b.length; i++) {\n                        Object obj = ((Constant) value.getOps()[i]).value;\n                        if (obj instanceof String) {\n                            b[i] = (String) obj;\n                        } else if (Constant.Null.equals(obj)) {\n                            b[i] = null;\n                        } else {\n                            throw new RuntimeException();\n                        }\n                    }\n                    return b;\n                }\n                throw new RuntimeException();\n        }\n        throw new RuntimeException();\n    }\n\n    private String buildMethodDesc(String[] args, String ret) {\n        StringBuilder sb = new StringBuilder();\n        sb.append('(');\n        for (String s : args) {\n            sb.append(s);\n        }\n        return sb.append(')').append(ret).toString();\n    }\n\n    private void cleanDebug(MethodNode mn) {\n        for (AbstractInsnNode p = mn.instructions.getFirst(); p != null; ) {\n            if (p.getType() == AbstractInsnNode.LINE) {\n                AbstractInsnNode q = p.getNext();\n                mn.instructions.remove(p);\n                p = q;\n            } else {\n                p = p.getNext();\n            }\n        }\n        mn.localVariables = null;\n    }\n\n    void removeInsts(MethodNode m, MethodInsnNode mn, int pSize) {\n        // remove args\n        for (int i = 0; i < pSize; i++) {\n            m.instructions.remove(mn.getPrevious());\n        }\n        // remove INVOKESTATIC\n        m.instructions.remove(mn);\n    }\n\n    Object[] readArgumentValues(MethodInsnNode mn, Method jmethod, int pSize) {\n        AbstractInsnNode q = mn;\n        Object[] as = new Object[pSize];\n        for (int i = pSize - 1; i >= 0; i--) {\n            q = q.getPrevious();\n            Object object = readCst(q);\n            as[i] = convert(object, jmethod.getParameterTypes()[i]);\n        }\n        return as;\n    }\n\n    Object convert(Object object, Class<?> type) {\n        if (int.class.equals(type)) {\n            return ((Number) object).intValue();\n        }\n        if (byte.class.equals(type)) {\n            return ((Number) object).byteValue();\n        }\n        if (short.class.equals(type)) {\n            return ((Number) object).shortValue();\n        }\n        if (char.class.equals(type)) {\n            return (char) ((Number) object).intValue();\n        }\n        if (boolean.class.equals(type)) {\n            return (char) ((Number) object).intValue() != 0;\n        }\n        if (long.class.equals(type)) {\n            return (char) ((Number) object).longValue();\n        }\n        if (float.class.equals(type)) {\n            return (char) ((Number) object).floatValue();\n        }\n        if (double.class.equals(type)) {\n            return (char) ((Number) object).doubleValue();\n        }\n        return object;\n    }\n\n    /**\n     * load java methods from jar and --classpath\n     *\n     * @param jar\n     * @param methodConfigs\n     * @return\n     * @throws Exception\n     */\n    private Map<MethodConfig, MethodConfig> loadMethods(Path jar, List<MethodConfig> methodConfigs) throws Exception {\n        final Map<MethodConfig, MethodConfig> map = new HashMap<>();\n        List<String> list = new ArrayList<>();\n        if (classpath != null) {\n            list.addAll(Arrays.asList(classpath.split(\";|:\")));\n        }\n        list.add(jar.toAbsolutePath().toString());\n        URL[] urls = new URL[list.size()];\n        for (int i = 0; i < list.size(); i++) {\n            urls[i] = new File(list.get(i)).toURI().toURL();\n        }\n\n        URLClassLoader cl = new URLClassLoader(urls);\n        for (MethodConfig config : methodConfigs) {\n            Method jmethod;\n            try {\n                Class<?> clz = cl.loadClass(config.owner.replace('/', '.'));\n                if (clz == null) {\n                    System.err.println(\"clz is null:\" + config.owner);\n                }\n                jmethod = findAnyMethodMatch(clz, config.name,\n                        toJavaType(Type.getArgumentTypes(config.desc)));\n            } catch (Exception ex) {\n                System.err.println(\"can't load method: L\" + config.owner + \";->\" + config.name + config.desc);\n                throw ex;\n            }\n            if (jmethod != null) {\n                jmethod.setAccessible(true);\n                config.jmethod = jmethod;\n                map.put(config, config);\n            } else {\n                throw new NoSuchMethodException(\"can't find method \" + config.name + config.desc + \" on class \" + config.owner + \" or its parent\");\n            }\n        }\n        return map;\n    }\n\n    /**\n     * collect methods from --methods and --method-owner,--method-name\n     *\n     * @return\n     * @throws IOException\n     */\n    private List<MethodConfig> collectMethodConfigs() throws IOException {\n        List<MethodConfig> methodConfigs = new ArrayList<>();\n        if (this.method != null) {\n            for (String line : Files.readAllLines(this.method, StandardCharsets.UTF_8)) {\n                if (line.length() == 0 || line.startsWith(\"#\")) {\n                    continue;\n                }\n                methodConfigs.add(this.build(line));\n            }\n        }\n        if (methodOwner != null && methodName != null) {\n            if (this.parametersDescriptor != null) {\n                methodConfigs.add(this.build(\"L\" + methodOwner.replace('.', '/') + \";->\" + methodName + \"(\"\n                        + this.parametersDescriptor + \")Ljava/lang/String;\"));\n            } else if (this.parameterJTypes != null) {\n\n                //parameterJTypes is a comma-separated list of the decryption method's parameters\n                String[] type_list = parameterJTypes.split(\",|;|:\");\n                //switch for all the supported types. String is default\n                StringBuilder sb = new StringBuilder();\n                for (int i = 0; i < type_list.length; i++) {\n                    switch (type_list[i]) {\n                        case \"boolean\":\n                            sb.append(\"Z\");\n                            break;\n                        case \"byte\":\n                            sb.append(\"B\");\n                            break;\n                        case \"short\":\n                            sb.append(\"S\");\n                            break;\n                        case \"char\":\n                            sb.append(\"C\");\n                            break;\n                        case \"int\":\n                            sb.append(\"I\");\n                            break;\n                        case \"long\":\n                            sb.append(\"J\");\n                            break;\n                        case \"float\":\n                            sb.append(\"F\");\n                            break;\n                        case \"double\":\n                            sb.append(\"D\");\n                            break;\n                        case \"string\":\n                            sb.append(\"Ljava/lang/String;\");\n                            break;\n\n                        default:\n                            throw new RuntimeException(\"not support type \" + type_list[i] + \" on -t/--arg-types\");\n                    }\n                }\n                methodConfigs.add(this.build(\"L\" + methodOwner.replace('.', '/') + \";->\" + methodName + \"(\"\n                        + sb + \")Ljava/lang/String;\"));\n            } else {\n                methodConfigs.add(this.build(\"L\" + methodOwner.replace('.', '/') + \";->\" + methodName + \"(Ljava/lang/String;)Ljava/lang/String;\"));\n            }\n        }\n        return methodConfigs;\n    }\n\n    /**\n     * fix for issue 216, travel all the parent of class and use getDeclaredMethod to find methods\n     */\n    private Method findAnyMethodMatch(Class<?> clz, String name, Class<?>[] classes) {\n        try {\n            Method m = clz.getDeclaredMethod(name, classes);\n            if (m != null) {\n                return m;\n            }\n        } catch (NoSuchMethodException ignored) {\n            // https://github.com/pxb1988/dex2jar/issues/51\n            // mute exception stack\n        }\n        Class<?> sup = clz.getSuperclass();\n        if (sup != null) {\n            Method m = findAnyMethodMatch(sup, name, classes);\n            if (m != null) {\n                return m;\n            }\n        }\n        Class<?>[] itfs = clz.getInterfaces();\n        if (itfs != null && itfs.length > 0) {\n            for (Class<?> itf : itfs) {\n                Method m = findAnyMethodMatch(itf, name, classes);\n                if (m != null) {\n                    return m;\n                }\n            }\n        }\n        return null;\n    }\n\n    Object readCst(AbstractInsnNode q) {\n\n        switch (q.getOpcode()) {\n            case Opcodes.LDC:\n                // LDC: String, integer, long and double cases (Opcodes.LDC comprehends LDC_W and LDC2_W)\n                // push 32bit or 64bit int/float\n                // push string/type\n                LdcInsnNode ldc = (LdcInsnNode) q;\n                if (ldc.cst instanceof Type) {\n                    throw new RuntimeException(\"not support .class value yet!\");\n                }\n                return ldc.cst;\n\n            case Opcodes.BIPUSH:\n            case Opcodes.SIPUSH:\n                // INT_INSN (\"instruction with a single int operand\")\n                // push 8bit or 16bit int\n                IntInsnNode in = (IntInsnNode) q;\n                return in.operand;\n\n            case Opcodes.ICONST_M1:\n            case Opcodes.ICONST_0:\n            case Opcodes.ICONST_1:\n            case Opcodes.ICONST_2:\n            case Opcodes.ICONST_3:\n            case Opcodes.ICONST_4:\n            case Opcodes.ICONST_5:\n                // ICONST_*: push a tiny int, -1 <= value <= 5\n                return q.getOpcode() - Opcodes.ICONST_0;\n            case Opcodes.LCONST_0:\n            case Opcodes.LCONST_1:\n                return (long) (q.getOpcode() - Opcodes.LCONST_0);\n            case Opcodes.FCONST_0:\n            case Opcodes.FCONST_1:\n            case Opcodes.FCONST_2:\n                return (float) (q.getOpcode() - Opcodes.FCONST_0);\n            case Opcodes.DCONST_0:\n            case Opcodes.DCONST_1:\n                return (double) (q.getOpcode() - Opcodes.DCONST_0);\n            case Opcodes.ACONST_NULL:\n                return null;\n        }\n\n        throw new RuntimeException();\n    }\n\n    Class<?>[] toJavaType(Type[] pt) throws ClassNotFoundException {\n        Class<?> jt[] = new Class<?>[pt.length];\n        for (int i = 0; i < pt.length; i++) {\n            jt[i] = toJavaType(pt[i]);\n        }\n        return jt;\n    }\n\n    Class<?> toJavaType(Type t) throws ClassNotFoundException {\n        switch (t.getSort()) {\n            case Type.BOOLEAN:\n                return boolean.class;\n            case Type.BYTE:\n                return byte.class;\n            case Type.SHORT:\n                return short.class;\n            case Type.CHAR:\n                return char.class;\n            case Type.INT:\n                return int.class;\n            case Type.FLOAT:\n                return float.class;\n            case Type.LONG:\n                return long.class;\n            case Type.DOUBLE:\n                return double.class;\n            case Type.OBJECT:\n                return Class.forName(t.getClassName());\n            case Type.ARRAY:\n                return Class.forName(t.getDescriptor());\n            case Type.VOID:\n                return void.class;\n        }\n        throw new RuntimeException();\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport com.googlecode.d2j.dex.Dex2jar;\nimport com.googlecode.d2j.reader.BaseDexFileReader;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.MultiDexFileReader;\nimport com.googlecode.dex2jar.ir.ET;\n\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\n@BaseCmd.Syntax(cmd = \"d2j-dex2jar\", syntax = \"[options] <file0> [file1 ... fileN]\", desc = \"convert dex to jar\")\npublic class Dex2jarCmd extends BaseCmd {\n\n    public static void main(String... args) {\n        new Dex2jarCmd().doMain(args);\n    }\n\n    @Opt(opt = \"e\", longOpt = \"exception-file\", description = \"detail exception file, default is $current_dir/[file-name]-error.zip\", argName = \"file\")\n    private Path exceptionFile;\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"n\", longOpt = \"not-handle-exception\", hasArg = false, description = \"not handle any exceptions thrown by dex2jar\")\n    private boolean notHandleException = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .jar file, default is $current_dir/[file-name]-dex2jar.jar\", argName = \"out-jar-file\")\n    private Path output;\n\n    @Opt(opt = \"r\", longOpt = \"reuse-reg\", hasArg = false, description = \"reuse register while generate java .class file\")\n    private boolean reuseReg = false;\n\n    @Opt(opt = \"s\", hasArg = false, description = \"same with --topological-sort/-ts\")\n    private boolean topologicalSort1 = false;\n\n    @Opt(opt = \"ts\", longOpt = \"topological-sort\", hasArg = false, description = \"sort block by topological, that will generate more readable code, default enabled\")\n    private boolean topologicalSort = false;\n\n    @Opt(opt = \"d\", longOpt = \"debug-info\", hasArg = false, description = \"translate debug info\")\n    private boolean debugInfo = false;\n\n    @Opt(opt = \"p\", longOpt = \"print-ir\", hasArg = false, description = \"print ir to System.out\")\n    private boolean printIR = false;\n\n    @Opt(opt = \"os\", longOpt = \"optmize-synchronized\", hasArg = false, description = \"optimize-synchronized\")\n    private boolean optmizeSynchronized = false;\n\n    @Opt(longOpt = \"skip-exceptions\", hasArg = false, description = \"skip-exceptions\")\n    private boolean skipExceptions = false;\n\n    @Opt(opt = \"nc\", longOpt = \"no-code\", hasArg = false, description = \"\")\n    private boolean noCode = false;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length == 0) {\n            usage();\n            return;\n        }\n\n        if ((exceptionFile != null || output != null) && remainingArgs.length != 1) {\n            System.err.println(\"-e/-o can only used with one file\");\n            return;\n        }\n        if (debugInfo && reuseReg) {\n            System.err.println(\"-d/-r can not use together\");\n            return;\n        }\n\n        Path currentDir = new File(\".\").toPath();\n\n        if (output != null) {\n            if (Files.exists(output) && !forceOverwrite) {\n                System.err.println(output + \" exists, use --force to overwrite\");\n                return;\n            }\n        } else {\n            for (String fileName : remainingArgs) {\n                Path file = currentDir.resolve(getBaseName(new File(fileName).toPath()) + \"-dex2jar.jar\");\n                if (Files.exists(file) && !forceOverwrite) {\n                    System.err.println(file + \" exists, use --force to overwrite\");\n                    return;\n                }\n            }\n        }\n\n        for (String fileName : remainingArgs) {\n            // long baseTS = System.currentTimeMillis();\n            String baseName = getBaseName(new File(fileName).toPath());\n            Path file = output == null ? currentDir.resolve(baseName + \"-dex2jar.jar\") : output;\n            System.err.println(\"dex2jar \" + fileName + \" -> \" + file);\n\n            BaseDexFileReader reader = MultiDexFileReader.open(Files.readAllBytes(new File(fileName).toPath()));\n            BaksmaliBaseDexExceptionHandler handler = notHandleException ? null : new BaksmaliBaseDexExceptionHandler();\n            Dex2jar.from(reader).withExceptionHandler(handler).reUseReg(reuseReg).topoLogicalSort()\n                    .skipDebug(!debugInfo).optimizeSynchronized(this.optmizeSynchronized).printIR(printIR)\n                    .noCode(noCode).skipExceptions(skipExceptions).to(file);\n\n            if (!notHandleException) {\n                if (handler.hasException()) {\n                    Path errorFile = exceptionFile == null ? currentDir.resolve(baseName + \"-error.zip\")\n                            : exceptionFile;\n                    System.err.println(\"Detail Error Information in File \" + errorFile);\n                    System.err.println(BaksmaliBaseDexExceptionHandler.REPORT_MESSAGE);\n                    handler.dump(errorFile, orginalArgs);\n                }\n            }\n            // long endTS = System.currentTimeMillis();\n            // System.err.println(String.format(\"%.2f\", (float) (endTS - baseTS) / 1000));\n        }\n    }\n\n    @Override\n    protected String getVersionString() {\n        return \"reader-\" + DexFileReader.class.getPackage().getImplementationVersion() + \", translator-\"\n                + Dex2jar.class.getPackage().getImplementationVersion() + \", ir-\"\n                + ET.class.getPackage().getImplementationVersion();\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarMultiThreadCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.concurrent.*;\n\nimport com.googlecode.d2j.dex.LambadaNameSafeClassAdapter;\nimport com.googlecode.d2j.reader.BaseDexFileReader;\nimport com.googlecode.d2j.reader.MultiDexFileReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.Opcodes;\n\nimport com.googlecode.d2j.dex.ClassVisitorFactory;\nimport com.googlecode.d2j.dex.ExDex2Asm;\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport org.objectweb.asm.commons.Remapper;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\n\n@BaseCmd.Syntax(cmd = \"d2j-mt-dex2jar\", syntax = \"[options] <file0> [file1 ... fileN]\", desc = \"convert dex to jar\")\npublic class Dex2jarMultiThreadCmd extends BaseCmd {\n    public static void main(String... args) {\n        new Dex2jarMultiThreadCmd().doMain(args);\n    }\n\n    @Opt(opt = \"mt\", longOpt = \"multi-thread\", description = \"concurrent process, default is 4 thread\")\n    private int multiThread = 4;\n\n    @Opt(opt = \"fl\", longOpt = \"file-list\", description = \"a file contains a list of dex to process\")\n    private Path fileList;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        List<String> f = new ArrayList<>();\n        f.addAll(Arrays.asList(remainingArgs));\n        if (fileList != null) {\n            f.addAll(Files.readAllLines(fileList, StandardCharsets.UTF_8));\n        }\n        if (f.size() < 1) {\n            throw new HelpException();\n        }\n\n        final ExecutorService executorService = Executors.newFixedThreadPool(multiThread);\n\n        final Iterator<String> fileIt = f.iterator();\n        executorService.submit(new Runnable() {\n            @Override\n            public void run() {\n                if (fileIt.hasNext()) {\n                    String fileName = fileIt.next();\n                    try {\n                        run0(fileName, executorService);\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    } finally {\n                        executorService.submit(this); // run this job again\n                    }\n                } else {\n                    executorService.shutdown();\n                }\n            }\n        });\n        executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);\n    }\n\n    private void run0(String fileName, final ExecutorService executorService) throws IOException {\n        // long baseTS = System.currentTimeMillis();\n        String baseName = getBaseName(new File(fileName).toPath());\n        Path currentDir = new File(\".\").toPath();\n        Path file = currentDir.resolve(baseName + \"-dex2jar.jar\");\n        final Path errorFile = currentDir.resolve(baseName + \"-error.zip\");\n        System.err.println(\"dex2jar \" + fileName + \" -> \" + file);\n        final BaksmaliBaseDexExceptionHandler exceptionHandler = new BaksmaliBaseDexExceptionHandler();\n        BaseDexFileReader reader = MultiDexFileReader.open(Files.readAllBytes(new File(fileName).toPath()));\n        DexFileNode fileNode = new DexFileNode();\n        try {\n            reader.accept(fileNode, DexFileReader.SKIP_DEBUG | DexFileReader.IGNORE_READ_EXCEPTION);\n        } catch (Exception ex) {\n            exceptionHandler.handleFileException(ex);\n            throw ex;\n        }\n        final FileSystem fs = createZip(file);\n        final Path dist = fs.getPath(\"/\");\n        ClassVisitorFactory cvf = new ClassVisitorFactory() {\n            @Override\n            public ClassVisitor create(final String name) {\n                final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n                final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw);\n                return new ClassVisitor(Opcodes.ASM4, rca) {\n                    @Override\n                    public void visitEnd() {\n                        super.visitEnd();\n                        String className = rca.getClassName();\n                        byte[] data;\n                        try {\n                            // FIXME handle 'java.lang.RuntimeException: Method code too large!'\n                            data = cw.toByteArray();\n                        } catch (Exception ex) {\n                            System.err.println(String.format(\"ASM fail to generate .class file: %s\", className));\n                            exceptionHandler.handleFileException(ex);\n                            return;\n                        }\n                        try {\n                            Path dist1 = dist.resolve(className + \".class\");\n                            BaseCmd.createParentDirectories(dist1);\n                            Files.write(dist1, data);\n                        } catch (IOException e) {\n                            exceptionHandler.handleFileException(e);\n                        }\n                    }\n                };\n            }\n        };\n\n        new ExDex2Asm(exceptionHandler) {\n\n            @Override\n            public void convertDex(final DexFileNode fileNode, final ClassVisitorFactory cvf) {\n                if (fileNode.clzs != null) {\n                    final Map<String, Clz> classes = collectClzInfo(fileNode);\n                    final List<Future<?>> results = new ArrayList<>(fileNode.clzs.size());\n                    for (final DexClassNode classNode : fileNode.clzs) {\n                        results.add(executorService.submit(new Runnable() {\n                            @Override\n                            public void run() {\n                                convertClass(fileNode, classNode, cvf, classes);\n                            }\n                        }));\n                    }\n                    executorService.submit(new Runnable() {\n                        @Override\n                        public void run() {\n                            for (Future<?> result : results) {\n                                try {\n                                    result.get();\n                                } catch (InterruptedException | ExecutionException e) {\n                                    e.printStackTrace();\n                                }\n                            }\n                            BaksmaliBaseDexExceptionHandler exceptionHandler1 = (BaksmaliBaseDexExceptionHandler) exceptionHandler;\n                            if (exceptionHandler1.hasException()) {\n                                exceptionHandler1.dump(errorFile, new String[0]);\n                            }\n                            try {\n                                fs.close();\n                            } catch (IOException e) {\n                                e.printStackTrace();\n                            }\n                        }\n                    });\n                }\n            }\n        }.convertDex(fileNode, cvf);\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexRecomputeChecksum.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2014 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.tools;\r\n\r\nimport com.googlecode.d2j.dex.writer.DexFileWriter;\r\n\r\nimport java.io.File;\r\nimport java.nio.ByteBuffer;\r\nimport java.nio.ByteOrder;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\n\r\n@BaseCmd.Syntax(cmd = \"d2j-dex-recompute-checksum\", syntax = \"[options] dex\", desc = \"recompute crc and sha1 of dex.\")\r\npublic class DexRecomputeChecksum extends BaseCmd {\r\n    public static void main(String... args) {\r\n        new DexRecomputeChecksum().doMain(args);\r\n    }\r\n\r\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\r\n    private boolean forceOverwrite = false;\r\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .dex file, default is [dex-name]-rechecksum.dex\", argName = \"out-dex-file\")\r\n    private Path output;\r\n\r\n    @Override\r\n    protected void doCommandLine() throws Exception {\r\n        if (remainingArgs.length != 1) {\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        Path jar = new File(remainingArgs[0]).toPath();\r\n        if (!Files.exists(jar)) {\r\n            System.err.println(jar + \" is not exists\");\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        if (output == null) {\r\n            if (Files.isDirectory(jar)) {\r\n                output = new File(jar.getFileName() + \"-rechecksum.dex\").toPath();\r\n            } else {\r\n                output = new File(getBaseName(jar.getFileName().toString()) + \"-rechecksum.dex\").toPath();\r\n            }\r\n        }\r\n\r\n        if (Files.exists(output) && !forceOverwrite) {\r\n            System.err.println(output + \" exists, use --force to overwrite\");\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        byte[] data = Files.readAllBytes(jar);\r\n\r\n        ByteBuffer b = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);\r\n        b.putInt(32, data.length);\r\n        DexFileWriter.updateChecksum(b, data.length);\r\n        Files.write(output, data);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexWeaverCmd.java",
    "content": "package com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.dex.writer.DexFileWriter;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.d2j.smali.Utils;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\n@BaseCmd.Syntax(cmd = \"d2j-dex-weaver\", syntax = \"[options] dex\", desc = \"replace invoke in dex\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/DexWeaver\")\npublic class DexWeaverCmd extends BaseCmd {\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .dex file\", argName = \"out-dex-file\")\n    private Path output;\n    @Opt(opt = \"c\", longOpt = \"config\", description = \"config file\", argName = \"config\")\n    private Path config;\n    @Opt(opt = \"s\", longOpt = \"stub-dex\", description = \"stub dex\", argName = \"stub\")\n    private Path stub;\n\n    static Method parseMethod(String str) {\n        int i = str.indexOf('.');\n        String owner = str.substring(0, i);\n        int j = str.indexOf('(', i);\n        String name = str.substring(i + 1, j);\n        i = str.indexOf(')', j);\n        String args = str.substring(j + 1, i);\n        String ret = str.substring(i + 1);\n        return new Method(owner, name, Utils.toTypeList(args), ret);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length == 0) {\n            throw new HelpException(\"no odex\");\n        }\n\n        final Map<String, Method> map = new HashMap<>();\n        for (String ln : Files.readAllLines(config, StandardCharsets.UTF_8)) {\n            if (ln.startsWith(\"#\") || ln.length() == 0) {\n                continue;\n            }\n            String[] x = ln.split(\"=\");\n            map.put(x[0], parseMethod(x[1]));\n        }\n\n        DexFileWriter out = new DexFileWriter();\n        DexFileVisitor fv = new DexFileVisitor(out) {\n            @Override\n            public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {\n                DexClassVisitor dcv = super.visit(access_flags, className, superClass, interfaceNames);\n                if (dcv != null) {\n                    return new DexClassVisitor(dcv) {\n                        @Override\n                        public DexMethodVisitor visitMethod(int accessFlags, Method method) {\n                            DexMethodVisitor dmv = super.visitMethod(accessFlags, method);\n                            if (dmv != null) {\n                                return new DexMethodVisitor(dmv) {\n                                    @Override\n                                    public DexCodeVisitor visitCode() {\n                                        DexCodeVisitor code = super.visitCode();\n                                        if (code != null) {\n                                            return new DexCodeVisitor(code) {\n                                                @Override\n                                                public void visitMethodStmt(Op op, int[] args, Method method) {\n                                                    Method replaceTo = map.get(method.toString());\n                                                    if (replaceTo != null) {\n                                                        switch (op) {\n                                                        case INVOKE_DIRECT:\n                                                        case INVOKE_INTERFACE:\n                                                        case INVOKE_STATIC:\n                                                        case INVOKE_SUPER:\n                                                        case INVOKE_VIRTUAL:\n                                                            super.visitMethodStmt(Op.INVOKE_STATIC, args, replaceTo);\n                                                            break;\n                                                        case INVOKE_DIRECT_RANGE:\n                                                        case INVOKE_INTERFACE_RANGE:\n                                                        case INVOKE_STATIC_RANGE:\n                                                        case INVOKE_SUPER_RANGE:\n                                                        case INVOKE_VIRTUAL_RANGE:\n                                                            super.visitMethodStmt(Op.INVOKE_STATIC_RANGE, args, replaceTo);\n                                                            break;\n                                                        default:\n                                                            // impossible here\n                                                        }\n                                                    } else {\n                                                        super.visitMethodStmt(op, args, method);\n                                                    }\n                                                }\n                                            };\n                                        }\n                                        return code;\n                                    }\n                                };\n                            }\n                            return dmv;\n                        }\n                    };\n                }\n                return dcv;\n            }\n\n            @Override\n            public void visitEnd() {\n\n            }\n        };\n        for (String f : remainingArgs) {\n            byte[] data = ZipUtil.readDex(new File(f).toPath());\n            DexFileReader r = new DexFileReader(data);\n            r.accept(fv);\n        }\n        if (stub != null) {\n            byte[] data = ZipUtil.readDex(stub);\n            DexFileReader r = new DexFileReader(data);\n            r.accept(new DexFileVisitor(out) {\n                @Override\n                public void visitEnd() {\n\n                }\n            });\n        }\n\n        out.visitEnd();\n\n        byte[] data = out.toByteArray();\n        Files.write(output, data);\n\n    }\n\n    public static void main(String[] args) {\n        new DexWeaverCmd().doMain(args);\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/ExtractOdexFromCoredumpCmd.java",
    "content": "package com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.IntBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.SeekableByteChannel;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@BaseCmd.Syntax(cmd = \"extract-odex-from-coredump\", syntax = \"<core.xxxx>\", desc = \"Extract odex from dalvik memery core dump\")\npublic class ExtractOdexFromCoredumpCmd extends BaseCmd {\n    public static void main(String... args) {\n        new ExtractOdexFromCoredumpCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length < 1) {\n            throw new HelpException(\"<core.xxxx> is required.\");\n        }\n        Path core = new File(remainingArgs[0]).toPath();\n        try (SeekableByteChannel channel = FileChannel.open(core, StandardOpenOption.READ);) {\n            List<Long> possibleOdexs = findPossibleOdexLocation(channel);\n            extractDex(channel, possibleOdexs, core.getFileName().toString());\n        }\n    }\n\n    private static void extractDex(SeekableByteChannel channel, List<Long> possibleOdexs, String namePrefix) throws IOException {\n        int dexIndex = 0;\n        ByteBuffer odexHead = ByteBuffer.allocate(0x28).order(ByteOrder.LITTLE_ENDIAN);\n        ByteBuffer copyBuff = ByteBuffer.allocate(512 * 1024).order(ByteOrder.LITTLE_ENDIAN);\n        final int buffSize = 0x28 + 0x70;\n        ByteBuffer head = ByteBuffer.allocate(buffSize).order(ByteOrder.LITTLE_ENDIAN); // odex+dex head\n        for (long pos : possibleOdexs) {\n            System.err.println(String.format(\">> Check for %08x\", pos));\n            channel.position(pos);\n            head.position(0);\n            int c = channel.read(head);\n            head.position(0);\n            if (c == buffSize) {\n                int version = head.getInt(4);\n                if (version == 0x00363330 || version == 0x00353330) { // odexVersion\n                    int dexOffset = head.getInt(8);\n                    int dexLength = head.getInt(12);\n                    int depsOffset = head.getInt(16);\n                    int depsLength = head.getInt(20);\n                    int optOffset = head.getInt(24);\n                    int optLength = head.getInt(28);\n                    int flags = head.getInt(32);\n                    int checksum = head.getInt(36);\n                    if (dexOffset != 0x28) {\n                        System.err.println(String.format(\">>> dex offset is not 0x28\"));\n                    } else {\n                        int dexMagic = head.getInt(dexOffset + 0);\n                        int dexVersion = head.getInt(dexOffset + 4);\n                        if (dexMagic != 0x0a786564 || !(dexVersion == 0x00363330 || dexVersion == 0x00353330)) {\n                            System.err.println(String.format(\">>> dex magic is not dex.036 or dex.035: 0x%08x 0x%08x\", dexMagic, dexVersion));\n                        } else {\n                            int fileSize = head.getInt(dexOffset + 32);\n                            if (fileSize != dexLength) {\n                                System.err.println(String.format(\">>> dex file size is same with dexLength in odex %d vs %d\", fileSize, dexLength));\n                            } else {\n                                int endian = head.getInt(dexOffset + 40);\n                                if (endian != 0x12345678) {\n                                    System.err.println(String.format(\">>> dex endian is not 0x12345678\"));\n                                } else {\n                                    // find new dex\n                                    Path nFile = new File(String.format(\"%s-%02d.odex\", namePrefix, dexIndex++)).toPath();\n                                    System.out.println(String.format(\">>>> extract 0x%08x to %s\", pos, nFile));\n                                    try (SeekableByteChannel channel2 = Files.newByteChannel(nFile, StandardOpenOption.CREATE, StandardOpenOption.WRITE);) {\n\n                                        odexHead.rewind();\n                                        odexHead.putInt(0x0a796564);// dey\n                                        odexHead.putInt(0x00363330);// 036\n                                        odexHead.putInt(0x28);\n                                        odexHead.putInt(fileSize);\n                                        int nDepsOffset = 0x28 + fileSize;\n                                        int nDepsPadding = 0;\n                                        if (nDepsOffset % 8 != 0) {\n                                            nDepsPadding = 8 - (nDepsOffset % 8);\n                                            nDepsOffset += nDepsPadding;\n                                        }\n                                        odexHead.putInt(nDepsOffset);\n                                        odexHead.putInt(depsLength);\n                                        int nOptOffset = nDepsOffset + depsLength;\n                                        int nOptPadding = 0;\n                                        if (nOptOffset % 8 != 0) {\n                                            nOptPadding = 8 - (nOptOffset % 8);\n                                            nOptOffset += nOptPadding;\n                                        }\n                                        odexHead.putInt(nOptOffset);\n                                        odexHead.putInt(optLength);\n                                        odexHead.putInt(flags);\n                                        odexHead.putInt(checksum);\n                                        odexHead.position(0);\n                                        channel2.write(odexHead);\n\n                                        // copy dex\n                                        channel.position(pos + dexOffset);\n                                        copy(channel, channel2, copyBuff, fileSize);\n\n                                        if (nDepsPadding != 0) {\n                                            channel2.write(ByteBuffer.allocate(nDepsPadding));\n                                        }\n                                        // copy deps\n                                        channel.position(pos + depsOffset);\n                                        copy(channel, channel2, copyBuff, depsLength);\n\n                                        if (nOptPadding != 0) {\n                                            channel2.write(ByteBuffer.allocate(nOptPadding));\n                                        }\n                                        // copy opts\n                                        channel.position(pos + optOffset);\n                                        copy(channel, channel2, copyBuff, optLength);\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                }\n            }\n        }\n    }\n\n    private static void copy(SeekableByteChannel channel, SeekableByteChannel channel2, ByteBuffer copyBuff, int fileSize) throws IOException {\n        int remain = fileSize;\n\n        while (remain > 0) {\n            copyBuff.rewind();\n            copyBuff.limit(Math.min(remain, copyBuff.capacity()));\n            int read = channel.read(copyBuff);\n            copyBuff.position(0);\n            channel2.write(copyBuff);\n            remain -= read;\n        }\n\n    }\n\n    private static List<Long> findPossibleOdexLocation(SeekableByteChannel channel) throws IOException {\n        ByteBuffer buffer = ByteBuffer.allocate(1024 * 512).order(ByteOrder.LITTLE_ENDIAN);\n        IntBuffer intBuffer = buffer.asIntBuffer();\n        List<Long> possibleOdexs = new ArrayList<>();\n        while (true) {\n            long position = channel.position();\n            //System.out.printf(\"load @%x\\n\", position);\n            int count = channel.read(buffer);\n            if (count <= 0) {\n                break;\n            }\n            int s = count / 4;\n            for (int i = 0; i < s; i++) {\n                int u4 = intBuffer.get(i);\n                if (u4 == 0x0a796564) {// dey\n                    if (i + 1 < s) {\n                        int v4 = intBuffer.get(i + 1);\n                        if (v4 == 0x00363330 || v4 == 0x00353330) {\n                            possibleOdexs.add(position + 4 * i);\n                            System.err.println(String.format(\"> Possible %08x | %08x %08x\", position + i * 4, u4, v4));\n                        }\n                    } else {\n                        possibleOdexs.add(position + 4 * i);\n                        System.err.println(String.format(\"> Possible %08x | %08x\", position + i * 4, u4));\n                    }\n                }\n            }\n            buffer.position(0);\n            intBuffer.position(0);\n        }\n        return possibleOdexs;\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/GenerateCompileStubFromOdex.java",
    "content": "package com.googlecode.dex2jar.tools;\n\nimport com.googlecode.d2j.dex.ClassVisitorFactory;\nimport com.googlecode.d2j.dex.Dex2Asm;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport org.objectweb.asm.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\n@BaseCmd.Syntax(cmd = \"d2j-generate-stub-from-odex\", syntax = \"[options] <odex0> [odex1 ... odexN]\", desc = \"Genenerate no-code jar from odex\")\npublic class GenerateCompileStubFromOdex extends BaseCmd {\n    private static final int MAGIC_ODEX = 0x0A796564 & 0x00FFFFFF;// hex for 'dey ', ignore the 0A\n    private static final int MAGIC_DEX = 0x0A786564 & 0x00FFFFFF;// hex for 'dex ', ignore the 0A\n\n    public static void main(String... args) {\n        new GenerateCompileStubFromOdex().doMain(args);\n    }\n\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .jar file, default is stub.jar\", argName = \"out-jar-file\")\n    private Path output;\n    @Opt(opt = \"npri\", longOpt = \"no-private\", description = \"\", hasArg = false)\n    private boolean noPrivate;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length == 0) {\n            throw new HelpException(\"no odex\");\n        }\n        if (output == null) {\n            output = new File(\"stub.jar\").toPath();\n        }\n\n        try (FileSystem fs = createZip(output)) {\n            Path out = fs.getPath(\"/\");\n            for (String x : remainingArgs) {\n                System.err.println(\"process \" + x + \" ...\");\n                ByteBuffer bs = ByteBuffer.wrap(Files.readAllBytes(new File(x).toPath()))\n                        .order(ByteOrder.LITTLE_ENDIAN);\n                int magic = bs.getInt(0) & 0x00FFFFFF;\n                if (magic == MAGIC_ODEX) {\n                    int offset = bs.getInt(8);\n                    int length = bs.getInt(12);\n                    bs.position(offset);\n                    ByteBuffer n = (ByteBuffer) bs.slice().limit(length);\n                    doDex(n, out);\n                } else if (magic == MAGIC_DEX) {\n                    doDex(bs, out);\n                } else {\n                    throw new RuntimeException(\"file \" + x + \" is not an dex or odex\");\n                }\n\n            }\n        }\n    }\n\n    private void doDex(ByteBuffer bs, final Path out) {\n        DexFileReader reader = new DexFileReader(bs);\n        DexFileNode fileNode = new DexFileNode();\n        reader.accept(fileNode, DexFileReader.SKIP_CODE);\n        Dex2Asm dex2Asm = new Dex2Asm();\n        dex2Asm.convertDex(fileNode, new ClassVisitorFactory() {\n            @Override\n            public ClassVisitor create(final String classInternalName) {\n                final Path target = out.resolve(classInternalName + \".class\");\n                if (Files.exists(target)) {\n                    System.err.println(\"class \" + classInternalName + \" is already exists, skipping.\");\n                    return null;\n                }\n                return new ClassVisitor(Opcodes.ASM4, new ClassWriter(ClassWriter.COMPUTE_MAXS)) {\n                    @Override\n                    public void visitEnd() {\n                        super.visitEnd();\n                        ClassWriter cw = (ClassWriter) cv;\n                        byte[] data = cw.toByteArray();\n                        try {\n                            BaseCmd.createParentDirectories(target);\n                            Files.write(target, data);\n                        } catch (IOException e) {\n                            e.printStackTrace();\n                        }\n                    }\n\n                    @Override\n                    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {\n                        if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {\n                            return null;\n                        }\n                        return super.visitField(access, name, desc, signature, value);\n                    }\n\n                    @Override\n                    public MethodVisitor visitMethod(int access, String name, String desc, String signature,\n                            String[] exceptions) {\n                        if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {\n                            return null;\n                        }\n                        MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);\n                        if (0 != ((Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT) & access)) {\n                            return mv;\n                        }\n                        mv.visitTypeInsn(Opcodes.NEW, \"java/lang/RuntimeException\");\n                        mv.visitInsn(Opcodes.DUP);\n                        mv.visitLdcInsn(\"stub\");\n                        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, \"java/lang/RuntimeException\", \"<init>\",\n                                \"(Ljava/lang/String;)V\");\n                        mv.visitInsn(Opcodes.ATHROW);\n                        return mv;\n                    }\n                };\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/Jar2Dex.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.tools;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.lang.reflect.Method;\r\nimport java.nio.file.FileSystem;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.List;\r\n\r\n@BaseCmd.Syntax(cmd = \"d2j-jar2dex\", syntax = \"[options] <dir>\", desc = \"Convert jar to dex by invoking dx.\")\r\npublic class Jar2Dex extends BaseCmd {\r\n    public static void main(String... args) {\r\n        new Jar2Dex().doMain(args);\r\n    }\r\n\r\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\r\n    private boolean forceOverwrite = false;\r\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .dex file, default is $current_dir/[jar-name]-jar2dex.dex\", argName = \"out-dex-file\")\r\n    private Path output;\r\n\r\n    @Override\r\n    protected void doCommandLine() throws Exception {\r\n        if (remainingArgs.length != 1) {\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        Path jar = new File(remainingArgs[0]).toPath();\r\n        if (!Files.exists(jar)) {\r\n            System.err.println(jar + \" is not exists\");\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        if (output == null) {\r\n            if (Files.isDirectory(jar)) {\r\n                output = new File(jar.getFileName() + \"-jar2dex.dex\").toPath();\r\n            } else {\r\n                output = new File(getBaseName(jar.getFileName().toString()) + \"-jar2dex.dex\").toPath();\r\n            }\r\n        }\r\n\r\n        if (Files.exists(output) && !forceOverwrite) {\r\n            System.err.println(output + \" exists, use --force to overwrite\");\r\n            usage();\r\n            return;\r\n        }\r\n\r\n        Path tmp = null;\r\n        final Path realJar;\r\n        try {\r\n            if (Files.isDirectory(jar)) {\r\n                realJar = Files.createTempFile(\"d2j\", \".jar\");\r\n                tmp = realJar;\r\n                System.out.println(\"zipping \" + jar + \" -> \" + realJar);\r\n                try (FileSystem fs = createZip(realJar)) {\r\n                    final Path outRoot = fs.getPath(\"/\");\r\n                    walkJarOrDir(jar, new FileVisitorX() {\r\n                        @Override\r\n                        public void visitFile(Path file, String relative) throws IOException {\r\n                            if (file.getFileName().toString().endsWith(\".class\")) {\r\n                                Files.copy(file, outRoot.resolve(relative));\r\n                            }\r\n                        }\r\n                    });\r\n                }\r\n            } else {\r\n                realJar = jar;\r\n            }\r\n\r\n            System.out.println(\"jar2dex \" + realJar + \" -> \" + output);\r\n\r\n            Class<?> c = Class.forName(\"com.android.dx.command.Main\");\r\n            Method m = c.getMethod(\"main\", String[].class);\r\n\r\n            List<String> ps = new ArrayList<String>();\r\n            ps.addAll(Arrays.asList(\"--dex\", \"--no-strict\", \"--output=\" + output.toAbsolutePath().toString(), realJar\r\n                    .toAbsolutePath().toString()));\r\n            System.out.println(\"call com.android.dx.command.Main.main\" + ps);\r\n            m.invoke(null, new Object[] { ps.toArray(new String[ps.size()]) });\r\n        } finally {\r\n            if (tmp != null) {\r\n                Files.deleteIfExists(tmp);\r\n            }\r\n        }\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarAccessCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\nimport org.objectweb.asm.*;\n\n@BaseCmd.Syntax(cmd = \"d2j-jar-access\", syntax = \"[options] <jar>\", desc = \"add or remove class/method/field access in jar file\")\npublic class JarAccessCmd extends BaseCmd implements Opcodes {\n    public static void main(String... args) {\n        new JarAccessCmd().doMain(args);\n    }\n\n    @Opt(opt = \"f\", longOpt = \"force\", hasArg = false, description = \"force overwrite\")\n    private boolean forceOverwrite = false;\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output dir of .j files, default is $current_dir/[jar-name]-access.jar\", argName = \"out-dir\")\n    private Path output;\n\n    @Opt(opt = \"rd\", longOpt = \"remove-debug\", hasArg = false, description = \"remove debug info\")\n    private boolean removeDebug = false;\n\n    @Opt(opt = \"rf\", longOpt = \"remove-field-access\", description = \"remove access from field\", argName = \"ACC\")\n    private String removeFieldAccess;\n    @Opt(opt = \"rm\", longOpt = \"remove-method-access\", description = \"remove access from method\", argName = \"ACC\")\n    private String removeMethodAccess;\n    @Opt(opt = \"rc\", longOpt = \"remove-class-access\", description = \"remove access from class\", argName = \"ACC\")\n    private String removeClassAccess;\n    @Opt(opt = \"af\", longOpt = \"add-field-access\", description = \"add access from field\", argName = \"ACC\")\n    private String addFieldAccess;\n    @Opt(opt = \"am\", longOpt = \"add-method-access\", description = \"add access from method\", argName = \"ACC\")\n    private String addMethodAccess;\n    @Opt(opt = \"ac\", longOpt = \"add-class-access\", description = \"add access from class\", argName = \"ACC\")\n    private String addClassAccess;\n\n    static int str2acc(String s) {\n        if (s == null) {\n            return 0;\n        }\n        int result = 0;\n        s = s.toLowerCase();\n        if (s.contains(\"public\")) {\n            result |= Opcodes.ACC_PUBLIC;\n        }\n        if (s.contains(\"private\")) {\n            result |= Opcodes.ACC_PRIVATE;\n        }\n        if (s.contains(\"protected\")) {\n            result |= Opcodes.ACC_PROTECTED;\n        }\n        if (s.contains(\"final\")) {\n            result |= Opcodes.ACC_FINAL;\n        }\n        if (s.contains(\"static\")) {\n            result |= Opcodes.ACC_STATIC;\n        }\n        if (s.contains(\"super\")) {\n            result |= Opcodes.ACC_SUPER;\n        }\n        if (s.contains(\"synchronized\")) {\n            result |= Opcodes.ACC_SYNCHRONIZED;\n        }\n        if (s.contains(\"volatile\")) {\n            result |= Opcodes.ACC_VOLATILE;\n        }\n        if (s.contains(\"bridge\")) {\n            result |= Opcodes.ACC_BRIDGE;\n        }\n        if (s.contains(\"transient\")) {\n            result |= Opcodes.ACC_TRANSIENT;\n        }\n        if (s.contains(\"varargs\")) {\n            result |= Opcodes.ACC_VARARGS;\n        }\n        if (s.contains(\"native\")) {\n            result |= Opcodes.ACC_NATIVE;\n        }\n        if (s.contains(\"strict\")) {\n            result |= Opcodes.ACC_STRICT;\n        }\n        if (s.contains(\"interface\")) {\n            result |= Opcodes.ACC_INTERFACE;\n        }\n        if (s.contains(\"abstract\")) {\n            result |= Opcodes.ACC_ABSTRACT;\n        }\n        if (s.contains(\"synthetic\")) {\n            result |= Opcodes.ACC_SYNTHETIC;\n        }\n        if (s.contains(\"annotation\")) {\n            result |= Opcodes.ACC_ANNOTATION;\n        }\n        if (s.contains(\"enum\")) {\n            result |= Opcodes.ACC_ENUM;\n        }\n        if (s.contains(\"deprecated\")) {\n            result |= Opcodes.ACC_DEPRECATED;\n        }\n        return result;\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length != 1) {\n            usage();\n            return;\n        }\n\n        Path jar = new File(remainingArgs[0]).toPath();\n        if (!Files.exists(jar)) {\n            System.err.println(jar + \" is not exists\");\n            usage();\n            return;\n        }\n\n        if (output == null) {\n            if (Files.isDirectory(jar)) {\n                output = new File(jar.getFileName() + \"-access.jar\").toPath();\n            } else {\n                output = new File(getBaseName(jar.getFileName().toString()) + \"-access.jar\").toPath();\n            }\n        }\n\n        if (Files.exists(output) && !forceOverwrite) {\n            System.err.println(output + \" exists, use --force to overwrite\");\n            usage();\n            return;\n        }\n\n        final int rf = ~str2acc(removeFieldAccess);\n        final int rm = ~str2acc(removeMethodAccess);\n        final int rc = ~str2acc(removeClassAccess);\n\n        final int af = str2acc(addFieldAccess);\n        final int am = str2acc(addMethodAccess);\n        final int ac = str2acc(addClassAccess);\n\n        final int flags = removeDebug ? ClassReader.SKIP_DEBUG : 0;\n\n        try (FileSystem outFileSystem = createZip(output)) {\n            final Path outRoot = outFileSystem.getPath(\"/\");\n            walkJarOrDir(jar, new FileVisitorX() {\n                @Override\n                public void visitFile(Path file, String relative) throws IOException {\n                    if (file.getFileName().toString().endsWith(\".class\")) {\n\n                        final ClassReader r = new ClassReader(Files.readAllBytes(file));\n\n                        ClassWriter cr = new ClassWriter(0);\n                        r.accept(new ClassVisitor(ASM4, cr) {\n\n                            @Override\n                            public void visit(int version, int access, String name, String signature, String superName,\n                                    String[] interfaces) {\n                                int na = (access & rc) | ac;\n                                if (access != na) {\n                                    System.out.println(\"c \" + name);\n                                }\n                                super.visit(version, na, name, signature, superName, interfaces);\n                            }\n\n                            @Override\n                            public FieldVisitor visitField(int access, String name, String desc, String signature,\n                                    Object value) {\n                                int na = (access & rf) | af;\n                                if (na != access) {\n                                    System.out.println(\"f \" + r.getClassName() + \".\" + name);\n                                }\n                                return super.visitField(na, name, desc, signature, value);\n                            }\n\n                            @Override\n                            public MethodVisitor visitMethod(int access, String name, String desc, String signature,\n                                    String[] exceptions) {\n                                int na = (access & rm) | am;\n                                if (na != access) {\n                                    System.out.println(\"m \" + r.getClassName() + \".\" + name + desc);\n                                }\n                                return super.visitMethod(na, name, desc, signature, exceptions);\n                            }\n\n                        }, flags | ClassReader.EXPAND_FRAMES);\n                        Files.write(outRoot.resolve(relative), cr.toByteArray());\n\n                    } else {\n                        Files.copy(file, outRoot.resolve(relative));\n                    }\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarWeaverCmd.java",
    "content": "package com.googlecode.dex2jar.tools;\n\nimport com.googlecode.d2j.tools.jar.InvocationWeaver;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\n@BaseCmd.Syntax(cmd = \"d2j-jar-weaver\", syntax = \"[options] jar\", desc = \"replace invoke in jar\", onlineHelp = \"https://sourceforge.net/p/dex2jar/wiki/JarWeaver\")\npublic class JarWeaverCmd extends BaseCmd {\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"output .jar file\", argName = \"out-jar-file\", required = true)\n    private Path output;\n    @Opt(opt = \"c\", longOpt = \"config\", description = \"config file\", argName = \"config\", required = true)\n    private Path config;\n    @Opt(opt = \"s\", longOpt = \"stub-jar\", description = \"stub jar\", argName = \"stub\")\n    private Path stub;\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length == 0) {\n            throw new HelpException(\"no jar\");\n        }\n\n        InvocationWeaver invocationWeaver = (InvocationWeaver) new InvocationWeaver().withConfig(config);\n\n        try (FileSystem fs = createZip(output)) {\n            final Path outRoot = fs.getPath(\"/\");\n            for (String str : remainingArgs) {\n                Path p = new File(str).toPath();\n                System.err.println(p + \" -> \" + output);\n                if (Files.isDirectory(p)) {\n                    invocationWeaver.wave(p, outRoot);\n                } else {\n                    try (FileSystem fs2 = openZip(p)) {\n                        invocationWeaver.wave(fs2.getPath(\"/\"), outRoot);\n                    }\n                }\n            }\n            if (stub != null) {\n                System.err.println(stub + \" -> \" + output);\n                walkJarOrDir(stub, new FileVisitorX() {\n                    @Override\n                    public void visitFile(Path file, String relative) throws IOException {\n                        Path out = outRoot.resolve(relative);\n                        if (Files.exists(out)) {\n                            System.err.println(\"skip \" + relative + \" in \" + stub);\n                        } else {\n                            createParentDirectories(out);\n                            Files.copy(file, out);\n                        }\n                    }\n                });\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        new JarWeaverCmd().doMain(args);\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/StdApkCmd.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.tools;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\nimport com.googlecode.d2j.util.zip.AutoSTOREDZipOutputStream;\nimport com.googlecode.dex2jar.tools.BaseCmd.Syntax;\n\n@Syntax(cmd = \"d2j-std-zip\", syntax = \"[options] <zip>\", desc = \"clean up apk to standard zip\")\npublic class StdApkCmd extends BaseCmd {\n\n    @Opt(opt = \"o\", longOpt = \"output\", description = \"The output file\", argName = \"out\", required = true)\n    private Path output;\n\n    public static void main(String... args) {\n        new StdApkCmd().doMain(args);\n    }\n\n    @Override\n    protected void doCommandLine() throws Exception {\n        if (remainingArgs.length < 1) {\n            System.err.println(\"ERROR: no file to process\");\n            return;\n        }\n\n        System.err.printf(\"fix %s -> %s\\n\", remainingArgs[0], output);\n\n        byte[] buffer = new byte[1000];\n        try (ZipOutputStream zos = new AutoSTOREDZipOutputStream(Files.newOutputStream(output))) {\n            byte[] data = Files.readAllBytes(new File(remainingArgs[0]).toPath());\n            try(com.googlecode.d2j.util.zip.ZipFile zipFile = new com.googlecode.d2j.util.zip.ZipFile(data)) {\n                for (com.googlecode.d2j.util.zip.ZipEntry e : zipFile.entries()) {\n                    ZipEntry nEntry = new ZipEntry(e.getName());\n\n                    nEntry.setMethod(e.getMethod() == com.googlecode.d2j.util.zip.ZipEntry.STORED ? ZipEntry.STORED\n                            : ZipEntry.DEFLATED);\n                    zos.putNextEntry(nEntry);\n\n                    if (!nEntry.isDirectory()) {\n                        try (InputStream is = zipFile.getInputStream(e)) {\n                            while (true) {\n                                int c = is.read(buffer);\n                                if (c < 0) {\n                                    break;\n                                }\n                                zos.write(buffer, 0, c);\n                            }\n                        }\n                    }\n                    zos.closeEntry();\n                }\n            }\n            zos.finish();\n        }\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/main/java/com/googlecode/dex2jar/tools/to/Do.java",
    "content": "package com.googlecode.dex2jar.tools.to;\n\npublic class Do {\n\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n        System.out.println(\"This is not support!\");\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/test/java/com/googlecode/d2j/tools/jar/MethodInvocation.java",
    "content": "package com.googlecode.d2j.tools.jar;\n\n\npublic interface MethodInvocation {\n    Object proceed() throws Throwable;\n\n    String getMethodOwner();\n\n    String getMethodName();\n\n    String getMethodDesc();\n\n    Object getThis();\n    // @Nullale\n    Object[] getArguments();\n}\n"
  },
  {
    "path": "dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/DexWaveTest.java",
    "content": "package com.googlecode.d2j.tools.jar.test;\n\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.smali.BaksmaliDumpOut;\nimport com.googlecode.d2j.smali.BaksmaliDumper;\nimport com.googlecode.d2j.smali.Smali;\nimport com.googlecode.d2j.tools.jar.DexWeaver;\nimport org.antlr.runtime.RecognitionException;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.io.BufferedWriter;\nimport java.io.IOException;\nimport java.io.StringWriter;\n\npublic class DexWaveTest {\n    @Test\n    public void testA() throws IOException, RecognitionException {\n\n        DexWeaver iw = new DexWeaver();\n        iw.setInvocationInterfaceDesc(\"Lp;\");\n        iw.withConfig(\"d LA;.m()V=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m1()I=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m2()J=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m3(J)V=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m4()V=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m5(J)V=LB;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"d LA;.m6(J)J=LB;.t(Lp;)Ljava/lang/Object;\");\n        test0(iw, \"a\");\n    }\n\n    @Test\n    public void testB() throws IOException, RecognitionException {\n\n        DexWeaver iw = new DexWeaver();\n        iw.setInvocationInterfaceDesc(\"Lp;\");\n        iw.withConfig(\"r LB;.b=LX;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r LB;.c=LX;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r LB;.d=LX;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r LB;.e=LX;.t(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r LB;.f=LX;.t(Lp;)Ljava/lang/Object;\");\n        test0(iw, \"b\");\n    }\n\n    private void test0(DexWeaver iw, String prefix) throws IOException, RecognitionException {\n        DexClassNode before = Smali.smaliFile2Node(prefix + \"-before.smali\", getClass()\n                .getResourceAsStream(\"/weave/smali/\" + prefix + \"-before.smali\"));\n        DexClassNode expectedAfter = Smali.smaliFile2Node(prefix + \"-after.smali\", getClass()\n                .getResourceAsStream(\"/weave/smali/\" + prefix + \"-after.smali\"));\n\n        DexFileNode dfn = new DexFileNode();\n\n        before.accept(iw.wrap(dfn));\n\n        assertEqual(expectedAfter, dfn.clzs.get(0));\n\n        DexClassNode expectedGen = Smali.smaliFile2Node(prefix + \"-gen.j\", getClass()\n                .getResourceAsStream(\"/weave/smali/\" + prefix + \"-gen.smali\"));\n\n        dfn.clzs.clear();\n        iw.buildInvocationClz(dfn);\n\n        assertEqual(expectedGen, dfn.clzs.get(0));\n\n    }\n\n    private void assertEqual(DexClassNode expected, DexClassNode actual) throws IOException {\n        String stdExpect = toStd(expected);\n        String stdActual = toStd(actual);\n        Assert.assertEquals(stdExpect, stdActual);\n    }\n\n    public static String toStd(DexClassNode expected) throws IOException {\n        StringWriter stringWriter = new StringWriter();\n        BufferedWriter bufferedWriter = new BufferedWriter(stringWriter);\n        BaksmaliDumpOut out = new BaksmaliDumpOut(bufferedWriter);\n        final BaksmaliDumper bs = new BaksmaliDumper(true, false);\n        bs.baksmaliClass(expected, out);\n        bufferedWriter.close();\n        return stringWriter.toString();\n    }\n}\n"
  },
  {
    "path": "dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/WaveTest.java",
    "content": "package com.googlecode.d2j.tools.jar.test;\n\nimport com.googlecode.d2j.asm.LdcOptimizeAdapter;\nimport com.googlecode.d2j.jasmin.JasminDumper;\nimport com.googlecode.d2j.jasmin.Jasmins;\nimport com.googlecode.d2j.tools.jar.InvocationWeaver;\nimport org.antlr.runtime.RecognitionException;\nimport org.junit.Assert;\nimport org.junit.Test;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.tree.ClassNode;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\n\npublic class WaveTest {\n    @Test\n    public void testA() throws IOException, RecognitionException {\n\n        InvocationWeaver iw = new InvocationWeaver();\n        iw.setInvocationInterfaceDesc(\"Lp;\");\n        iw.withConfig(\"d LA;.m()V=LB;.t(Lp;)Ljava/lang/Object;\");\n\n        test0(iw, \"a\");\n    }\n\n    @Test\n    public void testB() throws IOException, RecognitionException {\n\n        InvocationWeaver iw = new InvocationWeaver();\n        iw.setInvocationInterfaceDesc(\"Lp;\");\n        iw.withConfig(\"r Ljava/util/ArrayList;.size=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.size(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r Ljava/util/ArrayList;.add=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.add(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;\");\n        iw.withConfig(\"r Ljava/io/PrintStream;.append(Ljava/lang/CharSequence;)Ljava/io/PrintStream;=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.append(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r Ljava/io/PrintStream;.println(Ljava/lang/String;)V=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.println(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;\");\n\n        test0(iw, \"b\");\n    }\n\n    @Test\n    public void testC() throws IOException, RecognitionException {\n\n        InvocationWeaver iw = new InvocationWeaver();\n        iw.setInvocationInterfaceDesc(\"Lp;\");\n        iw.withConfig(\"r LT;.a()V=LB;.a(Lp;)Ljava/lang/Object;\");\n        iw.withConfig(\"r LT;.b()V=LB;.b(Lp;)V\");\n        iw.withConfig(\"r LT;.c()I=LB;.c(Lp;)Ljava/lang/Object;\");\n        // iw.withConfig(\"r LT;.d()I=LB;.d(Lp;)V\");\n        test0(iw, \"c\");\n    }\n\n    private void test0(InvocationWeaver iw, String prefix) throws IOException, RecognitionException {\n        ClassNode before = Jasmins\n                .parse(prefix + \"-before.j\", getClass().getResourceAsStream(\"/weave/\" + prefix + \"-before.j\"));\n        ClassNode expectedAfter = Jasmins\n                .parse(prefix + \"-after.j\", getClass().getResourceAsStream(\"/weave/\" + prefix + \"-after.j\"));\n        ClassNode expectedGen = Jasmins\n                .parse(prefix + \"-gen.j\", getClass().getResourceAsStream(\"/weave/\" + prefix + \"-gen.j\"));\n\n        ClassNode after = new ClassNode();\n\n        before.accept(iw.wrapper(after));\n\n        assertEqual(expectedAfter, after);\n\n        ClassNode gen = new ClassNode();\n        iw.buildInvocationClz(LdcOptimizeAdapter.wrap(gen));\n\n        assertEqual(expectedGen, gen);\n    }\n\n    private void assertEqual(ClassNode expected, ClassNode actual) throws IOException {\n        String stdExpect = toStd(expected);\n        String stdActual = toStd(actual);\n        Assert.assertEquals(stdExpect, stdActual);\n    }\n\n    public static String toStd(ClassNode expected) throws IOException {\n        expected.access &= ~Opcodes.ACC_SUPER;\n        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n        expected.accept(LdcOptimizeAdapter.wrap(cw));\n\n        ClassReader cr = new ClassReader(cw.toByteArray());\n        ClassNode n = new ClassNode(Opcodes.ASM4);\n        cr.accept(n, ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);\n\n        StringWriter stringWriter = new StringWriter();\n        new JasminDumper(new PrintWriter(stringWriter, true)).dump(n);\n        return stringWriter.toString();\n    }\n\n}\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/a-after.j",
    "content": ".bytecode 50.0\n.class A\n.super java/lang/Object\n\n.method m()V\n    new d2j/gen/MI__000\n    dup\n    aload 0\n    aconst_null\n    iconst_0\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic B/t(Lp;)Ljava/lang/Object;\n    pop\n    return\n  .limit locals 1\n  .limit stack 5\n.end method\n\n.method public static m_A001_CB002(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    aload 0\n    checkcast A\n    invokevirtual A/m_A001()V\n    aconst_null\n    areturn\n  .limit locals 2\n  .limit stack 1\n.end method\n\n.method public m_A001()V\n    return\n  .limit locals 1\n  .limit stack 0\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/a-before.j",
    "content": ".bytecode 50.0\n.class A\n.super java/lang/Object\n\n.method m()V\n    return\n  .limit locals -1\n  .limit stack -1\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/a-gen.j",
    "content": ".bytecode 50.0\n.class public d2j/gen/MI__000\n.super java/lang/Object\n.implements p\n\n.field private final 'thiz' Ljava/lang/Object;\n\n.field private final 'args' [Ljava/lang/Object;\n\n.field private final 'idx' I\n\n.method public <init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    aload 0\n    invokespecial java/lang/Object/<init>()V\n    aload 0\n    aload 1\n    putfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    aload 0\n    aload 2\n    putfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    aload 0\n    iload 3\n    putfield d2j/gen/MI__000/idx I\n    return\n  .limit locals 4\n  .limit stack 2\n.end method\n\n.method public getMethodOwner()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      default : L1\n  L0:\n    ldc \"A\"\n    areturn\n  L1:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodName()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      default : L1\n  L0:\n    ldc \"m\"\n    areturn\n  L1:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodDesc()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      default : L1\n  L0:\n    ldc \"()V\"\n    areturn\n  L1:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getArguments()[Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public getThis()Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public proceed()Ljava/lang/Object;\n.throws java/lang/Throwable\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      default : L1\n  L0:\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokestatic A/m_A001_CB002(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L1:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/b-after.j",
    "content": ".bytecode 50.0\n.class public com/googlecode/d2j/tools/jar/test/res/Res\n.super java/util/ArrayList\n\n.method public <init>()V\n    aload 0\n    invokespecial java/util/ArrayList/<init>()V\n    return\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public static varargs main([Ljava/lang/String;)V\n    getstatic java/lang/System/out Ljava/io/PrintStream;\n    ldc \"\"\n    invokestatic com/googlecode/d2j/tools/jar/test/res/Res/append_A001(Ljava/io/PrintStream;Ljava/lang/CharSequence;)Ljava/io/PrintStream;\n    pop\n    getstatic java/lang/System/out Ljava/io/PrintStream;\n    ldc \"test\"\n    invokestatic com/googlecode/d2j/tools/jar/test/WaveTest/println(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;\n    pop\n    return\n  .limit locals 1\n  .limit stack 2\n.end method\n\n.method private static synthetic append_A001(Ljava/io/PrintStream;Ljava/lang/CharSequence;)Ljava/io/PrintStream;\n    new d2j/gen/MI__000\n    dup\n    aload 0\n    iconst_1\n    anewarray java/lang/Object\n    dup\n    iconst_0\n    aload 1\n    aastore\n    iconst_0\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic com/googlecode/d2j/tools/jar/test/WaveTest/append(Lp;)Ljava/lang/Object;\n    checkcast java/io/PrintStream\n    areturn\n  .limit locals 2\n  .limit stack 7\n.end method\n\n.method public static append_CB002(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    aload 0\n    checkcast java/io/PrintStream\n    aload 1\n    iconst_0\n    aaload\n    checkcast java/lang/CharSequence\n    invokevirtual java/io/PrintStream/append(Ljava/lang/CharSequence;)Ljava/io/PrintStream;\n    areturn\n  .limit locals 2\n  .limit stack 3\n.end method\n\n.method public size()I\n    aload 0\n    invokestatic com/googlecode/d2j/tools/jar/test/res/Res/size_A003(Ljava/util/ArrayList;)I\n    ireturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method private static synthetic size_A003(Ljava/util/ArrayList;)I\n    new d2j/gen/MI__000\n    dup\n    aload 0\n    aconst_null\n    iconst_1\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic com/googlecode/d2j/tools/jar/test/WaveTest/size(Lp;)Ljava/lang/Object;\n    checkcast java/lang/Number\n    invokevirtual java/lang/Number/intValue()I\n    ireturn\n  .limit locals 1\n  .limit stack 5\n.end method\n\n.method public size_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    aload 0\n    invokespecial java/util/ArrayList/size()I\n    invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;\n    areturn\n  .limit locals 2\n  .limit stack 1\n.end method\n\n.method public add(Ljava/lang/Object;)Z\n    aload 0\n    aload 1\n    invokestatic com/googlecode/d2j/tools/jar/test/WaveTest/add(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;\n    checkcast java/lang/Boolean\n    invokevirtual java/lang/Boolean/booleanValue()Z\n    ireturn\n  .limit locals 2\n  .limit stack 2\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/b-before.j",
    "content": ".bytecode 50.0\n.class public super com/googlecode/d2j/tools/jar/test/res/Res\n.super java/util/ArrayList\n\n.method public <init>()V\n    aload 0\n    invokespecial java/util/ArrayList/<init>()V\n    return\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public static varargs main([Ljava/lang/String;)V\n    getstatic java/lang/System/out Ljava/io/PrintStream;\n    ldc \"\"\n    invokevirtual java/io/PrintStream/append(Ljava/lang/CharSequence;)Ljava/io/PrintStream;\n    pop\n    getstatic java/lang/System/out Ljava/io/PrintStream;\n    ldc \"test\"\n    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V\n    return\n  .limit locals 1\n  .limit stack 2\n.end method\n\n.method public size()I\n    aload 0\n    invokespecial java/util/ArrayList/size()I\n    ireturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public add(Ljava/lang/Object;)Z\n    aload 0\n    aload 1\n    invokespecial java/util/ArrayList/add(Ljava/lang/Object;)Z\n    ireturn\n  .limit locals 2\n  .limit stack 2\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/b-gen.j",
    "content": ".bytecode 50.0\n.class public d2j/gen/MI__000\n.super java/lang/Object\n.implements p\n\n.field private final 'thiz' Ljava/lang/Object;\n\n.field private final 'args' [Ljava/lang/Object;\n\n.field private final 'idx' I\n\n.method public <init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    aload 0\n    invokespecial java/lang/Object/<init>()V\n    aload 0\n    aload 1\n    putfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    aload 0\n    aload 2\n    putfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    aload 0\n    iload 3\n    putfield d2j/gen/MI__000/idx I\n    return\n  .limit locals 4\n  .limit stack 2\n.end method\n\n.method public getMethodOwner()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      default : L2\n  L0:\n    ldc \"java/io/PrintStream\"\n    areturn\n  L1:\n    ldc \"java/util/ArrayList\"\n    areturn\n  L2:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodName()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      default : L2\n  L0:\n    ldc \"append\"\n    areturn\n  L1:\n    ldc \"size\"\n    areturn\n  L2:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodDesc()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      default : L2\n  L1:\n    ldc \"()I\"\n    areturn\n  L0:\n    ldc \"(Ljava/lang/CharSequence;)Ljava/io/PrintStream;\"\n    areturn\n  L2:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getArguments()[Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public getThis()Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public proceed()Ljava/lang/Object;\n.throws java/lang/Throwable\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      default : L2\n  L0:\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokestatic com/googlecode/d2j/tools/jar/test/res/Res/append_CB002(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L1:\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    checkcast com/googlecode/d2j/tools/jar/test/res/Res\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokevirtual com/googlecode/d2j/tools/jar/test/res/Res/size_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L2:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/c-after.j",
    "content": ".bytecode 50.0\n.class A\n.super java/lang/Object\n\n.method m()V\n    invokestatic A/a_A001()V\n    invokestatic A/b_A003()V\n    invokestatic A/c_A005()I\n    pop\n    invokestatic T/d()I\n    pop\n    return\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method private static synthetic a_A001()V\n    new d2j/gen/MI__000\n    dup\n    aconst_null\n    aconst_null\n    iconst_0\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic B/a(Lp;)Ljava/lang/Object;\n    pop\n    return\n  .limit locals 0\n  .limit stack 5\n.end method\n\n.method public static a_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    invokestatic T/a()V\n    aconst_null\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method private static synthetic b_A003()V\n    new d2j/gen/MI__000\n    dup\n    aconst_null\n    aconst_null\n    iconst_1\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic B/b(Lp;)V\n    return\n  .limit locals 0\n  .limit stack 5\n.end method\n\n.method public static b_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    invokestatic T/b()V\n    aconst_null\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method private static synthetic c_A005()I\n    new d2j/gen/MI__000\n    dup\n    aconst_null\n    aconst_null\n    iconst_2\n    invokespecial d2j/gen/MI__000/<init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invokestatic B/c(Lp;)Ljava/lang/Object;\n    checkcast java/lang/Number\n    invokevirtual java/lang/Number/intValue()I\n    ireturn\n  .limit locals 0\n  .limit stack 5\n.end method\n\n.method public static c_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    invokestatic T/c()I\n    invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/c-before.j",
    "content": ".bytecode 50.0\n.class A\n.super java/lang/Object\n\n.method m()V\n    invokestatic T/a()V\n    invokestatic T/b()V\n    invokestatic T/c()I\n    pop\n    invokestatic T/d()I\n    pop\n    return\n  .limit locals -1\n  .limit stack -1\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/c-gen.j",
    "content": ".bytecode 50.0\n.class public d2j/gen/MI__000\n.super java/lang/Object\n.implements p\n\n.field private final 'thiz' Ljava/lang/Object;\n\n.field private final 'args' [Ljava/lang/Object;\n\n.field private final 'idx' I\n\n.method public <init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    aload 0\n    invokespecial java/lang/Object/<init>()V\n    aload 0\n    aload 1\n    putfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    aload 0\n    aload 2\n    putfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    aload 0\n    iload 3\n    putfield d2j/gen/MI__000/idx I\n    return\n  .limit locals 4\n  .limit stack 2\n.end method\n\n.method public getMethodOwner()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L0\n      L0\n      default : L1\n  L0:\n    ldc \"T\"\n    areturn\n  L1:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodName()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      L2\n      default : L3\n  L0:\n    ldc \"a\"\n    areturn\n  L1:\n    ldc \"b\"\n    areturn\n  L2:\n    ldc \"c\"\n    areturn\n  L3:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getMethodDesc()Ljava/lang/String;\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L0\n      L1\n      default : L2\n  L1:\n    ldc \"()I\"\n    areturn\n  L0:\n    ldc \"()V\"\n    areturn\n  L2:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n\n.method public getArguments()[Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public getThis()Ljava/lang/Object;\n    aload 0\n    getfield d2j/gen/MI__000/thiz Ljava/lang/Object;\n    areturn\n  .limit locals 1\n  .limit stack 1\n.end method\n\n.method public proceed()Ljava/lang/Object;\n.throws java/lang/Throwable\n    aload 0\n    getfield d2j/gen/MI__000/idx I\n    tableswitch 0\n      L0\n      L1\n      L2\n      default : L3\n  L0:\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokestatic A/a_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L1:\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokestatic A/b_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L2:\n    aload 0\n    getfield d2j/gen/MI__000/args [Ljava/lang/Object;\n    invokestatic A/c_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    areturn\n  L3:\n    new java/lang/RuntimeException\n    dup\n    ldc \"invalid idx\"\n    invokespecial java/lang/RuntimeException/<init>(Ljava/lang/String;)V\n    athrow\n  .limit locals 1\n  .limit stack 3\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/a-after.smali",
    "content": ".class LA;\n.super Ljava/lang/Object;\n\n.method static m()V\n    .registers 4\n    const/4 v0, 0\n    const/4 v1, 0\n    const v2, 0\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static m_A001_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 2\n    invoke-static/range { }, LA;->m_A001()V\n    const v0, 0\n    return-object v0\n.end method\n\n.method public static m_A001()V\n    .registers 0\n    invoke-static { }, LB;->b()V\n    return-void\n.end method\n\n.method static m1()I\n    .registers 4\n    const/4 v0, 0\n    const/4 v1, 0\n    const v2, 1\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Integer;\n    invoke-virtual/range { v0 .. v0 }, Ljava/lang/Integer;->intValue()I\n    move-result v0\n    return v0\n.end method\n\n.method public static m1_A003_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 2\n    invoke-static/range { }, LA;->m1_A003()I\n    move-result v0\n    invoke-static/range { v0 .. v0 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v0\n    return-object v0\n.end method\n\n.method public static m1_A003()I\n    .registers 1\n    invoke-static { }, LB;->b()V\n    const v0, 0\n    return v0\n.end method\n\n.method static m2()J\n    .registers 4\n    const/4 v0, 0\n    const/4 v1, 0\n    const v2, 2\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Long;\n    invoke-virtual/range { v0 .. v0 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v0\n    return-wide v0\n.end method\n\n.method public static m2_A005_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 2\n    invoke-static/range { }, LA;->m2_A005()J\n    move-result-wide v0\n    invoke-static/range { v0 .. p0 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v0\n    return-object v0\n.end method\n\n.method public static m2_A005()J\n    .registers 2\n    invoke-static { }, LB;->b()V\n    const-wide v0, 0\n    return-wide v0\n.end method\n\n.method static m3(J)V\n    .registers 6\n    const/4 v0, 0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p0 .. p1 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 3\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static m3_A007_CB008([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 4\n    const v0, 0\n    aget-object v1, p0, v0\n    check-cast v1, Ljava/lang/Long;\n    invoke-virtual/range { v1 .. v1 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v1\n    invoke-static/range { v1 .. v2 }, LA;->m3_A007(J)V\n    const v0, 0\n    return-object v0\n.end method\n\n.method public static m3_A007(J)V\n    .registers 2\n    invoke-static { }, LB;->b()V\n    return-void\n.end method\n\n.method m4()V\n    .registers 5\n    move-object v0, p0\n    const/4 v1, 0\n    const v2, 4\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static m4_A009_CB010(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 3\n    check-cast p0, LA;\n    invoke-virtual/range { p0 .. p0 }, LA;->m4_A009()V\n    const v0, 0\n    return-object v0\n.end method\n\n.method public m4_A009()V\n    .registers 1\n    invoke-static { }, LB;->b()V\n    return-void\n.end method\n\n.method m5(J)V\n    .registers 7\n    move-object v0, p0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p1 .. p2 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 5\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static m5_A011_CB012(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 5\n    move-object v1, p0\n    check-cast v1, LA;\n    const v0, 0\n    aget-object v2, p1, v0\n    check-cast v2, Ljava/lang/Long;\n    invoke-virtual/range { v2 .. v2 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v2\n    invoke-virtual/range { v1 .. p0 }, LA;->m5_A011(J)V\n    const v0, 0\n    return-object v0\n.end method\n\n.method public m5_A011(J)V\n    .registers 3\n    invoke-static { }, LB;->b()V\n    return-void\n.end method\n\n.method m6(J)J\n    .registers 7\n    move-object v0, p0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p1 .. p2 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 6\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LB;->t(Lp;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Long;\n    invoke-virtual/range { v0 .. v0 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v0\n    return-wide v0\n.end method\n\n.method public static m6_A013_CB014(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 5\n    move-object v1, p0\n    check-cast v1, LA;\n    const v0, 0\n    aget-object v2, p1, v0\n    check-cast v2, Ljava/lang/Long;\n    invoke-virtual/range { v2 .. v2 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v2\n    invoke-virtual/range { v1 .. p0 }, LA;->m6_A013(J)J\n    move-result-wide v0\n    invoke-static/range { v0 .. v1 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v0\n    return-object v0\n.end method\n\n.method public m6_A013(J)J\n    .registers 3\n    invoke-static { }, LB;->b()V\n    return-wide p1\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/a-before.smali",
    "content": ".class LA;\n.super Ljava/lang/Object;\n\n.method static m()V\n.registers 0\n    invoke-static {}, LB;->b()V\n    return-void\n.end method\n\n.method static m1()I\n.registers 1\n    invoke-static {}, LB;->b()V\n    const v0, 0\n    return v0\n.end method\n\n.method static m2()J\n.registers 2\n    invoke-static {}, LB;->b()V\n    const-wide v0,0\n    return-wide v0\n.end method\n\n.method static m3(J)V\n.registers 2\n    invoke-static {}, LB;->b()V\n    return-void\n.end method\n\n.method m4()V\n.registers 1\n    invoke-static {}, LB;->b()V\n    return-void\n.end method\n\n.method m5(J)V\n.registers 3\n    invoke-static {}, LB;->b()V\n    return-void\n.end method\n\n.method m6(J)J\n.registers 3\n    invoke-static {}, LB;->b()V\n    return-wide p1\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/a-gen.smali",
    "content": ".class public Ld2j/gen/MI__000;\n.super Ljava/lang/Object;\n.implements Lp;\n\n.field private final thiz:Ljava/lang/Object;\n\n.field private final args:[Ljava/lang/Object;\n\n.field private final idx:I\n\n.method public constructor <init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    .registers 4\n    iput-object p1, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    iput-object p2, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    iput p3, p0, Ld2j/gen/MI__000;->idx:I\n    return-void\n.end method\n\n.method public getMethodOwner()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L1\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"A\"\n    return-object v0\n    :L1\n    .packed-switch 0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n    .end packed-switch\n.end method\n\n.method public getMethodName()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L7\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"m\"\n    return-object v0\n    :L1\n    const-string v0, \"m1\"\n    return-object v0\n    :L2\n    const-string v0, \"m2\"\n    return-object v0\n    :L3\n    const-string v0, \"m3\"\n    return-object v0\n    :L4\n    const-string v0, \"m4\"\n    return-object v0\n    :L5\n    const-string v0, \"m5\"\n    return-object v0\n    :L6\n    const-string v0, \"m6\"\n    return-object v0\n    :L7\n    .packed-switch 0\n        :L0\n        :L1\n        :L2\n        :L3\n        :L4\n        :L5\n        :L6\n    .end packed-switch\n.end method\n\n.method public getMethodDesc()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L5\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"()I\"\n    return-object v0\n    :L1\n    const-string v0, \"()J\"\n    return-object v0\n    :L2\n    const-string v0, \"()V\"\n    return-object v0\n    :L3\n    const-string v0, \"(J)J\"\n    return-object v0\n    :L4\n    const-string v0, \"(J)V\"\n    return-object v0\n    :L5\n    .packed-switch 0\n        :L2\n        :L0\n        :L1\n        :L4\n        :L2\n        :L4\n        :L3\n    .end packed-switch\n.end method\n\n.method public getArguments()[Ljava/lang/Object;\n    .registers 2\n    iget v0, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    return-object v0\n.end method\n\n.method public getThis()Ljava/lang/Object;\n    .registers 2\n    iget v0, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    return-object v0\n.end method\n\n.method public proceed()Ljava/lang/Object;\n    .registers 4\n    iget v0, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    iget v1, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    iget v2, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v2, :L7\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    invoke-static { v1 }, LA;->m_A001_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L1\n    invoke-static { v1 }, LA;->m1_A003_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L2\n    invoke-static { v1 }, LA;->m2_A005_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L3\n    invoke-static { v1 }, LA;->m3_A007_CB008([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L4\n    invoke-static { v0, v1 }, LA;->m4_A009_CB010(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L5\n    invoke-static { v0, v1 }, LA;->m5_A011_CB012(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L6\n    invoke-static { v0, v1 }, LA;->m6_A013_CB014(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L7\n    .packed-switch 0\n        :L0\n        :L1\n        :L2\n        :L3\n        :L4\n        :L5\n        :L6\n    .end packed-switch\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/b-after.smali",
    "content": ".class LA;\n.super Ljava/lang/Object;\n\n.method static m()V\n    .registers 2\n    invoke-static { }, LA;->b_A001()V\n    invoke-static { }, LA;->b_A001()V\n    const v0, 1\n    invoke-static { v0 }, LA;->c_A003(I)V\n    const-wide v0, 0\n    invoke-static { v0, v1 }, LA;->d_A005(J)V\n    return-void\n.end method\n\n.method private static b_A001()V\n    .registers 4\n    const/4 v0, 0\n    const/4 v1, 0\n    const v2, 0\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static b_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 2\n    invoke-static { }, LB;->b()V\n    const v0, 0\n    return-object v0\n.end method\n\n.method private static c_A003(I)V\n    .registers 5\n    const/4 v0, 0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p0 .. p0 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 1\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static c_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 3\n    const v0, 0\n    aget-object v1, p0, v0\n    check-cast v1, Ljava/lang/Integer;\n    invoke-virtual/range { v1 .. v1 }, Ljava/lang/Integer;->intValue()I\n    move-result v1\n    invoke-static { v1 }, LB;->c(I)V\n    const v0, 0\n    return-object v0\n.end method\n\n.method private static d_A005(J)V\n    .registers 6\n    const/4 v0, 0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p0 .. p1 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 2\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static d_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 4\n    const v0, 0\n    aget-object v1, p0, v0\n    check-cast v1, Ljava/lang/Long;\n    invoke-virtual/range { v1 .. v1 }, Ljava/lang/Long;->longValue()J\n    move-result-wide v1\n    invoke-static { v1, v2 }, LB;->d(J)V\n    const v0, 0\n    return-object v0\n.end method\n\n.method m()V\n    .registers 3\n    const v0, 0\n    invoke-static { p0 }, LA;->e_A007(LB;)V\n    invoke-static { p0 }, LA;->f_A009(LB;)V\n    invoke-static { p0, v0 }, LA;->e_A011(LB;I)V\n    invoke-static { p0, v0 }, LA;->f_A013(LB;I)V\n    return-void\n.end method\n\n.method private static e_A007(LB;)V\n    .registers 5\n    move-object v0, p0\n    const/4 v1, 0\n    const v2, 3\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static e_CB008(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 3\n    check-cast p0, LB;\n    invoke-virtual { p0 }, LB;->e()V\n    const v0, 0\n    return-object v0\n.end method\n\n.method private static f_A009(LB;)V\n    .registers 5\n    move-object v0, p0\n    const/4 v1, 0\n    const v2, 4\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public f_CB010([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 3\n    invoke-super { p0 }, LB;->f()V\n    const v0, 0\n    return-object v0\n.end method\n\n.method private static e_A011(LB;I)V\n    .registers 6\n    move-object v0, p0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p1 .. p1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 5\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public static e_CB012(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 4\n    move-object v1, p0\n    check-cast v1, LB;\n    const v0, 0\n    aget-object p0, p1, v0\n    check-cast p0, Ljava/lang/Integer;\n    invoke-virtual/range { p0 .. p0 }, Ljava/lang/Integer;->intValue()I\n    move-result p0\n    invoke-virtual { v1, p0 }, LB;->e(I)V\n    const v0, 0\n    return-object v0\n.end method\n\n.method private static f_A013(LB;I)V\n    .registers 6\n    move-object v0, p0\n    const v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const v2, 0\n    invoke-static/range { p1 .. p1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v3\n    aput-object v3, v1, v2\n    const v2, 6\n    new-instance v3, Ld2j/gen/MI__000;\n    invoke-direct { v3, v0, v1, v2 }, Ld2j/gen/MI__000;-><init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    invoke-static { v3 }, LX;->t(Lp;)Ljava/lang/Object;\n    return-void\n.end method\n\n.method public f_CB014([Ljava/lang/Object;)Ljava/lang/Object;\n    .registers 4\n    move-object v1, p0\n    const v0, 0\n    aget-object p0, p1, v0\n    check-cast p0, Ljava/lang/Integer;\n    invoke-virtual/range { p0 .. p0 }, Ljava/lang/Integer;->intValue()I\n    move-result p0\n    invoke-super { v1, p0 }, LB;->f(I)V\n    const v0, 0\n    return-object v0\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/b-before.smali",
    "content": ".class LA;\n.super Ljava/lang/Object;\n\n.method static m()V\n.registers 2\n    invoke-static {}, LB;->b()V\n    invoke-static {}, LB;->b()V\n    const v0, 1\n    invoke-static {v0}, LB;->c(I)V\n    const-wide v0, 0\n    invoke-static {v0,v1}, LB;->d(J)V\n    return-void\n.end method\n\n.method m()V\n.registers 3\n    const v0, 0\n    invoke-virtual {v2}, LB;->e()V\n    invoke-super {v2}, LB;->f()V\n    invoke-virtual {v2,v0}, LB;->e(I)V\n    invoke-super {v2,v0}, LB;->f(I)V\n    return-void\n.end method\n"
  },
  {
    "path": "dex-tools/src/test/resources/weave/smali/b-gen.smali",
    "content": ".class public Ld2j/gen/MI__000;\n.super Ljava/lang/Object;\n.implements Lp;\n\n.field private final thiz:Ljava/lang/Object;\n\n.field private final args:[Ljava/lang/Object;\n\n.field private final idx:I\n\n.method public constructor <init>(Ljava/lang/Object;[Ljava/lang/Object;I)V\n    .registers 4\n    iput-object p1, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    iput-object p2, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    iput p3, p0, Ld2j/gen/MI__000;->idx:I\n    return-void\n.end method\n\n.method public getMethodOwner()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L1\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"B\"\n    return-object v0\n    :L1\n    .packed-switch 0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n        :L0\n    .end packed-switch\n.end method\n\n.method public getMethodName()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L5\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"b\"\n    return-object v0\n    :L1\n    const-string v0, \"c\"\n    return-object v0\n    :L2\n    const-string v0, \"d\"\n    return-object v0\n    :L3\n    const-string v0, \"e\"\n    return-object v0\n    :L4\n    const-string v0, \"f\"\n    return-object v0\n    :L5\n    .packed-switch 0\n        :L0\n        :L1\n        :L2\n        :L3\n        :L4\n        :L3\n        :L4\n    .end packed-switch\n.end method\n\n.method public getMethodDesc()Ljava/lang/String;\n    .registers 3\n    iget v0, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v0, :L3\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    const-string v0, \"()V\"\n    return-object v0\n    :L1\n    const-string v0, \"(I)V\"\n    return-object v0\n    :L2\n    const-string v0, \"(J)V\"\n    return-object v0\n    :L3\n    .packed-switch 0\n        :L0\n        :L1\n        :L2\n        :L0\n        :L0\n        :L1\n        :L1\n    .end packed-switch\n.end method\n\n.method public getArguments()[Ljava/lang/Object;\n    .registers 2\n    iget v0, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    return-object v0\n.end method\n\n.method public getThis()Ljava/lang/Object;\n    .registers 2\n    iget v0, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    return-object v0\n.end method\n\n.method public proceed()Ljava/lang/Object;\n    .registers 4\n    iget v0, p0, Ld2j/gen/MI__000;->thiz:Ljava/lang/Object;\n    iget v1, p0, Ld2j/gen/MI__000;->args:[Ljava/lang/Object;\n    iget v2, p0, Ld2j/gen/MI__000;->idx:I\n    packed-switch v2, :L7\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string v1, \"invalid idx\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n    :L0\n    invoke-static { v1 }, LB;->b_CB002([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L1\n    invoke-static { v1 }, LB;->c_CB004([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L2\n    invoke-static { v1 }, LB;->d_CB006([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L3\n    invoke-static { v0, v1 }, LB;->e_CB008(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L4\n    check-cast v0, LB;\n    invoke-virtual { v0, v1 }, LB;->f_CB010([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L5\n    invoke-static { v0, v1 }, LB;->e_CB012(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L6\n    check-cast v0, LB;\n    invoke-virtual { v0, v1 }, LB;->f_CB014([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    return-object v0\n    :L7\n    .packed-switch 0\n        :L0\n        :L1\n        :L2\n        :L3\n        :L4\n        :L5\n        :L6\n    .end packed-switch\n.end method\n"
  },
  {
    "path": "dex-translator/build.gradle",
    "content": "description = 'Dex Translator'\n\ndependencies {\n  compile project(':dex-reader')\n  compile project(':dex-ir')\n  compile project(':d2j-base-cmd')\n  compile 'org.ow2.asm:asm-debug-all:5.0.3'\n  testCompile project(':d2j-smali')\n  testCompile project(':d2j-jasmin')\n}\n\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/asm/LdcOptimizeAdapter.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.asm;\r\n\r\nimport org.objectweb.asm.ClassVisitor;\r\nimport org.objectweb.asm.MethodVisitor;\r\nimport org.objectweb.asm.Opcodes;\r\nimport org.objectweb.asm.Type;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class LdcOptimizeAdapter extends MethodVisitor implements Opcodes {\r\n\r\n    /**\r\n     * @param mv\r\n     */\r\n    public LdcOptimizeAdapter(MethodVisitor mv) {\r\n        super(Opcodes.ASM4, mv);\r\n    }\r\n\r\n    /*\r\n     * (non-Javadoc)\r\n     * \r\n     * @see org.objectweb.asm.MethodAdapter#visitLdcInsn(java.lang.Object)\r\n     */\r\n    @Override\r\n    public void visitLdcInsn(Object cst) {\r\n        if (cst == null) {\r\n            this.visitInsn(ACONST_NULL);\r\n        } else if (cst instanceof Integer) {\r\n            int value = (Integer) cst;\r\n            if (value >= -1 && value <= 5) {\r\n                super.visitInsn(ICONST_0 + value);\r\n            } else if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {\r\n                super.visitIntInsn(BIPUSH, value);\r\n            } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {\r\n                super.visitIntInsn(SIPUSH, value);\r\n            } else {\r\n                super.visitLdcInsn(cst);\r\n            }\r\n        } else if (cst instanceof Long) {\r\n            long value = (Long) cst;\r\n            if (value == 0L || value == 1L) {\r\n                super.visitInsn(LCONST_0 + ((int) value));\r\n            } else {\r\n                super.visitLdcInsn(cst);\r\n            }\r\n        } else if (cst instanceof Float) {\r\n            float value = (Float) cst;\r\n            if (value == 0.0F) {\r\n                super.visitInsn(FCONST_0);\r\n            } else if (value == 1.0F) {\r\n                super.visitInsn(FCONST_1);\r\n            } else if (value == 2.0F) {\r\n                super.visitInsn(FCONST_2);\r\n            } else {\r\n                super.visitLdcInsn(cst);\r\n            }\r\n        } else if (cst instanceof Double) {\r\n            double value = (Double) cst;\r\n            if (value == 0.0D) {\r\n                super.visitInsn(DCONST_0);\r\n            } else if (value == 1.0D) {\r\n                super.visitInsn(DCONST_1);\r\n            } else {\r\n                super.visitLdcInsn(cst);\r\n            }\r\n        } else if(cst instanceof Type){\r\n            Type t= (Type) cst;\r\n            switch (t.getSort()) {\r\n                case Type.BOOLEAN:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Boolean\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.BYTE:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Byte\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.CHAR:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Character\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.DOUBLE:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Double\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.FLOAT:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Float\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.INT:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Integer\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.LONG:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Long\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                case Type.SHORT:\r\n                    super.visitFieldInsn(GETSTATIC, \"java/lang/Short\", \"TYPE\", \"Ljava/lang/Class;\");\r\n                    break;\r\n                default:\r\n                    super.visitLdcInsn(cst);\r\n            }\r\n        } else {\r\n            super.visitLdcInsn(cst);\r\n        }\r\n    }\r\n\r\n    public static MethodVisitor wrap(MethodVisitor mv) {\r\n        return mv == null ? null : new LdcOptimizeAdapter(mv);\r\n    }\r\n\r\n    public static ClassVisitor wrap(ClassVisitor cv) {\r\n        return cv == null ? null : new ClassVisitor(Opcodes.ASM4, cv) {\r\n            @Override\r\n            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\r\n                return wrap(super.visitMethod(access, name, desc, signature, exceptions));\r\n            }\r\n        };\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/converter/Dex2IRConverter.java",
    "content": "package com.googlecode.d2j.converter;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.node.DexCodeNode;\nimport com.googlecode.d2j.node.TryCatchNode;\nimport com.googlecode.d2j.node.analysis.DvmFrame;\nimport com.googlecode.d2j.node.analysis.DvmInterpreter;\nimport com.googlecode.d2j.node.insn.*;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.TypeClass;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.expr.Value;\nimport com.googlecode.dex2jar.ir.stmt.*;\n\nimport java.util.*;\n\nimport static com.googlecode.dex2jar.ir.expr.Exprs.*;\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\n\npublic class Dex2IRConverter {\n    Map<DexLabel, DexLabelStmtNode> labelMap = new HashMap<>();\n    List<DexStmtNode> insnList;\n    int[] parentCount;\n    IrMethod target;\n    DexCodeNode dexCodeNode;\n    List<Stmt> preEmit = new ArrayList<>();\n    List<Stmt> currentEmit;\n    Map<DexLabel, LabelStmt> map = new HashMap<>();\n    private Dex2IrFrame[] frames;\n    private ArrayList<Stmt>[] emitStmts;\n    boolean initAllToZero = true;\n\n    static int sizeofType(String s) {\n        char t = s.charAt(0);\n        if (t == 'J' || t == 'D') {\n            return 2;\n        } else {\n            return 1;\n        }\n    }\n\n    static class Dex2IrFrame extends DvmFrame<DvmValue> {\n        public Dex2IrFrame(int totalRegister) {\n            super(totalRegister);\n        }\n    }\n\n    static int methodArgCount(String[] args) {\n        int i = 0;\n        for (String s : args) {\n            i += sizeofType(s);\n        }\n        return i;\n    }\n\n    public IrMethod convert(boolean isStatic, Method method, DexCodeNode dexCodeNode) {\n        this.dexCodeNode = dexCodeNode;\n        IrMethod irMethod = new IrMethod();\n        irMethod.args = method.getParameterTypes();\n        irMethod.ret = method.getReturnType();\n        irMethod.owner = method.getOwner();\n        irMethod.name = method.getName();\n        irMethod.isStatic = isStatic;\n        target = irMethod;\n\n\n        insnList = dexCodeNode.stmts;\n        for (int i = 0; i < insnList.size(); i++) {\n            DexStmtNode stmtNode = insnList.get(i);\n            stmtNode.__index = i;\n            if (stmtNode instanceof DexLabelStmtNode) {\n                DexLabelStmtNode dexLabelStmtNode = (DexLabelStmtNode) stmtNode;\n                labelMap.put(dexLabelStmtNode.label, dexLabelStmtNode);\n            }\n        }\n\n        fixExceptionHandlers();\n\n        BitSet[] exBranch = new BitSet[insnList.size()];\n        parentCount = new int[insnList.size()];\n        initParentCount(parentCount);\n\n        BitSet handlers = new BitSet(insnList.size());\n        initExceptionHandlers(dexCodeNode, exBranch, handlers);\n\n        DvmInterpreter<DvmValue> interpreter = buildInterpreter();\n        frames = new Dex2IrFrame[insnList.size()];\n        emitStmts = new ArrayList[insnList.size()];\n        BitSet access = new BitSet(insnList.size());\n\n        dfs(exBranch, handlers, access, interpreter);\n\n\n        StmtList stmts = target.stmts;\n        stmts.addAll(preEmit);\n        for (int i = 0; i < insnList.size(); i++) {\n            DexStmtNode p = insnList.get(i);\n            if (access.get(i)) {\n                List<Stmt> es = emitStmts[i];\n                if (es != null) {\n                    stmts.addAll(es);\n                }\n            } else {\n                if (p instanceof DexLabelStmtNode) {\n                    stmts.add(getLabel(((DexLabelStmtNode) p).label));\n                }\n            }\n        }\n        emitStmts = null;\n\n\n        Queue<DvmValue> queue = new LinkedList<>();\n\n        for (int i1 = 0; i1 < frames.length; i1++) {\n            Dex2IrFrame frame = frames[i1];\n            if (parentCount[i1] > 1 && frame != null && access.get(i1)) {\n                for (int j = 0; j < frame.getTotalRegisters(); j++) {\n                    DvmValue v = frame.getReg(j);\n                    addToQueue(queue, v);\n                }\n            }\n\n        }\n\n        while (!queue.isEmpty()) {\n            DvmValue v = queue.poll();\n            getLocal(v);\n            if (v.parent != null) {\n                if (v.parent.local == null) {\n                    queue.add(v.parent);\n                }\n            }\n            if (v.otherParent != null) {\n                for (DvmValue v2 : v.otherParent) {\n                    if (v2.local == null) {\n                        queue.add(v2);\n                    }\n                }\n            }\n        }\n\n        Set<com.googlecode.dex2jar.ir.expr.Value> phiValues = new HashSet<>();\n        List<LabelStmt> phiLabels = new ArrayList<>();\n        for (int i = 0; i < frames.length; i++) {\n            Dex2IrFrame frame = frames[i];\n            if (parentCount[i] > 1 && frame != null && access.get(i)) {\n                DexStmtNode p = insnList.get(i);\n                LabelStmt labelStmt = getLabel(((DexLabelStmtNode) p).label);\n                List<AssignStmt> phis = new ArrayList<>();\n                for (int j = 0; j < frame.getTotalRegisters(); j++) {\n                    DvmValue v = frame.getReg(j);\n                    addPhi(v, phiValues, phis);\n                }\n\n                labelStmt.phis = phis;\n                phiLabels.add(labelStmt);\n            }\n        }\n        if (phiLabels.size() > 0) {\n            target.phiLabels = phiLabels;\n        }\n\n        return target;\n    }\n\n    /**\n     * issue 63\n     * <pre>\n     * L1:\n     *    STMTs\n     * L2:\n     *    RETURN\n     * L1~L2 > L2 Exception\n     * </pre>\n     * <p/>\n     * fix to\n     * <p/>\n     * <pre>\n     * L1:\n     *    STMTs\n     * L2:\n     *    RETURN\n     * L3:\n     *    goto L2\n     * L1~L2 > L3 Exception\n     * </pre>\n     */\n    private void fixExceptionHandlers() {\n        if (dexCodeNode.tryStmts == null) {\n            return;\n        }\n        Queue<Integer> q = new LinkedList<>();\n        Set<Integer> handlers = new TreeSet<>();\n        for (TryCatchNode tcb : dexCodeNode.tryStmts) {\n            for (DexLabel h : tcb.handler) {\n                int index = indexOf(h);\n                q.add(index + 1); // add the next insn after label\n                handlers.add(index);\n            }\n        }\n\n        q.add(0);\n\n        Map<Integer, DexLabel> needChange = new HashMap<>();\n\n        BitSet access = new BitSet(insnList.size());\n        while (!q.isEmpty()) {\n            Integer key = q.poll();\n            int index = key;\n            if (access.get(index)) {\n                continue;\n            } else {\n                access.set(index);\n            }\n            if (handlers.contains(key)) { // the cfg goes to a exception handler\n                needChange.put(key, null);\n            }\n            DexStmtNode node = insnList.get(key);\n            if (node.op == null) {\n                q.add(index + 1);\n            } else {\n                Op op = node.op;\n                if (op.canContinue()) {\n                    q.add(index + 1);\n                }\n                if (op.canBranch()) {\n                    JumpStmtNode jump = (JumpStmtNode) node;\n                    q.add(indexOf(jump.label));\n                }\n                if (op.canSwitch()) {\n                    for (DexLabel dexLabel : ((BaseSwitchStmtNode) node).labels) {\n                        q.add(indexOf(dexLabel));\n                    }\n                }\n            }\n        }\n\n        if (needChange.size() > 0) {\n            for (TryCatchNode tcb : dexCodeNode.tryStmts) {\n                DexLabel[] handler = tcb.handler;\n                for (int i = 0; i < handler.length; i++) {\n                    DexLabel h = handler[i];\n                    int index = indexOf(h);\n                    if (needChange.containsKey(index)) {\n                        DexLabel n = needChange.get(index);\n                        if (n == null) {\n                            n = new DexLabel();\n                            needChange.put(index, n);\n                            DexLabelStmtNode dexStmtNode = new DexLabelStmtNode(n);\n                            dexStmtNode.__index = insnList.size();\n                            insnList.add(dexStmtNode);\n                            labelMap.put(n, dexStmtNode);\n                            JumpStmtNode jumpStmtNode = new JumpStmtNode(Op.GOTO, 0, 0, h);\n                            jumpStmtNode.__index = insnList.size();\n                            insnList.add(jumpStmtNode);\n                        }\n                        handler[i] = n;\n                    }\n                }\n            }\n        }\n    }\n\n    private void initExceptionHandlers(DexCodeNode dexCodeNode, BitSet[] exBranch, BitSet handlers) {\n        if (dexCodeNode.tryStmts != null) {\n            for (TryCatchNode tcb : dexCodeNode.tryStmts) {\n                for (DexLabel h : tcb.handler) {\n                    handlers.set(indexOf(h));\n                }\n                boolean hasEx = false;\n                int endIndex = indexOf(tcb.end);\n                for (int p = indexOf(tcb.start) + 1; p < endIndex; p++) {\n                    DexStmtNode stmt = insnList.get(p);\n                    if (stmt.op != null && stmt.op.canThrow()) {\n                        hasEx = true;\n                        BitSet x = exBranch[p];\n                        if (x == null) {\n                            x = exBranch[p] = new BitSet(insnList.size());\n                        }\n                        for (DexLabel h : tcb.handler) {\n                            int hIndex = indexOf(h);\n                            x.set(hIndex);\n                            parentCount[hIndex]++;\n                        }\n                    }\n                }\n                if (hasEx) {\n                    target.traps.add(new Trap(getLabel(tcb.start), getLabel(tcb.end), getLabels(tcb.handler),\n                            tcb.type));\n                }\n            }\n        }\n    }\n\n    private void addPhi(DvmValue v, Set<com.googlecode.dex2jar.ir.expr.Value> phiValues, List<AssignStmt> phis) {\n        if (v != null) {\n            if (v.local != null) {\n                if (v.parent != null) {\n                    phiValues.add(getLocal(v.parent));\n                }\n                if (v.otherParent != null) {\n                    for (DvmValue v2 : v.otherParent) {\n                        phiValues.add(getLocal(v2));\n                    }\n                }\n                if (phiValues.size() > 0) {\n                    phis.add(Stmts.nAssign(v.local, Exprs\n                            .nPhi(phiValues.toArray(new com.googlecode.dex2jar.ir.expr.Value[phiValues.size()]))));\n                    phiValues.clear();\n                }\n            }\n        }\n    }\n\n    Local getLocal(DvmValue value) {\n        Local local = value.local;\n        if (local == null) {\n            local = value.local = newLocal();\n        }\n        return local;\n    }\n\n    private void addToQueue(Queue<DvmValue> queue, DvmValue v) {\n        if (v != null) {\n            if (v.local != null) {\n                if (v.parent != null) {\n                    if (v.parent.local == null) {\n                        queue.add(v.parent);\n                    }\n                }\n                if (v.otherParent != null) {\n                    for (DvmValue v2 : v.otherParent) {\n                        if (v2.local == null) {\n                            queue.add(v2);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private void setCurrentEmit(int index) {\n        currentEmit = emitStmts[index];\n        if (currentEmit == null) {\n            currentEmit = emitStmts[index] = new ArrayList<>(1);\n        }\n    }\n\n    private void dfs(BitSet[] exBranch, BitSet handlers, BitSet access, DvmInterpreter<DvmValue> interpreter) {\n        currentEmit = preEmit;\n\n        Dex2IrFrame first = initFirstFrame(dexCodeNode, target);\n        if (parentCount[0] > 1) {\n            merge(first, 0);\n        } else {\n            frames[0] = first;\n        }\n        Stack<DexStmtNode> stack = new Stack<>();\n        stack.push(insnList.get(0));\n        Dex2IrFrame tmp = new Dex2IrFrame(dexCodeNode.totalRegister);\n\n\n        while (!stack.isEmpty()) {\n            DexStmtNode p = stack.pop();\n            int index = p.__index;\n            if (!access.get(index)) {\n                access.set(index);\n            } else {\n                continue;\n            }\n            Dex2IrFrame frame = frames[index];\n            setCurrentEmit(index);\n\n            if (p instanceof DexLabelStmtNode) {\n                emit(getLabel(((DexLabelStmtNode) p).label));\n                if (handlers.get(index)) {\n                    Local ex = newLocal();\n                    emit(Stmts.nIdentity(ex, Exprs.nExceptionRef(\"Ljava/lang/Throwable;\")));\n                    frame.setTmp(new DvmValue(ex));\n                }\n            }\n            BitSet ex = exBranch[index];\n            if (ex != null) {\n                for (int i = ex.nextSetBit(0); i >= 0; i = ex.nextSetBit(i + 1)) {\n                    merge(frame, i);\n                    stack.push(insnList.get(i));\n                }\n            }\n\n            tmp.init(frame);\n            try {\n                if (p.op != null) {\n                    switch (p.op) {\n                        case RETURN_VOID:\n                            emit(nReturnVoid());\n                            break;\n                        case GOTO:\n                        case GOTO_16:\n                        case GOTO_32:\n                            emit(nGoto(getLabel(((JumpStmtNode) p).label)));\n                            break;\n                        case NOP:\n                            emit(nNop());\n                            break;\n                        case BAD_OP:\n                            emit(nThrow(nInvokeNew(new Value[]{nString(\"bad dex opcode\")}, new String[]{\n                                            \"Ljava/lang/String;\"},\n                                    \"Ljava/lang/VerifyError;\")));\n                            break;\n                        default:\n                            tmp.execute(p, interpreter);\n                            break;\n                    }\n                }\n            } catch (Exception exception) {\n                throw new RuntimeException(\"Fail on Op \" + p.op + \" index \" + index, exception);\n            }\n\n\n            if (p.op != null) {\n                Op op = p.op;\n                if (op.canBranch()) {\n                    JumpStmtNode jump = (JumpStmtNode) p;\n                    int targetIndex = indexOf(jump.label);\n                    stack.push(insnList.get(targetIndex));\n                    merge(tmp, targetIndex);\n                }\n                if (op.canSwitch()) {\n                    BaseSwitchStmtNode switchStmtNode = (BaseSwitchStmtNode) p;\n                    for (DexLabel label : switchStmtNode.labels) {\n                        int targetIndex = indexOf(label);\n                        stack.push(insnList.get(targetIndex));\n                        merge(tmp, targetIndex);\n                    }\n                }\n                if (op.canContinue()) {\n                    stack.push(insnList.get(index + 1));\n                    merge(tmp, index + 1);\n                }\n            } else {\n\n                stack.push(insnList.get(index + 1));\n                merge(tmp, index + 1);\n\n            }\n            // cleanup frame it is useless\n            if (parentCount[index] <= 1) {\n                frames[index] = null;\n            }\n\n        }\n\n    }\n\n    private void relate(DvmValue parent, DvmValue child) {\n        if (child.parent == null) {\n            child.parent = parent;\n        } else if (child.parent == parent) {\n            //\n        } else {\n            if (child.otherParent == null) {\n                child.otherParent = new HashSet<>(5);\n            }\n            child.otherParent.add(parent);\n        }\n    }\n\n    void merge(Dex2IrFrame src, int dst) {\n        Dex2IrFrame distFrame = frames[dst];\n        if (distFrame == null) {\n            distFrame = frames[dst] = new Dex2IrFrame(dexCodeNode.totalRegister);\n        }\n        if (parentCount[dst] > 1) {\n            for (int i = 0; i < src.getTotalRegisters(); i++) {\n                DvmValue p = src.getReg(i);\n                DvmValue q = distFrame.getReg(i);\n                if (p != null) {\n                    if (q == null) {\n                        q = new DvmValue();\n                        distFrame.setReg(i, q);\n                    }\n                    relate(p, q);\n                }\n            }\n        } else {\n            distFrame.init(src);\n        }\n    }\n\n    private Local newLocal() {\n        Local thiz = Exprs.nLocal(target.locals.size());\n        target.locals.add(thiz);\n        return thiz;\n    }\n\n    void emit(Stmt stmt) {\n        currentEmit.add(stmt);\n    }\n\n    private Dex2IrFrame initFirstFrame(DexCodeNode methodNode, IrMethod target) {\n        Dex2IrFrame first = new Dex2IrFrame(methodNode.totalRegister);\n        int x = methodNode.totalRegister - methodArgCount(target.args);\n        if (!target.isStatic) {// not static\n            Local thiz = newLocal();\n            emit(Stmts.nIdentity(thiz, Exprs.nThisRef(target.owner)));\n            first.setReg(x - 1, new DvmValue(thiz));\n        }\n        for (int i = 0; i < target.args.length; i++) {\n            Local p = newLocal();\n            emit(Stmts.nIdentity(p, Exprs.nParameterRef(target.args[i], i)));\n            first.setReg(x, new DvmValue(p));\n            x += sizeofType(target.args[i]);\n        }\n\n        if (initAllToZero) {\n            for (int i = 0; i < first.getTotalRegisters(); i++) {\n                if (first.getReg(i) == null) {\n                    Local p = newLocal();\n                    emit(nAssign(p, nInt(0)));\n                    first.setReg(i, new DvmValue(p));\n                }\n            }\n        }\n\n        return first;\n    }\n\n    private DvmInterpreter<DvmValue> buildInterpreter() {\n        return new DvmInterpreter<DvmValue>() {\n            DvmValue b(com.googlecode.dex2jar.ir.expr.Value value) {\n                Local local = newLocal();\n                emit(Stmts.nAssign(local, value));\n                return new DvmValue(local);\n            }\n\n            @Override\n            public DvmValue newOperation(DexStmtNode insn) {\n                switch (insn.op) {\n                    case CONST:\n                    case CONST_16:\n                    case CONST_4:\n                    case CONST_HIGH16:\n                        return b(nInt((Integer) ((ConstStmtNode) insn).value));\n                    case CONST_WIDE:\n                    case CONST_WIDE_16:\n                    case CONST_WIDE_32:\n                    case CONST_WIDE_HIGH16:\n                        return b(nLong((Long) ((ConstStmtNode) insn).value));\n                    case CONST_CLASS:\n                        return b(nType((DexType) ((ConstStmtNode) insn).value));\n                    case CONST_STRING:\n                    case CONST_STRING_JUMBO:\n                        return b(nString((String) ((ConstStmtNode) insn).value));\n                    case SGET:\n                    case SGET_BOOLEAN:\n                    case SGET_BYTE:\n                    case SGET_CHAR:\n                    case SGET_OBJECT:\n                    case SGET_SHORT:\n                    case SGET_WIDE:\n                        Field field = ((FieldStmtNode) insn).field;\n                        return b(nStaticField(field.getOwner(), field.getName(), field.getType()));\n                    case NEW_INSTANCE:\n                        return b(nNew(((TypeStmtNode) insn).type));\n                    default:\n                }\n                return null;\n            }\n\n            @Override\n            public DvmValue copyOperation(DexStmtNode insn, DvmValue value) {\n                if (value == null) {\n                    emitNotFindOperand(insn);\n                    return b(nInt(0));\n                }\n                return b(getLocal(value));\n            }\n\n            @Override\n            public DvmValue unaryOperation(DexStmtNode insn, DvmValue value) {\n                if (value == null) {\n                    emitNotFindOperand(insn);\n                    return b(nInt(0));\n                }\n                Local local = getLocal(value);\n                switch (insn.op) {\n                    case NOT_INT:\n                        return b(nNot(local, \"I\"));\n                    case NOT_LONG:\n                        return b(nNot(local, \"J\"));\n\n                    case NEG_DOUBLE:\n                        return b(nNeg(local, \"D\"));\n\n                    case NEG_FLOAT:\n                        return b(nNeg(local, \"F\"));\n\n                    case NEG_INT:\n                        return b(nNeg(local, \"I\"));\n\n                    case NEG_LONG:\n                        return b(nNeg(local, \"J\"));\n                    case INT_TO_BYTE:\n                        return b(nCast(local, \"I\", \"B\"));\n\n                    case INT_TO_CHAR:\n                        return b(nCast(local, \"I\", \"C\"));\n\n                    case INT_TO_DOUBLE:\n                        return b(nCast(local, \"I\", \"D\"));\n\n                    case INT_TO_FLOAT:\n                        return b(nCast(local, \"I\", \"F\"));\n\n                    case INT_TO_LONG:\n                        return b(nCast(local, \"I\", \"J\"));\n\n                    case INT_TO_SHORT:\n                        return b(nCast(local, \"I\", \"S\"));\n\n                    case FLOAT_TO_DOUBLE:\n                        return b(nCast(local, \"F\", \"D\"));\n\n                    case FLOAT_TO_INT:\n                        return b(nCast(local, \"F\", \"I\"));\n\n                    case FLOAT_TO_LONG:\n                        return b(nCast(local, \"F\", \"J\"));\n\n                    case DOUBLE_TO_FLOAT:\n                        return b(nCast(local, \"D\", \"F\"));\n\n                    case DOUBLE_TO_INT:\n                        return b(nCast(local, \"D\", \"I\"));\n\n                    case DOUBLE_TO_LONG:\n                        return b(nCast(local, \"D\", \"J\"));\n\n                    case LONG_TO_DOUBLE:\n                        return b(nCast(local, \"J\", \"D\"));\n\n                    case LONG_TO_FLOAT:\n                        return b(nCast(local, \"J\", \"F\"));\n\n                    case LONG_TO_INT:\n                        return b(nCast(local, \"J\", \"I\"));\n\n                    case ARRAY_LENGTH:\n                        return b(nLength(local));\n\n                    case IF_EQZ:\n                        emit(nIf(Exprs\n                                .nEq(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_GEZ:\n                        emit(nIf(Exprs.nGe(local, nInt(0), \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_GTZ:\n                        emit(nIf(Exprs.nGt(local, nInt(0), \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_LEZ:\n                        emit(nIf(Exprs.nLe(local, nInt(0), \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_LTZ:\n                        emit(nIf(Exprs.nLt(local, nInt(0), \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_NEZ:\n                        emit(nIf(Exprs\n                                .nNe(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case PACKED_SWITCH:\n                    case SPARSE_SWITCH:\n                        DexLabel[] labels = ((BaseSwitchStmtNode) insn).labels;\n                        LabelStmt[] lss = new LabelStmt[labels.length];\n                        for (int i = 0; i < labels.length; i++) {\n                            lss[i] = getLabel(labels[i]);\n                        }\n                        LabelStmt d = new LabelStmt();\n                        if (insn.op == Op.PACKED_SWITCH) {\n                            emit(nTableSwitch(local, ((PackedSwitchStmtNode) insn).first_case, lss, d));\n                        } else {\n                            emit(nLookupSwitch(local, ((SparseSwitchStmtNode) insn).cases, lss, d));\n                        }\n                        emit(d);\n                        return null;\n\n                    case SPUT:\n                    case SPUT_BOOLEAN:\n                    case SPUT_BYTE:\n                    case SPUT_CHAR:\n                    case SPUT_OBJECT:\n                    case SPUT_SHORT:\n                    case SPUT_WIDE: {\n                        Field field = ((FieldStmtNode) insn).field;\n                        emit(nAssign(nStaticField(field.getOwner(), field.getName(), field.getType()), local));\n                        return null;\n                    }\n                    case IGET:\n                    case IGET_BOOLEAN:\n                    case IGET_BYTE:\n                    case IGET_CHAR:\n                    case IGET_OBJECT:\n                    case IGET_SHORT:\n                    case IGET_WIDE: {\n                        Field field = ((FieldStmtNode) insn).field;\n                        return b(nField(local, field.getOwner(), field.getName(), field.getType()));\n                    }\n                    case INSTANCE_OF:\n                        return b(nInstanceOf(local, ((TypeStmtNode) insn).type));\n\n                    case NEW_ARRAY:\n                        return b(nNewArray(((TypeStmtNode) insn).type.substring(1), local));\n\n                    case CHECK_CAST:\n                        return b(nCheckCast(local, ((TypeStmtNode) insn).type));\n\n                    case MONITOR_ENTER:\n                        emit(nLock(local));\n                        return null;\n                    case MONITOR_EXIT:\n                        emit(nUnLock(local));\n                        return null;\n                    case THROW:\n                        emit(nThrow(local));\n                        return null;\n                    case ADD_INT_LIT16:\n                    case ADD_INT_LIT8:\n                        return b(nAdd(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case RSUB_INT_LIT8:\n                    case RSUB_INT://\n                        return b(nSub(nInt(((Stmt2R1NNode) insn).content), local, \"I\"));\n\n                    case MUL_INT_LIT8:\n                    case MUL_INT_LIT16:\n                        return b(nMul(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case DIV_INT_LIT16:\n                    case DIV_INT_LIT8:\n                        return b(nDiv(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case REM_INT_LIT16:\n                    case REM_INT_LIT8:\n                        return b(nRem(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case AND_INT_LIT16:\n                    case AND_INT_LIT8:\n                        return b(nAnd(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? \"I\" : TypeClass.ZI.name));\n\n                    case OR_INT_LIT16:\n                    case OR_INT_LIT8:\n                        return b(nOr(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? \"I\" : TypeClass.ZI.name));\n\n                    case XOR_INT_LIT16:\n                    case XOR_INT_LIT8:\n                        return b(nXor(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? \"I\" : TypeClass.ZI.name));\n\n                    case SHL_INT_LIT8:\n                        return b(nShl(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case SHR_INT_LIT8:\n                        return b(nShr(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n\n                    case USHR_INT_LIT8:\n                        return b(nUshr(local, nInt(((Stmt2R1NNode) insn).content), \"I\"));\n                    case FILL_ARRAY_DATA:\n                        emit(nFillArrayData(local, nArrayValue(((FillArrayDataStmtNode) insn).array)));\n                        return null;\n                }\n                throw new RuntimeException();\n            }\n\n            @Override\n            public DvmValue binaryOperation(DexStmtNode insn, DvmValue value1, DvmValue value2) {\n                if (value1 == null || value2 == null) {\n                    emitNotFindOperand(insn);\n                    return b(nInt(0));\n                }\n                Local local1 = getLocal(value1);\n                Local local2 = getLocal(value2);\n                switch (insn.op) {\n                    case AGET:\n                        return b(nArray(local1, local2, TypeClass.IF.name));\n\n                    case AGET_BOOLEAN:\n                        return b(nArray(local1, local2, \"Z\"));\n\n                    case AGET_BYTE:\n                        return b(nArray(local1, local2, \"B\"));\n\n                    case AGET_CHAR:\n                        return b(nArray(local1, local2, \"C\"));\n\n                    case AGET_OBJECT:\n                        return b(nArray(local1, local2, \"L\"));\n\n                    case AGET_SHORT:\n                        return b(nArray(local1, local2, \"S\"));\n\n                    case AGET_WIDE:\n                        return b(nArray(local1, local2, TypeClass.JD.name));\n\n                    case CMP_LONG:\n                        return b(nLCmp(local1, local2));\n\n                    case CMPG_DOUBLE:\n                        return b(nDCmpg(local1, local2));\n\n                    case CMPG_FLOAT:\n                        return b(nFCmpg(local1, local2));\n\n                    case CMPL_DOUBLE:\n                        return b(nDCmpl(local1, local2));\n\n                    case CMPL_FLOAT:\n                        return b(nFCmpl(local1, local2));\n\n                    case ADD_DOUBLE:\n                        return b(nAdd(local1, local2, \"D\"));\n\n                    case ADD_FLOAT:\n                        return b(nAdd(local1, local2, \"F\"));\n\n                    case ADD_INT:\n                        return b(nAdd(local1, local2, \"I\"));\n\n                    case ADD_LONG:\n                        return b(nAdd(local1, local2, \"J\"));\n\n                    case SUB_DOUBLE:\n                        return b(nSub(local1, local2, \"D\"));\n\n                    case SUB_FLOAT:\n                        return b(nSub(local1, local2, \"F\"));\n\n                    case SUB_INT:\n                        return b(nSub(local1, local2, \"I\"));\n\n                    case SUB_LONG:\n                        return b(nSub(local1, local2, \"J\"));\n\n                    case MUL_DOUBLE:\n                        return b(nMul(local1, local2, \"D\"));\n\n                    case MUL_FLOAT:\n                        return b(nMul(local1, local2, \"F\"));\n\n                    case MUL_INT:\n                        return b(nMul(local1, local2, \"I\"));\n\n                    case MUL_LONG:\n                        return b(nMul(local1, local2, \"J\"));\n\n                    case DIV_DOUBLE:\n                        return b(nDiv(local1, local2, \"D\"));\n\n                    case DIV_FLOAT:\n                        return b(nDiv(local1, local2, \"F\"));\n\n                    case DIV_INT:\n                        return b(nDiv(local1, local2, \"I\"));\n\n                    case DIV_LONG:\n                        return b(nDiv(local1, local2, \"J\"));\n\n                    case REM_DOUBLE:\n                        return b(nRem(local1, local2, \"D\"));\n\n                    case REM_FLOAT:\n                        return b(nRem(local1, local2, \"F\"));\n\n                    case REM_INT:\n                        return b(nRem(local1, local2, \"I\"));\n\n                    case REM_LONG:\n                        return b(nRem(local1, local2, \"J\"));\n\n                    case AND_INT:\n                        return b(nAnd(local1, local2, TypeClass.ZI.name));\n\n                    case AND_LONG:\n                        return b(nAnd(local1, local2, \"J\"));\n\n                    case OR_INT:\n                        return b(nOr(local1, local2, TypeClass.ZI.name));\n\n                    case OR_LONG:\n                        return b(nOr(local1, local2, \"J\"));\n\n                    case XOR_INT:\n                        return b(nXor(local1, local2, TypeClass.ZI.name));\n\n                    case XOR_LONG:\n                        return b(nXor(local1, local2, \"J\"));\n\n                    case SHL_INT:\n                        return b(nShl(local1, local2, \"I\"));\n\n                    case SHL_LONG:\n                        return b(nShl(local1, local2, \"J\"));\n\n                    case SHR_INT:\n                        return b(nShr(local1, local2, \"I\"));\n\n                    case SHR_LONG:\n                        return b(nShr(local1, local2, \"J\"));\n\n                    case USHR_INT:\n                        return b(nUshr(local1, local2, \"I\"));\n\n                    case USHR_LONG:\n                        return b(nUshr(local1, local2, \"J\"));\n\n                    case IF_EQ:\n                        emit(nIf(Exprs\n                                .nEq(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_GE:\n                        emit(nIf(Exprs.nGe(local1, local2, \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_GT:\n                        emit(nIf(Exprs.nGt(local1, local2, \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_LE:\n                        emit(nIf(Exprs.nLe(local1, local2, \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_LT:\n                        emit(nIf(Exprs.nLt(local1, local2, \"I\"), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IF_NE:\n                        emit(nIf(Exprs\n                                .nNe(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));\n                        return null;\n\n                    case IPUT:\n                    case IPUT_BOOLEAN:\n                    case IPUT_BYTE:\n                    case IPUT_CHAR:\n                    case IPUT_OBJECT:\n                    case IPUT_SHORT:\n                    case IPUT_WIDE:\n                        Field field = ((FieldStmtNode) insn).field;\n                        emit(nAssign(nField(local1, field.getOwner(), field.getName(), field.getType()), local2));\n                        return null;\n\n                    case ADD_DOUBLE_2ADDR:\n                        return b(nAdd(local1, local2, \"D\"));\n\n                    case ADD_FLOAT_2ADDR:\n                        return b(nAdd(local1, local2, \"F\"));\n\n                    case ADD_INT_2ADDR:\n                        return b(nAdd(local1, local2, \"I\"));\n\n                    case ADD_LONG_2ADDR:\n                        return b(nAdd(local1, local2, \"J\"));\n\n                    case SUB_DOUBLE_2ADDR:\n                        return b(nSub(local1, local2, \"D\"));\n\n                    case SUB_FLOAT_2ADDR:\n                        return b(nSub(local1, local2, \"F\"));\n\n                    case SUB_INT_2ADDR:\n                        return b(nSub(local1, local2, \"I\"));\n\n                    case SUB_LONG_2ADDR:\n                        return b(nSub(local1, local2, \"J\"));\n\n                    case MUL_DOUBLE_2ADDR:\n                        return b(nMul(local1, local2, \"D\"));\n\n                    case MUL_FLOAT_2ADDR:\n                        return b(nMul(local1, local2, \"F\"));\n\n                    case MUL_INT_2ADDR:\n                        return b(nMul(local1, local2, \"I\"));\n\n                    case MUL_LONG_2ADDR:\n                        return b(nMul(local1, local2, \"J\"));\n\n                    case DIV_DOUBLE_2ADDR:\n                        return b(nDiv(local1, local2, \"D\"));\n\n                    case DIV_FLOAT_2ADDR:\n                        return b(nDiv(local1, local2, \"F\"));\n\n                    case DIV_INT_2ADDR:\n                        return b(nDiv(local1, local2, \"I\"));\n\n                    case DIV_LONG_2ADDR:\n                        return b(nDiv(local1, local2, \"J\"));\n\n                    case REM_DOUBLE_2ADDR:\n                        return b(nRem(local1, local2, \"D\"));\n\n                    case REM_FLOAT_2ADDR:\n                        return b(nRem(local1, local2, \"F\"));\n\n                    case REM_INT_2ADDR:\n                        return b(nRem(local1, local2, \"I\"));\n\n                    case REM_LONG_2ADDR:\n                        return b(nRem(local1, local2, \"J\"));\n\n                    case AND_INT_2ADDR:\n                        return b(nAnd(local1, local2, TypeClass.ZI.name));\n\n                    case AND_LONG_2ADDR:\n                        return b(nAnd(local1, local2, \"J\"));\n\n                    case OR_INT_2ADDR:\n                        return b(nOr(local1, local2, TypeClass.ZI.name));\n\n                    case OR_LONG_2ADDR:\n                        return b(nOr(local1, local2, \"J\"));\n\n                    case XOR_INT_2ADDR:\n                        return b(nXor(local1, local2, TypeClass.ZI.name));\n\n                    case XOR_LONG_2ADDR:\n                        return b(nXor(local1, local2, \"J\"));\n\n                    case SHL_INT_2ADDR:\n                        return b(nShl(local1, local2, \"I\"));\n\n                    case SHL_LONG_2ADDR:\n                        return b(nShl(local1, local2, \"J\"));\n\n                    case SHR_INT_2ADDR:\n                        return b(nShr(local1, local2, \"I\"));\n\n                    case SHR_LONG_2ADDR:\n                        return b(nShr(local1, local2, \"J\"));\n\n                    case USHR_INT_2ADDR:\n                        return b(nUshr(local1, local2, \"I\"));\n\n                    case USHR_LONG_2ADDR:\n                        return b(nUshr(local1, local2, \"J\"));\n\n                }\n                throw new RuntimeException();\n            }\n\n            @Override\n            public DvmValue ternaryOperation(DexStmtNode insn, DvmValue value1, DvmValue value2, DvmValue value3) {\n                if (value1 == null || value2 == null || value3 == null) {\n                    emitNotFindOperand(insn);\n                    return b(nInt(0));\n                }\n                Local localArray = getLocal(value1);\n                Local localIndex = getLocal(value2);\n                Local localValue = getLocal(value3);\n                switch (insn.op) {\n                    case APUT:\n                        emit(nAssign(nArray(localArray, localIndex, TypeClass.IF.name), localValue));\n                        break;\n                    case APUT_BOOLEAN:\n                        emit(nAssign(nArray(localArray, localIndex, \"Z\"), localValue));\n                        break;\n                    case APUT_BYTE:\n                        emit(nAssign(nArray(localArray, localIndex, \"B\"), localValue));\n                        break;\n                    case APUT_CHAR:\n                        emit(nAssign(nArray(localArray, localIndex, \"C\"), localValue));\n                        break;\n                    case APUT_OBJECT:\n                        emit(nAssign(nArray(localArray, localIndex, \"L\"), localValue));\n                        break;\n                    case APUT_SHORT:\n                        emit(nAssign(nArray(localArray, localIndex, \"S\"), localValue));\n                        break;\n                    case APUT_WIDE:\n                        emit(nAssign(nArray(localArray, localIndex, TypeClass.JD.name), localValue));\n                        break;\n                }\n                return null;\n            }\n\n            @Override\n            public DvmValue naryOperation(DexStmtNode insn, List<? extends DvmValue> values) {\n                for (DvmValue v : values) {\n                    if (v == null) {\n                        emitNotFindOperand(insn);\n                        return b(nInt(0));\n                    }\n                }\n\n\n                switch (insn.op) {\n                    case FILLED_NEW_ARRAY:\n                    case FILLED_NEW_ARRAY_RANGE:\n                        DvmValue value = new DvmValue();\n                        FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;\n                        String type = filledNewArrayStmtNode.type;\n\n                        String elem = type.substring(1);\n                        emit(nAssign(getLocal(value), nNewArray(elem, nInt(values.size()))));\n                        for (int i = 0; i < values.size(); i++) {\n                            emit(nAssign(nArray(getLocal(value), nInt(i), elem), getLocal(values.get(i))));\n                        }\n\n                        return value;\n                    case INVOKE_CUSTOM:\n                    case INVOKE_CUSTOM_RANGE: {\n                        Value[] vs = new Value[values.size()];\n                        for (int i = 0; i < vs.length; i++) {\n                            vs[i] = getLocal(values.get(i));\n                        }\n                        MethodCustomStmtNode n = (MethodCustomStmtNode) insn;\n                        Value invoke = nInvokeCustom(vs, n.name, n.proto, n.bsm, n.bsmArgs);\n                        if (\"V\".equals(n.getProto().getReturnType())) {\n                            emit(nVoidInvoke(invoke));\n                            return null;\n                        } else {\n                            return b(invoke);\n                        }\n                    }\n                    case INVOKE_POLYMORPHIC:\n                    case INVOKE_POLYMORPHIC_RANGE: {\n                        Value[] vs = new Value[values.size()];\n                        for (int i = 0; i < vs.length; i++) {\n                            vs[i] = getLocal(values.get(i));\n                        }\n                        MethodPolymorphicStmtNode n = (MethodPolymorphicStmtNode) insn;\n                        Value invoke = nInvokePolymorphic(vs, n.proto, n.method);\n                        if (\"V\".equals(n.getProto().getReturnType())) {\n                            emit(nVoidInvoke(invoke));\n                            return null;\n                        } else {\n                            return b(invoke);\n                        }\n                    }\n                    default:\n                        Op op = insn.op;\n                        Value[] vs = new Value[values.size()];\n                        for (int i = 0; i < vs.length; i++) {\n                            vs[i] = getLocal(values.get(i));\n                        }\n\n                        Method method = ((MethodStmtNode) insn).method;\n                        Value invoke = null;\n                        switch (op) {\n                            case INVOKE_VIRTUAL_RANGE:\n                            case INVOKE_VIRTUAL:\n                                invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method\n                                                .getParameterTypes(),\n                                        method.getReturnType());\n                                break;\n                            case INVOKE_SUPER_RANGE:\n                            case INVOKE_DIRECT_RANGE:\n                            case INVOKE_SUPER:\n                            case INVOKE_DIRECT:\n                                invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method\n                                                .getParameterTypes(),\n                                        method.getReturnType());\n                                break;\n                            case INVOKE_STATIC_RANGE:\n                            case INVOKE_STATIC:\n                                invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method\n                                                .getParameterTypes(),\n                                        method.getReturnType());\n                                break;\n                            case INVOKE_INTERFACE_RANGE:\n                            case INVOKE_INTERFACE:\n                                invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method\n                                                .getParameterTypes(),\n                                        method.getReturnType());\n                                break;\n                            default:\n                                throw new RuntimeException();\n                        }\n                        if (\"V\".equals(method.getReturnType())) {\n                            emit(nVoidInvoke(invoke));\n                            return null;\n                        } else {\n                            return b(invoke);\n                        }\n\n                }\n\n\n            }\n\n            void emitNotFindOperand(DexStmtNode insn) {\n                String msg;\n                switch (insn.op) {\n                    case MOVE_RESULT:\n                    case MOVE_RESULT_OBJECT:\n                    case MOVE_RESULT_WIDE:\n                        msg = \"can't get operand(s) for \" + insn.op + \", wrong position ?\";\n                        break;\n                    default:\n                        msg = \"can't get operand(s) for \" + insn.op + \", out-of-range or not initialized ?\";\n                        break;\n                }\n\n                System.err.println(\"WARN: \" + msg);\n                emit(nThrow(nInvokeNew(new Value[]{nString(\"d2j: \" + msg)},\n                        new String[]{\"Ljava/lang/String;\"}, \"Ljava/lang/VerifyError;\")));\n            }\n\n            @Override\n            public void returnOperation(DexStmtNode insn, DvmValue value) {\n                if (value == null) {\n                    emitNotFindOperand(insn);\n                    return;\n                }\n\n                emit(nReturn(getLocal(value)));\n            }\n        };\n    }\n\n    private LabelStmt[] getLabels(DexLabel[] handler) {\n        LabelStmt[] ts = new LabelStmt[handler.length];\n        for (int i = 0; i < handler.length; i++) {\n            ts[i] = getLabel(handler[i]);\n        }\n        return ts;\n    }\n\n    LabelStmt getLabel(DexLabel label) {\n        LabelStmt ls = map.get(label);\n        if (ls == null) {\n            ls = Stmts.nLabel();\n            map.put(label, ls);\n        }\n        return ls;\n    }\n\n    private void initParentCount(int[] parentCount) {\n        parentCount[0] = 1; // first stmt always have one parent\n        for (DexStmtNode p : insnList) {\n            Op op = p.op;\n            if (op == null) {\n                if (p.__index < parentCount.length - 1) { // not the last label\n                    parentCount[p.__index + 1]++;\n                }\n            } else {\n                if (op.canBranch()) {\n                    parentCount[indexOf(((JumpStmtNode) p).label)]++;\n                }\n                if (op.canSwitch()) {\n                    BaseSwitchStmtNode switchStmtNode = (BaseSwitchStmtNode) p;\n                    for (DexLabel label : switchStmtNode.labels) {\n                        parentCount[indexOf(label)]++;\n                    }\n                }\n                if (op.canContinue()) {\n                    parentCount[p.__index + 1]++;\n                }\n            }\n        }\n    }\n\n    int indexOf(DexLabel label) {\n        DexLabelStmtNode dexLabelStmtNode = labelMap.get(label);\n        return dexLabelStmtNode.__index;\n    }\n\n    static class DvmValue {\n        public DvmValue parent;\n        public Set<DvmValue> otherParent;\n        Local local;\n\n        public DvmValue(Local thiz) {\n            this.local = thiz;\n        }\n\n        public DvmValue() {\n\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/converter/IR2JConverter.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.converter;\r\n\r\nimport com.googlecode.d2j.DexType;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Proto;\r\nimport com.googlecode.d2j.asm.LdcOptimizeAdapter;\r\nimport com.googlecode.d2j.dex.Dex2Asm;\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.Trap;\r\nimport com.googlecode.dex2jar.ir.expr.*;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E1Expr;\r\nimport com.googlecode.dex2jar.ir.expr.Value.E2Expr;\r\nimport com.googlecode.dex2jar.ir.expr.Value.EnExpr;\r\nimport com.googlecode.dex2jar.ir.expr.Value.VT;\r\nimport com.googlecode.dex2jar.ir.stmt.*;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt.ST;\r\nimport org.objectweb.asm.*;\r\n\r\nimport java.lang.reflect.Array;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\n@SuppressWarnings(\"incomplete-switch\")\r\npublic class IR2JConverter implements Opcodes {\r\n\r\n    private boolean optimizeSynchronized = false;\r\n\r\n    public IR2JConverter() {\r\n        super();\r\n    }\r\n\r\n    public IR2JConverter(boolean optimizeSynchronized) {\r\n        super();\r\n        this.optimizeSynchronized = optimizeSynchronized;\r\n    }\r\n\r\n    public void convert(IrMethod ir, MethodVisitor asm) {\r\n        mapLabelStmt(ir);\r\n        reBuildInstructions(ir, asm);\r\n        reBuildTryCatchBlocks(ir, asm);\r\n    }\r\n\r\n    private void mapLabelStmt(IrMethod ir) {\r\n        for (Stmt p : ir.stmts) {\r\n            if (p.st == ST.LABEL) {\r\n                LabelStmt labelStmt = (LabelStmt) p;\r\n                labelStmt.tag = new Label();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * an empty try-catch block will cause other crash, we check this by finding non-label stmts between\r\n     * {@link Trap#start} and {@link Trap#end}. if find we add the try-catch or we drop the try-catch.\r\n     *\r\n     * @param ir\r\n     * @param asm\r\n     */\r\n    private void reBuildTryCatchBlocks(IrMethod ir, MethodVisitor asm) {\r\n        for (Trap trap : ir.traps) {\r\n            boolean needAdd = false;\r\n            for (Stmt p = trap.start.getNext(); p != null && p != trap.end; p = p.getNext()) {\r\n                if (p.st != ST.LABEL) {\r\n                    needAdd = true;\r\n                    break;\r\n                }\r\n            }\r\n            if (needAdd) {\r\n                for (int i = 0; i < trap.handlers.length; i++) {\r\n                    String type = trap.types[i];\r\n                    asm.visitTryCatchBlock((Label) trap.start.tag, (Label) trap.end.tag, (Label) trap.handlers[i].tag,\r\n                            type == null ? null : toInternal(type));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    static String toInternal(String n) {\r\n        // TODO replace\r\n        return Type.getType(n).getInternalName();\r\n    }\r\n\r\n\r\n\r\n    private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {\r\n        asm = new LdcOptimizeAdapter(asm);\r\n        int maxLocalIndex = 0;\r\n        for (Local local : ir.locals) {\r\n            maxLocalIndex = Math.max(maxLocalIndex, local._ls_index);\r\n        }\r\n        Map<String, Integer> lockMap = new HashMap<String, Integer>();\r\n        for (Stmt st : ir.stmts) {\r\n            switch (st.st) {\r\n            case LABEL:\r\n                LabelStmt labelStmt = (LabelStmt) st;\r\n                Label label = (Label) labelStmt.tag;\r\n                asm.visitLabel(label);\r\n                if (labelStmt.lineNumber >= 0) {\r\n                    asm.visitLineNumber(labelStmt.lineNumber, label);\r\n                }\r\n                break;\r\n            case ASSIGN: {\r\n                E2Stmt e2 = (E2Stmt) st;\r\n                Value v1 = e2.op1;\r\n                Value v2 = e2.op2;\r\n                switch (v1.vt) {\r\n                case LOCAL:\r\n\r\n                    Local local = ((Local) v1);\r\n                    int i = local._ls_index;\r\n\r\n                    boolean skipOrg = false;\r\n                    if (v2.vt == VT.LOCAL && (i == ((Local) v2)._ls_index)) {// check for a=a\r\n                        skipOrg = true;\r\n                    } else if (v1.valueType.charAt(0) == 'I') {// check for IINC\r\n                        if (v2.vt == VT.ADD) {\r\n                            if (isLocalWithIndex(v2.getOp1(), i) && v2.getOp2().vt == VT.CONSTANT) { // a=a+1;\r\n                                int increment = (Integer) ((Constant) v2.getOp2()).value;\r\n                                if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {\r\n                                    asm.visitIincInsn(i, increment);\r\n                                    skipOrg = true;\r\n                                }\r\n                            } else if (isLocalWithIndex(v2.getOp2(), i) && v2.getOp1().vt == VT.CONSTANT) { // a=1+a;\r\n                                int increment = (Integer) ((Constant) v2.getOp1()).value;\r\n                                if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {\r\n                                    asm.visitIincInsn(i, increment);\r\n                                    skipOrg = true;\r\n                                }\r\n                            }\r\n                        } else if (v2.vt == VT.SUB) {\r\n                            if (isLocalWithIndex(v2.getOp1(), i) && v2.getOp2().vt == VT.CONSTANT) { // a=a-1;\r\n                                int increment = -(Integer) ((Constant) v2.getOp2()).value;\r\n                                if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {\r\n                                    asm.visitIincInsn(i, increment);\r\n                                    skipOrg = true;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                    if (!skipOrg) {\r\n                        accept(v2, asm);\r\n                        if (i >= 0) {\r\n                            asm.visitVarInsn(getOpcode(v1, ISTORE), i);\r\n                        } else if (!v1.valueType.equals(\"V\")) { // skip void type locals\r\n                            switch (v1.valueType.charAt(0)) {\r\n                            case 'J':\r\n                            case 'D':\r\n                                asm.visitInsn(POP2);\r\n                                break;\r\n                            default:\r\n                                asm.visitInsn(POP);\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                    break;\r\n                case STATIC_FIELD: {\r\n                    StaticFieldExpr fe = (StaticFieldExpr) v1;\r\n                    accept(v2, asm);\r\n                    insertI2x(v2.valueType, fe.type, asm);\r\n                    asm.visitFieldInsn(PUTSTATIC, toInternal(fe.owner), fe.name, fe.type);\r\n                    break;\r\n                }\r\n                case FIELD: {\r\n                    FieldExpr fe = (FieldExpr) v1;\r\n                    accept(fe.op, asm);\r\n                    accept(v2, asm);\r\n                    insertI2x(v2.valueType, fe.type, asm);\r\n                    asm.visitFieldInsn(PUTFIELD, toInternal(fe.owner), fe.name, fe.type);\r\n                    break;\r\n                }\r\n                case ARRAY:\r\n                    ArrayExpr ae = (ArrayExpr) v1;\r\n                    accept(ae.op1, asm);\r\n                    accept(ae.op2, asm);\r\n                    accept(v2, asm);\r\n                    String tp1 = ae.op1.valueType;\r\n                    String tp2 = ae.valueType;\r\n                    if (tp1.charAt(0) == '[') {\r\n                        String arrayElementType = tp1.substring(1);\r\n                        insertI2x(v2.valueType, arrayElementType, asm);\r\n                        asm.visitInsn(getOpcode(arrayElementType, IASTORE));\r\n                    } else {\r\n                        asm.visitInsn(getOpcode(tp2, IASTORE));\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n                break;\r\n            case IDENTITY: {\r\n                E2Stmt e2 = (E2Stmt) st;\r\n                if (e2.op2.vt == VT.EXCEPTION_REF) {\r\n                    int index = ((Local) e2.op1)._ls_index;\r\n                    if (index >= 0) {\r\n                        asm.visitVarInsn(ASTORE, index);\r\n                    } else {\r\n                        asm.visitInsn(POP);\r\n                    }\r\n                }\r\n            }\r\n                break;\r\n\r\n            case FILL_ARRAY_DATA:{\r\n                E2Stmt e2 = (E2Stmt) st;\r\n                if (e2.getOp2().vt == VT.CONSTANT) {\r\n                    Object arrayData = ((Constant) e2.getOp2()).value;\r\n                    int arraySize = Array.getLength(arrayData);\r\n                    String arrayValueType = e2.getOp1().valueType;\r\n                    String elementType;\r\n                    if (arrayValueType.charAt(0) == '[') {\r\n                        elementType = arrayValueType.substring(1);\r\n                    } else {\r\n                        elementType = \"I\";\r\n                    }\r\n                    int iastoreOP = getOpcode(elementType, IASTORE);\r\n                    accept(e2.getOp1(), asm);\r\n                    for (int i = 0; i < arraySize; i++) {\r\n                        asm.visitInsn(DUP);\r\n                        asm.visitLdcInsn(i);\r\n                        asm.visitLdcInsn(Array.get(arrayData, i));\r\n                        asm.visitInsn(iastoreOP);\r\n                    }\r\n                    asm.visitInsn(POP);\r\n                } else {\r\n                    FilledArrayExpr filledArrayExpr = (FilledArrayExpr) e2.getOp2();\r\n                    int arraySize = filledArrayExpr.ops.length;\r\n                    String arrayValueType = e2.getOp1().valueType;\r\n                    String elementType;\r\n                    if (arrayValueType.charAt(0) == '[') {\r\n                        elementType = arrayValueType.substring(1);\r\n                    } else {\r\n                        elementType = \"I\";\r\n                    }\r\n                    int iastoreOP = getOpcode(elementType, IASTORE);\r\n                    accept(e2.getOp1(), asm);\r\n                    for (int i = 0; i < arraySize; i++) {\r\n                        asm.visitInsn(DUP);\r\n                        asm.visitLdcInsn(i);\r\n                        accept(filledArrayExpr.ops[i], asm);\r\n                        asm.visitInsn(iastoreOP);\r\n                    }\r\n                    asm.visitInsn(POP);\r\n                }\r\n            }\r\n            break;\r\n            case GOTO:\r\n                asm.visitJumpInsn(GOTO, (Label) ((GotoStmt) st).target.tag);\r\n                break;\r\n            case IF:\r\n                reBuildJumpInstructions((IfStmt) st, asm);\r\n                break;\r\n            case LOCK: {\r\n                Value v = ((UnopStmt) st).op;\r\n                accept(v, asm);\r\n                if (optimizeSynchronized) {\r\n                    switch (v.vt) {\r\n                    case LOCAL:\r\n                        // FIXME do we have to disable local due to OptSyncTest ?\r\n                        // break;\r\n                    case CONSTANT: {\r\n                        String key;\r\n                        if (v.vt == VT.LOCAL) {\r\n                            key = \"L\" + ((Local) v)._ls_index;\r\n                        } else {\r\n                            key = \"C\" + ((Constant) v).value;\r\n                        }\r\n                        Integer integer = lockMap.get(key);\r\n                        int nIndex = integer != null ? integer : ++maxLocalIndex;\r\n                        asm.visitInsn(DUP);\r\n                        asm.visitVarInsn(getOpcode(v, ISTORE), nIndex);\r\n                        lockMap.put(key, nIndex);\r\n                    }\r\n                        break;\r\n                    default:\r\n                        throw new RuntimeException();\r\n                    }\r\n                }\r\n                asm.visitInsn(MONITORENTER);\r\n            }\r\n                break;\r\n            case UNLOCK: {\r\n                Value v = ((UnopStmt) st).op;\r\n                if (optimizeSynchronized) {\r\n                    switch (v.vt) {\r\n                    case LOCAL:\r\n                    case CONSTANT: {\r\n                        String key;\r\n                        if (v.vt == VT.LOCAL) {\r\n                            key = \"L\" + ((Local) v)._ls_index;\r\n                        } else {\r\n                            key = \"C\" + ((Constant) v).value;\r\n                        }\r\n                        Integer integer = lockMap.get(key);\r\n                        if (integer != null) {\r\n                            asm.visitVarInsn(getOpcode(v, ILOAD), integer);\r\n                        } else {\r\n                            accept(v, asm);\r\n                        }\r\n                    }\r\n                        break;\r\n                    // TODO other\r\n                    default: {\r\n                        accept(v, asm);\r\n                        break;\r\n                    }\r\n                    }\r\n                } else {\r\n                    accept(v, asm);\r\n                }\r\n                asm.visitInsn(MONITOREXIT);\r\n            }\r\n                break;\r\n            case NOP:\r\n                break;\r\n            case RETURN: {\r\n                Value v = ((UnopStmt) st).op;\r\n                accept(v, asm);\r\n                insertI2x(v.valueType, ir.ret, asm);\r\n                asm.visitInsn(getOpcode(v, IRETURN));\r\n            }\r\n                break;\r\n            case RETURN_VOID:\r\n                asm.visitInsn(RETURN);\r\n                break;\r\n            case LOOKUP_SWITCH: {\r\n                LookupSwitchStmt lss = (LookupSwitchStmt) st;\r\n                accept(lss.op, asm);\r\n                Label targets[] = new Label[lss.targets.length];\r\n                for (int i = 0; i < targets.length; i++) {\r\n                    targets[i] = (Label) lss.targets[i].tag;\r\n                }\r\n                asm.visitLookupSwitchInsn((Label) lss.defaultTarget.tag, lss.lookupValues, targets);\r\n            }\r\n                break;\r\n            case TABLE_SWITCH: {\r\n                TableSwitchStmt tss = (TableSwitchStmt) st;\r\n                accept(tss.op, asm);\r\n                Label targets[] = new Label[tss.targets.length];\r\n                for (int i = 0; i < targets.length; i++) {\r\n                    targets[i] = (Label) tss.targets[i].tag;\r\n                }\r\n                asm.visitTableSwitchInsn(tss.lowIndex, tss.lowIndex + targets.length - 1,\r\n                        (Label) tss.defaultTarget.tag, targets);\r\n            }\r\n                break;\r\n            case THROW:\r\n                accept(((UnopStmt) st).op, asm);\r\n                asm.visitInsn(ATHROW);\r\n                break;\r\n            case VOID_INVOKE:\r\n                Value op = st.getOp();\r\n                accept(op, asm);\r\n\r\n                String ret = op.valueType;\r\n                if (op.vt == VT.INVOKE_NEW) {\r\n                    asm.visitInsn(POP);\r\n                } else if (!\"V\".equals(ret)) {\r\n                    switch (ret.charAt(0)) {\r\n                        case 'J':\r\n                        case 'D':\r\n                            asm.visitInsn(POP2);\r\n                            break;\r\n                        default:\r\n                            asm.visitInsn(POP);\r\n                            break;\r\n                    }\r\n                }\r\n                break;\r\n            default:\r\n                throw new RuntimeException(\"not support st: \" + st.st);\r\n            }\r\n\r\n        }\r\n    }\r\n\r\n    private static boolean isLocalWithIndex(Value v, int i) {\r\n        return v.vt == VT.LOCAL && ((Local) v)._ls_index == i;\r\n    }\r\n\r\n    /**\r\n     * insert I2x instruction\r\n     *\r\n     * @param tos\r\n     * @param expect\r\n     * @param mv\r\n     */\r\n    private static void insertI2x(String tos, String expect, MethodVisitor mv) {\r\n        switch (expect.charAt(0)) {\r\n        case 'B':\r\n            switch (tos.charAt(0)) {\r\n            case 'S':\r\n            case 'C':\r\n            case 'I':\r\n                mv.visitInsn(I2B);\r\n            }\r\n            break;\r\n        case 'S':\r\n            switch (tos.charAt(0)) {\r\n            case 'C':\r\n            case 'I':\r\n                mv.visitInsn(I2S);\r\n            }\r\n            break;\r\n        case 'C':\r\n            switch (tos.charAt(0)) {\r\n            case 'I':\r\n                mv.visitInsn(I2C);\r\n            }\r\n            break;\r\n        }\r\n    }\r\n\r\n    static boolean isZeroOrNull(Value v1) {\r\n        if (v1.vt == VT.CONSTANT) {\r\n            Object v = ((Constant) v1).value;\r\n            return Integer.valueOf(0).equals(v) || Constant.Null.equals(v);\r\n        }\r\n        return false;\r\n    }\r\n\r\n    private void reBuildJumpInstructions(IfStmt st, MethodVisitor asm) {\r\n        Label target = (Label) st.target.tag;\r\n        Value v = st.op;\r\n        Value v1 = v.getOp1();\r\n        Value v2 = v.getOp2();\r\n\r\n        String type = v1.valueType;\r\n\r\n        switch (type.charAt(0)) {\r\n        case '[':\r\n        case 'L':\r\n            // IF_ACMPx\r\n            // IF[non]null\r\n            if (isZeroOrNull(v1) || isZeroOrNull(v2)) { // IF[non]null\r\n                if (isZeroOrNull(v2)) {// v2 is null\r\n                    accept(v1, asm);\r\n                } else {\r\n                    accept(v2, asm);\r\n                }\r\n                asm.visitJumpInsn(v.vt == VT.EQ ? IFNULL : IFNONNULL, target);\r\n            } else {\r\n                accept(v1, asm);\r\n                accept(v2, asm);\r\n                asm.visitJumpInsn(v.vt == VT.EQ ? IF_ACMPEQ : IF_ACMPNE, target);\r\n            }\r\n            break;\r\n        default:\r\n            // IFx\r\n            // IF_ICMPx\r\n            if (isZeroOrNull(v1) || isZeroOrNull(v2)) { // IFx\r\n                if (isZeroOrNull(v2)) {// v2 is zero\r\n                    accept(v1, asm);\r\n                } else {\r\n                    accept(v2, asm);\r\n                }\r\n                switch (v.vt) {\r\n                case NE:\r\n                    asm.visitJumpInsn(IFNE, target);\r\n                    break;\r\n                case EQ:\r\n                    asm.visitJumpInsn(IFEQ, target);\r\n                    break;\r\n                case GE:\r\n                    asm.visitJumpInsn(IFGE, target);\r\n                    break;\r\n                case GT:\r\n                    asm.visitJumpInsn(IFGT, target);\r\n                    break;\r\n                case LE:\r\n                    asm.visitJumpInsn(IFLE, target);\r\n                    break;\r\n                case LT:\r\n                    asm.visitJumpInsn(IFLT, target);\r\n                    break;\r\n                }\r\n            } else { // IF_ICMPx\r\n                accept(v1, asm);\r\n                accept(v2, asm);\r\n                switch (v.vt) {\r\n                case NE:\r\n                    asm.visitJumpInsn(IF_ICMPNE, target);\r\n                    break;\r\n                case EQ:\r\n                    asm.visitJumpInsn(IF_ICMPEQ, target);\r\n                    break;\r\n                case GE:\r\n                    asm.visitJumpInsn(IF_ICMPGE, target);\r\n                    break;\r\n                case GT:\r\n                    asm.visitJumpInsn(IF_ICMPGT, target);\r\n                    break;\r\n                case LE:\r\n                    asm.visitJumpInsn(IF_ICMPLE, target);\r\n                    break;\r\n                case LT:\r\n                    asm.visitJumpInsn(IF_ICMPLT, target);\r\n                    break;\r\n                }\r\n            }\r\n            break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @param v\r\n     * @param op\r\n     *            DUP\r\n     * @return\r\n     */\r\n    static int getOpcode(Value v, int op) {\r\n        return getOpcode(v.valueType, op);\r\n    }\r\n\r\n    static int getOpcode(String v, int op) {\r\n        switch (v.charAt(0)) {\r\n            case 'L':\r\n            case '[':\r\n                return Type.getType(\"La;\").getOpcode(op);\r\n            case 'Z':\r\n                return Type.BOOLEAN_TYPE.getOpcode(op);\r\n            case 'B':\r\n                return Type.BYTE_TYPE.getOpcode(op);\r\n            case 'S':\r\n                return Type.SHORT_TYPE.getOpcode(op);\r\n            case 'C':\r\n                return Type.CHAR_TYPE.getOpcode(op);\r\n            case 'I':\r\n                return Type.INT_TYPE.getOpcode(op);\r\n            case 'F':\r\n                return Type.FLOAT_TYPE.getOpcode(op);\r\n            case 'J':\r\n                return Type.LONG_TYPE.getOpcode(op);\r\n            case 'D':\r\n                return Type.DOUBLE_TYPE.getOpcode(op);\r\n            default:\r\n                // FIXME handle undetected types\r\n                return Type.INT_TYPE.getOpcode(op); // treat other as int\r\n        }\r\n    }\r\n\r\n    private static void accept(Value value, MethodVisitor asm) {\r\n\r\n        switch (value.et) {\r\n        case E0:\r\n            switch (value.vt) {\r\n            case LOCAL:\r\n                asm.visitVarInsn(getOpcode(value, ILOAD), ((Local) value)._ls_index);\r\n                break;\r\n            case CONSTANT:\r\n                Constant cst = (Constant) value;\r\n                if (cst.value.equals(Constant.Null)) {\r\n                    asm.visitInsn(ACONST_NULL);\r\n                } else if (cst.value instanceof DexType) {\r\n                    asm.visitLdcInsn(Type.getType(((DexType) cst.value).desc));\r\n                } else {\r\n                    asm.visitLdcInsn(cst.value);\r\n                }\r\n                break;\r\n            case NEW:\r\n                asm.visitTypeInsn(NEW, toInternal(((NewExpr) value).type));\r\n                break;\r\n            case STATIC_FIELD:\r\n                StaticFieldExpr sfe= (StaticFieldExpr) value;\r\n                asm.visitFieldInsn(GETSTATIC,toInternal(sfe.owner),sfe.name,sfe.type);\r\n                break;\r\n            }\r\n            break;\r\n        case E1:\r\n            reBuildE1Expression((E1Expr) value, asm);\r\n            break;\r\n        case E2:\r\n            reBuildE2Expression((E2Expr) value, asm);\r\n            break;\r\n        case En:\r\n            reBuildEnExpression((EnExpr) value, asm);\r\n            break;\r\n        }\r\n    }\r\n\r\n    private static void reBuildEnExpression(EnExpr value, MethodVisitor asm) {\r\n        if (value.vt == VT.FILLED_ARRAY) {\r\n            FilledArrayExpr fae = (FilledArrayExpr) value;\r\n            reBuildE1Expression(Exprs.nNewArray(fae.type, Exprs.nInt(fae.ops.length)), asm);\r\n            String tp1 = fae.valueType;\r\n            int xastore = IASTORE;\r\n            String elementType = null;\r\n            if (tp1.charAt(0) == '[') {\r\n                elementType = tp1.substring(1);\r\n                xastore = getOpcode(elementType, IASTORE);\r\n            }\r\n\r\n            for (int i = 0; i < fae.ops.length; i++) {\r\n                if (fae.ops[i] == null)\r\n                    continue;\r\n                asm.visitInsn(DUP);\r\n                asm.visitLdcInsn(i);\r\n                accept(fae.ops[i], asm);\r\n                String tp2 = fae.ops[i].valueType;\r\n                if (elementType != null) {\r\n                    insertI2x(tp2, elementType, asm);\r\n                }\r\n                asm.visitInsn(xastore);\r\n            }\r\n            return;\r\n        }\r\n\r\n        switch (value.vt) {\r\n        case NEW_MUTI_ARRAY:\r\n            for (Value vb : value.ops) {\r\n                accept(vb, asm);\r\n            }\r\n            NewMutiArrayExpr nmae = (NewMutiArrayExpr) value;\r\n            StringBuilder sb = new StringBuilder();\r\n            for (int i = 0; i < nmae.dimension; i++) {\r\n                sb.append('[');\r\n            }\r\n            sb.append(nmae.baseType);\r\n            asm.visitMultiANewArrayInsn(sb.toString(), value.ops.length);\r\n            break;\r\n        case INVOKE_NEW:\r\n            asm.visitTypeInsn(NEW, toInternal(((InvokeExpr) value).getOwner()));\r\n            asm.visitInsn(DUP);\r\n            // pass through\r\n        case INVOKE_INTERFACE:\r\n        case INVOKE_SPECIAL:\r\n        case INVOKE_STATIC:\r\n        case INVOKE_VIRTUAL: {\r\n            InvokeExpr ie = (InvokeExpr) value;\r\n            int i = 0;\r\n            if (value.vt != VT.INVOKE_STATIC && value.vt != VT.INVOKE_NEW) {\r\n                i = 1;\r\n                accept(value.ops[0], asm);\r\n            }\r\n            for (int j = 0; i < value.ops.length; i++, j++) {\r\n                Value vb = value.ops[i];\r\n                accept(vb, asm);\r\n                insertI2x(vb.valueType, ie.getArgs()[j], asm);\r\n            }\r\n\r\n            int opcode;\r\n            switch (value.vt) {\r\n            case INVOKE_VIRTUAL:\r\n                opcode = INVOKEVIRTUAL;\r\n                break;\r\n            case INVOKE_INTERFACE:\r\n                opcode = INVOKEINTERFACE;\r\n                break;\r\n            case INVOKE_NEW:\r\n            case INVOKE_SPECIAL:\r\n                opcode = INVOKESPECIAL;\r\n                break;\r\n            case INVOKE_STATIC:\r\n                opcode = INVOKESTATIC;\r\n                break;\r\n            default:\r\n                opcode = -1;\r\n            }\r\n\r\n            Proto p = ie.getProto();\r\n            if (ie.vt == VT.INVOKE_NEW) {\r\n                p = new Proto(p.getParameterTypes(), \"V\");\r\n            }\r\n            asm.visitMethodInsn(opcode, toInternal(ie.getOwner()), ie.getName(), p.getDesc());\r\n        }\r\n        break;\r\n        case INVOKE_CUSTOM: {\r\n            InvokeCustomExpr ice = (InvokeCustomExpr) value;\r\n            String argTypes[] = ice.getProto().getParameterTypes();\r\n            Value[] vbs = ice.getOps();\r\n            if (argTypes.length == vbs.length) {\r\n                for (int i = 0; i < vbs.length; i++) {\r\n                    Value vb = vbs[i];\r\n                    accept(vb, asm);\r\n                    insertI2x(vb.valueType, argTypes[i], asm);\r\n                }\r\n            } else if (argTypes.length + 1 == vbs.length) {\r\n                accept(vbs[0], asm);\r\n                for (int i = 1; i < vbs.length; i++) {\r\n                    Value vb = vbs[i];\r\n                    accept(vb, asm);\r\n                    insertI2x(vb.valueType, argTypes[i - 1], asm);\r\n                }\r\n            } else {\r\n                throw new RuntimeException();\r\n            }\r\n            asm.visitInvokeDynamicInsn(ice.name, ice.proto.getDesc(), (Handle) Dex2Asm.convertConstantValue(ice.handle), Dex2Asm.convertConstantValues(ice.bsmArgs));\r\n        }\r\n        break;\r\n        case INVOKE_POLYMORPHIC: {\r\n            InvokePolymorphicExpr ipe = (InvokePolymorphicExpr) value;\r\n            Method m = ipe.method;\r\n            String argTypes[] = ipe.getProto().getParameterTypes();\r\n            Value[] vbs = ipe.getOps();\r\n            accept(vbs[0], asm);\r\n            for (int i = 1; i < vbs.length; i++) {\r\n                Value vb = vbs[i];\r\n                accept(vb, asm);\r\n                insertI2x(vb.valueType, argTypes[i - 1], asm);\r\n            }\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, toInternal(m.getOwner()), m.getName(), ipe.getProto().getDesc(), false);\r\n        }\r\n        }\r\n    }\r\n\r\n    private static void box(String provideType, String expectedType, MethodVisitor asm) {\r\n        if(provideType.equals(expectedType)){\r\n            return;\r\n        }\r\n        if(expectedType.equals(\"V\")){\r\n            switch (provideType.charAt(0)) {\r\n            case 'J':\r\n            case 'D':\r\n                asm.visitInsn(POP2);\r\n                break;\r\n            default:\r\n                asm.visitInsn(POP);\r\n                break;\r\n            }\r\n            return;\r\n        }\r\n\r\n        char p = provideType.charAt(0);\r\n        char e = expectedType.charAt(0);\r\n\r\n        if (expectedType.equals(\"Ljava/lang/Object;\") && (p == '[' || p == 'L')) {\r\n            return;\r\n        }\r\n        if (provideType.equals(\"Ljava/lang/Object;\") && (e == '[' || e == 'L')) {\r\n            asm.visitTypeInsn(CHECKCAST, toInternal(expectedType));\r\n            return;\r\n        }\r\n\r\n        switch (provideType + expectedType) {\r\n        case \"ZLjava/lang/Object;\":\r\n        case \"ZLjava/lang/Boolean;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Boolean\", \"valueOf\", \"(Z)Ljava/lang/Boolean;\", false);\r\n            break;\r\n        case \"BLjava/lang/Object;\":\r\n        case \"BLjava/lang/Byte;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Byte\", \"valueOf\", \"(B)Ljava/lang/Byte;\", false);\r\n            break;\r\n        case \"SLjava/lang/Object;\":\r\n        case \"SLjava/lang/Short;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Short\", \"valueOf\", \"(S)Ljava/lang/Short;\", false);\r\n            break;\r\n        case \"CLjava/lang/Object;\":\r\n        case \"CLjava/lang/Character;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Character\", \"valueOf\", \"(C)Ljava/lang/Character;\", false);\r\n            break;\r\n        case \"ILjava/lang/Object;\":\r\n        case \"ILjava/lang/Integer;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Integer\", \"valueOf\", \"(I)Ljava/lang/Integer;\", false);\r\n            break;\r\n        case \"FLjava/lang/Object;\":\r\n        case \"FLjava/lang/Float;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Float\", \"valueOf\", \"(F)Ljava/lang/Float;\", false);\r\n            break;\r\n        case \"JLjava/lang/Object;\":\r\n        case \"JLjava/lang/Long;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Long\", \"valueOf\", \"(J)Ljava/lang/Long;\", false);\r\n            break;\r\n        case \"DLjava/lang/Object;\":\r\n        case \"DLjava/lang/Double;\":\r\n            asm.visitMethodInsn(INVOKESTATIC, \"java/lang/Double\", \"valueOf\", \"(D)Ljava/lang/Double;\", false);\r\n            break;\r\n\r\n        case \"Ljava/lang/Object;Z\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Boolean\");\r\n            // pass through\r\n        case \"Ljava/lang/Boolean;Z\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Boolean\", \"booleanValue\", \"()Z\", false);\r\n            break;\r\n\r\n\r\n        case \"Ljava/lang/Object;B\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Byte\");\r\n            // pass through\r\n        case \"Ljava/lang/Byte;B\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Byte\", \"byteValue\", \"()B\", false);\r\n            break;\r\n\r\n\r\n        case \"Ljava/lang/Object;S\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Short\");\r\n            // pass through\r\n        case \"Ljava/lang/Short;S\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Short\", \"shortValue\", \"()S\", false);\r\n            break;\r\n\r\n\r\n        case \"Ljava/lang/Object;C\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Character\");\r\n            // pass through\r\n        case \"Ljava/lang/Character;C\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Character\", \"charValue\", \"()C\", false);\r\n            break;\r\n\r\n\r\n        case \"Ljava/lang/Object;I\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Integer\");\r\n            // pass through\r\n        case \"Ljava/lang/Integer;I\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Integer\", \"intValue\", \"()I\", false);\r\n            break;\r\n\r\n        case \"Ljava/lang/Object;F\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Float\");\r\n            // pass through\r\n        case \"Ljava/lang/Float;F\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Float\", \"floatValue\", \"()F\", false);\r\n            break;\r\n\r\n\r\n        case \"Ljava/lang/Object;J\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Long\");\r\n            // pass through\r\n        case \"Ljava/lang/Long;J\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Long\", \"longValue\", \"()J\", false);\r\n            break;\r\n\r\n        case \"Ljava/lang/Object;D\":\r\n            asm.visitTypeInsn(CHECKCAST, \"java/lang/Double\");\r\n            // pass through\r\n        case \"Ljava/lang/Double;D\":\r\n            asm.visitMethodInsn(INVOKEVIRTUAL, \"java/lang/Double\", \"doubleValue\", \"()D\", false);\r\n            break;\r\n\r\n        default:\r\n            throw new RuntimeException(\"i have trouble to auto convert from \" + provideType + \" to \" + expectedType + \" currently\");\r\n        }\r\n    }\r\n\r\n    private static void reBuildE1Expression(E1Expr e1, MethodVisitor asm) {\r\n        accept(e1.getOp(), asm);\r\n        switch (e1.vt) {\r\n        case STATIC_FIELD: {\r\n            FieldExpr fe = (FieldExpr) e1;\r\n            asm.visitFieldInsn(GETSTATIC, toInternal(fe.owner), fe.name, fe.type);\r\n            break;\r\n        }\r\n        case FIELD: {\r\n            FieldExpr fe = (FieldExpr) e1;\r\n            asm.visitFieldInsn(GETFIELD, toInternal(fe.owner), fe.name, fe.type);\r\n            break;\r\n        }\r\n        case NEW_ARRAY: {\r\n            TypeExpr te = (TypeExpr) e1;\r\n            switch (te.type.charAt(0)) {\r\n            case '[':\r\n            case 'L':\r\n                asm.visitTypeInsn(ANEWARRAY, toInternal(te.type));\r\n                break;\r\n            case 'Z':\r\n                asm.visitIntInsn(NEWARRAY, T_BOOLEAN);\r\n                break;\r\n            case 'B':\r\n                asm.visitIntInsn(NEWARRAY, T_BYTE);\r\n                break;\r\n            case 'S':\r\n                asm.visitIntInsn(NEWARRAY, T_SHORT);\r\n                break;\r\n            case 'C':\r\n                asm.visitIntInsn(NEWARRAY, T_CHAR);\r\n                break;\r\n            case 'I':\r\n                asm.visitIntInsn(NEWARRAY, T_INT);\r\n                break;\r\n            case 'F':\r\n                asm.visitIntInsn(NEWARRAY, T_FLOAT);\r\n                break;\r\n            case 'J':\r\n                asm.visitIntInsn(NEWARRAY, T_LONG);\r\n                break;\r\n            case 'D':\r\n                asm.visitIntInsn(NEWARRAY, T_DOUBLE);\r\n                break;\r\n            }\r\n        }\r\n            break;\r\n        case CHECK_CAST:\r\n        case INSTANCE_OF: {\r\n            TypeExpr te = (TypeExpr) e1;\r\n            asm.visitTypeInsn(e1.vt == VT.CHECK_CAST ? CHECKCAST : INSTANCEOF, toInternal(te.type));\r\n        }\r\n            break;\r\n        case CAST: {\r\n            CastExpr te = (CastExpr) e1;\r\n            cast2(e1.op.valueType, te.to, asm);\r\n        }\r\n            break;\r\n        case LENGTH:\r\n            asm.visitInsn(ARRAYLENGTH);\r\n            break;\r\n        case NEG:\r\n            asm.visitInsn(getOpcode(e1, INEG));\r\n            break;\r\n        }\r\n    }\r\n\r\n    private static void reBuildE2Expression(E2Expr e2, MethodVisitor asm) {\r\n        String type = e2.op2.valueType;\r\n        accept(e2.op1, asm);\r\n        if ((e2.vt == VT.ADD || e2.vt == VT.SUB) && e2.op2.vt == VT.CONSTANT) {\r\n            // [x + (-1)] to [x - 1]\r\n            // [x - (-1)] to [x + 1]\r\n            Constant constant = (Constant) e2.op2;\r\n            String t = constant.valueType;\r\n            switch (t.charAt(0)) {\r\n            case 'S':\r\n            case 'B':\r\n            case 'I': {\r\n                int s = (Integer) constant.value;\r\n                if (s < 0) {\r\n                    asm.visitLdcInsn(-s);\r\n                    asm.visitInsn(getOpcode(type, e2.vt == VT.ADD ? ISUB : IADD));\r\n                    return;\r\n                }\r\n            }\r\n                break;\r\n            case 'F': {\r\n                float s = (Float) constant.value;\r\n                if (s < 0) {\r\n                    asm.visitLdcInsn(-s);\r\n                    asm.visitInsn(getOpcode(type, e2.vt == VT.ADD ? ISUB : IADD));\r\n                    return;\r\n                }\r\n            }\r\n                break;\r\n            case 'J': {\r\n                long s = (Long) constant.value;\r\n                if (s < 0) {\r\n                    asm.visitLdcInsn(-s);\r\n                    asm.visitInsn(getOpcode(type, e2.vt == VT.ADD ? ISUB : IADD));\r\n                    return;\r\n                }\r\n            }\r\n                break;\r\n            case 'D': {\r\n                double s = (Double) constant.value;\r\n                if (s < 0) {\r\n                    asm.visitLdcInsn(-s);\r\n                    asm.visitInsn(getOpcode(type, e2.vt == VT.ADD ? ISUB : IADD));\r\n                    return;\r\n                }\r\n            }\r\n                break;\r\n            }\r\n        }\r\n\r\n        accept(e2.op2, asm);\r\n\r\n        String tp1 = e2.op1.valueType;\r\n        switch (e2.vt) {\r\n        case ARRAY:\r\n            String tp2 = e2.valueType;\r\n            if (tp1.charAt(0) == '[') {\r\n                asm.visitInsn(getOpcode(tp1.substring(1), IALOAD));\r\n            } else {\r\n                asm.visitInsn(getOpcode(tp2, IALOAD));\r\n            }\r\n            break;\r\n        case ADD:\r\n            asm.visitInsn(getOpcode(type, IADD));\r\n            break;\r\n        case SUB:\r\n            asm.visitInsn(getOpcode(type, ISUB));\r\n            break;\r\n        case IDIV:\r\n        case LDIV:\r\n        case FDIV:\r\n        case DDIV:\r\n            asm.visitInsn(getOpcode(type, IDIV));\r\n            break;\r\n        case MUL:\r\n            asm.visitInsn(getOpcode(type, IMUL));\r\n            break;\r\n        case REM:\r\n            asm.visitInsn(getOpcode(type, IREM));\r\n            break;\r\n        case AND:\r\n            asm.visitInsn(getOpcode(type, IAND));\r\n            break;\r\n        case OR:\r\n            asm.visitInsn(getOpcode(type, IOR));\r\n            break;\r\n        case XOR:\r\n            asm.visitInsn(getOpcode(type, IXOR));\r\n            break;\r\n\r\n        case SHL:\r\n            asm.visitInsn(getOpcode(tp1, ISHL));\r\n            break;\r\n        case SHR:\r\n            asm.visitInsn(getOpcode(tp1, ISHR));\r\n            break;\r\n        case USHR:\r\n            asm.visitInsn(getOpcode(tp1, IUSHR));\r\n            break;\r\n        case LCMP:\r\n            asm.visitInsn(LCMP);\r\n            break;\r\n        case FCMPG:\r\n            asm.visitInsn(FCMPG);\r\n            break;\r\n        case DCMPG:\r\n            asm.visitInsn(DCMPG);\r\n            break;\r\n        case FCMPL:\r\n            asm.visitInsn(FCMPL);\r\n            break;\r\n        case DCMPL:\r\n            asm.visitInsn(DCMPL);\r\n            break;\r\n        }\r\n    }\r\n\r\n    private static void cast2(String t1, String t2, MethodVisitor asm) {\r\n        if (t1.equals(t2)) {\r\n            return;\r\n        }\r\n        switch (t1.charAt(0)) {\r\n        case 'Z':\r\n        case 'B':\r\n        case 'C':\r\n        case 'S':\r\n        case 'I': {\r\n            switch (t2.charAt(0)) {\r\n            case 'F':\r\n                asm.visitInsn(I2F);\r\n                break;\r\n            case 'J':\r\n                asm.visitInsn(I2L);\r\n                break;\r\n            case 'D':\r\n                asm.visitInsn(I2D);\r\n                break;\r\n            case 'C':\r\n                asm.visitInsn(I2C);\r\n                break;\r\n            case 'B':\r\n                asm.visitInsn(I2B);\r\n                break;\r\n            case 'S':\r\n                asm.visitInsn(I2S);\r\n                break;\r\n            }\r\n        }\r\n            break;\r\n        case 'J': {\r\n            switch (t2.charAt(0)) {\r\n            case 'I':\r\n                asm.visitInsn(L2I);\r\n                break;\r\n            case 'F':\r\n                asm.visitInsn(L2F);\r\n                break;\r\n            case 'D':\r\n                asm.visitInsn(L2D);\r\n                break;\r\n            }\r\n        }\r\n            break;\r\n        case 'D': {\r\n            switch (t2.charAt(0)) {\r\n            case 'I':\r\n                asm.visitInsn(D2I);\r\n                break;\r\n            case 'F':\r\n                asm.visitInsn(D2F);\r\n                break;\r\n            case 'J':\r\n                asm.visitInsn(D2L);\r\n                break;\r\n            }\r\n        }\r\n            break;\r\n        case 'F': {\r\n            switch (t2.charAt(0)) {\r\n            case 'I':\r\n                asm.visitInsn(F2I);\r\n                break;\r\n            case 'J':\r\n                asm.visitInsn(F2L);\r\n                break;\r\n            case 'D':\r\n                asm.visitInsn(F2D);\r\n                break;\r\n            }\r\n            break;\r\n        }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java",
    "content": "package com.googlecode.d2j.converter;\n\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.Trap;\nimport com.googlecode.dex2jar.ir.expr.Exprs;\nimport com.googlecode.dex2jar.ir.expr.Local;\nimport com.googlecode.dex2jar.ir.stmt.*;\nimport org.objectweb.asm.Handle;\nimport org.objectweb.asm.Label;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.Type;\nimport org.objectweb.asm.tree.*;\nimport org.objectweb.asm.tree.analysis.AnalyzerException;\nimport org.objectweb.asm.tree.analysis.Frame;\nimport org.objectweb.asm.tree.analysis.Interpreter;\nimport org.objectweb.asm.tree.analysis.Value;\n\nimport java.util.*;\n\nimport static org.objectweb.asm.Opcodes.*;\n\npublic class J2IRConverter {\n    Map<Label, LabelStmt> map = new HashMap<>();\n    InsnList insnList;\n    int[] parentCount;\n    JvmFrame[] frames;\n    MethodNode methodNode;\n    IrMethod target;\n    List<Stmt> emitStmts[];\n    List<Stmt> preEmit = new ArrayList<>();\n    List<Stmt> currentEmit;\n\n    private J2IRConverter() {\n    }\n\n    public static IrMethod convert(String owner, MethodNode methodNode) throws AnalyzerException {\n        return new J2IRConverter().convert0(owner, methodNode);\n    }\n\n    LabelStmt getLabel(LabelNode labelNode) {\n        Label label = labelNode.getLabel();\n        LabelStmt ls = map.get(label);\n        if (ls == null) {\n            ls = Stmts.nLabel();\n            map.put(label, ls);\n        }\n        return ls;\n    }\n\n    void emit(Stmt stmt) {\n        currentEmit.add(stmt);\n    }\n\n    IrMethod populate(String owner, MethodNode source) {\n        IrMethod target = new IrMethod();\n        target.name = source.name;\n        target.owner = \"L\" + owner + \";\";\n        target.ret = Type.getReturnType(source.desc).getDescriptor();\n        Type[] args = Type.getArgumentTypes(source.desc);\n        String sArgs[] = new String[args.length];\n        target.args = sArgs;\n        for (int i = 0; i < args.length; i++) {\n            sArgs[i] = args[i].getDescriptor();\n        }\n        target.isStatic = 0 != (source.access & Opcodes.ACC_STATIC);\n        return target;\n    }\n\n    IrMethod convert0(String owner, MethodNode methodNode) throws AnalyzerException {\n        this.methodNode = methodNode;\n        target = populate(owner, methodNode);\n        if (methodNode.instructions.size() == 0) {\n            return target;\n        }\n\n        insnList = methodNode.instructions;\n        BitSet[] exBranch = new BitSet[insnList.size()];\n        parentCount = new int[insnList.size()];\n\n        initParentCount(parentCount);\n\n\n        BitSet handlers = new BitSet(insnList.size());\n        if (methodNode.tryCatchBlocks != null) {\n            for (TryCatchBlockNode tcb : methodNode.tryCatchBlocks) {\n                target.traps.add(new Trap(getLabel(tcb.start), getLabel(tcb.end), new LabelStmt[]{getLabel(tcb.handler)},\n                        new String[]{tcb.type == null ? null : Type.getObjectType(tcb.type).getDescriptor()}));\n                int handlerIdx = insnList.indexOf(tcb.handler);\n                handlers.set(handlerIdx);\n\n                for (AbstractInsnNode p = tcb.start.getNext(); p != tcb.end; p = p.getNext()) {\n\n                    BitSet x = exBranch[insnList.indexOf(p)];\n                    if (x == null) {\n                        x = exBranch[insnList.indexOf(p)] = new BitSet(insnList.size());\n                    }\n                    x.set(handlerIdx);\n                    parentCount[handlerIdx]++;\n                }\n            }\n        }\n\n        Interpreter<JvmValue> interpreter = buildInterpreter();\n        frames = new JvmFrame[insnList.size()];\n        emitStmts = new ArrayList[insnList.size()];\n        BitSet access = new BitSet(insnList.size());\n\n        dfs(exBranch, handlers, access, interpreter);\n\n        StmtList stmts = target.stmts;\n        stmts.addAll(preEmit);\n        for (int i = 0; i < insnList.size(); i++) {\n            AbstractInsnNode p = insnList.get(i);\n            if (access.get(i)) {\n                List<Stmt> es = emitStmts[i];\n                if (es != null) {\n                    stmts.addAll(es);\n                }\n            } else {\n                if (p.getType() == AbstractInsnNode.LABEL) {\n                    stmts.add(getLabel((LabelNode) p));\n                }\n            }\n        }\n        emitStmts = null;\n\n\n        Queue<JvmValue> queue = new LinkedList<>();\n\n        for (int i1 = 0; i1 < frames.length; i1++) {\n            JvmFrame frame = frames[i1];\n            if (parentCount[i1] > 1 && frame != null && access.get(i1)) {\n                for (int j = 0; j < frame.getLocals(); j++) {\n                    JvmValue v = frame.getLocal(j);\n                    addToQueue(queue, v);\n                }\n                for (int j = 0; j < frame.getStackSize(); j++) {\n                    addToQueue(queue, frame.getStack(j));\n                }\n            }\n\n        }\n\n        while (!queue.isEmpty()) {\n            JvmValue v = queue.poll();\n            getLocal(v);\n            if (v.parent != null) {\n                if (v.parent.local == null) {\n                    queue.add(v.parent);\n                }\n            }\n            if (v.otherParent != null) {\n                for (JvmValue v2 : v.otherParent) {\n                    if (v2.local == null) {\n                        queue.add(v2);\n                    }\n                }\n            }\n        }\n\n        Set<com.googlecode.dex2jar.ir.expr.Value> phiValues = new HashSet<>();\n        List<LabelStmt> phiLabels = new ArrayList<>();\n        for (int i = 0; i < frames.length; i++) {\n            JvmFrame frame = frames[i];\n            if (parentCount[i] > 1 && frame != null && access.get(i)) {\n                AbstractInsnNode p = insnList.get(i);\n                LabelStmt labelStmt = getLabel((LabelNode) p);\n                List<AssignStmt> phis = new ArrayList<>();\n                for (int j = 0; j < frame.getLocals(); j++) {\n                    JvmValue v = frame.getLocal(j);\n                    addPhi(v, phiValues, phis);\n                }\n                for (int j = 0; j < frame.getStackSize(); j++) {\n                    addPhi(frame.getStack(j), phiValues, phis);\n                }\n                labelStmt.phis = phis;\n                phiLabels.add(labelStmt);\n            }\n        }\n        if (phiLabels.size() > 0) {\n            target.phiLabels = phiLabels;\n        }\n\n        return target;\n\n    }\n\n    private void addPhi(JvmValue v, Set<com.googlecode.dex2jar.ir.expr.Value> phiValues, List<AssignStmt> phis) {\n        if (v != null) {\n            if (v.local != null) {\n                if (v.parent != null) {\n                    phiValues.add(getLocal(v.parent));\n                }\n                if (v.otherParent != null) {\n                    for (JvmValue v2 : v.otherParent) {\n                        phiValues.add(getLocal(v2));\n                    }\n                }\n                if (phiValues.size() > 0) {\n                    phis.add(Stmts.nAssign(v.local, Exprs.nPhi(phiValues.toArray(new com.googlecode.dex2jar.ir.expr.Value[phiValues.size()]))));\n                    phiValues.clear();\n                }\n            }\n        }\n    }\n\n    private void addToQueue(Queue<JvmValue> queue, JvmValue v) {\n        if (v != null) {\n            if (v.local != null) {\n                if (v.parent != null) {\n                    if (v.parent.local == null) {\n                        queue.add(v.parent);\n                    }\n                }\n                if (v.otherParent != null) {\n                    for (JvmValue v2 : v.otherParent) {\n                        if (v2.local == null) {\n                            queue.add(v2);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private void dfs(BitSet[] exBranch, BitSet handlers, BitSet access, Interpreter<JvmValue> interpreter) throws AnalyzerException {\n        currentEmit = preEmit;\n        JvmFrame first = initFirstFrame(methodNode, target);\n        if (parentCount[0] > 1) {\n            merge(first, 0);\n        } else {\n            frames[0] = first;\n        }\n        Stack<AbstractInsnNode> stack = new Stack<>();\n        stack.push(insnList.getFirst());\n\n        JvmFrame tmp = new JvmFrame(methodNode.maxLocals, methodNode.maxStack);\n\n        while (!stack.isEmpty()) {\n            AbstractInsnNode p = stack.pop();\n            int index = insnList.indexOf(p);\n            if (!access.get(index)) {\n                access.set(index);\n            } else {\n                continue;\n            }\n            JvmFrame frame = frames[index];\n            setCurrentEmit(index);\n\n            if (p.getType() == AbstractInsnNode.LABEL) {\n                emit(getLabel((LabelNode) p));\n                if (handlers.get(index)) {\n                    Local ex = newLocal();\n                    emit(Stmts.nIdentity(ex, Exprs.nExceptionRef(\"Ljava/lang/Throwable;\")));\n                    frame.clearStack();\n                    frame.push(new JvmValue(1, ex));\n                }\n            }\n            BitSet ex = exBranch[index];\n            if (ex != null) {\n                for (int i = ex.nextSetBit(0); i >= 0; i = ex.nextSetBit(i + 1)) {\n                    mergeEx(frame, i);\n                    stack.push(insnList.get(i));\n                }\n            }\n\n            tmp.init(frame);\n            tmp.execute(p, interpreter);\n\n            int op = p.getOpcode();\n            if (p.getType() == AbstractInsnNode.JUMP_INSN) {\n                JumpInsnNode jump = (JumpInsnNode) p;\n                stack.push(jump.label);\n                merge(tmp, insnList.indexOf(jump.label));\n            }\n\n            if (op == Opcodes.TABLESWITCH || op == Opcodes.LOOKUPSWITCH) {\n                if (op == Opcodes.TABLESWITCH) {\n                    TableSwitchInsnNode tsin = (TableSwitchInsnNode) p;\n                    for (LabelNode label : tsin.labels) {\n                        stack.push(label);\n                        merge(tmp, insnList.indexOf(label));\n                    }\n                    stack.push(tsin.dflt);\n                    merge(tmp, insnList.indexOf(tsin.dflt));\n\n                } else {\n                    LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) p;\n                    for (LabelNode label : lsin.labels) {\n                        stack.push(label);\n                        merge(tmp, insnList.indexOf(label));\n                    }\n                    stack.push(lsin.dflt);\n                    merge(tmp, insnList.indexOf(lsin.dflt));\n                }\n            }\n            if ((op >= Opcodes.GOTO && op <= Opcodes.RETURN) || op == Opcodes.ATHROW) {\n                // can't continue\n            } else {\n                stack.push(p.getNext());\n                merge(tmp, index + 1);\n            }\n\n            // cleanup frame it is useless\n            if (parentCount[index] <= 1) {\n                frames[index] = null;\n            }\n\n        }\n    }\n\n    private void setCurrentEmit(int index) {\n        currentEmit = emitStmts[index];\n        if (currentEmit == null) {\n            currentEmit = emitStmts[index] = new ArrayList<>(1);\n        }\n    }\n\n    private Interpreter<JvmValue> buildInterpreter() {\n        return new Interpreter<JvmValue>(Opcodes.ASM4) {\n            @Override\n            public JvmValue newValue(Type type) {\n                return null;\n            }\n\n            @Override\n            public JvmValue newOperation(AbstractInsnNode insn) throws AnalyzerException {\n                switch (insn.getOpcode()) {\n                    case ACONST_NULL:\n                        return b(1, Exprs.nNull());\n                    case ICONST_M1:\n                    case ICONST_0:\n                    case ICONST_1:\n                    case ICONST_2:\n                    case ICONST_3:\n                    case ICONST_4:\n                    case ICONST_5:\n                        return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));\n                    case LCONST_0:\n                    case LCONST_1:\n                        return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));\n                    case FCONST_0:\n                    case FCONST_1:\n                    case FCONST_2:\n                        return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));\n                    case DCONST_0:\n                    case DCONST_1:\n                        return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));\n                    case BIPUSH:\n                    case SIPUSH:\n                        return b(1, Exprs.nInt(((IntInsnNode) insn).operand));\n                    case LDC:\n                        Object cst = ((LdcInsnNode) insn).cst;\n                        if (cst instanceof Integer) {\n                            return b(1, Exprs.nInt((Integer) cst));\n                        } else if (cst instanceof Float) {\n                            return b(1, Exprs.nFloat((Float) cst));\n                        } else if (cst instanceof Long) {\n                            return b(2, Exprs.nLong((Long) cst));\n                        } else if (cst instanceof Double) {\n                            return b(2, Exprs.nDouble((Double) cst));\n                        } else if (cst instanceof String) {\n                            return b(1, Exprs.nString((String) cst));\n                        } else if (cst instanceof Type) {\n                            Type type = (Type) cst;\n                            int sort = type.getSort();\n                            if (sort == Type.OBJECT || sort == Type.ARRAY) {\n                                return b(1, Exprs.nType(type.getDescriptor()));\n                            } else if (sort == Type.METHOD) {\n                                throw new UnsupportedOperationException(\"Not supported yet.\");\n                            } else {\n                                throw new IllegalArgumentException(\"Illegal LDC constant \" + cst);\n                            }\n                        } else if (cst instanceof Handle) {\n                            throw new UnsupportedOperationException(\"Not supported yet.\");\n                        } else {\n                            throw new IllegalArgumentException(\"Illegal LDC constant \" + cst);\n                        }\n                    case JSR:\n                        throw new UnsupportedOperationException(\"Not supported yet.\");\n                    case GETSTATIC:\n                        FieldInsnNode fin = (FieldInsnNode) insn;\n                        return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField(\"L\" + fin.owner + \";\", fin.name,\n                                fin.desc));\n                    case NEW:\n                        return b(1, Exprs.nNew(\"L\" + ((TypeInsnNode) insn).desc + \";\"));\n                    default:\n                        throw new Error(\"Internal error.\");\n                }\n            }\n\n            @Override\n            public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws AnalyzerException {\n                return b(value.getSize(), getLocal(value));\n            }\n\n            @Override\n            public JvmValue unaryOperation(AbstractInsnNode insn, JvmValue value0) throws AnalyzerException {\n                Local local = value0 == null ? null : getLocal(value0);\n                switch (insn.getOpcode()) {\n                    case INEG:\n                        return b(1, Exprs.nNeg(local, \"I\"));\n                    case IINC:\n                        return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), \"I\"));\n                    case L2I:\n                        return b(1, Exprs.nCast(local, \"J\", \"I\"));\n                    case F2I:\n                        return b(1, Exprs.nCast(local, \"F\", \"I\"));\n                    case D2I:\n                        return b(1, Exprs.nCast(local, \"D\", \"I\"));\n                    case I2B:\n                        return b(1, Exprs.nCast(local, \"I\", \"B\"));\n                    case I2C:\n                        return b(1, Exprs.nCast(local, \"I\", \"C\"));\n                    case I2S:\n                        return b(1, Exprs.nCast(local, \"I\", \"S\"));\n                    case FNEG:\n                        return b(1, Exprs.nNeg(local, \"F\"));\n                    case I2F:\n                        return b(1, Exprs.nCast(local, \"I\", \"F\"));\n                    case L2F:\n                        return b(1, Exprs.nCast(local, \"J\", \"F\"));\n                    case D2F:\n                        return b(1, Exprs.nCast(local, \"D\", \"F\"));\n                    case LNEG:\n                        return b(2, Exprs.nNeg(local, \"J\"));\n                    case I2L:\n                        return b(2, Exprs.nCast(local, \"I\", \"J\"));\n                    case F2L:\n                        return b(2, Exprs.nCast(local, \"F\", \"J\"));\n                    case D2L:\n                        return b(2, Exprs.nCast(local, \"D\", \"J\"));\n                    case DNEG:\n                        return b(2, Exprs.nNeg(local, \"D\"));\n                    case I2D:\n                        return b(2, Exprs.nCast(local, \"I\", \"D\"));\n                    case L2D:\n                        return b(2, Exprs.nCast(local, \"J\", \"D\"));\n                    case F2D:\n                        return b(2, Exprs.nCast(local, \"F\", \"D\"));\n                    case IFEQ:\n                        emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFNE:\n                        emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFLT:\n                        emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFGE:\n                        emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFGT:\n                        emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFLE:\n                        emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case TABLESWITCH: {\n                        TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;\n                        LabelStmt targets[] = new LabelStmt[ts.labels.size()];\n                        for (int i = 0; i < ts.labels.size(); i++) {\n                            targets[i] = getLabel((LabelNode) ts.labels.get(i));\n                        }\n                        emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));\n                        return null;\n                    }\n                    case LOOKUPSWITCH: {\n                        LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;\n                        LabelStmt targets[] = new LabelStmt[ls.labels.size()];\n                        int[] lookupValues = new int[ls.labels.size()];\n                        for (int i = 0; i < ls.labels.size(); i++) {\n                            targets[i] = getLabel((LabelNode) ls.labels.get(i));\n                            lookupValues[i] = (Integer) ls.keys.get(i);\n                        }\n                        emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));\n                        return null;\n                    }\n                    case IRETURN:\n                    case LRETURN:\n                    case FRETURN:\n                    case DRETURN:\n                    case ARETURN:\n                        // skip, move to returnOperation\n                        return null;\n                    case PUTSTATIC: {\n                        FieldInsnNode fin = (FieldInsnNode) insn;\n                        emit(Stmts.nAssign(Exprs.nStaticField(\"L\" + fin.owner + \";\", fin.name, fin.desc), local));\n                        return null;\n                    }\n                    case GETFIELD: {\n                        FieldInsnNode fin = (FieldInsnNode) insn;\n                        Type fieldType = Type.getType(fin.desc);\n                        return b(fieldType.getSize(), Exprs.nField(local, \"L\" + fin.owner + \";\", fin.name, fin.desc));\n                    }\n                    case NEWARRAY:\n                        switch (((IntInsnNode) insn).operand) {\n                            case T_BOOLEAN:\n                                return b(1, Exprs.nNewArray(\"Z\", local));\n                            case T_CHAR:\n                                return b(1, Exprs.nNewArray(\"C\", local));\n                            case T_BYTE:\n                                return b(1, Exprs.nNewArray(\"B\", local));\n                            case T_SHORT:\n                                return b(1, Exprs.nNewArray(\"S\", local));\n                            case T_INT:\n                                return b(1, Exprs.nNewArray(\"I\", local));\n                            case T_FLOAT:\n                                return b(1, Exprs.nNewArray(\"F\", local));\n                            case T_DOUBLE:\n                                return b(1, Exprs.nNewArray(\"D\", local));\n                            case T_LONG:\n                                return b(1, Exprs.nNewArray(\"D\", local));\n                            default:\n                                throw new AnalyzerException(insn, \"Invalid array type\");\n                        }\n                    case ANEWARRAY:\n                        String desc = \"L\" + ((TypeInsnNode) insn).desc + \";\";\n                        return b(1, Exprs.nNewArray(desc, local));\n                    case ARRAYLENGTH:\n                        return b(1, Exprs.nLength(local));\n                    case ATHROW:\n                        emit(Stmts.nThrow(local));\n                        return null;\n                    case CHECKCAST:\n                        String orgDesc = ((TypeInsnNode) insn).desc;\n                        desc = orgDesc.startsWith(\"[\") ? orgDesc : (\"L\" + orgDesc + \";\");\n                        return b(1, Exprs.nCheckCast(local, desc));\n                    case INSTANCEOF:\n                        return b(1, Exprs.nInstanceOf(local, \"L\" + ((TypeInsnNode) insn).desc + \";\"));\n                    case MONITORENTER:\n                        emit(Stmts.nLock(local));\n                        return null;\n                    case MONITOREXIT:\n                        emit(Stmts.nUnLock(local));\n                        return null;\n                    case IFNULL:\n                        emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), \"L\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IFNONNULL:\n                        emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), \"L\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case GOTO: // special case\n                        emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    default:\n                        throw new Error(\"Internal error.\");\n                }\n            }\n\n            JvmValue b(int size, com.googlecode.dex2jar.ir.expr.Value value) {\n                Local local = newLocal();\n                emit(Stmts.nAssign(local, value));\n                return new JvmValue(size, local);\n            }\n\n            @Override\n            public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20)\n                    throws AnalyzerException {\n                Local local1 = getLocal(value10);\n                Local local2 = getLocal(value20);\n                switch (insn.getOpcode()) {\n\n                    case IALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"I\"));\n                    case BALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"B\"));\n                    case CALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"C\"));\n                    case SALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"S\"));\n                    case FALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"F\"));\n                    case AALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"L\"));\n                    case DALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"D\"));\n                    case LALOAD:\n                        return b(1, Exprs.nArray(local1, local2, \"J\"));\n                    case IADD:\n                        return b(1, Exprs.nAdd(local1, local2, \"I\"));\n                    case ISUB:\n                        return b(1, Exprs.nSub(local1, local2, \"I\"));\n                    case IMUL:\n                        return b(1, Exprs.nMul(local1, local2, \"I\"));\n                    case IDIV:\n                        return b(1, Exprs.nDiv(local1, local2, \"I\"));\n                    case IREM:\n                        return b(1, Exprs.nRem(local1, local2, \"I\"));\n                    case ISHL:\n                        return b(1, Exprs.nShl(local1, local2, \"I\"));\n                    case ISHR:\n                        return b(1, Exprs.nShr(local1, local2, \"I\"));\n                    case IUSHR:\n                        return b(1, Exprs.nUshr(local1, local2, \"I\"));\n                    case IAND:\n                        return b(1, Exprs.nAnd(local1, local2, \"I\"));\n                    case IOR:\n                        return b(1, Exprs.nOr(local1, local2, \"I\"));\n                    case IXOR:\n                        return b(1, Exprs.nXor(local1, local2, \"I\"));\n                    case FADD:\n                        return b(1, Exprs.nAdd(local1, local2, \"F\"));\n                    case FSUB:\n                        return b(1, Exprs.nSub(local1, local2, \"F\"));\n                    case FMUL:\n                        return b(1, Exprs.nMul(local1, local2, \"F\"));\n                    case FDIV:\n                        return b(1, Exprs.nDiv(local1, local2, \"F\"));\n                    case FREM:\n                        return b(1, Exprs.nRem(local1, local2, \"F\"));\n                    case LADD:\n                        return b(2, Exprs.nAdd(local1, local2, \"J\"));\n                    case LSUB:\n                        return b(2, Exprs.nSub(local1, local2, \"J\"));\n                    case LMUL:\n                        return b(2, Exprs.nMul(local1, local2, \"J\"));\n                    case LDIV:\n                        return b(2, Exprs.nDiv(local1, local2, \"J\"));\n                    case LREM:\n                        return b(2, Exprs.nRem(local1, local2, \"J\"));\n                    case LSHL:\n                        return b(2, Exprs.nShl(local1, local2, \"J\"));\n                    case LSHR:\n                        return b(2, Exprs.nShr(local1, local2, \"J\"));\n                    case LUSHR:\n                        return b(2, Exprs.nUshr(local1, local2, \"J\"));\n                    case LAND:\n                        return b(2, Exprs.nAnd(local1, local2, \"J\"));\n                    case LOR:\n                        return b(2, Exprs.nOr(local1, local2, \"J\"));\n                    case LXOR:\n                        return b(2, Exprs.nXor(local1, local2, \"J\"));\n\n                    case DADD:\n                        return b(2, Exprs.nAdd(local1, local2, \"D\"));\n                    case DSUB:\n                        return b(2, Exprs.nSub(local1, local2, \"D\"));\n                    case DMUL:\n                        return b(2, Exprs.nMul(local1, local2, \"D\"));\n                    case DDIV:\n                        return b(2, Exprs.nDiv(local1, local2, \"D\"));\n                    case DREM:\n                        return b(2, Exprs.nRem(local1, local2, \"D\"));\n\n                    case LCMP:\n                        return b(2, Exprs.nLCmp(local1, local2));\n                    case FCMPL:\n                        return b(1, Exprs.nFCmpl(local1, local2));\n                    case FCMPG:\n                        return b(1, Exprs.nFCmpg(local1, local2));\n                    case DCMPL:\n                        return b(2, Exprs.nDCmpl(local1, local2));\n                    case DCMPG:\n                        return b(2, Exprs.nDCmpg(local1, local2));\n\n                    case IF_ICMPEQ:\n                        emit(Stmts.nIf(Exprs.nEq(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ICMPNE:\n                        emit(Stmts.nIf(Exprs.nNe(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ICMPLT:\n                        emit(Stmts.nIf(Exprs.nLt(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ICMPGE:\n                        emit(Stmts.nIf(Exprs.nGe(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ICMPGT:\n                        emit(Stmts.nIf(Exprs.nGt(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ICMPLE:\n                        emit(Stmts.nIf(Exprs.nLe(local1, local2, \"I\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ACMPEQ:\n                        emit(Stmts.nIf(Exprs.nEq(local1, local2, \"L\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case IF_ACMPNE:\n                        emit(Stmts.nIf(Exprs.nNe(local1, local2, \"L\"),\n                                getLabel(((JumpInsnNode) insn).label)));\n                        return null;\n                    case PUTFIELD:\n                        FieldInsnNode fin = (FieldInsnNode) insn;\n                        emit(Stmts.nAssign(Exprs.nField(local1, \"L\" + fin.owner + \";\", fin.name, fin.desc), local2));\n                        return null;\n                    default:\n                        throw new Error(\"Internal error.\");\n                }\n            }\n\n            @Override\n            public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3)\n                    throws AnalyzerException {\n                Local local1 = getLocal(value1);\n                Local local2 = getLocal(value2);\n                Local local3 = getLocal(value3);\n                switch (insn.getOpcode()) {\n                    case IASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"I\"),\n                                local3));\n                        break;\n                    case LASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"J\"),\n                                local3));\n                        break;\n                    case FASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"F\"),\n                                local3));\n                        break;\n                    case DASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"D\"),\n                                local3));\n                        break;\n                    case AASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"L\"),\n                                local3));\n                        break;\n                    case BASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"B\"),\n                                local3));\n                        break;\n                    case CASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"C\"),\n                                local3));\n                        break;\n                    case SASTORE:\n                        emit(Stmts.nAssign(Exprs.nArray(local1, local2, \"S\"),\n                                local3));\n                        break;\n                }\n\n                return null;\n            }\n\n            public String[] toDescArray(Type[] ts) {\n                String[] ds = new String[ts.length];\n                for (int i = 0; i < ts.length; i++) {\n                    ds[i] = ts[i].getDescriptor();\n                }\n                return ds;\n            }\n\n            @Override\n            public JvmValue naryOperation(AbstractInsnNode insn, List<? extends JvmValue> xvalues) throws AnalyzerException {\n\n                com.googlecode.dex2jar.ir.expr.Value values[] = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];\n                for (int i = 0; i < xvalues.size(); i++) {\n                    values[i] = getLocal(xvalues.get(i));\n                }\n                if (insn.getOpcode() == MULTIANEWARRAY) {\n                    throw new UnsupportedOperationException(\"Not supported yet.\");\n                } else {\n                    MethodInsnNode mi = (MethodInsnNode) insn;\n                    com.googlecode.dex2jar.ir.expr.Value v = null;\n                    String ret = Type.getReturnType(mi.desc).getDescriptor();\n                    String owner = \"L\" + mi.owner + \";\";\n                    String ps[] = toDescArray(Type.getArgumentTypes(mi.desc));\n                    switch (insn.getOpcode()) {\n                        case INVOKEVIRTUAL:\n                            v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);\n                            break;\n                        case INVOKESPECIAL:\n                            v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);\n                            break;\n                        case INVOKESTATIC:\n                            v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);\n                            break;\n                        case INVOKEINTERFACE:\n                            v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);\n                            break;\n                        case INVOKEDYNAMIC:\n                            throw new UnsupportedOperationException(\"Not supported yet.\");\n                    }\n                    if (\"V\".equals(ret)) {\n                        emit(Stmts.nVoidInvoke(v));\n                        return null;\n                    } else {\n                        return b(Type.getReturnType(mi.desc).getSize(), v);\n                    }\n                }\n            }\n\n            @Override\n            public JvmValue merge(JvmValue v, JvmValue w) {\n                throw new UnsupportedOperationException(\"Not supported yet.\");\n            }\n\n            @Override\n            public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) throws AnalyzerException {\n                switch (insn.getOpcode()) {\n                    case IRETURN:\n                    case LRETURN:\n                    case FRETURN:\n                    case DRETURN:\n                    case ARETURN:\n                        emit(Stmts.nReturn(getLocal(value)));\n                        break;\n                    case RETURN:\n                        emit(Stmts.nReturnVoid());\n                        break;\n                }\n\n            }\n        };\n    }\n\n    Local getLocal(JvmValue value) {\n        Local local = value.local;\n        if (local == null) {\n            local = value.local = newLocal();\n        }\n        return local;\n    }\n\n    private void initParentCount(int[] parentCount) {\n        parentCount[0] = 1;\n        for (AbstractInsnNode p = insnList.getFirst(); p != null; p = p.getNext()) {\n            if (p.getType() == AbstractInsnNode.JUMP_INSN) {\n                JumpInsnNode jump = (JumpInsnNode) p;\n                parentCount[insnList.indexOf(jump.label)]++;\n            }\n            int op = p.getOpcode();\n            if (op == Opcodes.TABLESWITCH || op == Opcodes.LOOKUPSWITCH) {\n                if (op == Opcodes.TABLESWITCH) {\n                    TableSwitchInsnNode tsin = (TableSwitchInsnNode) p;\n                    for (LabelNode label : tsin.labels) {\n                        parentCount[insnList.indexOf(label)]++;\n                    }\n                    parentCount[insnList.indexOf(tsin.dflt)]++;\n                } else {\n                    LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) p;\n                    for (LabelNode label : lsin.labels) {\n                        parentCount[insnList.indexOf(label)]++;\n                    }\n                    parentCount[insnList.indexOf(lsin.dflt)]++;\n                }\n            }\n            if ((op >= Opcodes.GOTO && op <= Opcodes.RETURN) || op == Opcodes.ATHROW) {\n                // can't continue\n            } else {\n                AbstractInsnNode next = p.getNext();\n                if(next!=null) {\n                    parentCount[insnList.indexOf(p.getNext())]++;\n                }\n            }\n        }\n    }\n\n    private void mergeEx(JvmFrame src, int dst) {\n        JvmFrame distFrame = frames[dst];\n        if (distFrame == null) {\n            distFrame = frames[dst] = new JvmFrame(methodNode.maxLocals, methodNode.maxStack);\n        }\n        for (int i = 0; i < src.getLocals(); i++) {\n            JvmValue p = src.getLocal(i);\n            JvmValue q = distFrame.getLocal(i);\n            if (p != null) {\n                if (q == null) {\n                    q = new JvmValue(p.getSize());\n                    distFrame.setLocal(i, q);\n                }\n                relate(p, q);\n            }\n        }\n    }\n\n    private void merge(JvmFrame src, int dst) {\n        JvmFrame distFrame = frames[dst];\n        if (distFrame == null) {\n            distFrame = frames[dst] = new JvmFrame(methodNode.maxLocals, methodNode.maxStack);\n        }\n        if (parentCount[dst] > 1) {\n            for (int i = 0; i < src.getLocals(); i++) {\n                JvmValue p = src.getLocal(i);\n                JvmValue q = distFrame.getLocal(i);\n                if (p != null) {\n                    if (q == null) {\n                        q = new JvmValue(p.getSize());\n                        distFrame.setLocal(i, q);\n                    }\n                    relate(p, q);\n                }\n            }\n            if (src.getStackSize() > 0) {\n                if (distFrame.getStackSize() == 0) {\n                    for (int i = 0; i < src.getStackSize(); i++) {\n                        distFrame.push(new JvmValue(src.getStack(i).getSize()));\n                    }\n                } else if (distFrame.getStackSize() != src.getStackSize()) {\n                    throw new RuntimeException(\"stack not balanced\");\n                }\n                for (int i = 0; i < src.getStackSize(); i++) {\n                    JvmValue p = src.getStack(i);\n                    JvmValue q = distFrame.getStack(i);\n                    relate(p, q);\n                }\n            }\n        } else {\n            distFrame.init(src);\n        }\n    }\n\n    private void relate(JvmValue parent, JvmValue child) {\n        if (child.parent == null) {\n            child.parent = parent;\n        } else if (child.parent == parent) {\n            //\n        } else {\n            if (child.otherParent == null) {\n                child.otherParent = new HashSet<>(5);\n            }\n            child.otherParent.add(parent);\n        }\n    }\n\n    private JvmFrame initFirstFrame(MethodNode methodNode, IrMethod target) {\n        JvmFrame first = new JvmFrame(methodNode.maxLocals, methodNode.maxStack);\n        int x = 0;\n        if (!target.isStatic) {// not static\n            Local thiz = newLocal();\n            emit(Stmts.nIdentity(thiz, Exprs.nThisRef(target.owner)));\n            first.setLocal(x++, new JvmValue(1, thiz));\n        }\n        for (int i = 0; i < target.args.length; i++) {\n            Local p = newLocal();\n            emit(Stmts.nIdentity(p, Exprs.nParameterRef(target.args[i], i)));\n            int sizeOfType = sizeOfType(target.args[i]);\n            first.setLocal(x, new JvmValue(sizeOfType, p));\n            x += sizeOfType;\n        }\n        return first;\n    }\n\n    private int sizeOfType(String arg) {\n        switch (arg.charAt(0)) {\n            case 'J':\n            case 'D':\n                return 2;\n            default:\n                return 1;\n        }\n    }\n\n    private Local newLocal() {\n        Local thiz = Exprs.nLocal(target.locals.size());\n        target.locals.add(thiz);\n        return thiz;\n    }\n\n    static class JvmFrame extends Frame<JvmValue> {\n\n        public JvmFrame(int nLocals, int nStack) {\n            super(nLocals, nStack);\n        }\n\n        @Override\n        public void execute(AbstractInsnNode insn, Interpreter<JvmValue> interpreter) throws AnalyzerException {\n            if (insn.getType() == AbstractInsnNode.FRAME || insn.getType() == AbstractInsnNode.LINE || insn.getType() == AbstractInsnNode.LABEL) {\n                return;\n            }\n            if (insn.getOpcode() == Opcodes.RETURN) {\n                interpreter.returnOperation(insn, null, null);\n            } else if (insn.getOpcode() == Opcodes.GOTO) {\n                interpreter.unaryOperation(insn, null);\n            } else if (insn.getOpcode() == RET) {\n                throw new RuntimeException(\"not support yet!\");\n            } else {\n                super.execute(insn, interpreter);\n            }\n        }\n    }\n\n    public static class JvmValue implements Value {\n        private final int size;\n        public JvmValue parent;\n        public Set<JvmValue> otherParent;\n        Local local;\n\n        public JvmValue(int size, Local local) {\n            this.size = size;\n            this.local = local;\n        }\n\n        public JvmValue(int size) {\n            this.size = size;\n        }\n\n        @Override\n        public int getSize() {\n            return size;\n        }\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/BaseDexExceptionHandler.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\n\npublic class BaseDexExceptionHandler implements DexExceptionHandler {\n    @Override\n    public void handleFileException(Exception e) {\n        e.printStackTrace(System.err);\n    }\n\n    @Override\n    public void handleMethodTranslateException(Method method, DexMethodNode methodNode, MethodVisitor mv, Exception e) {\n        // replace the generated code with\n        // 'return new RuntimeException(\"D2jFail translate: xxxxxxxxxxxxx\");'\n        StringWriter s = new StringWriter();\n        s.append(\"d2j fail translate: \");\n        e.printStackTrace(new PrintWriter(s));\n        String msg = s.toString();\n        mv.visitTypeInsn(Opcodes.NEW, \"java/lang/RuntimeException\");\n        mv.visitInsn(Opcodes.DUP);\n        mv.visitLdcInsn(msg);\n        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, \"java/lang/RuntimeException\", \"<init>\", \"(Ljava/lang/String;)V\");\n        mv.visitInsn(Opcodes.ATHROW);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/ClassVisitorFactory.java",
    "content": "package com.googlecode.d2j.dex;\n\nimport org.objectweb.asm.ClassVisitor;\n\npublic interface ClassVisitorFactory {\n\n    /**\n     * \n     * @param classInternalName\n     *            class name\n     * @return a ClassVisitor, to generate validate .class file, ClassWriter.COMPUTE_MAXS is required for ClassWriter\n     */\n    ClassVisitor create(String classInternalName);\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java",
    "content": "package com.googlecode.d2j.dex;\n\nimport java.util.*;\n\nimport com.googlecode.d2j.converter.Dex2IRConverter;\nimport org.objectweb.asm.*;\nimport org.objectweb.asm.tree.InnerClassNode;\n\nimport com.googlecode.d2j.*;\nimport com.googlecode.d2j.converter.IR2JConverter;\nimport com.googlecode.d2j.node.*;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.ts.*;\nimport com.googlecode.dex2jar.ir.ts.array.FillArrayTransformer;\n\npublic class Dex2Asm {\n\n    protected static class Clz {\n        public int access;\n        public Clz enclosingClass;\n        public Method enclosingMethod;\n        public String innerName;\n        public Set<Clz> inners = null;\n        public final String name;\n\n        public Clz(String name) {\n            super();\n            this.name = name;\n        }\n\n        void addInner(Clz clz) {\n            if (inners == null) {\n                inners = new HashSet<Clz>();\n            }\n            inners.add(clz);\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj)\n                return true;\n            if (obj == null)\n                return false;\n            if (getClass() != obj.getClass())\n                return false;\n            Clz other = (Clz) obj;\n            if (name == null) {\n                if (other.name != null)\n                    return false;\n            } else if (!name.equals(other.name))\n                return false;\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            final int prime = 31;\n            int result = 1;\n            result = prime * result + ((name == null) ? 0 : name.hashCode());\n            return result;\n        }\n\n        public String toString() {\n            return \"\" + name;\n        }\n    }\n\n    protected static final int ACC_INTERFACE_ABSTRACT = (Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT);\n\n    private static final int NO_CODE_MASK = DexConstants.ACC_ABSTRACT | DexConstants.ACC_NATIVE\n            | DexConstants.ACC_ANNOTATION;\n\n    protected static final CleanLabel T_cleanLabel = new CleanLabel();\n    protected static final EndRemover T_endRemove = new EndRemover();\n    protected static final Ir2JRegAssignTransformer T_ir2jRegAssign = new Ir2JRegAssignTransformer();\n    protected static final NewTransformer T_new = new NewTransformer();\n    protected static final RemoveConstantFromSSA T_removeConst = new RemoveConstantFromSSA();\n    protected static final RemoveLocalFromSSA T_removeLocal = new RemoveLocalFromSSA();\n    protected static final ExceptionHandlerTrim T_trimEx = new ExceptionHandlerTrim();\n    protected static final TypeTransformer T_type = new TypeTransformer();\n    // protected static final TopologicalSort T_topologicalSort = new TopologicalSort();\n    protected static final DeadCodeTransformer T_deadCode = new DeadCodeTransformer();\n    protected static final FillArrayTransformer T_fillArray = new FillArrayTransformer();\n    protected static final AggTransformer T_agg = new AggTransformer();\n    protected static final UnSSATransformer T_unssa = new UnSSATransformer();\n    protected static final ZeroTransformer T_zero = new ZeroTransformer();\n    protected static final VoidInvokeTransformer T_voidInvoke = new VoidInvokeTransformer();\n    protected static final NpeTransformer T_npe = new NpeTransformer();\n    protected static final MultiArrayTransformer T_multiArray = new MultiArrayTransformer();\n\n    static private int clearClassAccess(boolean isInner, int access) {\n        if ((access & Opcodes.ACC_INTERFACE) == 0) { // issue 55\n            access |= Opcodes.ACC_SUPER;// 解决生成的class文件使用dx重新转换时使用的指令与原始指令不同的问题\n        }\n        // access in class has no acc_static or acc_private\n        access &= ~(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);\n        if (isInner && (access & Opcodes.ACC_PROTECTED) != 0) {// protected inner class are public\n            access &= ~Opcodes.ACC_PROTECTED;\n            access |= Opcodes.ACC_PUBLIC;\n        }\n        access &= ~DexConstants.ACC_DECLARED_SYNCHRONIZED; // clean ACC_DECLARED_SYNCHRONIZED\n        return access;\n    }\n\n    static private int clearInnerAccess(int access) {\n        access &= (~Opcodes.ACC_SUPER);// inner class attr has no acc_super\n        if (0 != (access & Opcodes.ACC_PRIVATE)) {// clear public/protected if it is private\n            access &= ~(Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED);\n        } else if (0 != (access & Opcodes.ACC_PROTECTED)) {// clear public if it is protected\n            access &= ~(Opcodes.ACC_PUBLIC);\n        }\n        return access;\n    }\n\n    protected static String toInternalName(DexType type) {\n        return toInternalName(type.desc);\n    }\n\n    protected static String toInternalName(String desc) {\n        // TODO without creating object\n        return Type.getType(desc).getInternalName();\n    }\n\n    public static void accept(DexAnnotationNode ann, ClassVisitor v) {\n        AnnotationVisitor av = v.visitAnnotation(ann.type, ann.visibility != Visibility.BUILD);\n        if (av != null) {\n            accept(ann.items, av);\n            av.visitEnd();\n        }\n    }\n\n    public static void accept(List<DexAnnotationNode> anns, ClassVisitor cv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                if (ann.visibility != Visibility.SYSTEM) {\n                    accept(ann, cv);\n                }\n            }\n        }\n    }\n\n    public static void accept(List<DexAnnotationNode> anns, FieldVisitor fv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                if (ann.visibility != Visibility.SYSTEM) {\n                    accept(ann, fv);\n                }\n            }\n        }\n    }\n\n    public static void accept(List<DexAnnotationNode> anns, MethodVisitor mv) {\n        if (anns != null) {\n            for (DexAnnotationNode ann : anns) {\n                if (ann.visibility != Visibility.SYSTEM) {\n                    accept(ann, mv);\n                }\n            }\n        }\n    }\n\n    public static void accept(DexAnnotationNode ann, MethodVisitor v) {\n        AnnotationVisitor av = v.visitAnnotation(ann.type, ann.visibility != Visibility.BUILD);\n        if (av != null) {\n            accept(ann.items, av);\n            av.visitEnd();\n        }\n    }\n\n    public static void acceptParameter(DexAnnotationNode ann, int index, MethodVisitor v) {\n        AnnotationVisitor av = v.visitParameterAnnotation(index, ann.type, ann.visibility != Visibility.BUILD);\n        if (av != null) {\n            accept(ann.items, av);\n            av.visitEnd();\n        }\n    }\n\n    public static void accept(DexAnnotationNode ann, FieldVisitor v) {\n        AnnotationVisitor av = v.visitAnnotation(ann.type, ann.visibility != Visibility.BUILD);\n        if (av != null) {\n            accept(ann.items, av);\n            av.visitEnd();\n        }\n    }\n\n    public static void accept(List<DexAnnotationNode.Item> items, AnnotationVisitor av) {\n        for (DexAnnotationNode.Item item : items) {\n            accept(av, item.name, item.value);\n        }\n    }\n\n    private static void accept(AnnotationVisitor dav, String name, Object o) {\n        if (o instanceof Object[]) {\n            AnnotationVisitor arrayVisitor = dav.visitArray(name);\n            if (arrayVisitor != null) {\n                Object[] array = (Object[]) o;\n                for (Object e : array) {\n                    accept(arrayVisitor, null, e);\n                }\n                arrayVisitor.visitEnd();\n            }\n        } else if (o instanceof DexAnnotationNode) {\n            DexAnnotationNode ann = (DexAnnotationNode) o;\n            AnnotationVisitor av = dav.visitAnnotation(name, ann.type);\n            if (av != null) {\n                for (DexAnnotationNode.Item item : ann.items) {\n                    accept(av, item.name, item.value);\n                }\n                av.visitEnd();\n            }\n        } else if (o instanceof Field) {\n            Field f = (Field) o;\n            dav.visitEnum(name, f.getType(), f.getName());\n        } else if (o instanceof DexType) {\n            dav.visit(name, Type.getType(((DexType) o).desc));\n        } else if (o instanceof Method) {\n            System.err.println(\"WARN: ignored method annotation value\");\n        } else {\n            if (o == null) {\n                System.err.println(\"WARN: ignored null annotation value\");\n            } else {\n                dav.visit(name, o);\n            }\n        }\n    }\n\n    private static MethodVisitor collectBasicMethodInfo(DexMethodNode methodNode, ClassVisitor cv) {\n        String xthrows[] = null;\n        String signature = null;\n        if (methodNode.anns != null) {\n            for (DexAnnotationNode ann : methodNode.anns) {\n                if (ann.visibility == Visibility.SYSTEM) {\n                    switch (ann.type) {\n                    case DexConstants.ANNOTATION_THROWS_TYPE: {\n                        Object[] strs = (Object[]) findAnnotationAttribute(ann, \"value\");\n                        if (strs != null) {\n                            xthrows = new String[strs.length];\n                            for (int i = 0; i < strs.length; i++) {\n                                DexType type = (DexType) strs[i];\n                                xthrows[i] = toInternalName(type);\n                            }\n                        }\n                    }\n                        break;\n                    case DexConstants.ANNOTATION_SIGNATURE_TYPE: {\n                        Object[] strs = (Object[]) findAnnotationAttribute(ann, \"value\");\n                        if (strs != null) {\n                            StringBuilder sb = new StringBuilder();\n                            for (Object str : strs) {\n                                sb.append(str);\n                            }\n                            signature = sb.toString();\n                        }\n                    }\n                        break;\n                    }\n                }\n            }\n        }\n        int access = methodNode.access;\n        // clear ACC_DECLARED_SYNCHRONIZED and ACC_CONSTRUCTOR from method flags\n        final int cleanFlag = ~((DexConstants.ACC_DECLARED_SYNCHRONIZED | DexConstants.ACC_CONSTRUCTOR));\n        access &= cleanFlag;\n        return cv.visitMethod(access, methodNode.method.getName(), methodNode.method.getDesc(), signature, xthrows);\n    }\n\n    protected static Map<String, Clz> collectClzInfo(DexFileNode fileNode) {\n        Map<String, Clz> classes = new HashMap<>();\n        for (DexClassNode classNode : fileNode.clzs) {\n            Clz clz = get(classes, classNode.className);\n            clz.access = (clz.access & ~ACC_INTERFACE_ABSTRACT) | classNode.access;\n            if (classNode.anns != null) {\n                for (DexAnnotationNode ann : classNode.anns) {\n                    if (ann.visibility == Visibility.SYSTEM) {\n                        switch (ann.type) {\n                        case DexConstants.ANNOTATION_ENCLOSING_CLASS_TYPE: {\n                            DexType type = (DexType) findAnnotationAttribute(ann, \"value\");\n                            Clz enclosingClass = get(classes, type.desc);\n                            clz.enclosingClass = enclosingClass;\n\n                            // apply patch from ChaeHoon Lim,\n                            // obfuscated code may declare itself as enclosing class\n                            // which cause dex2jar to endless loop\n                            //if(!clz.name.equals(clz.enclosingClass.name)) {\n                            //    enclosingClass.addInner(clz);\n                            //}\n                            enclosingClass.addInner(clz);\n\n                        }\n                            break;\n                        case DexConstants.ANNOTATION_ENCLOSING_METHOD_TYPE: {\n                            Method m = (Method) findAnnotationAttribute(ann, \"value\");\n                            Clz enclosingClass = get(classes, m.getOwner());\n                            clz.enclosingClass = enclosingClass;\n                            clz.enclosingMethod = m;\n                            enclosingClass.addInner(clz);\n                        }\n                            break;\n                        case DexConstants.ANNOTATION_INNER_CLASS_TYPE: {\n                            for (DexAnnotationNode.Item it : ann.items) {\n                                if (\"accessFlags\".equals(it.name)) {\n                                    clz.access |= (Integer) it.value & ~ACC_INTERFACE_ABSTRACT;\n                                } else if (\"name\".equals(it.name)) {\n                                    clz.innerName = (String) it.value;\n                                }\n                            }\n                        }\n                            break;\n                        case DexConstants.ANNOTATION_MEMBER_CLASSES_TYPE: {\n                            Object ts[] = (Object[]) findAnnotationAttribute(ann, \"value\");\n                            for (Object v : ts) {\n                                DexType type = (DexType) v;\n                                Clz inner = get(classes, type.desc);\n                                clz.addInner(inner);\n                                inner.enclosingClass = clz;\n                            }\n                        }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        return classes;\n    }\n\n    public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf, DexFileNode fileNode) {\n        convertClass(fileNode.dexVersion, classNode, cvf, collectClzInfo(fileNode));\n    }\n\n    public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf) {\n        convertClass(DexConstants.DEX_035, classNode, cvf);\n    }\n    public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf) {\n        convertClass(dexVersion, classNode, cvf, new HashMap<String, Clz>());\n    }\n\n    private static boolean isJavaIdentifier(String str) {\n        if (str.length() < 1) {\n            return false;\n        }\n        if (!Character.isJavaIdentifierStart(str.charAt(0))) {\n            return false;\n        }\n        for (int i = 1; i < str.length(); i++) {\n            if (!Character.isJavaIdentifierPart(str.charAt(i))) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf, Map<String, Clz> classes) {\n        convertClass(DexConstants.DEX_035, classNode, cvf, classes);\n    }\n    public void convertClass(DexFileNode dfn, DexClassNode classNode, ClassVisitorFactory cvf, Map<String, Clz> classes) {\n        convertClass(dfn.dexVersion, classNode, cvf, classes);\n    }\n    public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf, Map<String, Clz> classes) {\n        ClassVisitor cv = cvf.create(toInternalName(classNode.className));\n        if (cv == null) {\n            return;\n        }\n        // the default value of static-final field are omitted by dex, fix it\n        DexFix.fixStaticFinalFieldValue(classNode);\n\n        String signature = null;\n        if (classNode.anns != null) {\n            for (DexAnnotationNode ann : classNode.anns) {\n                if (ann.visibility == Visibility.SYSTEM) {\n                    switch (ann.type) {\n                    case DexConstants.ANNOTATION_SIGNATURE_TYPE: {\n                        Object[] strs = (Object[]) findAnnotationAttribute(ann, \"value\");\n                        if (strs != null) {\n                            StringBuilder sb = new StringBuilder();\n                            for (Object str : strs) {\n                                sb.append(str);\n                            }\n                            signature = sb.toString();\n                        }\n                    }\n                        break;\n                    }\n                }\n            }\n        }\n        String interfaceInterNames[] = null;\n        if (classNode.interfaceNames != null) {\n            interfaceInterNames = new String[classNode.interfaceNames.length];\n            for (int i = 0; i < classNode.interfaceNames.length; i++) {\n                interfaceInterNames[i] = toInternalName(classNode.interfaceNames[i]);\n            }\n        }\n\n        Clz clzInfo = classes.get(classNode.className);\n        int access = classNode.access;\n        boolean isInnerClass = false;\n        if (clzInfo != null) {\n            isInnerClass = clzInfo.enclosingClass != null || clzInfo.enclosingMethod != null;\n        }\n        access = clearClassAccess(isInnerClass, access);\n\n        int version = dexVersion >= DexConstants.DEX_037 ? Opcodes.V1_8 : Opcodes.V1_6;\n        cv.visit(version, access, toInternalName(classNode.className), signature,\n                classNode.superClass == null ? null : toInternalName(classNode.superClass), interfaceInterNames);\n\n        List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>(5);\n        if (clzInfo != null) {\n            searchInnerClass(clzInfo, innerClassNodes, classNode.className);\n        }\n        if (isInnerClass) {\n            // build Outer Clz\n            if (clzInfo.innerName == null) {// anonymous Innerclass\n                Method enclosingMethod = clzInfo.enclosingMethod;\n                if (enclosingMethod != null) {\n                    cv.visitOuterClass(toInternalName(enclosingMethod.getOwner()), enclosingMethod.getName(),\n                            enclosingMethod.getDesc());\n                } else {\n                    Clz enclosingClass = clzInfo.enclosingClass;\n                    cv.visitOuterClass(toInternalName(enclosingClass.name), null, null);\n                }\n            }\n            searchEnclosing(clzInfo, innerClassNodes);\n        }\n        Collections.sort(innerClassNodes, INNER_CLASS_NODE_COMPARATOR);\n        for (InnerClassNode icn : innerClassNodes) {\n            if (icn.innerName != null && !isJavaIdentifier(icn.innerName)) {\n                System.err.println(\"WARN: ignored invalid inner class name \" + \", treat as anonymous inner class.\");\n                icn.innerName = null;\n                icn.outerName = null;\n            }\n            icn.accept(cv);\n        }\n\n        accept(classNode.anns, cv);\n\n        if (classNode.fields != null) {\n            for (DexFieldNode fieldNode : classNode.fields) {\n                convertField(classNode, fieldNode, cv);\n            }\n        }\n        if (classNode.methods != null) {\n            for (DexMethodNode methodNode : classNode.methods) {\n                convertMethod(classNode, methodNode, cv);\n            }\n        }\n        cv.visitEnd();\n    }\n\n    public void convertCode(DexMethodNode methodNode, MethodVisitor mv) {\n        IrMethod irMethod = dex2ir(methodNode);\n        optimize(irMethod);\n        ir2j(irMethod, mv);\n    }\n\n    public void convertDex(DexFileNode fileNode, ClassVisitorFactory cvf) {\n        if (fileNode.clzs != null) {\n            Map<String, Clz> classes = collectClzInfo(fileNode);\n            for (DexClassNode classNode : fileNode.clzs) {\n                convertClass(fileNode, classNode, cvf, classes);\n            }\n        }\n    }\n\n    public void convertField(DexClassNode classNode, DexFieldNode fieldNode, ClassVisitor cv) {\n        String signature = null;\n        if (fieldNode.anns != null) {\n            for (DexAnnotationNode ann : fieldNode.anns) {\n                if (ann.visibility == Visibility.SYSTEM) {\n                    switch (ann.type) {\n                    case DexConstants.ANNOTATION_SIGNATURE_TYPE: {\n                        Object[] strs = (Object[]) findAnnotationAttribute(ann, \"value\");\n                        if (strs != null) {\n                            StringBuilder sb = new StringBuilder();\n                            for (Object str : strs) {\n                                sb.append(str);\n                            }\n                            signature = sb.toString();\n                        }\n                    }\n                        break;\n                    }\n                }\n            }\n        }\n        Object value = convertConstantValue(fieldNode.cst);\n        final int FieldCleanFlag = ~DexConstants.ACC_DECLARED_SYNCHRONIZED;\n        FieldVisitor fv = cv.visitField(fieldNode.access & FieldCleanFlag, fieldNode.field.getName(),\n                fieldNode.field.getType(), signature, value);\n        if (fv == null) {\n            return;\n        }\n        accept(fieldNode.anns, fv);\n        fv.visitEnd();\n    }\n\n    public static Object[] convertConstantValues(Object[] v) {\n        Object[] copy = Arrays.copyOf(v, v.length);\n        for (int i = 0; i < copy.length; i++) {\n            Object ele = copy[i];\n            ele = convertConstantValue(ele);\n            copy[i] = ele;\n        }\n        return copy;\n    }\n\n    public static Object convertConstantValue(Object ele) {\n        if (ele instanceof DexType) {\n            ele = Type.getType(((DexType) ele).desc);\n        } else if (ele instanceof MethodHandle) {\n            Handle h = null;\n            MethodHandle mh = (MethodHandle) ele;\n            switch (mh.getType()) {\n                case MethodHandle.INSTANCE_GET:\n                    h = new Handle(Opcodes.H_GETFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType());\n                    break;\n                case MethodHandle.INSTANCE_PUT:\n                    h = new Handle(Opcodes.H_PUTFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType());\n                    break;\n                case MethodHandle.STATIC_GET:\n                    h = new Handle(Opcodes.H_GETFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType());\n                    break;\n                case MethodHandle.STATIC_PUT:\n                    h = new Handle(Opcodes.H_PUTFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType());\n                    break;\n                case MethodHandle.INVOKE_INSTANCE:\n                    h = new Handle(Opcodes.H_INVOKEVIRTUAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc());\n                    break;\n                case MethodHandle.INVOKE_STATIC:\n                    h = new Handle(Opcodes.H_INVOKESTATIC, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc());\n                    break;\n                case MethodHandle.INVOKE_CONSTRUCTOR:\n                    h = new Handle(Opcodes.H_NEWINVOKESPECIAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc());\n                    break;\n                case MethodHandle.INVOKE_DIRECT:\n                    h = new Handle(Opcodes.H_INVOKESPECIAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc());\n                    break;\n                case MethodHandle.INVOKE_INTERFACE:\n                    h = new Handle(Opcodes.H_INVOKEINTERFACE, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc());\n                    break;\n            }\n            ele = h;\n        } else if (ele instanceof Proto) {\n            ele = Type.getMethodType(((Proto) ele).getDesc());\n        }\n        return ele;\n    }\n\n    public void convertMethod(DexClassNode classNode, DexMethodNode methodNode, ClassVisitor cv) {\n\n        MethodVisitor mv = collectBasicMethodInfo(methodNode, cv);\n\n        if (mv == null) {\n            return;\n        }\n        if (0 != (classNode.access & DexConstants.ACC_ANNOTATION)) { // its inside an annotation\n            Object defaultValue = null;\n            if (classNode.anns != null) {\n                for (DexAnnotationNode ann : classNode.anns) {\n                    if (ann.visibility == Visibility.SYSTEM && ann.type.equals(DexConstants.ANNOTATION_DEFAULT_TYPE)) {\n                        DexAnnotationNode node = (DexAnnotationNode) findAnnotationAttribute(ann, \"value\");\n                        if (node != null) {\n                            defaultValue = findAnnotationAttribute(node, methodNode.method.getName());\n                        }\n                        break;\n                    }\n                }\n            }\n            if (defaultValue != null) {\n                AnnotationVisitor av = mv.visitAnnotationDefault();\n                if (av != null) {\n                    accept(av, null, defaultValue);\n                    av.visitEnd();\n                }\n            }\n        }\n\n        accept(methodNode.anns, mv);\n\n        if (methodNode.parameterAnns != null) {\n            for (int i = 0; i < methodNode.parameterAnns.length; i++) {\n                List<DexAnnotationNode> anns = methodNode.parameterAnns[i];\n                if (anns != null) {\n                    for (DexAnnotationNode ann : anns) {\n                        if (ann.visibility != Visibility.SYSTEM) {\n                            acceptParameter(ann, i, mv);\n                        }\n                    }\n                }\n            }\n        }\n\n        if ((NO_CODE_MASK & methodNode.access) == 0) { // has code\n            if (methodNode.codeNode != null) {\n                mv.visitCode();\n                convertCode(methodNode, mv);\n            }\n        }\n\n        mv.visitEnd();\n\n    }\n\n    public IrMethod dex2ir(DexMethodNode methodNode) {\n        return new Dex2IRConverter()\n                .convert(0 != (methodNode.access & DexConstants.ACC_STATIC), methodNode.method, methodNode.codeNode);\n    }\n\n    protected static Object findAnnotationAttribute(DexAnnotationNode ann, String name) {\n        for (DexAnnotationNode.Item item : ann.items) {\n            if (item.name.equals(name)) {\n                return item.value;\n            }\n        }\n        return null;\n    }\n\n    private static Clz get(Map<String, Clz> classes, String name) {\n        Clz clz = classes.get(name);\n        if (clz == null) {\n            clz = new Clz(name);\n            classes.put(name, clz);\n        }\n        return clz;\n    }\n\n    public void ir2j(IrMethod irMethod, MethodVisitor mv) {\n        new IR2JConverter(false).convert(irMethod, mv);\n        mv.visitMaxs(-1, -1);\n    }\n\n    public void optimize(IrMethod irMethod) {\n        T_cleanLabel.transform(irMethod);\n        T_deadCode.transform(irMethod);\n        T_removeLocal.transform(irMethod);\n        T_removeConst.transform(irMethod);\n        T_zero.transform(irMethod);\n        if (T_npe.transformReportChanged(irMethod)) {\n            T_deadCode.transform(irMethod);\n            T_removeLocal.transform(irMethod);\n            T_removeConst.transform(irMethod);\n        }\n        T_new.transform(irMethod);\n        T_fillArray.transform(irMethod);\n        T_agg.transform(irMethod);\n        T_multiArray.transform(irMethod);\n        T_voidInvoke.transform(irMethod);\n        T_type.transform(irMethod);\n        T_unssa.transform(irMethod);\n        T_trimEx.transform(irMethod);\n        T_ir2jRegAssign.transform(irMethod);\n    }\n\n    /**\n     * For structure\n     * \n     * <pre>\n     * class A {\n     *     class B {\n     *         class WeAreHere {\n     *         }\n     *     }\n     * }\n     * </pre>\n     * \n     * this method will add\n     * \n     * <pre>\n     * InnerClass  Outter\n     * A$B$WeAreHere A$B\n     * A$B           A\n     * </pre>\n     * \n     * to WeAreHere.class\n     * \n     */\n    private static void searchEnclosing(Clz clz, List<InnerClassNode> innerClassNodes) {\n        Set<Clz> visitedClz = new HashSet<>();\n        for (Clz p = clz; p != null; p = p.enclosingClass) {\n            if (!visitedClz.add(p)) { // prevent endless loop\n                break;\n            }\n            Clz enclosingClass = p.enclosingClass;\n            if (enclosingClass == null) {\n                break;\n            }\n            if (enclosingClass == clz) {\n                // enclosing itself, that is impossible\n                break;\n            }\n            int accessInInner = clearInnerAccess(p.access);\n            if (p.innerName != null) {// non-anonymous Innerclass\n                innerClassNodes.add(new InnerClassNode(toInternalName(p.name),\n                        toInternalName(enclosingClass.name), p.innerName, accessInInner));\n            } else {// anonymous Innerclass\n                innerClassNodes.add(new InnerClassNode(toInternalName(p.name), null, null, accessInInner));\n            }\n        }\n    }\n\n    /**\n     * For structure\n     * \n     * <pre>\n     * class WeAreHere {\n     *     class A {\n     *         class B {\n     * \n     *         }\n     *     }\n     * }\n     * </pre>\n     * \n     * this method will add\n     * \n     * <pre>\n     * InnerClass      Outter\n     * WeAreHere$A$B   WeAreHere$A\n     * WeAreHere$A     WeAreHere\n     * </pre>\n     * \n     * to WeAreHere.class\n     * \n     * @param clz\n     */\n    private static void searchInnerClass(Clz clz, List<InnerClassNode> innerClassNodes, String className) {\n        Set<Clz> visited = new HashSet<>();\n        Stack<Clz> stack = new Stack<>();\n        stack.push(clz);\n        while (!stack.empty()) {\n            clz = stack.pop();\n            if (visited.contains(clz)) {\n                continue;\n            } else {\n                visited.add(clz);\n            }\n            if (clz.inners != null) {\n                for (Clz inner : clz.inners) {\n                    if (inner.innerName == null) {// anonymous Innerclass\n                        innerClassNodes.add(new InnerClassNode(toInternalName(inner.name), null, null,\n                                clearInnerAccess(inner.access)));\n                    } else {// non-anonymous Innerclass\n                        innerClassNodes.add(new InnerClassNode(toInternalName(inner.name), toInternalName(className),\n                                inner.innerName, clearInnerAccess(inner.access)));\n                    }\n                    stack.push(inner);\n                }\n            }\n        }\n    }\n\n    private static final Comparator<InnerClassNode> INNER_CLASS_NODE_COMPARATOR = new Comparator<InnerClassNode>() {\n        @Override\n        public int compare(InnerClassNode o1, InnerClassNode o2) {\n            return o1.name.compareTo(o2.name);\n        }\n    };\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2IrAdapter.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.dex;\r\n\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nAdd;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nAnd;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nArray;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nArrayValue;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nCast;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nCheckCast;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nDCmpg;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nDCmpl;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nDiv;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nExceptionRef;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nFCmpg;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nFCmpl;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nField;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInstanceOf;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInt;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeInterface;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeNew;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeSpecial;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeStatic;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeVirtual;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nLCmp;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nLength;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nLong;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nMul;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nNeg;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nNew;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nNot;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nOr;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nRem;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nShl;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nShr;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nStaticField;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nString;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nSub;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nType;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nUshr;\r\nimport static com.googlecode.dex2jar.ir.expr.Exprs.nXor;\r\nimport static com.googlecode.dex2jar.ir.stmt.Stmts.*;\r\n\r\nimport java.util.*;\r\n\r\nimport com.googlecode.d2j.node.DexCodeNode;\r\nimport com.googlecode.d2j.node.TryCatchNode;\r\nimport com.googlecode.d2j.node.insn.DexLabelStmtNode;\r\nimport com.googlecode.d2j.node.insn.FilledNewArrayStmtNode;\r\nimport com.googlecode.d2j.node.insn.DexStmtNode;\r\nimport com.googlecode.d2j.node.insn.MethodStmtNode;\r\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\r\nimport com.googlecode.dex2jar.ir.TypeClass;\r\nimport org.objectweb.asm.Opcodes;\r\n\r\nimport com.googlecode.d2j.DexLabel;\r\nimport com.googlecode.d2j.DexConstants;\r\nimport com.googlecode.d2j.DexType;\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.reader.Op;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.dex2jar.ir.IrMethod;\r\nimport com.googlecode.dex2jar.ir.Trap;\r\nimport com.googlecode.dex2jar.ir.expr.Exprs;\r\nimport com.googlecode.dex2jar.ir.expr.Local;\r\nimport com.googlecode.dex2jar.ir.expr.Value;\r\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\r\nimport com.googlecode.dex2jar.ir.stmt.StmtList;\r\nimport com.googlecode.dex2jar.ir.stmt.Stmts;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * @version $Rev$\r\n */\r\npublic class Dex2IrAdapter extends DexCodeVisitor implements Opcodes, DexConstants {\r\n\r\n    protected IrMethod irMethod;\r\n    private Method method;\r\n    private boolean isStatic;\r\n    private StmtList list;\r\n    private Local[] locals;\r\n    Map<DexLabel, LabelStmt> labelStmtMap = new HashMap<>();\r\n    /**\r\n     * 函数调用的返回值保存的寄存器\r\n     */\r\n    private Local tmpLocal;\r\n\r\n    /**\r\n     * @param isStatic\r\n     * @param method\r\n     */\r\n    public Dex2IrAdapter(boolean isStatic, Method method) {\r\n        super();\r\n        IrMethod irMethod = new IrMethod();\r\n        irMethod.args = method.getParameterTypes();\r\n        irMethod.ret = method.getReturnType();\r\n        irMethod.owner = method.getOwner();\r\n        irMethod.name = method.getName();\r\n        irMethod.isStatic = isStatic;\r\n        this.irMethod = irMethod;\r\n        this.list = irMethod.stmts;\r\n        this.irMethod = irMethod;\r\n        this.method = method;\r\n        this.isStatic = isStatic;\r\n    }\r\n\r\n    private LabelStmt toLabelStmt(DexLabel label) {\r\n        LabelStmt ls = labelStmtMap.get(label);\r\n        if (ls == null) {\r\n            ls = new LabelStmt();\r\n            labelStmtMap.put(label, ls);\r\n        }\r\n        return ls;\r\n    }\r\n\r\n    static int countParameterRegisters(Method m, boolean isStatic) {\r\n        int a = isStatic ? 0 : 1;\r\n        for (String t : m.getParameterTypes()) {\r\n            switch (t.charAt(0)) {\r\n            case 'J':\r\n            case 'D':\r\n                a += 2;\r\n                break;\r\n            default:\r\n                a += 1;\r\n                break;\r\n            }\r\n        }\r\n        return a;\r\n    }\r\n\r\n    void x(Stmt stmt) {\r\n        list.add(stmt);\r\n    }\r\n\r\n    @Override\r\n    public void visitRegister(int total) {\r\n        Local[] locals = new Local[total];\r\n        this.locals = locals;\r\n        this.tmpLocal = new Local(total);\r\n        for (int i = 0; i < locals.length; i++) {\r\n            locals[i] = new Local(i);\r\n        }\r\n        int nextReg = total - countParameterRegisters(method, isStatic);\r\n        int nextReg0 = nextReg;\r\n        if (!isStatic) {// is not static\r\n            x(Stmts.nIdentity(locals[nextReg], Exprs.nThisRef(method.getOwner())));\r\n            nextReg++;\r\n        }\r\n        String[] args = method.getParameterTypes();\r\n        for (int i = 0; i < args.length; i++) {\r\n            String t = args[i];\r\n            x(Stmts.nIdentity(locals[nextReg], Exprs.nParameterRef(t, i)));\r\n            nextReg++;\r\n            if (t.equals(\"J\") || t.equals(\"D\")) {\r\n                nextReg++;\r\n            }\r\n        }\r\n        // simple fix for issue 219, init all tmp register to 0 at the start of insn.\r\n        for (int i = 0; i < nextReg0; i++) {\r\n            x(Stmts.nAssign(locals[i], nInt(0)));\r\n        }\r\n        x(Stmts.nAssign(tmpLocal, nInt(0)));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R1N(Op op, int a, int b, int content) {\r\n        Local va = locals[a];\r\n        Local vb = locals[b];\r\n        Value to;\r\n        switch (op) {\r\n        case ADD_INT_LIT16:\r\n        case ADD_INT_LIT8:\r\n            to = nAdd(vb, nInt(content), \"I\");\r\n            break;\r\n        case RSUB_INT_LIT8:\r\n        case RSUB_INT://\r\n            to = nSub(nInt(content), vb, \"I\");\r\n            break;\r\n        case MUL_INT_LIT8:\r\n        case MUL_INT_LIT16:\r\n            to = nMul(vb, nInt(content), \"I\");\r\n            break;\r\n        case DIV_INT_LIT16:\r\n        case DIV_INT_LIT8:\r\n            to = nDiv(vb, nInt(content), \"I\");\r\n            break;\r\n        case REM_INT_LIT16:\r\n        case REM_INT_LIT8:\r\n            to = nRem(vb, nInt(content), \"I\");\r\n            break;\r\n        case AND_INT_LIT16:\r\n        case AND_INT_LIT8:\r\n            to = nAnd(vb, nInt(content), content < 0 || content > 1 ? \"I\" : TypeClass.ZI.name);\r\n            break;\r\n        case OR_INT_LIT16:\r\n        case OR_INT_LIT8:\r\n            to = nOr(vb, nInt(content), content < 0 || content > 1 ? \"I\" : TypeClass.ZI.name);\r\n            break;\r\n        case XOR_INT_LIT16:\r\n        case XOR_INT_LIT8:\r\n            to = nXor(vb, nInt(content), content < 0 || content > 1 ? \"I\" : TypeClass.ZI.name);\r\n            break;\r\n        case SHL_INT_LIT8:\r\n            to = nShl(vb, nInt(content), \"I\");\r\n            break;\r\n        case SHR_INT_LIT8:\r\n            to = nShr(vb, nInt(content), \"I\");\r\n            break;\r\n        case USHR_INT_LIT8:\r\n            to = nUshr(vb, nInt(content), \"I\");\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n        x(nAssign(va, to));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt3R(Op op, int a, int b, int c) {\r\n        Value va = locals[a];\r\n        Value vb = locals[b];\r\n        Value vc = locals[c];\r\n        switch (op) {\r\n        case APUT:\r\n            x(nAssign(nArray(vb, vc, TypeClass.IF.name), va));\r\n            break;\r\n        case APUT_BOOLEAN:\r\n            x(nAssign(nArray(vb, vc, \"Z\"), va));\r\n            break;\r\n        case APUT_BYTE:\r\n            x(nAssign(nArray(vb, vc, \"B\"), va));\r\n            break;\r\n        case APUT_CHAR:\r\n            x(nAssign(nArray(vb, vc, \"C\"), va));\r\n            break;\r\n        case APUT_OBJECT:\r\n            x(nAssign(nArray(vb, vc, \"L\"), va));\r\n            break;\r\n        case APUT_SHORT:\r\n            x(nAssign(nArray(vb, vc, \"S\"), va));\r\n            break;\r\n        case APUT_WIDE:\r\n            x(nAssign(nArray(vb, vc, TypeClass.JD.name), va));\r\n            break;\r\n        case AGET:\r\n            x(nAssign(va, nArray(vb, vc, TypeClass.IF.name)));\r\n            break;\r\n        case AGET_BOOLEAN:\r\n            x(nAssign(va, nArray(vb, vc, \"Z\")));\r\n            break;\r\n        case AGET_BYTE:\r\n            x(nAssign(va, nArray(vb, vc, \"B\")));\r\n            break;\r\n        case AGET_CHAR:\r\n            x(nAssign(va, nArray(vb, vc, \"C\")));\r\n            break;\r\n        case AGET_OBJECT:\r\n            x(nAssign(va, nArray(vb, vc, \"L\")));\r\n            break;\r\n        case AGET_SHORT:\r\n            x(nAssign(va, nArray(vb, vc, \"S\")));\r\n            break;\r\n        case AGET_WIDE:\r\n            x(nAssign(va, nArray(vb, vc, TypeClass.JD.name)));\r\n            break;\r\n        case CMP_LONG:\r\n            x(nAssign(va, nLCmp(vb, vc)));\r\n            break;\r\n        case CMPG_DOUBLE:\r\n            x(nAssign(va, nDCmpg(vb, vc)));\r\n            break;\r\n        case CMPG_FLOAT:\r\n            x(nAssign(va, nFCmpg(vb, vc)));\r\n            break;\r\n        case CMPL_DOUBLE:\r\n            x(nAssign(va, nDCmpl(vb, vc)));\r\n            break;\r\n        case CMPL_FLOAT:\r\n            x(nAssign(va, nFCmpl(vb, vc)));\r\n            break;\r\n        case ADD_DOUBLE:\r\n            x(nAssign(va, nAdd(vb, vc, \"D\")));\r\n            break;\r\n        case ADD_FLOAT:\r\n            x(nAssign(va, nAdd(vb, vc, \"F\")));\r\n            break;\r\n        case ADD_INT:\r\n            x(nAssign(va, nAdd(vb, vc, \"I\")));\r\n            break;\r\n        case ADD_LONG:\r\n            x(nAssign(va, nAdd(vb, vc, \"J\")));\r\n            break;\r\n        case SUB_DOUBLE:\r\n            x(nAssign(va, nSub(vb, vc, \"D\")));\r\n            break;\r\n        case SUB_FLOAT:\r\n            x(nAssign(va, nSub(vb, vc, \"F\")));\r\n            break;\r\n        // case RSUB_INT:\r\n        // x(nAssign(va, nSub(vc, vb, \"I\")));\r\n        // break;\r\n        case SUB_INT:\r\n            x(nAssign(va, nSub(vb, vc, \"I\")));\r\n            break;\r\n        case SUB_LONG:\r\n            x(nAssign(va, nSub(vb, vc, \"J\")));\r\n            break;\r\n        case MUL_DOUBLE:\r\n            x(nAssign(va, nMul(vb, vc, \"D\")));\r\n            break;\r\n        case MUL_FLOAT:\r\n            x(nAssign(va, nMul(vb, vc, \"F\")));\r\n            break;\r\n        case MUL_INT:\r\n            x(nAssign(va, nMul(vb, vc, \"I\")));\r\n            break;\r\n        case MUL_LONG:\r\n            x(nAssign(va, nMul(vb, vc, \"J\")));\r\n            break;\r\n        case DIV_DOUBLE:\r\n            x(nAssign(va, nDiv(vb, vc, \"D\")));\r\n            break;\r\n        case DIV_FLOAT:\r\n            x(nAssign(va, nDiv(vb, vc, \"F\")));\r\n            break;\r\n        case DIV_INT:\r\n            x(nAssign(va, nDiv(vb, vc, \"I\")));\r\n            break;\r\n        case DIV_LONG:\r\n            x(nAssign(va, nDiv(vb, vc, \"J\")));\r\n            break;\r\n        case REM_DOUBLE:\r\n            x(nAssign(va, nRem(vb, vc, \"D\")));\r\n            break;\r\n        case REM_FLOAT:\r\n            x(nAssign(va, nRem(vb, vc, \"F\")));\r\n            break;\r\n        case REM_INT:\r\n            x(nAssign(va, nRem(vb, vc, \"I\")));\r\n            break;\r\n        case REM_LONG:\r\n            x(nAssign(va, nRem(vb, vc, \"J\")));\r\n            break;\r\n        case AND_INT:\r\n            x(nAssign(va, nAnd(vb, vc, TypeClass.ZI.name)));\r\n            break;\r\n        case AND_LONG:\r\n            x(nAssign(va, nAnd(vb, vc, \"J\")));\r\n            break;\r\n        case OR_INT:\r\n            x(nAssign(va, nOr(vb, vc, TypeClass.ZI.name)));\r\n            break;\r\n        case OR_LONG:\r\n            x(nAssign(va, nOr(vb, vc, \"J\")));\r\n            break;\r\n        case XOR_INT:\r\n            x(nAssign(va, nXor(vb, vc, TypeClass.ZI.name)));\r\n            break;\r\n        case XOR_LONG:\r\n            x(nAssign(va, nXor(vb, vc, \"J\")));\r\n            break;\r\n        case SHL_INT:\r\n            x(nAssign(va, nShl(vb, vc, \"I\")));\r\n            break;\r\n        case SHL_LONG:\r\n            x(nAssign(va, nShl(vb, vc, \"J\")));\r\n            break;\r\n        case SHR_INT:\r\n            x(nAssign(va, nShr(vb, vc, \"I\")));\r\n            break;\r\n        case SHR_LONG:\r\n            x(nAssign(va, nShr(vb, vc, \"J\")));\r\n            break;\r\n        case USHR_INT:\r\n            x(nAssign(va, nUshr(vb, vc, \"I\")));\r\n            break;\r\n        case USHR_LONG:\r\n            x(nAssign(va, nUshr(vb, vc, \"J\")));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitTypeStmt(Op op, int a, int b, String type) {\r\n        switch (op) {\r\n        case INSTANCE_OF:\r\n            list.add(nAssign(locals[a], nInstanceOf(locals[b], type)));\r\n            break;\r\n        case NEW_ARRAY:\r\n            list.add(nAssign(locals[a], nNewArray(type.substring(1), locals[b])));\r\n            break;\r\n        case CHECK_CAST:\r\n            list.add(nAssign(locals[a], nCheckCast(locals[a], type)));\r\n            break;\r\n        case NEW_INSTANCE:\r\n            list.add(nAssign(locals[a], nNew(type)));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitFillArrayDataStmt(Op op, int ra, Object array) {\r\n        x(nFillArrayData(locals[ra], nArrayValue(array)));\r\n    }\r\n\r\n    @Override\r\n    public void visitConstStmt(Op op, int toReg, Object value) {\r\n        switch (op) {\r\n        case CONST:\r\n        case CONST_16:\r\n        case CONST_4:\r\n        case CONST_HIGH16:\r\n            x(nAssign(locals[toReg], nInt((Integer) value)));\r\n            break;\r\n        case CONST_WIDE:\r\n        case CONST_WIDE_16:\r\n        case CONST_WIDE_32:\r\n        case CONST_WIDE_HIGH16:\r\n            x(nAssign(locals[toReg], nLong((Long) value)));\r\n            break;\r\n        case CONST_CLASS:\r\n            x(nAssign(locals[toReg], nType((DexType) value)));\r\n            break;\r\n        case CONST_STRING:\r\n        case CONST_STRING_JUMBO:\r\n            x(nAssign(locals[toReg], nString((String) value)));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    /*\r\n     * (non-Javadoc)\r\n     * \r\n     * @see com.googlecode.dex2jar.visitors.DexCodeVisitor#visitEnd()\r\n     */\r\n    @Override\r\n    public void visitEnd() {\r\n        irMethod.locals.addAll(Arrays.asList(this.locals));\r\n        irMethod.locals.add(tmpLocal);\r\n        this.locals = null;\r\n    }\r\n\r\n    @Override\r\n    public void visitFieldStmt(Op op, int a, int b, Field field) {\r\n        switch (op) {\r\n        case IGET:\r\n        case IGET_BOOLEAN:\r\n        case IGET_BYTE:\r\n        case IGET_CHAR:\r\n        case IGET_OBJECT:\r\n        case IGET_SHORT:\r\n        case IGET_WIDE:\r\n            list.add(nAssign(locals[a], nField(locals[b], field.getOwner(), field.getName(), field.getType())));\r\n            break;\r\n        case IPUT:\r\n        case IPUT_BOOLEAN:\r\n        case IPUT_BYTE:\r\n        case IPUT_CHAR:\r\n        case IPUT_OBJECT:\r\n        case IPUT_SHORT:\r\n        case IPUT_WIDE:\r\n            list.add(nAssign(nField(locals[b], field.getOwner(), field.getName(), field.getType()), locals[a]));\r\n            break;\r\n        case SGET:\r\n        case SGET_BOOLEAN:\r\n        case SGET_BYTE:\r\n        case SGET_CHAR:\r\n        case SGET_OBJECT:\r\n        case SGET_SHORT:\r\n        case SGET_WIDE:\r\n            list.add(nAssign(locals[a], nStaticField(field.getOwner(), field.getName(), field.getType())));\r\n            break;\r\n        case SPUT:\r\n        case SPUT_BOOLEAN:\r\n        case SPUT_BYTE:\r\n        case SPUT_CHAR:\r\n        case SPUT_OBJECT:\r\n        case SPUT_SHORT:\r\n        case SPUT_WIDE:\r\n            list.add(nAssign(nStaticField(field.getOwner(), field.getName(), field.getType()), locals[a]));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitFilledNewArrayStmt(Op opc, int[] args, String type) {\r\n        Local array = tmpLocal;\r\n        String elem = type.substring(1);\r\n        list.add(nAssign(array, nNewArray(elem, nInt(args.length))));\r\n        for (int i = 0; i < args.length; i++) {\r\n            list.add(nAssign(nArray(array, nInt(i), elem), locals[args[i]]));\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\r\n        switch (op) {\r\n        case GOTO:\r\n        case GOTO_16:\r\n        case GOTO_32:\r\n            x(nGoto(toLabelStmt(label)));\r\n            break;\r\n        case IF_EQ:\r\n            x(nIf(Exprs.nEq(locals[a], locals[b], TypeClass.ZIL.name), toLabelStmt(label)));\r\n            break;\r\n        case IF_GE:\r\n            x(nIf(Exprs.nGe(locals[a], locals[b], \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_GT:\r\n            x(nIf(Exprs.nGt(locals[a], locals[b], \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_LE:\r\n            x(nIf(Exprs.nLe(locals[a], locals[b], \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_LT:\r\n            x(nIf(Exprs.nLt(locals[a], locals[b], \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_NE:\r\n            x(nIf(Exprs.nNe(locals[a], locals[b], TypeClass.ZIL.name), toLabelStmt(label)));\r\n            break;\r\n        case IF_EQZ:\r\n            x(nIf(Exprs.nEq(locals[a], nInt(0), TypeClass.ZIL.name), toLabelStmt(label)));\r\n            break;\r\n        case IF_GEZ:\r\n            x(nIf(Exprs.nGe(locals[a], nInt(0), \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_GTZ:\r\n            x(nIf(Exprs.nGt(locals[a], nInt(0), \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_LEZ:\r\n            x(nIf(Exprs.nLe(locals[a], nInt(0), \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_LTZ:\r\n            x(nIf(Exprs.nLt(locals[a], nInt(0), \"I\"), toLabelStmt(label)));\r\n            break;\r\n        case IF_NEZ:\r\n            x(nIf(Exprs.nNe(locals[a], nInt(0), TypeClass.ZIL.name), toLabelStmt(label)));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitLabel(DexLabel label) {\r\n        list.add(toLabelStmt(label));\r\n    }\r\n\r\n    @Override\r\n    public void visitSparseSwitchStmt(Op op, int aA, int[] cases, DexLabel[] labels) {\r\n        LabelStmt[] lss = new LabelStmt[cases.length];\r\n        for (int i = 0; i < cases.length; i++) {\r\n            lss[i] = toLabelStmt(labels[i]);\r\n        }\r\n        LabelStmt d = new LabelStmt();\r\n        x(nLookupSwitch(locals[aA], cases, lss, d));\r\n        x(d);\r\n    }\r\n\r\n    @Override\r\n    public void visitMethodStmt(Op op, int[] args, Method method) {\r\n        Value[] vs;\r\n        if (args.length > 0) {\r\n            int i = 0;\r\n            List<Local> ps = new ArrayList<Local>(args.length);\r\n            if (op == Op.INVOKE_STATIC || op == Op.INVOKE_STATIC_RANGE) {\r\n                ;\r\n            } else {\r\n                ps.add(locals[args[i]]);\r\n                i++;\r\n            }\r\n            for (String t : method.getParameterTypes()) {\r\n                ps.add(locals[args[i]]);\r\n                if (t.equals(\"J\") || t.equals(\"D\")) {\r\n                    i += 2;\r\n                } else {\r\n                    i++;\r\n                }\r\n            }\r\n            vs = ps.toArray(new Value[ps.size()]);\r\n        } else {\r\n            vs = new Value[0];\r\n        }\r\n\r\n        Value invoke = null;\r\n        switch (op) {\r\n        case INVOKE_VIRTUAL_RANGE:\r\n        case INVOKE_VIRTUAL:\r\n            invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method.getParameterTypes(),\r\n                    method.getReturnType());\r\n            break;\r\n        case INVOKE_SUPER_RANGE:\r\n        case INVOKE_DIRECT_RANGE:\r\n        case INVOKE_SUPER:\r\n        case INVOKE_DIRECT:\r\n            invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method.getParameterTypes(),\r\n                    method.getReturnType());\r\n            break;\r\n        case INVOKE_STATIC_RANGE:\r\n        case INVOKE_STATIC:\r\n            invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method.getParameterTypes(),\r\n                    method.getReturnType());\r\n            break;\r\n        case INVOKE_INTERFACE_RANGE:\r\n        case INVOKE_INTERFACE:\r\n            invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method.getParameterTypes(),\r\n                    method.getReturnType());\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n        if (\"V\".equals(method.getReturnType())) {\r\n            x(nVoidInvoke(invoke));\r\n        } else {\r\n            x(nAssign(tmpLocal, invoke));\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt1R(Op op, int reg) {\r\n        Local va = locals[reg];\r\n        switch (op) {\r\n        case MONITOR_ENTER:\r\n            x(nLock(va));\r\n            break;\r\n        case MONITOR_EXIT:\r\n            x(nUnLock(va));\r\n            break;\r\n        case RETURN:\r\n        case RETURN_WIDE:\r\n        case RETURN_OBJECT:\r\n            x(nReturn(va));\r\n            break;\r\n        case THROW:\r\n            x(nThrow(va));\r\n            break;\r\n        case MOVE_RESULT:\r\n        case MOVE_RESULT_WIDE:\r\n        case MOVE_RESULT_OBJECT:\r\n            if (lastIsInvokeOrFilledNewArray) { // right position\r\n                x(nAssign(va, tmpLocal));\r\n            } else { // wrong position, replace with throw new RuntimeExceptoin(\"...\");\r\n                System.err.println(\"WARN: find wrong position of \" + op + \" in method \" + method);\r\n                x(nThrow(nInvokeNew(new Value[] { nString(\"d2j: wrong position of \" + op) },\r\n                        new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/RuntimeException;\")));\r\n            }\r\n\r\n            break;\r\n        case MOVE_EXCEPTION:\r\n            x(nIdentity(va, nExceptionRef(\"Ljava/lang/Throwable;\")));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt2R(Op op, int a, int b) {\r\n        Local va = locals[a];\r\n        Local vb = locals[b];\r\n        Value to = null;\r\n        switch (op) {\r\n        case MOVE:\r\n        case MOVE_16:\r\n        case MOVE_FROM16:\r\n        case MOVE_OBJECT:\r\n        case MOVE_OBJECT_16:\r\n        case MOVE_OBJECT_FROM16:\r\n        case MOVE_WIDE:\r\n        case MOVE_WIDE_FROM16:\r\n        case MOVE_WIDE_16:\r\n            to = vb;\r\n            break;\r\n        case ARRAY_LENGTH:\r\n            to = nLength(vb);\r\n            break;\r\n        case ADD_DOUBLE_2ADDR:\r\n            to = nAdd(va, vb, \"D\");\r\n            break;\r\n        case ADD_FLOAT_2ADDR:\r\n            to = nAdd(va, vb, \"F\");\r\n            break;\r\n        case ADD_INT_2ADDR:\r\n            to = nAdd(va, vb, \"I\");\r\n            break;\r\n        case ADD_LONG_2ADDR:\r\n            to = nAdd(va, vb, \"J\");\r\n            break;\r\n        case SUB_DOUBLE_2ADDR:\r\n            to = nSub(va, vb, \"D\");\r\n            break;\r\n        case SUB_FLOAT_2ADDR:\r\n            to = nSub(va, vb, \"F\");\r\n            break;\r\n        case SUB_INT_2ADDR:\r\n            to = nSub(va, vb, \"I\");\r\n            break;\r\n        case SUB_LONG_2ADDR:\r\n            to = nSub(va, vb, \"J\");\r\n            break;\r\n        case MUL_DOUBLE_2ADDR:\r\n            to = nMul(va, vb, \"D\");\r\n            break;\r\n        case MUL_FLOAT_2ADDR:\r\n            to = nMul(va, vb, \"F\");\r\n            break;\r\n        case MUL_INT_2ADDR:\r\n            to = nMul(va, vb, \"I\");\r\n            break;\r\n        case MUL_LONG_2ADDR:\r\n            to = nMul(va, vb, \"J\");\r\n            break;\r\n        case DIV_DOUBLE_2ADDR:\r\n            to = nDiv(va, vb, \"D\");\r\n            break;\r\n        case DIV_FLOAT_2ADDR:\r\n            to = nDiv(va, vb, \"F\");\r\n            break;\r\n        case DIV_INT_2ADDR:\r\n            to = nDiv(va, vb, \"I\");\r\n            break;\r\n        case DIV_LONG_2ADDR:\r\n            to = nDiv(va, vb, \"J\");\r\n            break;\r\n        case REM_DOUBLE_2ADDR:\r\n            to = nRem(va, vb, \"D\");\r\n            break;\r\n        case REM_FLOAT_2ADDR:\r\n            to = nRem(va, vb, \"F\");\r\n            break;\r\n        case REM_INT_2ADDR:\r\n            to = nRem(va, vb, \"I\");\r\n            break;\r\n        case REM_LONG_2ADDR:\r\n            to = nRem(va, vb, \"J\");\r\n            break;\r\n        case AND_INT_2ADDR:\r\n            to = nAnd(va, vb, TypeClass.ZI.name);\r\n            break;\r\n        case AND_LONG_2ADDR:\r\n            to = nAnd(va, vb, \"J\");\r\n            break;\r\n        case OR_INT_2ADDR:\r\n            to = nOr(va, vb, TypeClass.ZI.name);\r\n            break;\r\n        case OR_LONG_2ADDR:\r\n            to = nOr(va, vb, \"J\");\r\n            break;\r\n        case XOR_INT_2ADDR:\r\n            to = nXor(va, vb, TypeClass.ZI.name);\r\n            break;\r\n        case XOR_LONG_2ADDR:\r\n            to = nXor(va, vb, \"J\");\r\n            break;\r\n        case SHL_INT_2ADDR:\r\n            to = nShl(va, vb, \"I\");\r\n            break;\r\n        case SHL_LONG_2ADDR:\r\n            to = nShl(va, vb, \"J\");\r\n            break;\r\n        case SHR_INT_2ADDR:\r\n            to = nShr(va, vb, \"I\");\r\n            break;\r\n        case SHR_LONG_2ADDR:\r\n            to = nShr(va, vb, \"J\");\r\n            break;\r\n        case USHR_INT_2ADDR:\r\n            to = nUshr(va, vb, \"I\");\r\n            break;\r\n        case USHR_LONG_2ADDR:\r\n            to = nUshr(va, vb, \"J\");\r\n            break;\r\n        case NOT_INT:\r\n            to = nNot(vb, \"I\");\r\n            break;\r\n        case NOT_LONG:\r\n            to = nNot(vb, \"J\");\r\n            break;\r\n        case NEG_DOUBLE:\r\n            to = nNeg(vb, \"D\");\r\n            break;\r\n        case NEG_FLOAT:\r\n            to = nNeg(vb, \"F\");\r\n            break;\r\n        case NEG_INT:\r\n            to = nNeg(vb, \"I\");\r\n            break;\r\n        case NEG_LONG:\r\n            to = nNeg(vb, \"J\");\r\n            break;\r\n        case INT_TO_BYTE:\r\n            to = nCast(vb, \"I\", \"B\");\r\n            break;\r\n        case INT_TO_CHAR:\r\n            to = nCast(vb, \"I\", \"C\");\r\n            break;\r\n        case INT_TO_DOUBLE:\r\n            to = nCast(vb, \"I\", \"D\");\r\n            break;\r\n        case INT_TO_FLOAT:\r\n            to = nCast(vb, \"I\", \"F\");\r\n            break;\r\n        case INT_TO_LONG:\r\n            to = nCast(vb, \"I\", \"J\");\r\n            break;\r\n        case INT_TO_SHORT:\r\n            to = nCast(vb, \"I\", \"S\");\r\n            break;\r\n        case FLOAT_TO_DOUBLE:\r\n            to = nCast(vb, \"F\", \"D\");\r\n            break;\r\n        case FLOAT_TO_INT:\r\n            to = nCast(vb, \"F\", \"I\");\r\n            break;\r\n        case FLOAT_TO_LONG:\r\n            to = nCast(vb, \"F\", \"J\");\r\n            break;\r\n        case DOUBLE_TO_FLOAT:\r\n            to = nCast(vb, \"D\", \"F\");\r\n            break;\r\n        case DOUBLE_TO_INT:\r\n            to = nCast(vb, \"D\", \"I\");\r\n            break;\r\n        case DOUBLE_TO_LONG:\r\n            to = nCast(vb, \"D\", \"J\");\r\n            break;\r\n        case LONG_TO_DOUBLE:\r\n            to = nCast(vb, \"J\", \"D\");\r\n            break;\r\n        case LONG_TO_FLOAT:\r\n            to = nCast(vb, \"J\", \"F\");\r\n            break;\r\n        case LONG_TO_INT:\r\n            to = nCast(vb, \"J\", \"I\");\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n        x(nAssign(va, to));\r\n    }\r\n\r\n    @Override\r\n    public void visitStmt0R(Op op) {\r\n        switch (op) {\r\n        case RETURN_VOID:\r\n            x(nReturnVoid());\r\n            break;\r\n        case NOP:\r\n            // ignore\r\n            break;\r\n        case BAD_OP:\r\n            x(nThrow(nInvokeNew(new Value[] { nString(\"bad dex opcode\") }, new String[] { \"Ljava/lang/String;\" },\r\n                    \"Ljava/lang/VerifyError;\")));\r\n            break;\r\n        default:\r\n            throw new RuntimeException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void visitPackedSwitchStmt(Op op, int aA, int first_case, DexLabel[] labels) {\r\n        LabelStmt[] lss = new LabelStmt[labels.length];\r\n        for (int i = 0; i < labels.length; i++) {\r\n            lss[i] = toLabelStmt(labels[i]);\r\n        }\r\n        LabelStmt d = new LabelStmt();\r\n        x(nTableSwitch(locals[aA], first_case, lss, d));\r\n        x(d);\r\n    }\r\n\r\n    @Override\r\n    public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handlers, String[] types) {\r\n        LabelStmt xlabelStmts[] = new LabelStmt[types.length];\r\n        for (int i = 0; i < types.length; i++) {\r\n            xlabelStmts[i] = toLabelStmt(handlers[i]);\r\n        }\r\n        irMethod.traps.add(new Trap(toLabelStmt(start), toLabelStmt(end), xlabelStmts, types));\r\n    }\r\n\r\n    boolean lastIsInvokeOrFilledNewArray = false;\r\n\r\n    public IrMethod convert(DexCodeNode codeNode) {\r\n        if (codeNode.tryStmts != null) {\r\n            for (TryCatchNode n : codeNode.tryStmts) {\r\n                n.accept(this);\r\n            }\r\n        }\r\n        if (codeNode.debugNode != null) {\r\n            DexDebugVisitor ddv = this.visitDebug();\r\n            if (ddv != null) {\r\n                codeNode.debugNode.accept(ddv);\r\n                ddv.visitEnd();\r\n            }\r\n        }\r\n        lastIsInvokeOrFilledNewArray = false;\r\n        if (codeNode.totalRegister >= 0) {\r\n            this.visitRegister(codeNode.totalRegister);\r\n        }\r\n        for (DexStmtNode n : codeNode.stmts) {\r\n            n.accept(this);\r\n            if (n instanceof FilledNewArrayStmtNode) {\r\n                lastIsInvokeOrFilledNewArray = true;\r\n            } else if (n instanceof MethodStmtNode) {\r\n                lastIsInvokeOrFilledNewArray = !((MethodStmtNode) n).method.getReturnType().equals(\"V\");\r\n            } else if (!(n instanceof DexLabelStmtNode)) {\r\n                lastIsInvokeOrFilledNewArray = false;\r\n            }\r\n        }\r\n\r\n        visitEnd();\r\n        return irMethod;\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2jar.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.file.FileSystem;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.spi.FileSystemProvider;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.googlecode.d2j.node.DexMethodNode;\nimport com.googlecode.d2j.reader.BaseDexFileReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\nimport com.googlecode.d2j.converter.IR2JConverter;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.dex2jar.ir.IrMethod;\nimport com.googlecode.dex2jar.ir.stmt.LabelStmt;\nimport com.googlecode.dex2jar.ir.stmt.Stmt;\nimport org.objectweb.asm.commons.Remapper;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\n\npublic class Dex2jar {\n    public static Dex2jar from(byte[] in) throws IOException {\n        return from(new DexFileReader(ZipUtil.readDex(in)));\n    }\n\n    public static Dex2jar from(ByteBuffer in) throws IOException {\n        return from(new DexFileReader(in));\n    }\n\n    public static Dex2jar from(BaseDexFileReader reader) {\n        return new Dex2jar(reader);\n    }\n\n    public static Dex2jar from(File in) throws IOException {\n        return from(Files.readAllBytes(in.toPath()));\n    }\n\n    public static Dex2jar from(InputStream in) throws IOException {\n        return from(new DexFileReader(in));\n    }\n\n    public static Dex2jar from(String in) throws IOException {\n        return from(new File(in));\n    }\n\n    private DexExceptionHandler exceptionHandler;\n\n    final private BaseDexFileReader reader;\n    private int readerConfig;\n    private int v3Config;\n\n    private Dex2jar(BaseDexFileReader reader) {\n        super();\n        this.reader = reader;\n        readerConfig |= DexFileReader.SKIP_DEBUG;\n    }\n\n    private void doTranslate(final Path dist) throws IOException {\n\n        DexFileNode fileNode = new DexFileNode();\n        try {\n            reader.accept(fileNode, readerConfig | DexFileReader.IGNORE_READ_EXCEPTION);\n        } catch (Exception ex) {\n            exceptionHandler.handleFileException(ex);\n        }\n        ClassVisitorFactory cvf = new ClassVisitorFactory() {\n            @Override\n            public ClassVisitor create(final String name) {\n                final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n                final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw);\n                return new ClassVisitor(Opcodes.ASM5, rca) {\n                    @Override\n                    public void visitEnd() {\n                        super.visitEnd();\n                        String className = rca.getClassName();\n                        byte[] data;\n                        try {\n                            // FIXME handle 'java.lang.RuntimeException: Method code too large!'\n                            data = cw.toByteArray();\n                        } catch (Exception ex) {\n                            System.err.println(String.format(\"ASM fail to generate .class file: %s\", className));\n                            exceptionHandler.handleFileException(ex);\n                            return;\n                        }\n                        try {\n                            Path dist1 = dist.resolve(className + \".class\");\n                            Path parent = dist1.getParent();\n                            if (parent != null && !Files.exists(parent)) {\n                                Files.createDirectories(parent);\n                            }\n                            Files.write(dist1, data);\n                        } catch (IOException e) {\n                            e.printStackTrace(System.err);\n                        }\n                    }\n                };\n            }\n        };\n\n        new ExDex2Asm(exceptionHandler) {\n            public void convertCode(DexMethodNode methodNode, MethodVisitor mv) {\n                if ((readerConfig & DexFileReader.SKIP_CODE) != 0 && methodNode.method.getName().equals(\"<clinit>\")) {\n                    // also skip clinit\n                    return;\n                }\n                super.convertCode(methodNode, mv);\n            }\n\n            @Override\n            public void optimize(IrMethod irMethod) {\n                T_cleanLabel.transform(irMethod);\n                if (0 != (v3Config & V3.TOPOLOGICAL_SORT)) {\n                    // T_topologicalSort.transform(irMethod);\n                }\n                T_deadCode.transform(irMethod);\n                T_removeLocal.transform(irMethod);\n                T_removeConst.transform(irMethod);\n                T_zero.transform(irMethod);\n                if (T_npe.transformReportChanged(irMethod)) {\n                    T_deadCode.transform(irMethod);\n                    T_removeLocal.transform(irMethod);\n                    T_removeConst.transform(irMethod);\n                }\n                T_new.transform(irMethod);\n                T_fillArray.transform(irMethod);\n                T_agg.transform(irMethod);\n                T_multiArray.transform(irMethod);\n                T_voidInvoke.transform(irMethod);\n                if (0 != (v3Config & V3.PRINT_IR)) {\n                    int i = 0;\n                    for (Stmt p : irMethod.stmts) {\n                        if (p.st == Stmt.ST.LABEL) {\n                            LabelStmt labelStmt = (LabelStmt) p;\n                            labelStmt.displayName = \"L\" + i++;\n                        }\n                    }\n                    System.out.println(irMethod);\n                }\n                T_type.transform(irMethod);\n                T_unssa.transform(irMethod);\n                T_ir2jRegAssign.transform(irMethod);\n                T_trimEx.transform(irMethod);\n            }\n\n            @Override\n            public void ir2j(IrMethod irMethod, MethodVisitor mv) {\n                new IR2JConverter(0 != (V3.OPTIMIZE_SYNCHRONIZED & v3Config)).convert(irMethod, mv);\n            }\n        }.convertDex(fileNode, cvf);\n\n    }\n\n    public DexExceptionHandler getExceptionHandler() {\n        return exceptionHandler;\n    }\n\n    public BaseDexFileReader getReader() {\n        return reader;\n    }\n\n    public Dex2jar reUseReg(boolean b) {\n        if (b) {\n            this.v3Config |= V3.REUSE_REGISTER;\n        } else {\n            this.v3Config &= ~V3.REUSE_REGISTER;\n        }\n        return this;\n    }\n\n    public Dex2jar topoLogicalSort(boolean b) {\n        if (b) {\n            this.v3Config |= V3.TOPOLOGICAL_SORT;\n        } else {\n            this.v3Config &= ~V3.TOPOLOGICAL_SORT;\n        }\n        return this;\n    }\n\n    public Dex2jar noCode(boolean b) {\n        if (b) {\n            this.readerConfig |= DexFileReader.SKIP_CODE | DexFileReader.KEEP_CLINIT;\n        } else {\n            this.readerConfig &= ~(DexFileReader.SKIP_CODE | DexFileReader.KEEP_CLINIT);\n        }\n        return this;\n    }\n\n    public Dex2jar optimizeSynchronized(boolean b) {\n        if (b) {\n            this.v3Config |= V3.OPTIMIZE_SYNCHRONIZED;\n        } else {\n            this.v3Config &= ~V3.OPTIMIZE_SYNCHRONIZED;\n        }\n        return this;\n    }\n\n    public Dex2jar printIR(boolean b) {\n        if (b) {\n            this.v3Config |= V3.PRINT_IR;\n        } else {\n            this.v3Config &= ~V3.PRINT_IR;\n        }\n        return this;\n    }\n\n    public Dex2jar reUseReg() {\n        this.v3Config |= V3.REUSE_REGISTER;\n        return this;\n    }\n\n    public Dex2jar optimizeSynchronized() {\n        this.v3Config |= V3.OPTIMIZE_SYNCHRONIZED;\n        return this;\n    }\n\n    public Dex2jar printIR() {\n        this.v3Config |= V3.PRINT_IR;\n        return this;\n    }\n\n    public Dex2jar topoLogicalSort() {\n        this.v3Config |= V3.TOPOLOGICAL_SORT;\n        return this;\n    }\n\n    public void setExceptionHandler(DexExceptionHandler exceptionHandler) {\n        this.exceptionHandler = exceptionHandler;\n    }\n\n    public Dex2jar skipDebug(boolean b) {\n        if (b) {\n            this.readerConfig |= DexFileReader.SKIP_DEBUG;\n        } else {\n            this.readerConfig &= ~DexFileReader.SKIP_DEBUG;\n        }\n        return this;\n    }\n\n    public Dex2jar skipDebug() {\n        this.readerConfig |= DexFileReader.SKIP_DEBUG;\n        return this;\n    }\n\n    public void to(Path file) throws IOException {\n        if (Files.exists(file) && Files.isDirectory(file)) {\n            doTranslate(file);\n        } else {\n            try (FileSystem fs = createZip(file)) {\n                doTranslate(fs.getPath(\"/\"));\n            }\n        }\n    }\n\n    private static FileSystem createZip(Path output) throws IOException {\n        Map<String, Object> env = new HashMap<>();\n        env.put(\"create\", \"true\");\n        Files.deleteIfExists(output);\n        Path parent = output.getParent();\n        if (parent != null && !Files.exists(parent)) {\n            Files.createDirectories(parent);\n        }\n        for (FileSystemProvider p : FileSystemProvider.installedProviders()) {\n            String s = p.getScheme();\n            if (\"jar\".equals(s) || \"zip\".equalsIgnoreCase(s)) {\n                return p.newFileSystem(output, env);\n            }\n        }\n        throw new IOException(\"cant find zipfs support\");\n    }\n\n    public Dex2jar withExceptionHandler(DexExceptionHandler exceptionHandler) {\n        this.exceptionHandler = exceptionHandler;\n        return this;\n    }\n\n    public Dex2jar skipExceptions(boolean b) {\n        if (b) {\n            this.readerConfig |= DexFileReader.SKIP_EXCEPTION;\n        } else {\n            this.readerConfig &= ~DexFileReader.SKIP_EXCEPTION;\n        }\n        return this;\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/DexExceptionHandler.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport org.objectweb.asm.MethodVisitor;\n\npublic interface DexExceptionHandler {\n    public void handleFileException(Exception e);\n\n    public void handleMethodTranslateException(Method method, DexMethodNode methodNode, MethodVisitor mv, Exception e);\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/DexFix.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFieldNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\n\n/**\n * 1. Dex omit the value of static-final filed if it is the default value.\n *\n * 2. static-final field init by zero, but assigned in clinit\n *\n * this method is try to fix the problems.\n */\npublic class DexFix {\n    private static final int ACC_STATIC_FINAL = DexConstants.ACC_STATIC | DexConstants.ACC_FINAL;\n\n    public static void fixStaticFinalFieldValue(final DexFileNode dex) {\n        if (dex.clzs != null) {\n            for (DexClassNode classNode : dex.clzs) {\n                fixStaticFinalFieldValue(classNode);\n            }\n        }\n    }\n\n    /**\n     * init value to default if the field is static and final, and the field is not init in clinit method\n     *\n     * erase the default value if the field is init in clinit method\n     * \n     * @param classNode\n     */\n    public static void fixStaticFinalFieldValue(final DexClassNode classNode) {\n        if (classNode.fields == null) {\n            return;\n        }\n        final Map<String, DexFieldNode> fs = new HashMap<>();\n        final Map<String, DexFieldNode> shouldNotBeAssigned = new HashMap<>();\n        for (DexFieldNode fn : classNode.fields) {\n            if ((fn.access & ACC_STATIC_FINAL) == ACC_STATIC_FINAL) {\n                if (fn.cst == null) {\n                    char t = fn.field.getType().charAt(0);\n                    if (t == 'L' || t == '[') {\n                        // ignore Object\n                        continue;\n                    }\n                    fs.put(fn.field.getName() + \":\" + fn.field.getType(), fn);\n                } else if (isPrimitiveZero(fn.field.getType(), fn.cst)) {\n                    shouldNotBeAssigned.put(fn.field.getName() + \":\" + fn.field.getType(), fn);\n                }\n            }\n        }\n        if (fs.isEmpty() && shouldNotBeAssigned.isEmpty()) {\n            return;\n        }\n        DexMethodNode node = null;\n        if (classNode.methods != null) {\n            for (DexMethodNode mn : classNode.methods) {\n                if (mn.method.getName().equals(\"<clinit>\")) {\n                    node = mn;\n                    break;\n                }\n            }\n        }\n        if (node != null) {\n            if (node.codeNode != null) {\n                node.codeNode.accept(new DexCodeVisitor() {\n                    @Override\n                    public void visitFieldStmt(Op op, int a, int b, Field field) {\n                        switch (op) {\n                        case SPUT:\n                        case SPUT_BOOLEAN:\n                        case SPUT_BYTE:\n                        case SPUT_CHAR:\n                        case SPUT_OBJECT:\n                        case SPUT_SHORT:\n                        case SPUT_WIDE:\n                            if (field.getOwner().equals(classNode.className)) {\n                                String key = field.getName() + \":\" + field.getType();\n                                fs.remove(key);\n                                DexFieldNode dn = shouldNotBeAssigned.get(key);\n                                if (dn != null) {\n                                    //System.out.println(field.getName() + \":\" + field.getType());\n                                    dn.cst = null;\n                                }\n                            }\n                            break;\n                        default:\n                            // ignored\n                            break;\n                        }\n                    }\n                });\n            } else {\n                // has init but no code\n                return;\n            }\n        }\n\n        for (DexFieldNode fn : fs.values()) {\n            fn.cst = getDefaultValueOfType(fn.field.getType().charAt(0));\n        }\n\n    }\n\n    private static Object getDefaultValueOfType(char t) {\n        switch (t) {\n        case 'B':\n            return Byte.valueOf((byte) 0);\n        case 'Z':\n            return Boolean.FALSE;\n        case 'S':\n            return Short.valueOf((short) 0);\n        case 'C':\n            return Character.valueOf((char) 0);\n        case 'I':\n            return 0;\n        case 'F':\n            return Float.valueOf((float) 0.0);\n        case 'J':\n            return Long.valueOf((long) 0);\n        case 'D':\n            return Double.valueOf(0.0);\n        case '[':\n        case 'L':\n        default:\n            return null;\n            // impossible\n        }\n    }\n\n    static boolean isPrimitiveZero(String desc, Object value) {\n        if (value != null && desc != null && desc.length() > 0) {\n            switch (desc.charAt(0)) {\n            // case 'V':// VOID_TYPE\n            case 'Z':// BOOLEAN_TYPE\n                return ((Boolean) value).booleanValue() == false;\n            case 'C':// CHAR_TYPE\n                return ((Character) value).charValue() == (char) 0;\n            case 'B':// BYTE_TYPE\n                return ((Byte) value).byteValue() == 0;\n            case 'S':// SHORT_TYPE\n                return ((Short) value).shortValue() == 0;\n            case 'I':// INT_TYPE\n                return ((Integer) value).intValue() == 0;\n            case 'F':// FLOAT_TYPE\n                return ((Float) value).floatValue() == 0f;\n            case 'J':// LONG_TYPE\n                return ((Long) value).longValue() == 0L;\n            case 'D':// DOUBLE_TYPE\n                return ((Double) value).doubleValue() == 0.0;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/ExDex2Asm.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\nimport org.objectweb.asm.AsmBridge;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.tree.MethodNode;\n\nimport com.googlecode.d2j.DexException;\nimport com.googlecode.d2j.node.DexMethodNode;\n\npublic class ExDex2Asm extends Dex2Asm {\n    final protected DexExceptionHandler exceptionHandler;\n\n    public ExDex2Asm(DexExceptionHandler exceptionHandler) {\n        this.exceptionHandler = exceptionHandler;\n    }\n\n    @Override\n    public void convertCode(DexMethodNode methodNode, MethodVisitor mv) {\n        MethodVisitor mw = AsmBridge.searchMethodWriter(mv);\n        MethodNode mn = new MethodNode(Opcodes.ASM5, methodNode.access, methodNode.method.getName(),\n                methodNode.method.getDesc(), null, null);\n        try {\n            super.convertCode(methodNode, mn);\n        } catch (Exception ex) {\n            if (exceptionHandler == null) {\n                throw new DexException(ex, \"fail convert code for %s\", methodNode.method);\n            } else {\n                mn.instructions.clear();\n                mn.tryCatchBlocks.clear();\n                exceptionHandler.handleMethodTranslateException(methodNode.method, methodNode, mn, ex);\n            }\n        }\n        // code convert ok, copy to MethodWriter and check for Size\n        mn.accept(mv);\n        if (mw != null) {\n            try {\n                AsmBridge.sizeOfMethodWriter(mw);\n            } catch (Exception ex) {\n                mn.instructions.clear();\n                mn.tryCatchBlocks.clear();\n                exceptionHandler.handleMethodTranslateException(methodNode.method, methodNode, mn, ex);\n                AsmBridge.replaceMethodWriter(mw, mn);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/LambadaNameSafeClassAdapter.java",
    "content": "package com.googlecode.d2j.dex;\n\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.commons.Remapper;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\n\npublic class LambadaNameSafeClassAdapter extends RemappingClassAdapter {\n    public String getClassName() {\n        return remapper.mapType(className);\n    }\n\n    public LambadaNameSafeClassAdapter(ClassVisitor cv) {\n        super(cv, new Remapper() {\n            @Override\n            public String mapType(String type) {\n                if (type == null) {\n                    return null;\n                }\n                return type.replace('-', '_');\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/dex/V3.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex;\n\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * @version $Rev$\n */\npublic class V3  {\n\n    public static final int REUSE_REGISTER = 1 << 0;\n    public static final int TOPOLOGICAL_SORT = 1 << 1;\n    public static final int PRINT_IR = 1 << 2;\n    public static final int OPTIMIZE_SYNCHRONIZED = 1 << 3;\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/com/googlecode/d2j/util/Types.java",
    "content": "package com.googlecode.d2j.util;\n\nimport com.googlecode.d2j.DexException;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Types {\n    /**\n     * @param desc\n     *            a asm method desc, ex: (II)V\n     * @return a array of argument types, ex: [I,I]\n     */\n    public static String[] getParameterTypeDesc(String desc) {\n\n        if (desc.charAt(0) != '(') {\n            throw new DexException(\"not a validate Method Desc %s\", desc);\n        }\n        int x = desc.lastIndexOf(')');\n        if (x < 0) {\n            throw new DexException(\"not a validate Method Desc %s\", desc);\n        }\n        List<String> ps = listDesc(desc.substring(1, x - 1));\n        return ps.toArray(new String[ps.size()]);\n    }\n\n    /**\n     * \n     * @param desc\n     *            a asm method desc, ex: (II)V\n     * @return the desc of return type, ex: V\n     */\n    public static String getReturnTypeDesc(String desc) {\n        int x = desc.lastIndexOf(')');\n        if (x < 0) {\n            throw new DexException(\"not a validate Method Desc %s\", desc);\n        }\n        return desc.substring(x + 1);\n    }\n\n    public static List<String> listDesc(String desc) {\n        List<String> list = new ArrayList<>(5);\n        if (desc == null) {\n            return list;\n        }\n        char[] chars = desc.toCharArray();\n        int i = 0;\n        while (i < chars.length) {\n            switch (chars[i]) {\n            case 'V':\n            case 'Z':\n            case 'C':\n            case 'B':\n            case 'S':\n            case 'I':\n            case 'F':\n            case 'J':\n            case 'D':\n                list.add(Character.toString(chars[i]));\n                i++;\n                break;\n            case '[': {\n                int count = 1;\n                while (chars[i + count] == '[') {\n                    count++;\n                }\n                if (chars[i + count] == 'L') {\n                    count++;\n                    while (chars[i + count] != ';') {\n                        count++;\n                    }\n                }\n                count++;\n                list.add(new String(chars, i, count));\n                i += count;\n                break;\n            }\n            case 'L': {\n                int count = 1;\n                while (chars[i + count] != ';') {\n                    ++count;\n                }\n                count++;\n                list.add(new String(chars, i, count));\n                i += count;\n                break;\n            }\n            default:\n                throw new RuntimeException(\"can't parse type list: \" + desc);\n            }\n        }\n        return list;\n    }\n\n    public static Object[] buildDexStyleSignature(String signature) {\n        int rawLength = signature.length();\n        ArrayList<String> pieces = new ArrayList<String>(20);\n\n        for (int at = 0; at < rawLength; /* at */) {\n            char c = signature.charAt(at);\n            int endAt = at + 1;\n            if (c == 'L') {\n                // Scan to ';' or '<'. Consume ';' but not '<'.\n                while (endAt < rawLength) {\n                    c = signature.charAt(endAt);\n                    if (c == ';') {\n                        endAt++;\n                        break;\n                    } else if (c == '<') {\n                        break;\n                    }\n                    endAt++;\n                }\n            } else {\n                // Scan to 'L' without consuming it.\n                while (endAt < rawLength) {\n                    c = signature.charAt(endAt);\n                    if (c == 'L') {\n                        break;\n                    }\n                    endAt++;\n                }\n            }\n\n            pieces.add(signature.substring(at, endAt));\n            at = endAt;\n        }\n        return pieces.toArray(new Object[pieces.size()]);\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/main/java/org/objectweb/asm/AsmBridge.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2014 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.objectweb.asm;\n\nimport org.objectweb.asm.tree.MethodNode;\n\npublic class AsmBridge {\n    public static MethodVisitor searchMethodWriter(MethodVisitor mv) {\n        while (mv != null && !(mv instanceof MethodWriter)) {\n            mv = mv.mv;\n        }\n        return mv;\n    }\n\n    public static int sizeOfMethodWriter(MethodVisitor mv) {\n        MethodWriter mw = (MethodWriter) mv;\n        return mw.getSize();\n    }\n\n    private static void removeMethodWriter(MethodWriter mw) {\n        // mv must be the last element\n        ClassWriter cw = mw.cw;\n        MethodWriter p = cw.firstMethod;\n        if (p == mw) {\n            cw.firstMethod = null;\n            if (cw.lastMethod == mw) {\n                cw.lastMethod = null;\n            }\n        } else {\n            while (p != null) {\n                if (p.mv == mw) {\n                    p.mv = mw.mv;\n                    if (cw.lastMethod == mw) {\n                        cw.lastMethod = p;\n                    }\n                    break;\n                } else {\n                    p = (MethodWriter) p.mv;\n                }\n            }\n        }\n    }\n\n    public static void replaceMethodWriter(MethodVisitor mv, MethodNode mn) {\n        MethodWriter mw = (MethodWriter) mv;\n        ClassWriter cw = mw.cw;\n        mn.accept(cw);\n        removeMethodWriter(mw);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/ASMifierTest.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.test;\r\n\r\nimport java.io.File;\r\nimport java.nio.file.FileSystem;\r\nimport java.nio.file.Path;\r\n\r\nimport org.junit.Test;\r\n\r\nimport com.googlecode.d2j.reader.DexFileReader;\r\nimport com.googlecode.d2j.util.ASMifierFileV;\r\nimport com.googlecode.dex2jar.tools.BaseCmd;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * \r\n */\r\npublic class ASMifierTest {\r\n    public static String getBaseName(String fn) {\r\n        int x = fn.lastIndexOf('.');\r\n        return x >= 0 ? fn.substring(0, x) : fn;\r\n    }\r\n\r\n    @Test\r\n    public void test() throws Exception {\r\n        try {\r\n            for (Path f : TestUtils.listTestDexFiles()) {\r\n                System.out.println(\"asmifier file \" + f);\r\n                File distDir = new File(\"target\", getBaseName(f.getFileName().toString()) + \"_asmifier.zip\");\r\n                try (FileSystem fs = BaseCmd.createZip(distDir.toPath())) {\r\n                    ASMifierFileV.doFile(f, fs.getPath(\"/\"));\r\n                }\r\n            }\r\n        } catch (Exception e) {\r\n            DexFileReader.niceExceptionMessage(e, 0);\r\n            throw e;\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/ArrayTypeTest.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport static com.googlecode.d2j.DexConstants.ACC_PUBLIC;\nimport static com.googlecode.d2j.DexConstants.ACC_STATIC;\nimport static com.googlecode.d2j.reader.Op.AGET;\nimport static com.googlecode.d2j.reader.Op.APUT;\nimport static com.googlecode.d2j.reader.Op.ARRAY_LENGTH;\nimport static com.googlecode.d2j.reader.Op.CONST;\nimport static com.googlecode.d2j.reader.Op.GOTO;\nimport static com.googlecode.d2j.reader.Op.INVOKE_VIRTUAL;\nimport static com.googlecode.d2j.reader.Op.NEW_ARRAY;\nimport static com.googlecode.d2j.reader.Op.RETURN_VOID;\n\nimport org.junit.Test;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.runner.RunWith;\n\n@RunWith(DexTranslatorRunner.class)\npublic class ArrayTypeTest {\n\n    @Test\n    public static void a120(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(3);\n        code.visitConstStmt(CONST, 0, Integer.valueOf(0));\n        code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 0 }, new Method(\"Ljava/lang/String;\", \"toString\",\n                new String[] {}, \"Ljava/lang/String;\"));\n        code.visitConstStmt(CONST, 1, Integer.valueOf(0));\n        code.visitStmt2R(ARRAY_LENGTH, 2, 1);\n        code.visitStmt0R(RETURN_VOID);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n\n    @Test\n    public static void a122(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(3);\n        code.visitConstStmt(CONST, 0, Integer.valueOf(0));\n        code.visitConstStmt(CONST, 2, Integer.valueOf(1));\n        code.visitStmt3R(AGET, 1, 0, 2);\n        code.visitStmt0R(RETURN_VOID);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n\n    @Test\n    public static void a123(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(3);\n        code.visitConstStmt(CONST, 0, 0);\n        code.visitConstStmt(CONST, 1, 1);\n        code.visitConstStmt(CONST, 2, 0x63);\n        code.visitStmt3R(APUT, 2, 0, 1);\n        code.visitStmt0R(RETURN_VOID);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n\n    @Test\n    public static void merge1(DexClassVisitor cv) {// obj = array\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        DexLabel L0 = new DexLabel();\n        DexLabel L1 = new DexLabel();\n        code.visitRegister(3);\n        code.visitConstStmt(CONST, 0, 0);\n        code.visitJumpStmt(GOTO, -1, -1, L1);\n        code.visitLabel(L0);\n        code.visitStmt2R(ARRAY_LENGTH, 1, 0);\n        code.visitConstStmt(CONST, 1, 0);\n        code.visitStmt3R(AGET, 2, 0, 1);\n        code.visitStmt0R(RETURN_VOID);\n        code.visitLabel(L1);\n        code.visitConstStmt(CONST, 1, 1);\n        code.visitTypeStmt(NEW_ARRAY, 0, 1, \"[Ljava/security/cert/X509Certificate;\");\n        code.visitJumpStmt(GOTO, -1, -1, L0);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/AutoCastTest.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport static com.googlecode.d2j.reader.Op.*;\n\npublic class AutoCastTest implements DexConstants {\n\n    /**\n     * generate code, it works fine on JVM, but fails on Dalvik VM\n     * \n     * <pre>\n     * class a {\n     *     private static short theField;\n     * \n     *     public a() {\n     *         theField = 0xffFFffFF + theField;// the 0xffFFffFF is not casted\n     *     }\n     * }\n     * </pre>\n     * \n     * @param cv\n     */\n    public static void strict(DexClassVisitor cv) {\n        Field f = new Field(\"La;\", \"theField\", \"S\");\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC, new Method(\"La;\", \"<init>\", new String[] {}, \"V\"));\n        if (mv != null) {\n            DexCodeVisitor code = mv.visitCode();\n            if (code != null) {\n                code.visitRegister(3);\n\n                code.visitMethodStmt(INVOKE_SUPER, new int[] { 2 }, new Method(\"Ljava/lang/Object;\", \"<init>\",\n                        new String[] {}, \"V\"));\n                code.visitFieldStmt(SGET_BOOLEAN, 0, -1, f);\n                code.visitConstStmt(CONST, 1, 0xffFFffFF);\n                code.visitStmt3R(ADD_INT, 0, 0, 1);\n                code.visitFieldStmt(SPUT_SHORT, 0, -1, f);\n                code.visitStmt0R(RETURN_VOID);\n                code.visitEnd();\n            }\n            mv.visitEnd();\n        }\n        DexFieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC, f, 0);\n        if (fv != null) {\n            fv.visitEnd();\n        }\n    }\n\n    @Test\n    public void test() throws Exception {\n        byte[] data = TestUtils.testDexASMifier(getClass(), \"strict\", \"a\");\n        Class<?> clz = TestUtils.defineClass(\"a\", data);\n        Object c = clz.newInstance();\n        Assert.assertNotNull(c);\n        java.lang.reflect.Field f = clz.getDeclaredField(\"theField\");\n        f.setAccessible(true);\n        Short r = (Short) f.get(null);\n        Assert.assertEquals(-1, r.intValue());\n\n        // it's already ok to run on JVM and able to convert to dex,\n        // // check for I2S instruction\n        // ClassReader cr = new ClassReader(data);\n        // ClassNode cn = new ClassNode();\n        // cr.accept(cn, 0);\n        // boolean find = false;\n        // for (Object m : cn.methods) {\n        // MethodNode method = (MethodNode) m;\n        // for (AbstractInsnNode p = method.instructions.getFirst(); p != null; p = p.getNext()) {\n        // if (p.getOpcode() == Opcodes.I2S) {\n        // find = true;\n        // break;\n        // }\n        // }\n        // }\n        // Assert.assertTrue(\"we need an I2S instruction\", find);\n\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/D2jTest.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Path;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\nimport org.junit.runner.Description;\nimport org.junit.runner.RunWith;\nimport org.junit.runner.Runner;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.ParentRunner;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\n\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\n@RunWith(D2jTest.S.class)\npublic class D2jTest {\n\n    public static class S extends ParentRunner<Runner> {\n\n        public S(Class<?> klass) throws InitializationError {\n            super(klass);\n            init(klass);\n        }\n\n        List<Runner> runners;\n\n        public void init(final Class<?> testClass) throws InitializationError {\n            Collection<Path> files = TestUtils.listTestDexFiles();\n\n            List<Runner> runners = new ArrayList<>(files.size());\n\n            for (final Path f : files) {\n                final DexFileNode fileNode = readDex(f);\n                runners.add(new ParentRunner<DexClassNode>(testClass) {\n                    @Override\n                    protected List<DexClassNode> getChildren() {\n                        return fileNode.clzs;\n                    }\n\n                    @Override\n                    protected String getName() {\n                        return \"d2j [\" + f.toString() + \"]\";\n                    }\n\n                    @Override\n                    protected Description describeChild(DexClassNode child) {\n                        return Description.createTestDescription(testClass, \"c [\" + child.className + \"]\");\n                    }\n\n                    @Override\n                    protected void runChild(final DexClassNode child, RunNotifier notifier) {\n                        runLeaf(new Statement() {\n                            @Override\n                            public void evaluate() throws Throwable {\n                                TestUtils.translateAndCheck(fileNode, child);\n                            }\n                        }, describeChild(child), notifier);\n                    }\n                });\n            }\n            this.runners = runners;\n        }\n\n        private DexFileNode readDex(Path f) {\n            DexFileNode fileNode = new DexFileNode();\n            DexFileReader reader = null;\n            try {\n                reader = new DexFileReader(ZipUtil.readDex(f));\n            } catch (IOException e) {\n                throw new RuntimeException(\"Fail to read dex:\" + f);\n            }\n            reader.accept(fileNode);\n            return fileNode;\n        }\n\n        @Override\n        protected List<Runner> getChildren() {\n            return runners;\n        }\n\n        @Override\n        protected Description describeChild(Runner child) {\n            return child.getDescription();\n        }\n\n        @Override\n        protected void runChild(Runner child, RunNotifier notifier) {\n            child.run(notifier);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/DexTranslatorRunner.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.node.DexClassNode;\nimport org.junit.runners.BlockJUnit4ClassRunner;\nimport org.junit.runners.model.FrameworkMethod;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\n\nimport java.util.List;\n\npublic class DexTranslatorRunner extends BlockJUnit4ClassRunner {\n\n    public DexTranslatorRunner(Class klass) throws InitializationError {\n        super(klass);\n    }\n\n    @Override\n    protected Statement methodInvoker(final FrameworkMethod method, final Object test) {\n        if (method.getMethod().getParameterTypes().length > 0) {\n            return new Statement() {\n                @Override\n                public void evaluate() throws Throwable {\n                    // 1.invoke the method\n                    DexClassNode clzNode = new DexClassNode(DexConstants.ACC_PUBLIC, \"La;\", \"Ljava/lang/Object;\", null);\n                    if (method.isStatic()) {\n                        method.invokeExplosively(null, clzNode);\n                    } else {\n                        method.invokeExplosively(test, clzNode);\n                    }\n                    // 2. convert and verify\n                    TestUtils.translateAndCheck(clzNode);\n                }\n            };\n        } else {\n            return super.methodInvoker(method, test);\n        }\n    }\n\n    @Override\n    protected void validateTestMethods(List<Throwable> errors) {\n        // All methods are validate\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/EmptyTrapTest.java",
    "content": "package com.googlecode.dex2jar.test;\r\n\r\nimport static com.googlecode.d2j.reader.Op.*;\r\n\r\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\r\nimport org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\n\r\nimport com.googlecode.d2j.DexLabel;\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\n\r\n@RunWith(DexTranslatorRunner.class)\r\npublic class EmptyTrapTest {\r\n\r\n    @Test\r\n    public static void m005_toJSONString(DexClassVisitor cv) {\r\n        DexMethodVisitor mv = cv.visitMethod(0, new Method(\"LJSResponseTest;\", \"toJSONString\", new String[] {},\r\n                \"Ljava/lang/String;\"));\r\n        if (mv != null) {\r\n            DexCodeVisitor code = mv.visitCode();\r\n            if (code != null) {\r\n                code.visitRegister(6);\r\n\r\n                DexLabel L8 = new DexLabel();\r\n                DexLabel L9 = new DexLabel();\r\n                DexLabel L10 = new DexLabel();\r\n\r\n                DexLabel L0 = new DexLabel();\r\n                DexLabel L1 = new DexLabel();\r\n                DexLabel L2 = new DexLabel();\r\n                code.visitTryCatch(L0, L1, new DexLabel[] { L2 }, new String[] { \"Lorg/json/JSONException;\" });\r\n                DexLabel L3 = new DexLabel();\r\n                DexLabel L4 = new DexLabel();\r\n                code.visitTryCatch(L3, L4, new DexLabel[] { L2 }, new String[] { \"Lorg/json/JSONException;\" });\r\n                DexLabel L5 = new DexLabel();\r\n                DexLabel L6 = new DexLabel();\r\n                code.visitTryCatch(L5, L6, new DexLabel[] { L2 }, new String[] { \"Lorg/json/JSONException;\" });\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"response\");\r\n                code.visitConstStmt(CONST_STRING, 4, \"\");\r\n                code.visitLabel(L0);\r\n                code.visitFieldStmt(IGET, 2, 5, new Field(\"LJSResponseTest;\", \"className\", \"Ljava/lang/String;\"));\r\n                code.visitJumpStmt(IF_EQZ, 2, -1, L8);\r\n                code.visitFieldStmt(IGET, 2, 5, new Field(\"LJSResponseTest;\", \"methodName\", \"Ljava/lang/String;\"));\r\n                code.visitJumpStmt(IF_NEZ, 2, -1, L10);\r\n                code.visitLabel(L8);\r\n                code.visitConstStmt(CONST_STRING, 2, \"\");\r\n                code.visitStmt2R(MOVE, 2, 4);\r\n                code.visitLabel(L9);\r\n                code.visitStmt1R(RETURN_OBJECT, 2);\r\n                code.visitLabel(L10);\r\n                code.visitTypeStmt(NEW_INSTANCE, 1, -1, \"Lorg/json/JSONObject;\");\r\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 1 }, new Method(\"Lorg/json/JSONObject;\", \"<init>\",\r\n                        new String[] {}, \"V\"));\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"class\");\r\n                code.visitFieldStmt(IGET, 3, 5, new Field(\"LJSResponseTest;\", \"className\", \"Ljava/lang/String;\"));\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method(\"Lorg/json/JSONObject;\", \"put\",\r\n                        new String[] { \"Ljava/lang/String;\", \"Ljava/lang/Object;\" }, \"Lorg/json/JSONObject;\"));\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"call\");\r\n                code.visitFieldStmt(IGET, 3, 5, new Field(\"LJSResponseTest;\", \"methodName\", \"Ljava/lang/String;\"));\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method(\"Lorg/json/JSONObject;\", \"put\",\r\n                        new String[] { \"Ljava/lang/String;\", \"Ljava/lang/Object;\" }, \"Lorg/json/JSONObject;\"));\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"result\");\r\n                code.visitFieldStmt(IGET, 3, 5, new Field(\"LJSResponseTest;\", \"result\", \"I\"));\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method(\"Lorg/json/JSONObject;\", \"put\",\r\n                        new String[] { \"Ljava/lang/String;\", \"I\" }, \"Lorg/json/JSONObject;\"));\r\n\r\n                code.visitFieldStmt(IGET, 2, 5, new Field(\"LJSResponseTest;\", \"response\", \"Ljava/lang/Object;\"));\r\n                code.visitJumpStmt(IF_EQZ, 2, -1, L3);\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"response\");\r\n                code.visitFieldStmt(IGET, 3, 5, new Field(\"LJSResponseTest;\", \"response\", \"Ljava/lang/Object;\"));\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method(\"Lorg/json/JSONObject;\", \"put\",\r\n                        new String[] { \"Ljava/lang/String;\", \"Ljava/lang/Object;\" }, \"Lorg/json/JSONObject;\"));\r\n                code.visitLabel(L1);\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method(\"Lorg/json/JSONObject;\", \"toString\",\r\n                        new String[] {}, \"Ljava/lang/String;\"));\r\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 2);\r\n                code.visitJumpStmt(GOTO, -1, -1, L9);\r\n                code.visitLabel(L3);\r\n                code.visitFieldStmt(IGET, 2, 5, new Field(\"LJSResponseTest;\", \"dataResponse\", \"[B\"));\r\n                code.visitJumpStmt(IF_EQZ, 2, -1, L5);\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"response\");\r\n                code.visitFieldStmt(IGET, 3, 5, new Field(\"LJSResponseTest;\", \"dataResponse\", \"[B\"));\r\n                code.visitMethodStmt(INVOKE_STATIC, new int[] { 3 }, new Method(\"LBase64;\", \"encode\",\r\n                        new String[] { \"[B\" }, \"Ljava/lang/String;\"));\r\n                code.visitStmt1R(MOVE_RESULT, 3);\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method(\"Lorg/json/JSONObject;\", \"put\",\r\n                        new String[] { \"Ljava/lang/String;\", \"Ljava/lang/Object;\" }, \"Lorg/json/JSONObject;\"));\r\n                code.visitLabel(L4);\r\n                code.visitJumpStmt(GOTO, -1, -1, L1);\r\n                code.visitLabel(L2);\r\n                code.visitStmt1R(MOVE_EXCEPTION, 2);\r\n                code.visitStmt2R(MOVE, 0, 2);\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"MillennialMediaSDK\");\r\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 0 }, new Method(\"Lorg/json/JSONException;\",\r\n                        \"getMessage\", new String[] {}, \"Ljava/lang/String;\"));\r\n                code.visitStmt1R(MOVE_RESULT, 3);\r\n                code.visitMethodStmt(INVOKE_STATIC, new int[] { 2, 3 }, new Method(\"Landroid/util/Log;\", \"e\",\r\n                        new String[] { \"Ljava/lang/String;\", \"Ljava/lang/String;\" }, \"I\"));\r\n\r\n                code.visitConstStmt(CONST_STRING, 2, \"\");\r\n                code.visitStmt2R(MOVE, 2, 4);\r\n                code.visitJumpStmt(GOTO, -1, -1, L9);\r\n                code.visitLabel(L5);\r\n                code.visitConstStmt(CONST_STRING, 2, \"\");\r\n                code.visitLabel(L6);\r\n                code.visitStmt2R(MOVE, 2, 4);\r\n                code.visitJumpStmt(GOTO, -1, -1, L9);\r\n\r\n                code.visitEnd();\r\n            }\r\n            mv.visitEnd();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/I101Test.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport static com.googlecode.d2j.DexConstants.ACC_PUBLIC;\nimport static com.googlecode.d2j.DexConstants.ACC_STATIC;\nimport static com.googlecode.d2j.reader.Op.CONST_STRING;\nimport static com.googlecode.d2j.reader.Op.INVOKE_VIRTUAL;\nimport static com.googlecode.d2j.reader.Op.MOVE_EXCEPTION;\nimport static com.googlecode.d2j.reader.Op.RETURN_VOID;\n\nimport org.junit.Test;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\npublic class I101Test {\n\n    public static void a(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(2);\n        DexLabel L0 = new DexLabel();\n        DexLabel L1 = new DexLabel();\n        DexLabel L2 = new DexLabel();\n        code.visitTryCatch(L0, L1, new DexLabel[] { L2 }, new String[] { \"Lsome/Exception;\" });\n\n        code.visitLabel(L0);\n        code.visitConstStmt(CONST_STRING, 0, \"abc\");\n        code.visitLabel(L1);\n\n        code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 0 }, new Method(\"Ljava/lang/String;\", \"toString\",\n                new String[] {}, \"Ljava/lang/String;\"));\n        code.visitStmt0R(RETURN_VOID);\n        code.visitLabel(L2);\n        code.visitStmt1R(MOVE_EXCEPTION, 1);\n        code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method(\"Ljava/lang/String;\", \"toString\",\n                new String[] {}, \"Ljava/lang/String;\"));\n        code.visitStmt0R(RETURN_VOID);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n\n    @Test\n    public void test() throws Exception {\n        byte[] data = TestUtils.testDexASMifier(getClass(), \"a\", \"Lt\");\n        TestUtils.defineClass(\"Lt\", data);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/I121Test.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static com.googlecode.d2j.DexConstants.*;\nimport static com.googlecode.d2j.reader.Op.*;\n\n@RunWith(DexTranslatorRunner.class)\npublic class I121Test {\n\n    @Test\n    public static void i121(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"a\", new String[] {\n                \"Ljava/lang/String;\", \"Ljava/lang/String;\" }, \"Ljava/lang/String;\"));\n        DexCodeVisitor code = mv.visitCode();\n        int p0 = 2;\n        int p1 = 3;\n        int v0 = 0;\n        int v1 = 1;\n\n        DexLabel cond_7 = new DexLabel();\n        DexLabel try_start_2 = new DexLabel();\n        DexLabel try_end_9 = new DexLabel();\n        DexLabel catch_a = new DexLabel();\n        DexLabel goto_2 = new DexLabel();\n\n        code.visitTryCatch(try_start_2, try_end_9, new DexLabel[] { catch_a },\n                new String[] { \"Ljava/io/UnsupportedEncodingException;\" });\n\n        code.visitRegister(4);\n\n        code.visitJumpStmt(IF_EQZ, p1, -1, cond_7);\n\n        code.visitLabel(goto_2);\n        code.visitLabel(try_start_2);\n\n        code.visitMethodStmt(INVOKE_STATIC, new int[] { p0, p1 }, new Method(\"Ljava/net/URLEncoder;\", \"encode\",\n                new String[] { \"Ljava/lang/String;\", \"Ljava/lang/String;\" }, \"Ljava/lang/String;\"));\n        code.visitStmt1R(MOVE_RESULT_OBJECT, v0);\n        code.visitStmt1R(RETURN_OBJECT, v0);\n        code.visitLabel(cond_7);\n        code.visitConstStmt(CONST_STRING, p1, \"ISO-8859-1\");\n\n        code.visitLabel(try_end_9);\n        code.visitJumpStmt(GOTO, -1, -1, goto_2);\n        code.visitLabel(catch_a);\n        code.visitStmt1R(MOVE_EXCEPTION, v0);\n        code.visitTypeStmt(NEW_INSTANCE, v1, -1, \"Ljava/lang/IllegalArgumentException;\");\n        code.visitMethodStmt(INVOKE_DIRECT, new int[] { v1, v0 }, new Method(\"Ljava/lang/IllegalArgumentException;\",\n                \"<init>\", new String[] { \"Ljava/lang/Throwable;\" }, \"V\"));\n        code.visitStmt1R(THROW, v1);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/I168Test.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport static com.googlecode.d2j.DexConstants.ACC_PUBLIC;\nimport static com.googlecode.d2j.DexConstants.ACC_STATIC;\n\nimport org.junit.Test;\n\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.runner.RunWith;\n\n/**\n * test for huge insn 20000 and locals 2000\n * \n * @author bob\n * \n */\n@RunWith(DexTranslatorRunner.class)\npublic class I168Test {\n\n    @Test\n    public static void i168(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"a\", new String[] {}, \"I\"));\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(2000); // 2000 locals\n        for (int i = 0; i < 2000; i++) {// 2000 insns\n            code.visitConstStmt(Op.CONST, i, i);\n        }\n        for (int i = 0; i < 18000; i++) {// 18000 insns\n            code.visitConstStmt(Op.CONST, 25, i);\n        }\n        code.visitStmt1R(Op.RETURN, 25);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/I63Test.java",
    "content": "package com.googlecode.dex2jar.test;\r\n\r\nimport com.googlecode.d2j.DexConstants;\r\nimport org.junit.Test;\r\n\r\nimport com.googlecode.d2j.DexLabel;\r\nimport com.googlecode.d2j.Field;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.reader.Op;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\nimport org.junit.runner.RunWith;\r\n\r\n/**\r\n * test case for issue 63\r\n */\r\n@RunWith(DexTranslatorRunner.class)\r\npublic class I63Test implements DexConstants {\r\n\r\n    @Test\r\n    public static void i63(DexClassVisitor cv) {\r\n        DexMethodVisitor mv = cv.visitMethod(ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"V\"));\r\n        if (mv != null) {\r\n            DexCodeVisitor code = mv.visitCode();\r\n            if (code != null) {\r\n                code.visitRegister(1);\r\n                DexLabel L1 = new DexLabel();\r\n                DexLabel L2 = new DexLabel();\r\n                code.visitLabel(L1);\r\n                code.visitFieldStmt(Op.SGET, 0, -1, new Field(\"La;\", \"f\", \"J\"));\r\n                code.visitLabel(L2);\r\n                code.visitStmt0R(Op.RETURN_VOID);\r\n                code.visitEnd();\r\n                code.visitTryCatch(L1, L2, new DexLabel[] { L2 }, new String[] { \"La;\" });\r\n            }\r\n            mv.visitEnd();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/Issue71Test.java",
    "content": "/*\r\n * Copyright (c) 2009-2012 Panxiaobo\r\n * \r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n * \r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n * \r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.dex2jar.test;\r\n\r\nimport org.junit.Test;\r\n\r\nimport com.googlecode.d2j.DexConstants;\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\nimport org.junit.runner.RunWith;\r\n\r\nimport static com.googlecode.d2j.reader.Op.*;\r\n\r\n/**\r\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\r\n * \r\n */\r\n@RunWith(DexTranslatorRunner.class)\r\npublic class Issue71Test implements DexConstants {\r\n    @Test\r\n    public static void i71(DexClassVisitor cv) {\r\n        DexMethodVisitor mv = cv.visitMethod(ACC_STATIC, new Method(\"La;\", \"test\", new String[] {}, \"V\"));\r\n        if (mv != null) {\r\n            DexCodeVisitor code = mv.visitCode();\r\n            if (code != null) {\r\n                code.visitRegister(2);\r\n                code.visitConstStmt(CONST_WIDE, 0, 0L);\r\n                code.visitConstStmt(CONST_WIDE, 1, 2L);\r\n                code.visitStmt3R(ADD_LONG, 0, 0, 1);\r\n                code.visitStmt0R(RETURN_VOID);\r\n                code.visitEnd();\r\n            }\r\n            mv.visitEnd();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/OptSyncTest.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport java.io.PrintStream;\n\nimport static com.googlecode.d2j.DexConstants.ACC_PUBLIC;\nimport static com.googlecode.d2j.DexConstants.ACC_STATIC;\nimport static com.googlecode.d2j.reader.Op.*;\n\n@RunWith(DexTranslatorRunner.class)\npublic class OptSyncTest {\n\n    public void a() {\n        synchronized (System.out) {\n            System.out.println();\n        }\n    }\n\n    public void b() {\n        PrintStream a = System.out;\n        synchronized (a) {\n            System.out.println();\n        }\n    }\n\n    public void c() {\n        Object a = null;\n        synchronized (a) {\n            System.out.println();\n        }\n    }\n\n    /**\n     * Generate the following code\n     * \n     * <pre>\n     * public static void a() {\n     * a0 = System.out\n     * L0: \n     * lock a0 <= a0 is inside a try-catch\n     * a1=\"haha\"\n     * a0.println(a1)\n     * L1: \n     * unlock a0 \n     * return\n     * L2: \n     * a1 := @Exception \n     * unlock a0 \n     * throw a1\n     * ============= \n     * .catch L0 - L1 > L2 // all \n     * }\n     * </pre>\n     * \n     * @param cv\n     */\n    @Test\n    public void test(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method(\"La;\", \"a\", new String[] {}, \"V\"));\n        DexCodeVisitor code = mv.visitCode();\n        int v0 = 0;\n        int v1 = 1;\n        DexLabel try_start = new DexLabel();\n        DexLabel try_end = new DexLabel();\n        DexLabel catch_a = new DexLabel();\n\n        code.visitTryCatch(try_start, try_end, new DexLabel[] { catch_a }, new String[] { null });\n        code.visitRegister(2);\n        code.visitFieldStmt(SGET_OBJECT, v0, -1, new Field(\"Ljava/lang/System;\", \"out\", \"Ljava/io/PrintStream;\"));\n        code.visitLabel(try_start);\n        code.visitStmt1R(MONITOR_ENTER, v0);\n        code.visitConstStmt(CONST_STRING, v1, \"haha\");\n        code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { v0, v1 }, new Method(\"Ljava/io/PrintString;\", \"println\",\n                new String[] { \"Ljava/lang/String;\" }, \"V\"));\n        code.visitLabel(try_end);\n        code.visitStmt1R(MONITOR_EXIT, v0);\n        code.visitStmt0R(RETURN_VOID);\n        code.visitLabel(catch_a);\n        code.visitStmt1R(MOVE_EXCEPTION, v1);\n        code.visitStmt1R(MONITOR_EXIT, v0);\n        code.visitStmt1R(THROW, v1);\n        code.visitEnd();\n        mv.visitEnd();\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/ResTest.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.test;\n\nimport java.io.File;\nimport java.net.URL;\nimport java.nio.file.Path;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.junit.Assert;\nimport org.junit.runner.Description;\nimport org.junit.runner.RunWith;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.ParentRunner;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\n\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.reader.DexFileReader;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\n@RunWith(ResTest.R.class)\npublic class ResTest {\n\n    public static class FileSet {\n        String name;\n        List<Path> files = new ArrayList<>(3);\n    }\n\n    public static class R extends ParentRunner<FileSet> {\n        public R(Class<?> testClass) throws InitializationError {\n            super(testClass);\n            init(testClass);\n        }\n\n        List<FileSet> fileSetList;\n        File dir;\n\n        void init(Class<?> testClass) {\n            URL url = testClass.getResource(\"/\" + testClass.getName().replace('.', '/') + \".class\");\n            Assert.assertNotNull(url);\n            String file = url.getFile();\n            Assert.assertNotNull(file);\n            String dirx = file.substring(0, file.length() - testClass.getName().length() - \".class\".length());\n\n            dir = new File(dirx, \"res\");\n            Map<String, FileSet> m = new HashMap<>();\n            for (Path f : TestUtils.listPath(dir, \".class\")) {\n                String name = getBaseName(f.getFileName().toString());\n\n                int i = name.indexOf('$');\n                String z = i > 0 ? name.substring(0, i) : name;\n                FileSet fs = m.get(z);\n                if (fs == null) {\n                    fs = new FileSet();\n                    fs.name = z;\n                    m.put(z, fs);\n                }\n                fs.files.add(f);\n            }\n            this.fileSetList = new ArrayList<>(m.values());\n        }\n\n        @Override\n        protected List<FileSet> getChildren() {\n            return fileSetList;\n        }\n\n        @Override\n        protected Description describeChild(FileSet child) {\n            return Description.createTestDescription(getTestClass().getJavaClass(), child.name);\n        }\n\n        @Override\n        protected void runChild(final FileSet child, RunNotifier notifier) {\n            runLeaf(new Statement() {\n                @Override\n                public void evaluate() throws Throwable {\n                    File dex = TestUtils.dexP(child.files, new File(dir, child.name + \".dex\"));\n                    File distFile = new File(dex.getParentFile(), getBaseName(dex.getName()) + \"_d2j.jar\");\n                    DexFileNode fileNode = new DexFileNode();\n                    DexFileReader r = new DexFileReader(dex);\n                    r.accept(fileNode);\n                    for (DexClassNode classNode : fileNode.clzs) {\n                        TestUtils.translateAndCheck(fileNode, classNode);\n                    }\n                }\n            }, describeChild(child), notifier);\n        }\n    }\n\n    public static String getBaseName(String fn) {\n        int x = fn.lastIndexOf('.');\n        return x >= 0 ? fn.substring(0, x) : fn;\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/Smali2jTest.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\n\nimport org.junit.Assert;\nimport org.junit.runner.Description;\nimport org.junit.runner.RunWith;\nimport org.junit.runner.Runner;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.ParentRunner;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\n\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.smali.Smali;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\n@RunWith(Smali2jTest.S.class)\npublic class Smali2jTest {\n\n    public static class S extends ParentRunner<Runner> {\n\n        public S(Class<?> klass) throws InitializationError {\n            super(klass);\n            init(klass);\n        }\n\n        List<Runner> runners;\n\n        public void init(final Class<?> testClass) throws InitializationError {\n            URL url = testClass.getResource(\"/smalis/writeString.smali\");\n            System.out.println(\"url is \" + url);\n            Assert.assertNotNull(url);\n\n            final String file = url.getFile();\n            Assert.assertNotNull(file);\n\n            Path dirxpath = new File(file).toPath();\n\n            final Path basePath = dirxpath.getParent();\n\n            final Set<Path> files = new TreeSet<>();\n            try {\n                Files.walkFileTree(basePath, new SimpleFileVisitor<Path>() {\n                    @Override\n                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                        if (file.getFileName().toString().endsWith(\".smali\")) {\n                            files.add(file);\n                        }\n                        return super.visitFile(file, attrs);\n                    }\n                });\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n\n            List<Runner> runners = new ArrayList<>();\n            for (final Path p : files) {\n\n                Smali smali = new Smali();\n                final DexFileNode fileNode = new DexFileNode();\n                try {\n                    smali.smaliFile(p, fileNode);\n                } catch (IOException e) {\n                    throw new RuntimeException(e);\n                }\n                runners.add(new ParentRunner<DexClassNode>(testClass) {\n                    @Override\n                    protected List<DexClassNode> getChildren() {\n                        return fileNode.clzs;\n                    }\n\n                    @Override\n                    protected String getName() {\n                        return \"s2j [\" + basePath.relativize(p) + \"]\";\n                    }\n\n                    @Override\n                    protected Description describeChild(DexClassNode child) {\n                        return Description.createTestDescription(testClass, \"[\" + child.className + \"]\");\n                    }\n\n                    @Override\n                    protected void runChild(final DexClassNode child, RunNotifier notifier) {\n                        runLeaf(new Statement() {\n                            @Override\n                            public void evaluate() throws Throwable {\n                                if(p.getFileName().toString().contains(\"mayfail\")) {\n                                    try {\n                                        TestUtils.translateAndCheck(fileNode, child);\n                                    } catch (Exception ex) {\n                                        ex.printStackTrace();\n                                    }\n                                } else {\n                                    TestUtils.translateAndCheck(fileNode, child);\n                                }\n                            }\n                        }, describeChild(child), notifier);\n                    }\n                });\n            }\n            this.runners = runners;\n        }\n\n        @Override\n        protected List<Runner> getChildren() {\n            return runners;\n        }\n\n        @Override\n        protected Description describeChild(Runner child) {\n            return child.getDescription();\n        }\n\n        @Override\n        protected void runChild(Runner child, RunNotifier notifier) {\n            child.run(notifier);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/TestDexClassV.java",
    "content": "package com.googlecode.dex2jar.test;\r\n\r\nimport com.googlecode.d2j.node.DexMethodNode;\r\nimport org.junit.Ignore;\r\nimport org.objectweb.asm.ClassWriter;\r\nimport org.objectweb.asm.Opcodes;\r\n\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.visitors.DexClassVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\n\r\n@Ignore\r\npublic class TestDexClassV extends DexClassVisitor {\r\n    private int config;\r\n    private ClassWriter cw;\r\n\r\n    public TestDexClassV(String clz, int config) {\r\n        super();\r\n        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\r\n        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clz, null, \"java/lang/Object\", null);\r\n        this.config = config;\r\n    }\r\n\r\n    public byte[] toByteArray() {\r\n        cw.visitEnd();\r\n        return cw.toByteArray();\r\n    }\r\n\r\n    @Override\r\n    public DexMethodVisitor visitMethod(int accessFlags, Method method) {\r\n        return new DexMethodNode(accessFlags, method) {\r\n\r\n            @Override\r\n            public void visitEnd() {\r\n                super.visitEnd();\r\n                // FIXME impl\r\n                //methodNode.accept(cw);\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/TestUtils.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.dex2jar.test;\n\nimport com.android.dx.cf.direct.DirectClassFile;\nimport com.android.dx.cf.direct.StdAttributeFactory;\nimport com.android.dx.cf.iface.ParseException;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.dx.dex.DexOptions;\nimport com.android.dx.dex.cf.CfOptions;\nimport com.android.dx.dex.cf.CfTranslator;\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.DexException;\nimport com.googlecode.d2j.dex.ClassVisitorFactory;\nimport com.googlecode.d2j.dex.Dex2Asm;\nimport com.googlecode.d2j.dex.LambadaNameSafeClassAdapter;\nimport com.googlecode.d2j.node.DexClassNode;\nimport com.googlecode.d2j.node.DexFileNode;\nimport com.googlecode.d2j.node.DexMethodNode;\nimport com.googlecode.d2j.reader.zip.ZipUtil;\nimport com.googlecode.d2j.smali.BaksmaliDumper;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport org.junit.Assert;\nimport org.junit.Ignore;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.commons.Remapper;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\nimport org.objectweb.asm.tree.ClassNode;\nimport org.objectweb.asm.tree.MethodNode;\nimport org.objectweb.asm.tree.TryCatchBlockNode;\nimport org.objectweb.asm.tree.analysis.Analyzer;\nimport org.objectweb.asm.tree.analysis.AnalyzerException;\nimport org.objectweb.asm.tree.analysis.BasicVerifier;\nimport org.objectweb.asm.tree.analysis.Frame;\nimport org.objectweb.asm.util.CheckClassAdapter;\nimport org.objectweb.asm.util.Printer;\nimport org.objectweb.asm.util.Textifier;\nimport org.objectweb.asm.util.TraceMethodVisitor;\n\nimport java.io.*;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.net.URL;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipException;\nimport java.util.zip.ZipFile;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\n@Ignore\npublic abstract class TestUtils {\n\n    public static void breakPoint() {\n    }\n\n    public static void checkZipFile(File zip) throws ZipException, Exception {\n        ZipFile zipFile = new ZipFile(zip);\n        for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) {\n            ZipEntry entry = e.nextElement();\n            if (entry.getName().endsWith(\".class\")) {\n                StringWriter sw = new StringWriter();\n                // PrintWriter pw = new PrintWriter(sw);\n\n                try (InputStream is = zipFile.getInputStream(entry)) {\n                    verify(new ClassReader(ZipUtil.toByteArray(is)));\n                }\n                Assert.assertTrue(sw.toString(), sw.toString().length() == 0);\n            }\n        }\n    }\n\n    public static File dex(File file, File distFile) throws Exception {\n        return dex(new File[] { file }, distFile);\n    }\n\n    public static File dex(File[] files) throws Exception {\n        return dex(files, null);\n    }\n\n    public static File dex(File[] files, File distFile) throws Exception {\n        return dex(Arrays.asList(files), distFile);\n    }\n\n    public static File dexP(List<Path> files, File distFile) throws Exception {\n        Class<?> c = com.android.dx.command.Main.class;\n        Method m = c.getMethod(\"main\", String[].class);\n\n        if (distFile == null) {\n            distFile = File.createTempFile(\"dex\", \".dex\");\n        }\n        List<String> args = new ArrayList<String>();\n        args.addAll(Arrays.asList(\"--dex\", \"--no-strict\", \"--output=\" + distFile.getCanonicalPath()));\n        for (Path f : files) {\n            args.add(f.toAbsolutePath().toString());\n        }\n        m.invoke(null, new Object[] { args.toArray(new String[0]) });\n        return distFile;\n    }\n\n    public static File dex(List<File> files, File distFile) throws Exception {\n        Class<?> c = com.android.dx.command.Main.class;\n        Method m = c.getMethod(\"main\", String[].class);\n\n        if (distFile == null) {\n            distFile = File.createTempFile(\"dex\", \".dex\");\n        }\n        List<String> args = new ArrayList<String>();\n        args.addAll(Arrays.asList(\"--dex\", \"--no-strict\", \"--output=\" + distFile.getCanonicalPath()));\n        for (File f : files) {\n            args.add(f.getCanonicalPath());\n        }\n        m.invoke(null, new Object[] { args.toArray(new String[0]) });\n        return distFile;\n    }\n\n    private static String getShortName(final String name) {\n        int n = name.lastIndexOf('/');\n        return n == -1 ? name : \"o\";\n    }\n\n    public static List<Path> listTestDexFiles() {\n\n        Class<?> testClass = TestUtils.class;\n        URL url = testClass.getResource(\"/dexes/i_jetty.dex\");\n        Assert.assertNotNull(url);\n\n        final String fileStr = url.getFile();\n        Assert.assertNotNull(fileStr);\n\n        return listPath(new File(fileStr).getParentFile(), \".apk\", \".dex\", \".zip\");\n    }\n\n    public static List<Path> listPath(File file, final String... exts) {\n        final List<Path> list = new ArrayList<>();\n\n        try {\n            Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {\n                @Override\n                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                    String name = file.getFileName().toString();\n                    boolean add = false;\n                    for (String ext : exts) {\n                        if (name.endsWith(ext)) {\n                            add = true;\n                            break;\n                        }\n                    }\n                    if (add) {\n                        list.add(file);\n                    }\n                    return super.visitFile(file, attrs);\n                }\n            });\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return list;\n    }\n\n    static Field buf;\n    static {\n        try {\n            buf = Printer.class.getDeclaredField(\"buf\");\n        } catch (NoSuchFieldException | SecurityException e) {\n            // TODO Auto-generated catch block\n            e.printStackTrace();\n        }\n        buf.setAccessible(true);\n    }\n\n    static void printAnalyzerResult(MethodNode method, Analyzer a, final PrintWriter pw)\n            throws IllegalArgumentException, IllegalAccessException {\n        Frame[] frames = a.getFrames();\n        Textifier t = new Textifier();\n        TraceMethodVisitor mv = new TraceMethodVisitor(t);\n        String format = \"%05d %-\" + (method.maxStack + method.maxLocals + 6) + \"s|%s\";\n        for (int j = 0; j < method.instructions.size(); ++j) {\n            method.instructions.get(j).accept(mv);\n\n            StringBuffer s = new StringBuffer();\n            Frame f = frames[j];\n            if (f == null) {\n                s.append('?');\n            } else {\n                for (int k = 0; k < f.getLocals(); ++k) {\n                    s.append(getShortName(f.getLocal(k).toString()));\n                }\n                s.append(\" : \");\n                for (int k = 0; k < f.getStackSize(); ++k) {\n                    s.append(getShortName(f.getStack(k).toString()));\n                }\n            }\n            pw.printf(format, j, s, buf.get(t)); // mv.text.get(j));\n        }\n        for (int j = 0; j < method.tryCatchBlocks.size(); ++j) {\n            ((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv);\n            pw.print(\" \" + buf.get(t));\n        }\n        pw.println();\n        pw.flush();\n    }\n\n    public static void verify(final ClassReader cr) throws AnalyzerException, IllegalArgumentException,\n            IllegalAccessException {\n        try {\n            verify(cr, new PrintWriter(new OutputStreamWriter(System.out, \"UTF-8\")));\n        } catch (UnsupportedEncodingException e) {\n            e.printStackTrace();\n        }\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n    public static void verify(final ClassReader cr, PrintWriter out) throws AnalyzerException,\n            IllegalArgumentException, IllegalAccessException {\n        ClassNode cn = new ClassNode();\n        cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);\n\n        List methods = cn.methods;\n\n        for (int i = 0; i < methods.size(); ++i) {\n            MethodNode method = (MethodNode) methods.get(i);\n\n            List tryCatchBlocks = method.tryCatchBlocks;\n            for (int j = 0; j < tryCatchBlocks.size(); j++) {\n                TryCatchBlockNode tcn = (TryCatchBlockNode) tryCatchBlocks.get(j);\n                if (tcn.start.equals(tcn.end)) {\n                    throw new DexException(\"try/catch block %d in %s has same start(%s) and end(%s)\", j, method.name,\n                            tcn.start.getLabel(), tcn.end.getLabel());\n                }\n            }\n\n            BasicVerifier verifier = new BasicVerifier();\n            Analyzer a = new Analyzer(verifier);\n            try {\n                a.analyze(cn.name, method);\n            } catch (Exception e) {\n                out.println(cr.getClassName() + \".\" + method.name + method.desc);\n                printAnalyzerResult(method, a, out);\n                e.printStackTrace(out);\n                out.flush();\n                throw new DexException(\"method \" + method.name + \" \" + method.desc, e);\n            }\n        }\n    }\n\n    public static byte[] testDexASMifier(Class<?> clz, String methodName) throws Exception {\n        return testDexASMifier(clz, methodName, \"xxxx/\" + methodName);\n    }\n\n    public static byte[] testDexASMifier(Class<?> clz, String methodName, String generateClassName) throws Exception {\n        DexClassNode clzNode = new DexClassNode(DexConstants.ACC_PUBLIC, \"L\" + generateClassName + \";\",\n                \"Ljava/lang/Object;\", null);\n        Method m = clz.getMethod(methodName, DexClassVisitor.class);\n        if (m == null) {\n            throw new java.lang.NoSuchMethodException(methodName);\n        }\n        m.setAccessible(true);\n        if (Modifier.isStatic(m.getModifiers())) {\n            m.invoke(null, clzNode);\n        } else {\n            m.invoke(clz.newInstance(), clzNode);\n        }\n        return translateAndCheck(clzNode);\n    }\n\n    public static byte[] translateAndCheck(DexFileNode fileNode, DexClassNode clzNode) throws AnalyzerException,\n            IllegalAccessException {\n        // 1. convert to .class\n        Dex2Asm dex2Asm = new Dex2Asm() {\n            @Override\n            public void convertCode(DexMethodNode methodNode, MethodVisitor mv) {\n                try {\n                    super.convertCode(methodNode, mv);\n                } catch (Exception ex) {\n                    BaksmaliDumper d = new BaksmaliDumper();\n                    try {\n                        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.err, \"UTF-8\"));\n                        d.baksmaliMethod(methodNode, out);\n                        out.flush();\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                    }\n                    throw new DexException(ex, \"fail convert code %s\", methodNode.method);\n                }\n            }\n        };\n        final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n        final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw);\n        ClassVisitorFactory cvf = new ClassVisitorFactory() {\n            @Override\n            public ClassVisitor create(String classInternalName) {\n                return rca;\n            }\n        };\n        if (fileNode != null) {\n            dex2Asm.convertClass(clzNode, cvf, fileNode);\n        } else {\n            dex2Asm.convertClass(clzNode, cvf);\n        }\n        byte[] data = cw.toByteArray();\n\n        // 2. verify .class\n        ClassReader cr = new ClassReader(data);\n        TestUtils.verify(cr);\n\n        // 3. convert back to dex\n        CfOptions cfOptions = new CfOptions();\n        cfOptions.strictNameCheck = false;\n        DexOptions dexOptions = new DexOptions();\n        if (fileNode != null && fileNode.dexVersion >= DexConstants.DEX_037) {\n            dexOptions.minSdkVersion = 26;\n        }\n\n        DirectClassFile dcf = new DirectClassFile(data, rca.getClassName() + \".class\", true);\n        dcf.setAttributeFactory(new StdAttributeFactory());\n        com.android.dx.dex.file.DexFile dxFile = new com.android.dx.dex.file.DexFile(dexOptions);\n        try {\n            CfTranslator.translate(new DxContext(), dcf, data, cfOptions, dexOptions, dxFile);\n        } catch (ParseException e) {\n            if (\"MethodHandle not supported\".equals(e.getMessage())) {\n                e.printStackTrace();\n            } else {\n                throw e;\n            }\n        }\n        return data;\n    }\n\n    public static byte[] translateAndCheck(DexClassNode clzNode) throws AnalyzerException, IllegalAccessException {\n        return translateAndCheck(null, clzNode);\n    }\n\n    public static Class<?> defineClass(String type, byte[] data) {\n        return new CL().xxxDefine(type, data);\n    }\n\n    static class CL extends ClassLoader {\n        public Class<?> xxxDefine(String type, byte[] data) {\n            return super.defineClass(type, data, 0, data.length);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/com/googlecode/dex2jar/test/ZeroTest.java",
    "content": "package com.googlecode.dex2jar.test;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static com.googlecode.d2j.reader.Op.*;\n\n@RunWith(DexTranslatorRunner.class)\npublic class ZeroTest implements DexConstants {\n    @Test\n    public static void testZero(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv\n                .visitMethod(ACC_STATIC, new Method(\"La;\", \"b\", new String[] {}, \"[Ljava/lang/Object;\"));\n        if (mv != null) {\n            DexCodeVisitor code = mv.visitCode();\n            if (code != null) {\n                int v0 = 0;\n                code.visitRegister(1);\n                DexLabel L1 = new DexLabel();\n                DexLabel L2 = new DexLabel();\n                DexLabel L3 = new DexLabel();\n                code.visitConstStmt(CONST, v0, 0);\n                code.visitJumpStmt(IF_EQ, v0, v0, L2);\n                code.visitLabel(L1);\n                code.visitStmt1R(RETURN_OBJECT, v0);\n                code.visitLabel(L2);\n                code.visitJumpStmt(IF_EQ, v0, v0, L3);\n                code.visitMethodStmt(INVOKE_STATIC, new int[0], new Method(\"La;\", \"getBytes\", new String[0], \"[B\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, v0);\n                code.visitLabel(L3);\n                code.visitMethodStmt(INVOKE_STATIC, new int[] { v0 }, new Method(\"La;\", \"useBytes\",\n                        new String[] { \"[B\" }, \"V\"));\n                code.visitMethodStmt(INVOKE_STATIC, new int[0], new Method(\"La;\", \"getObjects\", new String[0],\n                        \"[Ljava/lang/Object;\"));\n                code.visitStmt1R(MOVE_RESULT, v0);\n                code.visitJumpStmt(GOTO, -1, -1, L1);\n                code.visitEnd();\n            }\n            mv.visitEnd();\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/dex2jar/gen/FTPClient__parsePassiveModeReply.java",
    "content": "package dex2jar.gen;\n\nimport com.googlecode.d2j.*;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\nimport com.googlecode.dex2jar.test.DexTranslatorRunner;\nimport com.googlecode.dex2jar.test.TestUtils;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.objectweb.asm.Opcodes;\n\nimport static com.googlecode.d2j.reader.Op.*;\n@RunWith(DexTranslatorRunner.class)\npublic class FTPClient__parsePassiveModeReply implements Opcodes {\n    @Test\n    public static void m003___parsePassiveModeReply(DexClassVisitor cv) {\n        DexMethodVisitor mv = cv.visitMethod(ACC_PRIVATE, new Method(\"Lorg/apache/commons/net/ftp/FTPClient;\",\n                \"__parsePassiveModeReply\", new String[] { \"Ljava/lang/String;\" }, \"V\"));\n        if (mv != null) {\n            {\n                DexAnnotationVisitor av00 = mv.visitAnnotation(\"Ldalvik/annotation/Throws;\", Visibility.RUNTIME);\n                if (av00 != null) {\n                    {\n                        DexAnnotationVisitor av01 = av00.visitArray(\"value\");\n                        if (av01 != null) {\n                            av01.visit(null, new DexType(\"Lorg/apache/commons/net/MalformedServerReplyException;\"));\n                            av01.visitEnd();\n                        }\n                    }\n                    av00.visitEnd();\n                }\n            }\n            DexCodeVisitor code = mv.visitCode();\n            if (code != null) {\n                code.visitRegister(11);\n                DexLabel L0 = new DexLabel();\n                DexLabel L1 = new DexLabel();\n                DexLabel L2 = new DexLabel();\n                code.visitTryCatch(L0, L1, new DexLabel[] { L2 }, new String[] { \"Ljava/lang/NumberFormatException;\" });\n\n                code.visitConstStmt(CONST, 7, Integer.valueOf(46)); // int: 0x0000002e float:0.000000\n                code.visitConstStmt(CONST_STRING, 8, \"Could not parse passive host information.\\nServer Reply: \");\n\n                code.visitFieldStmt(SGET_OBJECT, 5,-1, new Field(\"Lorg/apache/commons/net/ftp/FTPClient;\", \"__parms_pat\",\n                        \"Ljava/util/regex/Pattern;\"));\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 10 }, new Method(\"Ljava/util/regex/Pattern;\",\n                        \"matcher\", new String[] { \"Ljava/lang/CharSequence;\" }, \"Ljava/util/regex/Matcher;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 1);\n\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method(\"Ljava/util/regex/Matcher;\",\n                        \"find\", new String[] {}, \"Z\"));\n                code.visitStmt1R(MOVE_RESULT, 5);\n                DexLabel L13 = new DexLabel();\n                code.visitJumpStmt(IF_NEZ, 5, -1,L13);\n\n                code.visitTypeStmt(NEW_INSTANCE, 5,-1, \"Lorg/apache/commons/net/MalformedServerReplyException;\");\n                code.visitTypeStmt(NEW_INSTANCE, 6,-1, \"Ljava/lang/StringBuilder;\");\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"<init>\", new String[] {}, \"V\"));\n                code.visitConstStmt(CONST_STRING, 7, \"Could not parse passive host information.\\nServer Reply: \");\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6, 8 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6, 10 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"toString\", new String[] {}, \"Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 5, 6 }, new Method(\n                        \"Lorg/apache/commons/net/MalformedServerReplyException;\", \"<init>\",\n                        new String[] { \"Ljava/lang/String;\" }, \"V\"));\n                code.visitStmt1R(THROW, 5);\n                code.visitLabel(L13);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method(\"Ljava/util/regex/Matcher;\",\n                        \"group\", new String[] {}, \"Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 10);\n\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method(\"Ljava/util/regex/Matcher;\",\n                        \"group\", new String[] {}, \"Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitConstStmt(CONST_STRING, 6, \",\");\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 6 }, new Method(\"Ljava/lang/String;\", \"split\",\n                        new String[] { \"Ljava/lang/String;\" }, \"[Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 4);\n\n                code.visitTypeStmt(NEW_INSTANCE, 5, -1,\"Ljava/lang/StringBuilder;\");\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 5 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"<init>\", new String[] {}, \"V\"));\n                code.visitConstStmt(CONST, 6, Integer.valueOf(0)); // int: 0x00000000 float:0.000000\n                code.visitStmt3R(AGET_OBJECT, 6, 4, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 7 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"C\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitConstStmt(CONST, 6, Integer.valueOf(1)); // int: 0x00000001 float:0.000000\n                code.visitStmt3R(AGET_OBJECT, 6, 4, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 7 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"C\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitConstStmt(CONST, 6, Integer.valueOf(2)); // int: 0x00000002 float:0.000000\n                code.visitStmt3R(AGET_OBJECT, 6, 4, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT, 5);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 7 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"C\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 5);\n                code.visitConstStmt(CONST, 6, Integer.valueOf(3)); // int: 0x00000003 float:0.000000\n                code.visitStmt3R(AGET_OBJECT, 6, 4, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5, 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT, 5);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 5 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"toString\", new String[] {}, \"Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT, 5);\n                code.visitFieldStmt(IPUT, 5, 9, new Field(\"Lorg/apache/commons/net/ftp/FTPClient;\", \"__passiveHost\",\n                        \"Ljava/lang/String;\"));\n                code.visitConstStmt(CONST, 5, Integer.valueOf(4)); // int: 0x00000004 float:0.000000\n                code.visitLabel(L0);\n                code.visitStmt3R(AGET_OBJECT, 5, 4, 5);\n                code.visitMethodStmt(INVOKE_STATIC, new int[] { 5 }, new Method(\"Ljava/lang/Integer;\", \"parseInt\",\n                        new String[] { \"Ljava/lang/String;\" }, \"I\"));\n                code.visitStmt1R(MOVE_RESULT, 2);\n\n                code.visitConstStmt(CONST, 5, Integer.valueOf(5)); // int: 0x00000005 float:0.000000\n                code.visitStmt3R(AGET_OBJECT, 5, 4, 5);\n                code.visitMethodStmt(INVOKE_STATIC, new int[] { 5 }, new Method(\"Ljava/lang/Integer;\", \"parseInt\",\n                        new String[] { \"Ljava/lang/String;\" }, \"I\"));\n                code.visitStmt1R(MOVE_RESULT, 3);\n                                     code.visitStmt2R1N(Op.SHL_INT_LIT8,5,2,8);\n\n                code.visitStmt3R(OR_INT, 5, 5, 3);\n                code.visitFieldStmt(IPUT, 5, 9, new Field(\"Lorg/apache/commons/net/ftp/FTPClient;\", \"__passivePort\",\n                        \"I\"));\n                code.visitLabel(L1);\n                code.visitStmt0R(RETURN_VOID);\n                code.visitLabel(L2);\n                code.visitStmt1R(MOVE_EXCEPTION, 5);\n                code.visitStmt2R(MOVE, 0, 5);\n\n                code.visitTypeStmt(NEW_INSTANCE, 5, -1,\"Lorg/apache/commons/net/MalformedServerReplyException;\");\n                code.visitTypeStmt(NEW_INSTANCE, 6,-1, \"Ljava/lang/StringBuilder;\");\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"<init>\", new String[] {}, \"V\"));\n                code.visitConstStmt(CONST_STRING, 7, \"Could not parse passive host information.\\nServer Reply: \");\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6, 8 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6, 10 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"append\", new String[] { \"Ljava/lang/String;\" }, \"Ljava/lang/StringBuilder;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 6 }, new Method(\"Ljava/lang/StringBuilder;\",\n                        \"toString\", new String[] {}, \"Ljava/lang/String;\"));\n                code.visitStmt1R(MOVE_RESULT_OBJECT, 6);\n                code.visitMethodStmt(INVOKE_DIRECT, new int[] { 5, 6 }, new Method(\n                        \"Lorg/apache/commons/net/MalformedServerReplyException;\", \"<init>\",\n                        new String[] { \"Ljava/lang/String;\" }, \"V\"));\n                code.visitStmt1R(THROW, 5);\n\n                code.visitEnd();\n            }\n            mv.visitEnd();\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ArrayRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class ArrayRes {\n\n    void array() {\n        int a[] = new int[] { 1, 2, 2, 3, 4, 5, 5, 6, 2, 7, };\n        System.out.println(a);\n        bb(1, 2, 4, 5, 6, 66, 77, 9, 77, 1, 123);\n        int b = a[2];\n        int c = (int) System.currentTimeMillis();\n        bb(b, c);\n\n    }\n\n    void adadfasd() {\n        Object object = new Object();\n        Object object1 = new Object();\n        Object object2 = new Object();\n        Object object3 = new Object();\n        Object object4 = new Object();\n        Object object5 = new Object();\n        Object object6 = new Object();\n        Object object7 = new Object();\n        Object object8 = new Object();\n        Object object9 = new Object();\n        Object object10 = new Object();\n        Object object11 = new Object[] { object, object1, object2, object3, object4, object5, object6, object7, object8, object9, object10 };\n\n    }\n\n    Object adssss() {\n        return new Object[] { new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(),\n                new Object(), new Object(), new Object() };\n    }\n\n    void bb(int... aaaaa) {\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ChineseRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class ChineseRes {\n    public void 你() {\n        System.out.println(\"你好\");\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ConstValues.java",
    "content": "package res;\n\npublic interface ConstValues {\n\n    byte b1 = 0;\n    byte b2 = -1;\n    byte b3 = 1;\n    byte b4 = 0x7F;\n\n    short s1 = 0;\n    short s2 = -1;\n    short s3 = 1;\n    short s4 = 0x7FFF;\n\n    char c1 = 0;\n    char c2 = 1;\n    char c3 = 0x7FFF;\n\n    int i1 = -1;\n    int i2 = 0;\n    int i3 = 0xFF;\n    int i4 = 0xFFFF;\n    int i5 = 0xFFFFFF;\n    int i6 = 0x7FFFFFFF;\n\n    float f1 = 0;\n    float f2 = -1;\n    float f3 = 1;\n    float f4 = Float.MAX_VALUE;\n    float f5 = Float.MIN_VALUE;\n\n    double d1 = 0;\n    double d2 = -1;\n    double d3 = 1;\n    double d4 = Double.MAX_VALUE;\n    double d5 = Double.MIN_VALUE;\n\n    long l1 = 0;\n    long l2 = -1;\n    long l3 = 1;\n    long l4 = 0x7FFFFFFFFFFFFFFFL;\n\n    boolean bl1 = true;\n    boolean bl2 = false;\n\n    Abc abc1 = null;\n    Abc abc2 = Abc.X;\n\n    enum Abc {\n        X, Y\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ExceptionRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class ExceptionRes {\n    public int a() {\n        try {\n            System.out.println(\"abc\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return 0;\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/Gh28Type.java",
    "content": "package res;\n\nimport java.lang.reflect.Array;\n\n/**\n * https://github.com/pxb1988/dex2jar/issues/28\n */\npublic class Gh28Type {\n\n    protected void onCreate() {\n        double t0[] = new double[2];\n        t0[0] = 1.0;\n        t0[1] = 2.0; // for https://github.com/pxb1988/dex2jar/issues/101\n        double t1[] = (double[]) Array.newInstance(Double.TYPE, 1);\n        t1[0] = 0;\n        double t2[][] = new double[1][1];\n        t2[0][0] = 0; // incorrectly translated to 0L (long) rather than 0.0 (double)\n        double t3[][] = (double[][]) Array.newInstance(Double.TYPE, 1, 1);\n        t3[0][0] = 0; // incorrectly translated to 0L (long) rather than 0.0 (double)\n        a(t0);\n        a(t1);\n        a(t2[0]);\n        a(t3[0]);\n    }\n\n    private void a(double[] t0) {\n        // Just to avoid optimization of unused local variables in onCreate here above\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/I142_annotation_default.java",
    "content": "package res;\n\npublic @interface I142_annotation_default {\n\n    enum AA {\n        A, B, C\n    }\n\n    AA aaa() default AA.A;\n\n    AA bbb();\n\n    String ccc() default \"\";\n\n    String ddd() default \"ddd\";\n\n    int eee() default 1;\n\n    byte fff() default 1;\n\n    short ggg() default 1;\n\n    char hhh() default 1;\n\n    boolean iii() default true;\n\n    long jjj() default 1L;\n\n    float kkk() default 1.0F;\n\n    double lll() default 1.0D;\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/I56_AccessFlag.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class I56_AccessFlag {\n    static class AStaticInnerClass {\n    }\n\n    class AInnerClass {\n        class AAA {\n        }\n    }\n\n    interface AInterface {\n    }\n\n    public static class B1 {\n    };\n\n    public static class B11 {\n        public static class XXX1 {\n        };\n    };\n\n    private static class B2 {\n    };\n\n    protected static class B3 {\n    };\n\n    /* package */static class B0 {\n    };\n\n    final static class B4 {\n    }\n\n    /* package */class C0 {\n    }\n\n    public class C1 {\n    }\n\n    private class C2 {\n    }\n\n    protected class C3 {\n    }\n\n    final class C4 {\n    }\n\n    abstract class C5 {\n    }\n\n    synchronized void sync1() {\n    }\n\n    /**\n     * seams that dx translate this method to\n     * \n     * <pre>\n     * void sync2() {\n     *     synchronized (this) {\n     *         new Object();\n     *     }\n     * }\n     * </pre>\n     */\n    synchronized void sync2() {\n        new Object();\n    }\n\n    void a() {\n        new Object() {\n            Object o = new Object() {\n            };\n\n            class AX {\n            }\n        };\n    }\n\n    Object o = new Object() {\n    };\n\n    static interface AStaticInterface {\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/I71.java",
    "content": "package res;\n\npublic class I71 {\n\n    /**\n     * code similar to edu.emory.mathcs.backport.java.util.concurrent.ConcurrentSkipListMap.SubMap.size()\n     * \n     * @return\n     */\n    public int size() {\n        long count = 0;\n        for (int i = 0; i < 5; i++) {\n            ++count;\n        }\n        return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) count;\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/I73.java",
    "content": "package res;\n\npublic class I73 {\n    String a() {\n        Object x = new Object();\n        String[] y = (String[]) x;\n        y[0] = null;\n        int[] z = (int[]) x;\n        z[0] = 0;\n        return \"\" + y + z;\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/I88.java",
    "content": "package res;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport res.I88.A;\n\n@A\npublic class I88 {\n\n    public static void main(String... args) {\n        A a = I88.class.getAnnotation(A.class);\n        System.out.println(a.a());\n    }\n\n    @A\n    I88() {\n    }\n\n    @A\n    int i;\n\n    @A\n    public void a(@A int i) {\n        @A\n        // TODO the annotation is gone.\n        String b = \"\";\n    }\n\n    @A\n    @Retention(RetentionPolicy.RUNTIME)\n    @Target({ ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE,\n            ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE })\n    public @interface A {\n        String a() default \"234\";\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/LongDoubleRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class LongDoubleRes {\n    long a(double d, double d2, long l1, long l2) {\n        long l3 = l1 + l2;\n        double d3 = d + d2;\n        return (long) (d3 + l3);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/NoEndRes.java",
    "content": "package res;\n\n/**\n * test case for issue 87, http://code.google.com/p/dex2jar/issues/detail?id=87\n * \n * @author Panxiaobo\n * \n */\npublic class NoEndRes {\n    public void b() {\n    }\n\n    public void a() {\n        while (true) {\n            b();\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/NullZero.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class NullZero {\n    void nullzero() {\n        String _null = null;\n        int zero = 0;\n        if (_null == null) {\n            _null = \"asdf\";\n            if (zero == 1) {\n                zero = 123;\n            }\n        }\n        System.out.println(0);\n        System.out.println((String) null);\n        System.out.println(_null);\n        System.out.println(zero);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/OptimizeSynchronized.java",
    "content": "package res;\n\nimport java.io.PrintStream;\n\npublic class OptimizeSynchronized {\n    public void a() {\n        synchronized (this) {\n            System.out.println(this);\n        }\n    }\n\n    Object b;\n\n    public void b() {\n        synchronized (OptimizeSynchronized.class) {\n            System.out.println(this);\n        }\n    }\n\n    public void c() {\n        synchronized (this.b) {\n            System.out.println(this);\n        }\n    }\n\n    public void d() {\n        PrintStream out = System.out;\n        synchronized (out) {\n            out.print(\"aa\");\n        }\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/PopRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class PopRes {\n\n    long aaa() {\n        return 0;\n    }\n\n    void bbb() {\n        aaa();\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ResChild.java",
    "content": "package res;\n\npublic class ResChild extends ResParent {\n    @Override\n    public void someMethod(int a, String b) {\n        super.someMethod(a, b);\n        this.someMethod(a, b);\n    }\n\n    public void anotherMethod() {\n        this.someMethod(0, null);\n        super.someMethod(0, null);\n        super.bbb(0, null);\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/ResParent.java",
    "content": "package res;\n\npublic class ResParent {\n    public void someMethod(int a, String b) {\n    }\n\n    public void bbb(int a, String b) {\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/SwitchRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class SwitchRes {\n\n    void sw1() {\n        int a = 1;\n        switch (a) {\n        case 1:\n        case 2:\n        case 3:\n            System.out.println(\"123\");\n            break;\n        case 100:\n            System.out.println(\"100\");\n            break;\n        default:\n            System.out.println(\"def\");\n            break;\n        }\n    }\n\n    void sw2() {\n        int a = 1;\n        int b = 2;\n        switch (a) {\n        case 1:\n            if (b == 2) {\n                System.out.println(\"b\");\n            } else {\n                System.out.println(\"bbb\");\n            }\n        case 2:\n        case 3:\n            System.out.println(\"123\");\n            break;\n        case 100:\n            System.out.println(\"100\");\n            break;\n        default:\n            System.out.println(\"def\");\n            break;\n        }\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/U0000String.java",
    "content": "package res;\n\npublic class U0000String {\n    void a() {\n        System.out.println(\"AAA\\u0000ZZZ\");\n    }\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/WideRes.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n * \n */\npublic class WideRes {\n    float aaa() {\n        float a = 1.01f + 2;\n        float b = 12 + a;\n        a = a + b;\n        a = a * b;\n        a = a - b;\n        a = a / b;\n        return a + 2;\n    }\n\n    double bbb() {\n        double b = 1.01 + 2;\n        double a = 12312.123 + b;\n        a = a + b;\n        a = a * b;\n        a = a - b;\n        a = a / b;\n        return b + 2;\n    }\n\n    int ccc() {\n        int b = 1 + 2;\n        int a = 12312 + b;\n        a += 1231231231;\n        a = a + b;\n        a = a * b;\n        a = a - b;\n        a = a / b;\n        return b + 2;\n    }\n\n    long ddd() {\n        long b = 1l + 2;\n        long a = 12312l + b;\n        a += 1231232134234234524L;\n        a = a + b;\n        a = a * b;\n        a = a - b;\n        a = a / b;\n        return b + 2;\n    }\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/i55/AAbstractClass.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res.i55;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n *\n */\npublic abstract class AAbstractClass {\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/i55/AClass.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res.i55;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n *\n */\npublic class AClass {\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/java/res/i55/AInterface.java",
    "content": "/*\n * Copyright (c) 2009-2012 Panxiaobo\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage res.i55;\n\n/**\n * @author <a href=\"mailto:pxb1988@gmail.com\">Panxiaobo</a>\n *\n */\npublic interface AInterface {\n\n}\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/0zs.smali",
    "content": ".class Li;\n.super Ljava/lang/Object;\n\n.method protected static getCallScreenClassName()Ljava/lang/String;\n    .registers 1\n\n    .prologue\n    .line 888\n    invoke-static {}, Landroid/telephony/MSimTelephonyManager;->getDefault()Landroid/telephony/MSimTelephonyManager;\n\n    move-result-object v0\n\n    invoke-virtual {v0}, Landroid/telephony/MSimTelephonyManager;->isMultiSimEnabled()Z\n\n    move-result v0\n\n    if-eqz v0, :cond_11\n\n    .line 889\n    const-class v0, Lcom/android/phone/MSimInCallScreen;\n\n    invoke-virtual {v0}, Ljava/lang/Class;->getName()Ljava/lang/String;\n\n    move-result-object v0\n\n    .line 891\n    :goto_10\n    return-object v0\n\n    :cond_11\n    const-class v0, Lcom/android/phone/InCallScreen;\n\n    invoke-virtual {v0}, Ljava/lang/Class;->getName()Ljava/lang/String;\n\n    move-result-object v0\n\n    goto :goto_10\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/ML.smali",
    "content": ".class LML;\n.super Ljava/lang/Object;\n.source \"ML.java\"\n\n\n# direct methods\n.method constructor <init>()V\n    .registers 1\n\n    .prologue\n    .line 1\n    invoke-direct {p0}, Ljava/lang/Object;-><init>()V\n\n    return-void\n.end method\n\n\n# virtual methods\n.method a()Ljava/lang/Object;\n    .registers 4\n\n    .prologue\n    .line 3\n    const/4 v0, 0x4\n\n    const/4 v1, 0x5\n\n    const/4 v2, 0x6\n\n    filled-new-array {v0, v1, v2}, [I\n\n    move-result-object v0\n\n    const-class v1, Ljava/lang/String;\n\n    invoke-static {v1, v0}, Ljava/lang/reflect/Array;->newInstance(Ljava/lang/Class;[I)Ljava/lang/Object;\n\n    move-result-object v0\n\n    check-cast v0, [[[Ljava/lang/String;\n\n    return-object v0\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/bb-1-can-not-merge-z-and-i.smali",
    "content": ".class Landroid/preference/MultiSelectListPreference;\n.super Ljava/lang/Object;\n\n.method test(Ljava/util/Set;Ljava/lang/Object;)V\n  .registers 3\n    invoke-interface { p1, p2 }, Ljava/util/Set;->add(Ljava/lang/Object;)Z\n    move-result p1\n    invoke-static { p0, p1 },  // p1 is boolean but used as integer\n        Landroid/preference/MultiSelectListPreference;->access$076(Landroid/preference/MultiSelectListPreference;I)Z\n    return-void\n.end method\n\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/bb-5-ArrayIndexOutOfBoundsOnType.smali",
    "content": ".class Li;\n.super Ljava/lang/Object;\n\n\n.method public final a(Ljava/lang/Object;IZ)Ljava/lang/Object;\n  .registers 8\n    const/4 v0, 0\n    instance-of v1, p1, Ljava/lang/Byte;\n    if-eqz v1, :L1\n    invoke-virtual { p0, v0, p2, p3 }, Lct/be;->a(BIZ)B\n    move-result v0\n    invoke-static { v0 }, Ljava/lang/Byte;->valueOf(B)Ljava/lang/Byte;\n    move-result-object v0\n  :L0\n    return-object v0\n  :L1\n    instance-of v1, p1, Ljava/lang/Boolean;\n    if-eqz v1, :L3\n    invoke-virtual { p0, v0, p2, p3 }, Lct/be;->a(BIZ)B\n    move-result v1\n    if-eqz v1, :L2\n    const/4 v0, 1\n  :L2\n    invoke-static { v0 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;\n    move-result-object v0\n    goto :L0\n  :L3\n    instance-of v1, p1, Ljava/lang/Short;\n    if-eqz v1, :L4\n    invoke-virtual { p0, v0, p2, p3 }, Lct/be;->a(SIZ)S\n    move-result v0\n    invoke-static { v0 }, Ljava/lang/Short;->valueOf(S)Ljava/lang/Short;\n    move-result-object v0\n    goto :L0\n  :L4\n    instance-of v1, p1, Ljava/lang/Integer;\n    if-eqz v1, :L5\n    invoke-virtual { p0, v0, p2, p3 }, Lct/be;->a(IIZ)I\n    move-result v0\n    invoke-static { v0 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v0\n    goto :L0\n  :L5\n    instance-of v1, p1, Ljava/lang/Long;\n    if-eqz v1, :L6\n    const-wide/16 v0, 0\n    invoke-virtual { p0, v0, v1, p2, p3 }, Lct/be;->a(JIZ)J\n    move-result-wide v0\n    invoke-static { v0, v1 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v0\n    goto :L0\n  :L6\n    instance-of v1, p1, Ljava/lang/Float;\n    if-eqz v1, :L7\n    const/4 v0, 0\n    invoke-direct { p0, v0, p2, p3 }, Lct/be;->a(FIZ)F\n    move-result v0\n    invoke-static { v0 }, Ljava/lang/Float;->valueOf(F)Ljava/lang/Float;\n    move-result-object v0\n    goto :L0\n  :L7\n    instance-of v1, p1, Ljava/lang/Double;\n    if-eqz v1, :L8\n    const-wide/16 v0, 0\n    invoke-direct { p0, v0, v1, p2, p3 }, Lct/be;->a(DIZ)D\n    move-result-wide v0\n    invoke-static { v0, v1 }, Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;\n    move-result-object v0\n    goto :L0\n  :L8\n    instance-of v1, p1, Ljava/lang/String;\n    if-eqz v1, :L9\n    invoke-virtual { p0, p2, p3 }, Lct/be;->a(IZ)Ljava/lang/String;\n    move-result-object v0\n    goto :L0\n  :L9\n    instance-of v1, p1, Ljava/util/Map;\n    if-eqz v1, :L10\n    check-cast p1, Ljava/util/Map;\n    new-instance v0, Ljava/util/HashMap;\n    invoke-direct { v0 }, Ljava/util/HashMap;-><init>()V\n    invoke-virtual { p0, v0, p1, p2, p3 }, Lct/be;->a(Ljava/util/Map;Ljava/util/Map;IZ)Ljava/util/Map;\n    move-result-object v0\n    check-cast v0, Ljava/util/HashMap;\n    goto :L0\n  :L10\n    instance-of v1, p1, Ljava/util/List;\n    if-eqz v1, :L16\n    check-cast p1, Ljava/util/List;\n    if-eqz p1, :L11\n    invoke-interface { p1 }, Ljava/util/List;->isEmpty()Z\n    move-result v1\n    if-eqz v1, :L12\n  :L11\n    new-instance v0, Ljava/util/ArrayList;\n    invoke-direct { v0 }, Ljava/util/ArrayList;-><init>()V\n    goto/16 :L0\n  :L12\n    invoke-interface { p1, v0 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object v1\n    invoke-direct { p0, v1, p2, p3 }, Lct/be;->b(Ljava/lang/Object;IZ)[Ljava/lang/Object;\n    move-result-object v2\n    if-nez v2, :L13\n    const/4 v0, 0\n    goto/16 :L0\n  :L13\n    new-instance v1, Ljava/util/ArrayList;\n    invoke-direct { v1 }, Ljava/util/ArrayList;-><init>()V\n  :L14\n    array-length v3, v2\n    if-ge v0, v3, :L15\n    aget-object v3, v2, v0\n    invoke-virtual { v1, v3 }, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z\n    add-int/lit8 v0, v0, 1\n    goto :L14\n  :L15\n    move-object v0, v1\n    goto/16 :L0\n  :L16\n    instance-of v1, p1, Lct/bg;\n    if-eqz v1, :L17\n    check-cast p1, Lct/bg;\n    invoke-virtual { p0, p1, p2, p3 }, Lct/be;->a(Lct/bg;IZ)Lct/bg;\n    move-result-object v0\n    goto/16 :L0\n  :L17\n    invoke-virtual { p1 }, Ljava/lang/Object;->getClass()Ljava/lang/Class;\n    move-result-object v1\n    invoke-virtual { v1 }, Ljava/lang/Class;->isArray()Z\n    move-result v1\n    if-eqz v1, :L28\n    instance-of v1, p1, [B\n    if-nez v1, :L18\n    instance-of v1, p1, [Ljava/lang/Byte;\n    if-eqz v1, :L19\n  :L18\n    invoke-virtual { p0, p2, p3 }, Lct/be;->b(IZ)[B\n    move-result-object v0\n    goto/16 :L0\n  :L19\n    instance-of v1, p1, [Z\n    if-eqz v1, :L20\n    invoke-direct { p0, p2, p3 }, Lct/be;->c(IZ)[Z\n    move-result-object v0\n    goto/16 :L0\n  :L20\n    instance-of v1, p1, [S\n    if-eqz v1, :L21\n    invoke-direct { p0, p2, p3 }, Lct/be;->d(IZ)[S\n    move-result-object v0\n    goto/16 :L0\n  :L21\n    instance-of v1, p1, [I\n    if-eqz v1, :L22\n    invoke-direct { p0, p2, p3 }, Lct/be;->e(IZ)[I\n    move-result-object v0\n    goto/16 :L0\n  :L22\n    instance-of v1, p1, [J\n    if-eqz v1, :L23\n    invoke-direct { p0, p2, p3 }, Lct/be;->f(IZ)[J\n    move-result-object v0\n    goto/16 :L0\n  :L23\n    instance-of v1, p1, [F\n    if-eqz v1, :L24\n    invoke-direct { p0, p2, p3 }, Lct/be;->g(IZ)[F\n    move-result-object v0\n    goto/16 :L0\n  :L24\n    instance-of v1, p1, [D\n    if-eqz v1, :L25\n    invoke-direct { p0, p2, p3 }, Lct/be;->h(IZ)[D\n    move-result-object v0\n    goto/16 :L0\n  :L25\n    check-cast p1, [Ljava/lang/Object;\n    if-eqz p1, :L26\n    array-length v1, p1\n    if-nez v1, :L27\n  :L26\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string/jumbo v1, \"unable to get type of key and value.\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n  :L27\n    aget-object v0, p1, v0\n    invoke-direct { p0, v0, p2, p3 }, Lct/be;->b(Ljava/lang/Object;IZ)[Ljava/lang/Object;\n    move-result-object v0\n    goto/16 :L0\n  :L28\n    new-instance v0, Ljava/lang/RuntimeException;\n    const-string/jumbo v1, \"read object error: unsupport type.\"\n    invoke-direct { v0, v1 }, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V\n    throw v0\n.end method\n\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/empty-try-catch-with-goto-head.smali",
    "content": ".class Letcwgh;\n.super Ljava/lang/Object;\n\n.method private aaa(F)V\n  .catch Ljava/lang/Exception; { :L1 .. :L2 } :L3\n  .registers 8\n  :L0\n    iget-object v0, p0, Lz;->z:Lz;\n    if-eqz v0, :L1\n    iget-object v0, p0, Lz;->z:Lz;\n    invoke-static { }, Ljava/util/Locale;->getDefault()Ljava/util/Locale;\n    move-result-object v1\n    const-string/jumbo v2, \"%.1f\"\n    const/4 v3, 1\n    new-array v3, v3, [Ljava/lang/Object;\n    const/4 v4, 0\n    invoke-static { p1 }, Ljava/lang/Float;->valueOf(F)Ljava/lang/Float;\n    move-result-object v5\n    aput-object v5, v3, v4\n    invoke-static { v1, v2, v3 }, Ljava/lang/String;->format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;\n    move-result-object v1\n    invoke-virtual { v0, v1 }, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V\n  :L1\n    return-void\n  :L2\n  :L3\n    goto :L0\n.end method"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/gh-issue-186.smali",
    "content": ".class Lgh/i186;\n.super Ljava/lang/Object;\n\n.method public getEntryIndex(FFLcom/github/mikephil/charting/data/DataSet$Rounding;)I\n  .registers 14\n    iget-object v0, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    const/4 v1, -1\n    if-eqz v0, :L16\n    iget-object v0, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v0 }, Ljava/util/List;->isEmpty()Z\n    move-result v0\n    if-eqz v0, :L0\n    goto/16 :L16\n  :L0\n    const/4 v0, 0\n    iget-object v2, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v2 }, Ljava/util/List;->size()I\n    move-result v2\n    add-int/lit8 v2, v2, -1\n  :L1\n    if-ge v0, v2, :L7\n    add-int v3, v0, v2\n    div-int/lit8 v3, v3, 2\n    iget-object v4, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v4, v3 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object v4\n    check-cast v4, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { v4 }, Lcom/github/mikephil/charting/data/Entry;->getX()F\n    move-result v4\n    sub-float/2addr v4, p1\n    iget-object v5, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    add-int/lit8 v6, v3, 1\n    invoke-interface { v5, v6 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object v5\n    check-cast v5, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { v5 }, Lcom/github/mikephil/charting/data/Entry;->getX()F\n    move-result v5\n    sub-float/2addr v5, p1\n    invoke-static { v4 }, Ljava/lang/Math;->abs(F)F\n    move-result v7\n    invoke-static { v5 }, Ljava/lang/Math;->abs(F)F\n    move-result v5\n    cmpg-float v8, v5, v7\n    if-gez v8, :L3\n  :L2\n    move v0, v6\n    goto :L1\n  :L3\n    cmpg-float v5, v7, v5\n    if-gez v5, :L4\n    goto :L5\n  :L4\n    float-to-double v4, v4\n    const-wide/16 v7, 0\n    cmpl-double v9, v4, v7\n    if-ltz v9, :L6\n  :L5\n    move v2, v3\n    goto :L1\n  :L6\n    cmpg-double v3, v4, v7\n    if-gez v3, :L1\n    goto :L2\n  :L7\n    if-eq v2, v1, :L15\n    iget-object v0, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v0, v2 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { v0 }, Lcom/github/mikephil/charting/data/Entry;->getX()F\n    move-result v0\n    sget-object v1, Lcom/github/mikephil/charting/data/DataSet$Rounding;->UP:Lcom/github/mikephil/charting/data/DataSet$Rounding;\n    if-ne p3, v1, :L8\n    cmpg-float p1, v0, p1\n    if-gez p1, :L9\n    iget-object p1, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { p1 }, Ljava/util/List;->size()I\n    move-result p1\n    add-int/lit8 p1, p1, -1\n    if-ge v2, p1, :L9\n    add-int/lit8 v2, v2, 1\n    goto :L9\n  :L8\n    sget-object v1, Lcom/github/mikephil/charting/data/DataSet$Rounding;->DOWN:Lcom/github/mikephil/charting/data/DataSet$Rounding;\n    if-ne p3, v1, :L9\n    cmpl-float p1, v0, p1\n    if-lez p1, :L9\n    if-lez v2, :L9\n    add-int/lit8 v2, v2, -1\n  :L9\n    invoke-static { p2 }, Ljava/lang/Float;->isNaN(F)Z\n    move-result p1\n    if-nez p1, :L15\n  :L10\n    if-lez v2, :L11\n    iget-object p1, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    add-int/lit8 p3, v2, -1\n    invoke-interface { p1, p3 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object p1\n    check-cast p1, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { p1 }, Lcom/github/mikephil/charting/data/Entry;->getX()F\n    move-result p1\n    cmpl-float p1, p1, v0\n    if-nez p1, :L11\n    add-int/lit8 v2, v2, -1\n    goto :L10\n  :L11\n    iget-object p1, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { p1, v2 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object p1\n    check-cast p1, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { p1 }, Lcom/github/mikephil/charting/data/Entry;->getY()F\n    move-result p1\n    move p3, p1\n  :L12\n    move p1, v2\n  :L13\n    add-int/lit8 v2, v2, 1\n    iget-object v1, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v1 }, Ljava/util/List;->size()I\n    move-result v1\n    if-ge v2, v1, :L14\n    iget-object v1, p0, Lcom/github/mikephil/charting/data/DataSet;->mValues:Ljava/util/List;\n    invoke-interface { v1, v2 }, Ljava/util/List;->get(I)Ljava/lang/Object;\n    move-result-object v1\n    check-cast v1, Lcom/github/mikephil/charting/data/Entry;\n    invoke-virtual { v1 }, Lcom/github/mikephil/charting/data/Entry;->getX()F\n    move-result v3\n    cmpl-float v3, v3, v0\n    if-nez v3, :L14\n    invoke-virtual { v1 }, Lcom/github/mikephil/charting/data/Entry;->getY()F\n    move-result v1\n    sub-float/2addr v1, p2\n    invoke-static { v1 }, Ljava/lang/Math;->abs(F)F\n    move-result v1\n    sub-float v3, p3, p2\n    invoke-static { v3 }, Ljava/lang/Math;->abs(F)F\n    move-result v3\n    cmpg-float v1, v1, v3\n    if-gez v1, :L13\n    move p3, p2\n    goto :L12\n  :L14\n    move v2, p1\n  :L15\n    return v2\n  :L16\n    return v1\n.end method\n\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/gh-issue-4.smali",
    "content": ".class Lgh/i4;\n.super Ljava/lang/Object;\n\n.method static public a(LIndenter;)Ljava/lang/Object;\n  .registers 2\n  if-nez v1, :L0\n    new-instance v0, LNopIndenter;\n    move-object v1, v0  #### use before init\n    invoke-direct { v0 }, LNopIndenter;-><init>()V\n  :L0\n    return-object v1\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/goto-first-label.smali",
    "content": ".class Lxgoto/first/label;\n.super Ljava/lang/Object;\n\n.method public static assertSlept()V\n    .registers 3\n    :L0\n    sget-object v1, LA;->sleepSemaphore:Ljava/util/concurrent/Semaphore;\n    invoke-virtual { v1 }, Ljava/util/concurrent/Semaphore;->availablePermits()I\n    move-result v1\n    if-nez v1, :L1\n    return-void\n    :L1\n    const-wide/16 v1, 50\n    invoke-static { v1, v2 }, Ljava/lang/Thread;->sleep(J)V\n    goto :L0\n.end method\n\n.method public static g2(LObj;)V\n    .registers 4\n    :L0\n    invoke-virtual { p0 }, LObj;->next()LObj;\n    move-result-object v3\n    if-nez v3, :L1\n    return-void\n    :L1\n    invoke-virtual { p0 }, LObj;->next()LObj;\n    move-result-object p0\n    goto :L0\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/i230.smali",
    "content": ".class Li230;\n.super Li230;\n\n.method public i230(II)F\n    .catchall { :L5 .. :L10 } :L9\n    .registers 10\n    move-object v0, p0\n    monitor-enter v0\n    :L5\n    int-to-float v0, p1\n    int-to-float v1, p2\n    div-float/2addr v1, v0\n    move-object v0, p0\n    monitor-exit v0\n    return v1\n\n    :L9\n    move-exception v1\n    monitor-exit v0\n    :L10\n    const v1, 0\n    return v1\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/int-or-boolean.smali",
    "content": ".class Li/or/Z;\n.super Ljava/lang/Object;\n\n.method static synthetic access$376(Lcom/google/android/finsky/widget/consumption/NowPlayingWidgetProvider$ViewTreeWrapper;I)Z\n    .registers 3\n    iget-boolean v0, v1, Lcom/google/android/finsky/widget/consumption/NowPlayingWidgetProvider$ViewTreeWrapper;->showBackground:Z\n    or-int/2addr v0, v2\n    int-to-byte v0, v0\n    iput-boolean v0, v1, Lcom/google/android/finsky/widget/consumption/NowPlayingWidgetProvider$ViewTreeWrapper;->showBackground:Z\n    return v0\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/issue-220-219-uninit-reg.smali",
    "content": ".class Li220/i219;\n.super Ljava/lang/Object;\n.method public static i219(Ljava/lang/String;)I\n    .registers 2\n    return v0\n.end method\n\n.method public i220()Ljava/lang/String;\n    .registers 7\n    if-eqz v1, :L0\n    move v0, v6\n    :L0\n    return-object v2\n.end method\n\n.method public onClick(Landroid/content/DialogInterface;I)V\n    .registers 5\n    iget-object v0, v2, Lcom/adroidbscpc/a15mSurvival3rh/MainA$2;->this$0:Lcom/adroidbscpc/a15mSurvival3rh/MainA;\n    move-result-object v0\n    iget-object v1, v2, Lcom/adroidbscpc/a15mSurvival3rh/MainA$2;->this$0:Lcom/adroidbscpc/a15mSurvival3rh/MainA;\n    return-void\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/loop-enclosing-class.smali",
    "content": ".class La;\n.super Ljava/lang/Object;\n\n# annotations\n.annotation system Ldalvik/annotation/EnclosingClass;\n    value = La;\n.end annotation\n.end class\n\n\n.class Lb;\n.super Ljava/lang/Object;\n\n# annotations\n.annotation system Ldalvik/annotation/EnclosingClass;\n    value = Lc;\n.end annotation\n.end class\n\n\n.class Lc;\n.super Ljava/lang/Object;\n\n# annotations\n.annotation system Ldalvik/annotation/EnclosingClass;\n    value = Lb;\n.end annotation\n.end class"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/mayfail-method-code-too-large.smali",
    "content": "\n.class Lcode.Large;\n\n.method private static constructor <clinit>()V\n  .catchall { :L2 .. :L3 } :L0\n  .catchall { :L6 .. :L7 } :L4\n  .catchall { :L10 .. :L11 } :L8\n  .catchall { :L14 .. :L15 } :L12\n  .catchall { :L18 .. :L19 } :L16\n  .catchall { :L22 .. :L23 } :L20\n  .catchall { :L27 .. :L28 } :L25\n  .catchall { :L30 .. :L31 } :L29\n  .catchall { :L34 .. :L35 } :L32\n  .catchall { :L39 .. :L40 } :L37\n  .catchall { :L43 .. :L44 } :L41\n  .catchall { :L48 .. :L49 } :L46\n  .catchall { :L53 .. :L54 } :L51\n  .catchall { :L57 .. :L58 } :L55\n  .catchall { :L61 .. :L62 } :L59\n  .catchall { :L65 .. :L66 } :L63\n  .catchall { :L70 .. :L71 } :L68\n  .catch Ljava/lang/Exception; { :L72 .. :L74 } :L97\n  .catchall { :L75 .. :L76 } :L73\n  .catch Ljava/lang/Exception; { :L78 .. :L79 } :L97\n  .catchall { :L80 .. :L81 } :L77\n  .catch Ljava/lang/Exception; { :L82 .. :L84 } :L97\n  .catchall { :L85 .. :L86 } :L83\n  .catch Ljava/lang/Exception; { :L88 .. :L89 } :L97\n  .catchall { :L90 .. :L91 } :L87\n  .catch Ljava/lang/Exception; { :L92 .. :L94 } :L97\n  .catchall { :L95 .. :L96 } :L93\n  .catchall { :L100 .. :L101 } :L98\n  .catchall { :L104 .. :L105 } :L102\n  .catchall { :L107 .. :L108 } :L106\n  .catchall { :L111 .. :L112 } :L109\n  .catchall { :L115 .. :L116 } :L113\n  .catchall { :L119 .. :L120 } :L117\n  .catchall { :L123 .. :L124 } :L121\n  .catchall { :L127 .. :L128 } :L125\n  .catchall { :L131 .. :L132 } :L129\n  .catchall { :L135 .. :L136 } :L133\n  .catch Ljava/lang/Exception; { :L138 .. :L139 } :L150\n  .catchall { :L140 .. :L141 } :L137\n  .catch Ljava/lang/Exception; { :L144 .. :L145 } :L151\n  .catchall { :L146 .. :L147 } :L143\n  .registers 18\n    const/16 v0, 648\n    new-array v0, v0, [S\n    fill-array-data v0, :L152\n    sput-object v0, Lo/\\ufee4$\\u1508;->\\u0399:[S\n    const/16 v0, 217\n    sput v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    const/16 v17, 0\n    const/4 v10, 0\n    const/4 v13, 0\n    const/16 v0, 5336\n    const/16 v1, 612\n    const/4 v2, 7\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    goto :L1\n  :L0\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L1\n    const/4 v1, 1\n  :L2\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5277\n    const/16 v2, 85\n    const/16 v3, 29\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/4 v2, 1\n    new-array v2, v2, [Ljava/lang/Class;\n    const-class v3, Ljava/lang/String;\n    const/4 v4, 0\n    aput-object v3, v2, v4\n    invoke-virtual { v0, v2 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v0\n    invoke-virtual { v0, v1 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L3\n    move-result-object v14\n    goto :L5\n  :L4\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L5\n    const/16 v0, 5277\n    const/16 v1, 85\n    const/16 v2, 29\n  :L6\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5284\n    const/16 v2, 438\n    const/16 v3, 33\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    invoke-virtual { v0, v14, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Boolean;\n    invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z\n  :L7\n    move-result v0\n    if-nez v0, :L24\n    const/16 v0, 5277\n    const/16 v1, 451\n    const/16 v2, 27\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    goto :L9\n  :L8\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L9\n    const/4 v1, 2\n  :L10\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 1\n    aput-object v0, v1, v2\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    sget v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v0, v0, 63\n    int-to-byte v0, v0\n    const/16 v2, 5277\n    const/16 v3, 493\n    invoke-static { v2, v3, v0 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5280\n    const/16 v3, 115\n    const/16 v4, 30\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 2\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v2, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L11\n    move-result-object v0\n    goto :L13\n  :L12\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L13\n    const/4 v1, 1\n  :L14\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5277\n    const/16 v2, 85\n    const/16 v3, 29\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/4 v2, 1\n    new-array v2, v2, [Ljava/lang/Class;\n    const-class v3, Ljava/lang/String;\n    const/4 v4, 0\n    aput-object v3, v2, v4\n    invoke-virtual { v0, v2 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v0\n    invoke-virtual { v0, v1 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L15\n    move-result-object v14\n    goto :L17\n  :L16\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L17\n    const/16 v0, 5277\n    const/16 v1, 85\n    const/16 v2, 29\n  :L18\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5284\n    const/16 v2, 438\n    const/16 v3, 33\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    invoke-virtual { v0, v14, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Boolean;\n    invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z\n  :L19\n    move-result v0\n    if-nez v0, :L24\n    goto :L21\n  :L20\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L21\n    const/16 v0, 5286\n    const/16 v1, 205\n    const/16 v2, 19\n  :L22\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    sget v1, Lo/\\ufee4$\\u1508;->\\u0406:I\n    or-int/lit8 v1, v1, 32\n    int-to-short v1, v1\n    const/16 v2, 5280\n    const/16 v3, 14\n    invoke-static { v2, v1, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L23\n    move-result-object v14\n  :L24\n    const/16 v0, 5300\n    const/16 v1, 427\n    const/16 v2, 33\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    goto :L26\n  :L25\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L26\n    const/4 v1, 1\n  :L27\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5277\n    const/16 v2, 420\n    const/16 v3, 15\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5280\n    const/16 v3, 184\n    const/16 v4, 30\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 1\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v2, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L28\n    move-result-object v12\n    goto :L30\n  :L29\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L30\n    sget v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v0, v0, 63\n    int-to-byte v0, v0\n    const/16 v1, 5277\n    const/16 v2, 493\n    invoke-static { v1, v2, v0 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    sget v1, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v1, v1, 62\n    int-to-byte v1, v1\n    const/16 v2, 5284\n    const/16 v3, 368\n    invoke-static { v2, v3, v1 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Long;\n    invoke-virtual { v0 }, Ljava/lang/Long;->longValue()J\n  :L31\n    move-result-wide v0\n    const-wide/32 v2, 166624680\n    xor-long/2addr v2, v0\n    goto :L33\n  :L32\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L33\n    const/4 v0, 1\n  :L34\n    new-array v1, v0, [Ljava/lang/Object;\n    invoke-static { v2, v3 }, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;\n    move-result-object v0\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5277\n    const/16 v2, 420\n    const/16 v3, 15\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5268\n    const/16 v3, 121\n    const/16 v4, 34\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 1\n    new-array v3, v3, [Ljava/lang/Class;\n    sget-object v4, Ljava/lang/Long;->TYPE:Ljava/lang/Class;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    invoke-virtual { v0, v12, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L35\n    new-instance v0, Ljava/lang/String;\n    const/4 v1, 4\n    new-array v1, v1, [C\n    const/4 v2, 0\n    const/16 v3, 46\n    goto/16 :L45\n  :L36\n    goto :L38\n  :L37\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L38\n    const/4 v3, 1\n  :L39\n    new-array v4, v3, [Ljava/lang/Object;\n    const v3, 65279\n    invoke-static { v3 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v3\n    const/4 v5, 0\n    aput-object v3, v4, v5\n    const/16 v3, 5277\n    const/16 v5, 420\n    const/16 v6, 15\n    invoke-static { v3, v5, v6 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    invoke-static { v3 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v3\n    const/16 v5, 5273\n    const/4 v6, 0\n    const/16 v7, 34\n    invoke-static { v5, v6, v7 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v5\n    const/4 v6, 1\n    new-array v6, v6, [Ljava/lang/Class;\n    sget-object v7, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v8, 0\n    aput-object v7, v6, v8\n    invoke-virtual { v3, v5, v6 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v3\n    invoke-virtual { v3, v12, v4 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v3\n    check-cast v3, Ljava/lang/Integer;\n    invoke-virtual { v3 }, Ljava/lang/Integer;->intValue()I\n  :L40\n    move-result v3\n    add-int/lit16 v3, v3, 256\n    goto :L42\n  :L41\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L42\n    const/4 v4, 1\n  :L43\n    new-array v5, v4, [Ljava/lang/Object;\n    invoke-static { v3 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v4\n    const/4 v6, 0\n    aput-object v4, v5, v6\n    const/16 v4, 5277\n    const/16 v6, 386\n    const/16 v7, 22\n    invoke-static { v4, v6, v7 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v4\n    invoke-static { v4 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v4\n    sget v6, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v6, v6, 55\n    int-to-byte v6, v6\n    const/16 v7, 5278\n    const/16 v8, 144\n    invoke-static { v7, v8, v6 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v6\n    const/4 v7, 1\n    new-array v7, v7, [Ljava/lang/Class;\n    sget-object v8, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v9, 0\n    aput-object v8, v7, v9\n    invoke-virtual { v4, v6, v7 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v4\n    const/4 v6, 0\n    invoke-virtual { v4, v6, v5 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v4\n    check-cast v4, Ljava/lang/Boolean;\n    invoke-virtual { v4 }, Ljava/lang/Boolean;->booleanValue()Z\n  :L44\n    move-result v4\n    if-nez v4, :L45\n    goto/16 :L36\n  :L45\n    int-to-char v3, v3\n    aput-char v3, v1, v2\n    add-int/lit8 v2, v2, 1\n    and-int/lit8 v3, v2, 3\n    if-nez v3, :L36\n    invoke-direct { v0, v1 }, Ljava/lang/String;-><init>([C)V\n    goto :L47\n  :L46\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L47\n    const/4 v1, 2\n  :L48\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 1\n    aput-object v0, v1, v2\n    const/4 v0, 0\n    aput-object v14, v1, v0\n    const/16 v0, 5277\n    const/16 v2, 85\n    const/16 v3, 29\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/4 v2, 2\n    new-array v2, v2, [Ljava/lang/Class;\n    const/16 v3, 5277\n    const/16 v4, 85\n    const/16 v5, 29\n    invoke-static { v3, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    invoke-static { v3 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v3\n    const/4 v4, 0\n    aput-object v3, v2, v4\n    const-class v3, Ljava/lang/String;\n    const/4 v4, 1\n    aput-object v3, v2, v4\n    invoke-virtual { v0, v2 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v0\n    invoke-virtual { v0, v1 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L49\n    move-result-object v10\n    if-nez v17, :L50\n    move-object/from16 v17, v10\n    goto/16 :L35\n  :L50\n    const/16 v0, 5272\n    const/16 v1, 154\n    const/16 v2, 36\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v16\n    const/16 v11, 2150\n    sget v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v0, v0, 62\n    int-to-byte v0, v0\n    const/16 v1, 5318\n    const/16 v2, 628\n    invoke-static { v1, v2, v0 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    const/16 v1, 5317\n    const/16 v2, 428\n    const/16 v3, 39\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    goto :L52\n  :L51\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L52\n    const/4 v1, 2\n  :L53\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v3, 1\n    aput-object v2, v1, v3\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5277\n    const/16 v2, 547\n    const/16 v3, 22\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5280\n    const/16 v3, 184\n    const/16 v4, 30\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 2\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v2, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L54\n    move-result-object v0\n    const/16 v1, 16\n    new-array v1, v1, [B\n    fill-array-data v1, :L153\n    const/16 v2, 5318\n    const/16 v3, 453\n    const/16 v4, 38\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    goto :L56\n  :L55\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L56\n    const/4 v2, 2\n  :L57\n    new-array v2, v2, [Ljava/lang/Object;\n    const/4 v4, 1\n    aput-object v3, v2, v4\n    const/4 v3, 0\n    aput-object v1, v2, v3\n    const/16 v1, 5277\n    const/16 v3, 30\n    const/16 v4, 10\n    invoke-static { v1, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    const/4 v3, 2\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, [B\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    invoke-virtual { v1, v3 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v1\n    invoke-virtual { v1, v2 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L58\n    move-result-object v1\n    const/16 v2, 16\n    new-array v2, v2, [B\n    fill-array-data v2, :L154\n    goto :L60\n  :L59\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L60\n    const/4 v3, 1\n  :L61\n    new-array v3, v3, [Ljava/lang/Object;\n    const/4 v4, 0\n    aput-object v2, v3, v4\n    sget v2, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v2, v2, 46\n    int-to-byte v2, v2\n    const/16 v4, 5277\n    const/16 v5, 579\n    invoke-static { v4, v5, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    invoke-static { v2 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v2\n    const/4 v4, 1\n    new-array v4, v4, [Ljava/lang/Class;\n    const-class v5, [B\n    const/4 v6, 0\n    aput-object v5, v4, v6\n    invoke-virtual { v2, v4 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v2\n    invoke-virtual { v2, v3 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L62\n    move-result-object v3\n    goto :L64\n  :L63\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L64\n    const/4 v2, 3\n  :L65\n    new-array v2, v2, [Ljava/lang/Object;\n    const/4 v4, 2\n    aput-object v3, v2, v4\n    const/4 v3, 1\n    aput-object v1, v2, v3\n    const/4 v1, 2\n    invoke-static { v1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v1\n    const/4 v3, 0\n    aput-object v1, v2, v3\n    const/16 v1, 5277\n    const/16 v3, 547\n    const/16 v4, 22\n    invoke-static { v1, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    sget v3, Lo/\\ufee4$\\u1508;->\\u0406:I\n    add-int/lit8 v3, v3, -1\n    int-to-short v3, v3\n    const/16 v4, 5278\n    const/16 v5, 37\n    invoke-static { v4, v3, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    const/4 v4, 3\n    new-array v4, v4, [Ljava/lang/Class;\n    sget-object v5, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v6, 0\n    aput-object v5, v4, v6\n    sget v5, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v5, v5, 62\n    int-to-byte v5, v5\n    const/16 v6, 5277\n    const/16 v7, 529\n    invoke-static { v6, v7, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v5\n    invoke-static { v5 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v5\n    const/4 v6, 1\n    aput-object v5, v4, v6\n    const/16 v5, 5277\n    const/16 v6, 342\n    const/4 v7, 0\n    invoke-static { v5, v6, v7 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v5\n    invoke-static { v5 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v5\n    const/4 v6, 2\n    aput-object v5, v4, v6\n    invoke-virtual { v1, v3, v4 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v1\n    invoke-virtual { v1, v0, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L66\n    const/16 v1, 17\n    const/16 v2, 2172\n    const/16 v3, 2189\n    new-array v3, v3, [B\n    fill-array-data v3, :L155\n  :L67\n    const/16 v4, 2188\n    aget-byte v4, v3, v4\n    add-int/lit8 v4, v4, 42\n    int-to-byte v4, v4\n    const/16 v5, 748\n    aput-byte v4, v3, v5\n    goto :L69\n  :L68\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L69\n    const/4 v4, 3\n  :L70\n    new-array v4, v4, [Ljava/lang/Object;\n    invoke-static { v2 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v2\n    const/4 v5, 2\n    aput-object v2, v4, v5\n    const/16 v1, 17\n    invoke-static { v1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v1\n    const/4 v2, 1\n    aput-object v1, v4, v2\n    const/4 v1, 0\n    aput-object v3, v4, v1\n    const/16 v1, 5277\n    const/16 v2, 547\n    const/16 v3, 22\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    const/16 v2, 5283\n    const/16 v3, 638\n    const/16 v5, 34\n    invoke-static { v2, v3, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 3\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v5, [B\n    const/4 v6, 0\n    aput-object v5, v3, v6\n    sget-object v5, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v6, 1\n    aput-object v5, v3, v6\n    sget-object v5, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v6, 2\n    aput-object v5, v3, v6\n    invoke-virtual { v1, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v1\n    invoke-virtual { v1, v0, v4 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, [B\n  :L71\n    move-object v15, v0\n    const/16 v0, 5286\n    const/16 v1, 302\n    const/16 v2, 20\n  :L72\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    const/4 v12, 0\n    const-class v0, Lo/\\ufee4$\\u1508;\n    invoke-virtual { v0 }, Ljava/lang/Class;->getClassLoader()Ljava/lang/ClassLoader;\n    move-result-object v0\n    goto :L74\n  :L73\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L74\n    const/4 v1, 1\n  :L75\n    new-array v2, v1, [Ljava/lang/Object;\n    const/4 v1, 1\n    invoke-static { v1 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;\n    move-result-object v1\n    const/4 v3, 0\n    aput-object v1, v2, v3\n    const/16 v1, 5277\n    const/16 v3, 474\n    const/16 v4, 19\n    invoke-static { v1, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    const/4 v3, 1\n    new-array v3, v3, [Ljava/lang/Class;\n    sget-object v4, Ljava/lang/Boolean;->TYPE:Ljava/lang/Class;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    invoke-virtual { v1, v3 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v1\n    invoke-virtual { v1, v2 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L76\n    move-result-object v3\n    add-int/lit8 v1, v11, -63\n    goto :L79\n  :L77\n    move-exception v0\n  :L78\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L79\n    const/4 v2, 3\n  :L80\n    new-array v2, v2, [Ljava/lang/Object;\n    invoke-static { v1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v1\n    const/4 v4, 2\n    aput-object v1, v2, v4\n    const/16 v1, 63\n    invoke-static { v1 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v1\n    const/4 v4, 1\n    aput-object v1, v2, v4\n    const/4 v1, 0\n    aput-object v15, v2, v1\n    const/16 v1, 5277\n    const/16 v4, 474\n    const/16 v5, 19\n    invoke-static { v1, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    sget v4, Lo/\\ufee4$\\u1508;->\\u0406:I\n    or-int/lit8 v4, v4, 6\n    int-to-short v4, v4\n    const/16 v5, 5268\n    const/16 v6, 33\n    invoke-static { v5, v4, v6 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v4\n    const/4 v5, 3\n    new-array v5, v5, [Ljava/lang/Class;\n    const-class v6, [B\n    const/4 v7, 0\n    aput-object v6, v5, v7\n    sget-object v6, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v7, 1\n    aput-object v6, v5, v7\n    sget-object v6, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v7, 2\n    aput-object v6, v5, v7\n    invoke-virtual { v1, v4, v5 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v1\n    invoke-virtual { v1, v3, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L81\n    const/16 v1, 44\n  :L82\n    aget-byte v1, v15, v1\n    and-int/lit16 v1, v1, 255\n    const/16 v2, 45\n    aget-byte v2, v15, v2\n    shl-int/lit8 v2, v2, 8\n    int-to-char v2, v2\n    or-int/2addr v1, v2\n    const/16 v2, 46\n    aget-byte v2, v15, v2\n    and-int/lit16 v2, v2, 255\n    shl-int/lit8 v2, v2, 16\n    or-int/2addr v1, v2\n    const/16 v2, 47\n    aget-byte v2, v15, v2\n    shl-int/lit8 v2, v2, 24\n    or-int/2addr v1, v2\n    new-array v1, v1, [B\n    goto :L84\n  :L83\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L84\n    const/4 v2, 1\n  :L85\n    new-array v4, v2, [Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v1, v4, v2\n    const/16 v2, 5277\n    const/16 v5, 474\n    const/16 v6, 19\n    invoke-static { v2, v5, v6 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    invoke-static { v2 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v2\n    const/16 v5, 5278\n    const/16 v6, 91\n    const/16 v7, 34\n    invoke-static { v5, v6, v7 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v5\n    const/4 v6, 1\n    new-array v6, v6, [Ljava/lang/Class;\n    const-class v7, [B\n    const/4 v8, 0\n    aput-object v7, v6, v8\n    invoke-virtual { v2, v5, v6 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v2\n    invoke-virtual { v2, v3, v4 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v2\n    check-cast v2, Ljava/lang/Integer;\n    invoke-virtual { v2 }, Ljava/lang/Integer;->intValue()I\n  :L86\n    goto :L89\n  :L87\n    move-exception v0\n  :L88\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L89\n    const/4 v2, 1\n  :L90\n    new-array v2, v2, [Ljava/lang/Object;\n    const/4 v3, 0\n    aput-object v1, v2, v3\n    const/16 v1, 5283\n    const/16 v3, 513\n    const/16 v4, 20\n    invoke-static { v1, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    const/16 v3, 5272\n    const/16 v4, 352\n    const/16 v5, 30\n    invoke-static { v3, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    const/4 v4, 1\n    new-array v4, v4, [Ljava/lang/Class;\n    const-class v5, [B\n    const/4 v6, 0\n    aput-object v5, v4, v6\n    invoke-virtual { v1, v3, v4 }, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v1\n    const/4 v3, 1\n    invoke-virtual { v1, v3 }, Ljava/lang/reflect/AccessibleObject;->setAccessible(Z)V\n    const/4 v3, 0\n    invoke-virtual { v1, v3, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v1\n    check-cast v1, Ljava/lang/Integer;\n    invoke-virtual { v1 }, Ljava/lang/Integer;->intValue()I\n  :L91\n    move-result v2\n  :L92\n    invoke-static { v2 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v14\n    goto :L94\n  :L93\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L94\n    const/4 v1, 3\n  :L95\n    new-array v1, v1, [Ljava/lang/Object;\n    invoke-static { v2 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v2\n    const/4 v3, 2\n    aput-object v2, v1, v3\n    const/4 v2, 1\n    aput-object v0, v1, v2\n    const/4 v0, 0\n    aput-object v16, v1, v0\n    const/16 v0, 5283\n    const/16 v2, 513\n    const/16 v3, 20\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5283\n    const/16 v3, 259\n    const/16 v4, 30\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 3\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const-class v4, Ljava/lang/ClassLoader;\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    sget-object v4, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v5, 2\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 1\n    invoke-virtual { v0, v2 }, Ljava/lang/reflect/AccessibleObject;->setAccessible(Z)V\n    const/4 v2, 0\n    invoke-virtual { v0, v2, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Class;\n  :L96\n    move-object v12, v0\n    goto/16 :L148\n  :L97\n    const/4 v12, 0\n    goto :L99\n  :L98\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L99\n    const/4 v0, 1\n  :L100\n    new-array v1, v0, [Ljava/lang/Object;\n    const/4 v0, 0\n    aput-object v17, v1, v0\n    sget v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v0, v0, 55\n    int-to-byte v0, v0\n    const/16 v2, 5277\n    const/16 v3, 282\n    invoke-static { v2, v3, v0 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/4 v2, 1\n    new-array v2, v2, [Ljava/lang/Class;\n    const/16 v3, 5277\n    const/16 v4, 85\n    const/16 v5, 29\n    invoke-static { v3, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    invoke-static { v3 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v3\n    const/4 v4, 0\n    aput-object v3, v2, v4\n    invoke-virtual { v0, v2 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v0\n    invoke-virtual { v0, v1 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n  :L101\n    move-result-object v1\n    goto :L103\n  :L102\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L103\n    const/4 v0, 3\n  :L104\n    new-array v2, v0, [Ljava/lang/Object;\n    invoke-static { v11 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v0\n    const/4 v3, 2\n    aput-object v0, v2, v3\n    const/16 v0, 22\n    invoke-static { v0 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v0\n    const/4 v3, 1\n    aput-object v0, v2, v3\n    const/4 v0, 0\n    aput-object v15, v2, v0\n    const/16 v0, 5277\n    const/16 v3, 49\n    const/16 v4, 21\n    invoke-static { v0, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v3, 5264\n    const/16 v4, 390\n    const/16 v5, 36\n    invoke-static { v3, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    const/4 v4, 3\n    new-array v4, v4, [Ljava/lang/Class;\n    const-class v5, [B\n    const/4 v6, 0\n    aput-object v5, v4, v6\n    sget-object v5, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v6, 1\n    aput-object v5, v4, v6\n    sget-object v5, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v6, 2\n    aput-object v5, v4, v6\n    invoke-virtual { v0, v3, v4 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L105\n    goto :L107\n  :L106\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L107\n    sget v0, Lo/\\ufee4$\\u1508;->\\u0406:I\n    and-int/lit8 v0, v0, 55\n    int-to-byte v0, v0\n    const/16 v2, 5277\n    const/16 v3, 282\n    invoke-static { v2, v3, v0 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5280\n    const/16 v3, 632\n    const/16 v4, 36\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 0\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L108\n    move-result-object v2\n    goto :L110\n  :L109\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L110\n    const/16 v0, 5277\n    const/16 v3, 70\n    const/16 v4, 19\n  :L111\n    invoke-static { v0, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v3, 5268\n    const/16 v4, 431\n    const/16 v5, 37\n    invoke-static { v3, v4, v5 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v3\n    const/4 v4, 0\n    invoke-virtual { v0, v3, v4 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v3, 0\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L112\n    goto :L114\n  :L113\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L114\n    const/16 v0, 5277\n    const/16 v2, 49\n    const/16 v3, 21\n  :L115\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5284\n    const/16 v3, 478\n    const/16 v4, 36\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 0\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L116\n    goto :L118\n  :L117\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L118\n    const/16 v0, 5277\n    const/16 v1, 85\n    const/16 v2, 29\n  :L119\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5280\n    const/16 v2, 105\n    const/16 v3, 26\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    move-object/from16 v1, v17\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L120\n    move-result-object v0\n    goto :L122\n  :L121\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L122\n    const/16 v1, 5277\n    const/16 v2, 85\n    const/16 v3, 29\n  :L123\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    invoke-static { v1 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v1\n    const/16 v2, 5280\n    const/16 v3, 105\n    const/16 v4, 26\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 0\n    invoke-virtual { v1, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v1, v10, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L124\n    move-result-object v2\n    goto :L126\n  :L125\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L126\n    const/4 v1, 3\n  :L127\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v3, 0\n    invoke-static { v3 }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;\n    move-result-object v3\n    const/4 v4, 2\n    aput-object v3, v1, v4\n    const/4 v3, 1\n    aput-object v2, v1, v3\n    const/4 v2, 0\n    aput-object v0, v1, v2\n    const/16 v0, 5283\n    const/16 v2, 513\n    const/16 v3, 20\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v2, 5275\n    const/16 v3, 150\n    const/16 v4, 34\n    invoke-static { v2, v3, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 3\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    sget-object v4, Ljava/lang/Integer;->TYPE:Ljava/lang/Class;\n    const/4 v5, 2\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v2, 0\n    invoke-virtual { v0, v2, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L128\n    move-result-object v14\n    const-class v0, Lo/\\ufee4$\\u1508;\n    invoke-virtual { v0 }, Ljava/lang/Class;->getClassLoader()Ljava/lang/ClassLoader;\n    move-result-object v0\n    goto :L130\n  :L129\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L130\n    const/4 v1, 2\n  :L131\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 1\n    aput-object v0, v1, v2\n    const/4 v0, 0\n    aput-object v16, v1, v0\n    const/16 v0, 5283\n    const/16 v2, 513\n    const/16 v3, 20\n    invoke-static { v0, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    sget v2, Lo/\\ufee4$\\u1508;->\\u0406:I\n    add-int/lit8 v2, v2, -4\n    int-to-short v2, v2\n    const/16 v3, 5275\n    const/16 v4, 32\n    invoke-static { v3, v2, v4 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v2\n    const/4 v3, 2\n    new-array v3, v3, [Ljava/lang/Class;\n    const-class v4, Ljava/lang/String;\n    const/4 v5, 0\n    aput-object v4, v3, v5\n    const/16 v4, 5277\n    const/16 v5, 174\n    const/16 v6, 20\n    invoke-static { v4, v5, v6 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v4\n    invoke-static { v4 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v4\n    const/4 v5, 1\n    aput-object v4, v3, v5\n    invoke-virtual { v0, v2, v3 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    invoke-virtual { v0, v14, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Class;\n  :L132\n    move-object v12, v0\n    if-eqz v12, :L136\n    goto :L134\n  :L133\n    move-exception v0\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L134\n    const/16 v0, 5283\n    const/16 v1, 513\n    const/16 v2, 20\n  :L135\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5284\n    const/16 v2, 478\n    const/16 v3, 36\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    invoke-virtual { v0, v14, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n  :L136\n    goto :L139\n  :L137\n    move-exception v0\n  :L138\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L139\n    const/16 v0, 5277\n    const/16 v1, 85\n    const/16 v2, 29\n  :L140\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5283\n    const/16 v2, 395\n    const/16 v3, 35\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    move-object/from16 v1, v17\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Boolean;\n    invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z\n  :L141\n    nop\n  :L142\n    goto :L145\n  :L143\n    move-exception v0\n  :L144\n    invoke-virtual { v0 }, Ljava/lang/Throwable;->getCause()Ljava/lang/Throwable;\n    move-result-object v0\n    throw v0\n  :L145\n    const/16 v0, 5277\n    const/16 v1, 85\n    const/16 v2, 29\n  :L146\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    invoke-static { v0 }, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;\n    move-result-object v0\n    const/16 v1, 5283\n    const/16 v2, 395\n    const/16 v3, 35\n    invoke-static { v1, v2, v3 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v1\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    invoke-virtual { v0, v10, v1 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Ljava/lang/Boolean;\n    invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z\n  :L147\n    nop\n  :L148\n    if-nez v12, :L149\n    const/4 v0, 1\n    new-array v0, v0, [Ljava/lang/Class;\n    const-class v1, Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v1, v0, v2\n    invoke-virtual { v13, v0 }, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;\n    move-result-object v0\n    const/4 v1, 1\n    new-array v1, v1, [Ljava/lang/Object;\n    const/4 v2, 0\n    aput-object v14, v1, v2\n    invoke-virtual { v0, v1 }, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    sput-object v0, Lo/\\ufee4$\\u1508;->\\u14bd:Ljava/lang/Object;\n    return-void\n  :L149\n    move-object v13, v12\n    const/16 v0, 5272\n    const/16 v1, 74\n    const/16 v2, 36\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v16\n    const v11, 45911\n    const/4 v0, 0\n    const/16 v1, 30\n    const/16 v2, 40\n    invoke-static { v0, v1, v2 }, Lo/\\ufee4$\\u1508;->\\u0456(SIB)Ljava/lang/String;\n    move-result-object v0\n    const/4 v1, 0\n    invoke-virtual { v12, v0, v1 }, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\n    move-result-object v0\n    const/4 v1, 0\n    const/4 v2, 0\n    invoke-virtual { v0, v1, v2 }, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\n    move-result-object v0\n    const v2, 45933\n    const v3, 45950\n    new-array v3, v3, [B\n    fill-array-data v3, :L156\n    goto/16 :L67\n  :L150\n    goto :L142\n  :L151\n    goto :L148\n  :L152\n  .array-data 2\n    9t 0t\n    118t 0t\n    127t 0t\n    -94t -1t\n    -40t 13t\n    12t 14t\n    -64t 13t\n    -34t 13t\n    -16t 13t\n    -40t 13t\n    -27t 13t\n    -44t 13t\n    17t 14t\n    -27t 13t\n    -33t 13t\n    -43t 13t\n    7t 14t\n    -49t 13t\n    -32t 13t\n    -25t 13t\n    -10t 13t\n    -60t 13t\n    -62t 13t\n    2t 14t\n    -46t 13t\n    -32t 13t\n    -29t 13t\n    -34t 13t\n    -34t 13t\n    -22t 13t\n    -82t 13t\n    -26t 13t\n    -48t 13t\n    -10t 13t\n    21t 14t\n    -82t 13t\n    -26t 13t\n    -48t 13t\n    -10t 13t\n    21t 14t\n    -81t 13t\n    -41t 13t\n    -27t 13t\n    34t 14t\n    -99t 13t\n    -10t 13t\n    -47t 13t\n    -21t 13t\n    -20t 13t\n    -48t 13t\n    -11t 13t\n    -37t 13t\n    -37t 13t\n    40t 14t\n    -99t 13t\n    -10t 13t\n    -47t 13t\n    -21t 13t\n    -20t 13t\n    -48t 13t\n    -11t 13t\n    -37t 13t\n    -37t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    -52t 13t\n    45t 14t\n    -82t 13t\n    -44t 13t\n    -36t 13t\n    -20t 13t\n    -33t 13t\n    -24t 13t\n    36t 14t\n    -98t 13t\n    -26t 13t\n    -18t 13t\n    -27t 13t\n    24t 14t\n    -56t 13t\n    -74t 13t\n    9t 14t\n    -46t 13t\n    -46t 13t\n    -12t 13t\n    -41t 13t\n    -21t 13t\n    -44t 13t\n    -14t 13t\n    -42t 13t\n    2t 14t\n    -58t 13t\n    -18t 13t\n    -27t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    -52t 13t\n    45t 14t\n    -82t 13t\n    -44t 13t\n    -36t 13t\n    -20t 13t\n    -33t 13t\n    -24t 13t\n    36t 14t\n    -50t 13t\n    -67t 13t\n    -36t 13t\n    -21t 13t\n    -26t 13t\n    -42t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -98t 13t\n    -15t 13t\n    -27t 13t\n    -47t 13t\n    -26t 13t\n    -20t 13t\n    -40t 13t\n    -34t 13t\n    46t 14t\n    -58t 13t\n    -55t 13t\n    -49t 13t\n    -26t 13t\n    -40t 13t\n    -39t 13t\n    -16t 13t\n    -31t 13t\n    32t 14t\n    -98t 13t\n    -35t 13t\n    -23t 13t\n    -30t 13t\n    -14t 13t\n    -37t 13t\n    34t 14t\n    -51t 13t\n    -62t 13t\n    -48t 13t\n    21t 14t\n    -64t 13t\n    -32t 13t\n    -22t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -91t 13t\n    -18t 13t\n    -42t 13t\n    -22t 13t\n    28t 14t\n    -66t 13t\n    -67t 13t\n    -23t 13t\n    -30t 13t\n    -14t 13t\n    -37t 13t\n    -38t 13t\n    -32t 13t\n    -33t 13t\n    -15t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -100t 13t\n    -28t 13t\n    -18t 13t\n    -32t 13t\n    33t 14t\n    -105t 13t\n    -12t 13t\n    -36t 13t\n    37t 14t\n    -56t 13t\n    -66t 13t\n    -21t 13t\n    -35t 13t\n    -18t 13t\n    -48t 13t\n    -14t 13t\n    -42t 13t\n    -33t 13t\n    -43t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -88t 13t\n    -35t 13t\n    36t 14t\n    -99t 13t\n    -22t 13t\n    -32t 13t\n    -17t 13t\n    -34t 13t\n    -38t 13t\n    -27t 13t\n    -42t 13t\n    -6t 13t\n    -56t 13t\n    -20t 13t\n    -40t 13t\n    -14t 13t\n    -35t 13t\n    -18t 13t\n    -18t 13t\n    -30t 13t\n    -18t 13t\n    -22t 13t\n    -13t 13t\n    -60t 13t\n    -31t 13t\n    -25t 13t\n    -22t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -98t 13t\n    -15t 13t\n    -27t 13t\n    -47t 13t\n    -26t 13t\n    -20t 13t\n    -40t 13t\n    -34t 13t\n    46t 14t\n    -66t 13t\n    -47t 13t\n    -27t 13t\n    -47t 13t\n    -26t 13t\n    -16t 13t\n    -10t 13t\n    -44t 13t\n    -42t 13t\n    -19t 13t\n    -40t 13t\n    -27t 13t\n    -30t 13t\n    -36t 13t\n    -22t 13t\n    -44t 13t\n    -14t 13t\n    -24t 13t\n    -20t 13t\n    -40t 13t\n    -14t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -91t 13t\n    -18t 13t\n    -42t 13t\n    -22t 13t\n    28t 14t\n    -50t 13t\n    -66t 13t\n    -22t 13t\n    -46t 13t\n    -12t 13t\n    -31t 13t\n    -46t 13t\n    -14t 13t\n    -42t 13t\n    -47t 13t\n    -26t 13t\n    -29t 13t\n    -16t 13t\n    -38t 13t\n    -35t 13t\n    3t 14t\n    -50t 13t\n    -33t 13t\n    -21t 13t\n    -5t 13t\n    -57t 13t\n    -32t 13t\n    -29t 13t\n    -26t 13t\n    -39t 13t\n    -30t 13t\n    -18t 13t\n    -38t 13t\n    13t 14t\n    -62t 13t\n    -48t 13t\n    21t 14t\n    -64t 13t\n    -32t 13t\n    -22t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -98t 13t\n    -15t 13t\n    -27t 13t\n    -47t 13t\n    -26t 13t\n    -20t 13t\n    -40t 13t\n    -34t 13t\n    46t 14t\n    -98t 13t\n    -26t 13t\n    -18t 13t\n    -27t 13t\n    24t 14t\n    -48t 13t\n    -72t 13t\n    -24t 13t\n    -37t 13t\n    -32t 13t\n    -20t 13t\n    -40t 13t\n    -17t 13t\n    -34t 13t\n    0t 14t\n    -46t 13t\n    -46t 13t\n    -12t 13t\n    -41t 13t\n    -21t 13t\n    -44t 13t\n    -14t 13t\n    -42t 13t\n    2t 14t\n    -58t 13t\n    -18t 13t\n    -27t 13t\n    -42t 13t\n    -19t 13t\n    -43t 13t\n    -26t 13t\n    -23t 13t\n    -24t 13t\n    25t 14t\n    -100t 13t\n    -28t 13t\n    -18t 13t\n    -32t 13t\n    33t 14t\n    -63t 13t\n    -63t 13t\n    -26t 13t\n    -30t 13t\n    -18t 13t\n    -42t 13t\n    -31t 13t\n    -34t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -88t 13t\n    -35t 13t\n    36t 14t\n    -53t 13t\n    -64t 13t\n    -32t 13t\n    -22t 13t\n    -7t 13t\n    -67t 13t\n    -28t 13t\n    -25t 13t\n    -34t 13t\n    -28t 13t\n    4t 14t\n    -62t 13t\n    -27t 13t\n    -16t 13t\n    -25t 13t\n    -41t 13t\n    -30t 13t\n    -30t 13t\n    -32t 13t\n    -34t 13t\n    -20t 13t\n    5t 14t\n    -70t 13t\n    -18t 13t\n    -47t 13t\n    -29t 13t\n    -27t 13t\n    -44t 13t\n    18t 14t\n    -80t 13t\n    -25t 13t\n    -14t 13t\n    -42t 13t\n    -25t 13t\n    -16t 13t\n    -40t 13t\n    -4t 13t\n    -62t 13t\n    -24t 13t\n    -32t 13t\n    -12t 13t\n    -35t 13t\n    -27t 13t\n    4t 14t\n    -66t 13t\n    -38t 13t\n    -16t 13t\n    -27t 13t\n    -46t 13t\n    -24t 13t\n    -32t 13t\n    -36t 13t\n    -15t 13t\n    -44t 13t\n    14t 14t\n    -66t 13t\n    -31t 13t\n    -34t 13t\n    -28t 13t\n    -34t 13t\n    -24t 13t\n    -40t 13t\n    -32t 13t\n    -15t 13t\n    -32t 13t\n    4t 14t\n    -70t 13t\n    -18t 13t\n    -47t 13t\n    -29t 13t\n    -42t 13t\n    -19t 13t\n    -43t 13t\n    -26t 13t\n    -23t 13t\n    -24t 13t\n    25t 14t\n    -94t 13t\n    -33t 13t\n    40t 14t\n    -52t 13t\n    -70t 13t\n    -37t 13t\n    -16t 13t\n    -38t 13t\n    -26t 13t\n    -28t 13t\n    -28t 13t\n    -21t 13t\n    -38t 13t\n    -35t 13t\n    -27t 13t\n    -44t 13t\n    14t 14t\n    -66t 13t\n    -34t 13t\n    -30t 13t\n    -10t 13t\n    -42t 13t\n    -18t 13t\n    -31t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -91t 13t\n    -18t 13t\n    -42t 13t\n    -22t 13t\n    28t 14t\n    -50t 13t\n    -70t 13t\n    -18t 13t\n    -47t 13t\n    -29t 13t\n    10t 14t\n    -64t 13t\n    -15t 13t\n    -32t 13t\n    -30t 13t\n    -42t 13t\n    35t 14t\n    46t 15t\n    -93t 12t\n    -47t -16t\n    -32t 13t\n    -15t 13t\n    -32t 13t\n    3t 14t\n    -62t 13t\n    -48t 13t\n    -39t 13t\n    1t 14t\n    -54t 13t\n    -24t 13t\n    -23t 13t\n    -41t 13t\n    -18t 13t\n    -30t 13t\n    -1t 13t\n    -56t 13t\n    -30t 13t\n    -38t 13t\n    -35t 13t\n    -18t 13t\n    -26t 13t\n    -32t 13t\n    -25t 13t\n    -42t 13t\n    2t 14t\n    -62t 13t\n    -10t 13t\n    -46t 13t\n    -31t 13t\n    -15t 13t\n    -44t 13t\n    4t 14t\n    -47t 13t\n    -29t 13t\n    -28t 13t\n    -27t 13t\n    -44t 13t\n    7t 14t\n    -63t 13t\n    -26t 13t\n    -30t 13t\n    -18t 13t\n    -42t 13t\n    -31t 13t\n    -34t 13t\n    -27t 13t\n    -44t 13t\n    22t 14t\n    -62t 13t\n    -46t 13t\n    -25t 13t\n    -26t 13t\n    -38t 13t\n    -28t 13t\n    -14t 13t\n    -8t 13t\n    -46t 13t\n    -48t 13t\n    -17t 13t\n    -34t 13t\n    -21t 13t\n    -35t 13t\n    -18t 13t\n    -48t 13t\n    -14t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -88t 13t\n    -35t 13t\n    36t 14t\n    -53t 13t\n    -64t 13t\n    -32t 13t\n    -22t 13t\n    35t 14t\n    46t 15t\n    -93t 12t\n    25t -8t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -88t 13t\n    -35t 13t\n    36t 14t\n    -53t 13t\n    -64t 13t\n    -32t 13t\n    -22t 13t\n    4t 14t\n    -62t 13t\n    -43t 13t\n    -13t 13t\n    -44t 13t\n    -20t 13t\n    -36t 13t\n    -33t 13t\n    -24t 13t\n    -32t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    22t 14t\n    -88t 13t\n    -35t 13t\n    36t 14t\n    -62t 13t\n    -67t 13t\n    -28t 13t\n    -25t 13t\n    -34t 13t\n    -28t 13t\n    4t 14t\n    -62t 13t\n    -27t 13t\n    -16t 13t\n    -25t 13t\n    -41t 13t\n    -20t 13t\n    -50t 13t\n    -8t 13t\n    -52t 13t\n    45t 14t\n    -82t 13t\n    -44t 13t\n    -36t 13t\n    -20t 13t\n    -33t 13t\n    -24t 13t\n    36t 14t\n    -98t 13t\n    -26t 13t\n    -18t 13t\n    -27t 13t\n    24t 14t\n    -66t 13t\n    -47t 13t\n    -27t 13t\n    -44t 13t\n    -16t 13t\n    -44t 13t\n    12t 14t\n    -55t 13t\n    -49t 13t\n    9t 14t\n    -58t 13t\n    -18t 13t\n    -27t 13t\n    -20t 13t\n    -48t 13t\n    -25t 13t\n    14t 14t\n    -66t 13t\n    -35t 13t\n  .end array-data\n  :L153\n  .array-data 1\n    79t\n    84t\n    114t\n    -55t\n    7t\n    58t\n    -20t\n    47t\n    98t\n    11t\n    55t\n    -34t\n    12t\n    -108t\n    -117t\n    -53t\n  .end array-data\n  :L154\n  .array-data 1\n    49t\n    74t\n    -19t\n    40t\n    14t\n    0t\n    45t\n    81t\n    109t\n    -80t\n    85t\n    -128t\n    -115t\n    -70t\n    127t\n    100t\n  .end array-data\n  :L155\n  .array-data 1\n    106t\n    97t\n    118t\n    97t\n    47t\n    108t\n    97t\n    110t\n    103t\n    47t\n    73t\n    110t\n    116t\n    101t\n    103t\n    101t\n    114t\n    -26t\n    -63t\n    -112t\n    26t\n    105t\n    114t\n    -88t\n    -90t\n    -18t\n    90t\n    126t\n    60t\n    -112t\n    -97t\n    97t\n    -64t\n    90t\n    78t\n    -121t\n    -116t\n    81t\n    17t\n    112t\n    0t\n    4t\n    -105t\n    8t\n    68t\n    98t\n    56t\n    12t\n    44t\n    -83t\n    -36t\n    -106t\n    -77t\n    70t\n    38t\n    -107t\n    -91t\n    12t\n    18t\n    -121t\n    -87t\n    19t\n    120t\n    85t\n    12t\n    57t\n    -32t\n    -25t\n    -53t\n    -24t\n    -69t\n    92t\n    4t\n    88t\n    52t\n    16t\n    -68t\n    -65t\n    -93t\n    96t\n    39t\n    -99t\n    28t\n    26t\n    32t\n    -81t\n    -38t\n    -108t\n    -48t\n    -70t\n    22t\n    39t\n    -125t\n    -13t\n    -18t\n    -122t\n    -19t\n    -64t\n    -38t\n    127t\n    -74t\n    31t\n    50t\n    -14t\n    -84t\n    -116t\n    -6t\n    -36t\n    -109t\n    27t\n    90t\n    -33t\n    40t\n    -38t\n    14t\n    -18t\n    104t\n    -55t\n    -29t\n    127t\n    -122t\n    86t\n    85t\n    93t\n    -124t\n    96t\n    42t\n    -6t\n    -30t\n    -9t\n    109t\n    117t\n    78t\n    54t\n    64t\n    -100t\n    80t\n    -68t\n    -23t\n    52t\n    -70t\n    32t\n    -51t\n    39t\n    -57t\n    -121t\n    -26t\n    0t\n    -65t\n    -37t\n    104t\n    4t\n    43t\n    44t\n    22t\n    95t\n    -75t\n    80t\n    97t\n    -7t\n    -14t\n    -67t\n    -25t\n    -112t\n    13t\n    43t\n    68t\n    57t\n    37t\n    119t\n    26t\n    68t\n    -46t\n    -70t\n    -75t\n    -12t\n    125t\n    -88t\n    36t\n    -90t\n    65t\n    117t\n    -124t\n    -102t\n    43t\n    41t\n    46t\n    -23t\n    -95t\n    -77t\n    92t\n    -11t\n    -69t\n    -9t\n    -46t\n    6t\n    -24t\n    67t\n    -48t\n    -17t\n    -41t\n    -4t\n    -123t\n    -24t\n    -117t\n    75t\n    37t\n    75t\n    36t\n    34t\n    -88t\n    99t\n    -102t\n    93t\n    -55t\n    -8t\n    -50t\n    22t\n    -25t\n    -127t\n    74t\n    -103t\n    -128t\n    71t\n    48t\n    11t\n    -32t\n    -18t\n    81t\n    -31t\n    61t\n    -102t\n    -89t\n    -98t\n    66t\n    -35t\n    127t\n    -67t\n    13t\n    -92t\n    81t\n    11t\n    21t\n    -113t\n    103t\n    81t\n    -39t\n    13t\n    -126t\n    107t\n    29t\n    114t\n    98t\n    100t\n    63t\n    11t\n    29t\n    -48t\n    -104t\n    44t\n    -52t\n    88t\n    112t\n    63t\n    -65t\n    97t\n    -83t\n    52t\n    97t\n    -57t\n    -126t\n    72t\n    -69t\n    -70t\n    33t\n    67t\n    100t\n    100t\n    19t\n    -61t\n    29t\n    82t\n    -86t\n    80t\n    106t\n    -45t\n    -67t\n    -5t\n    75t\n    20t\n    51t\n    -113t\n    -89t\n    56t\n    -69t\n    -98t\n    6t\n    23t\n    77t\n    97t\n    -17t\n    -58t\n    9t\n    -57t\n    -46t\n    85t\n    -26t\n    31t\n    84t\n    61t\n    -87t\n    -91t\n    -85t\n    12t\n    13t\n    77t\n    -16t\n    -40t\n    115t\n    100t\n    -91t\n    56t\n    -105t\n    -77t\n    -23t\n    98t\n    125t\n    62t\n    110t\n    -93t\n    -6t\n    35t\n    -118t\n    11t\n    101t\n    -55t\n    -45t\n    11t\n    -95t\n    -102t\n    99t\n    -99t\n    63t\n    119t\n    119t\n    -30t\n    37t\n    -92t\n    -92t\n    -25t\n    7t\n    46t\n    104t\n    16t\n    -32t\n    116t\n    76t\n    -108t\n    108t\n    -83t\n    -52t\n    15t\n    -10t\n    88t\n    68t\n    111t\n    110t\n    39t\n    59t\n    -20t\n    -98t\n    -72t\n    -96t\n    -121t\n    -113t\n    123t\n    24t\n    108t\n    86t\n    0t\n    -76t\n    59t\n    89t\n    -74t\n    -43t\n    83t\n    126t\n    51t\n    112t\n    68t\n    62t\n    42t\n    -12t\n    -68t\n    -124t\n    118t\n    103t\n    78t\n    -6t\n    -54t\n    -83t\n    123t\n    -89t\n    113t\n    9t\n    -100t\n    -119t\n    -51t\n    7t\n    -107t\n    -13t\n    -62t\n    -5t\n    79t\n    18t\n    -79t\n    -108t\n    -124t\n    -60t\n    -65t\n    -117t\n    -123t\n    -4t\n    -49t\n    -69t\n    -61t\n    124t\n    69t\n    -4t\n    55t\n    -115t\n    97t\n    -3t\n    -109t\n    36t\n    65t\n    -98t\n    62t\n    13t\n    -85t\n    116t\n    -25t\n    -3t\n    57t\n    111t\n    16t\n    9t\n    -33t\n    49t\n    113t\n    -67t\n    36t\n    -35t\n    11t\n    -42t\n    37t\n    -31t\n    24t\n    -39t\n    33t\n    -125t\n    8t\n    -81t\n    114t\n    20t\n    116t\n    107t\n    -98t\n    -97t\n    -51t\n    -81t\n    27t\n    14t\n    123t\n    -11t\n    74t\n    -66t\n    -48t\n    62t\n    -125t\n    -8t\n    -57t\n    -81t\n    29t\n    -41t\n    57t\n    92t\n    40t\n    122t\n    92t\n    66t\n    -3t\n    -108t\n    -72t\n    7t\n    113t\n    28t\n    79t\n    -32t\n    -70t\n    18t\n    81t\n    25t\n    -59t\n    103t\n    -115t\n    -75t\n    -118t\n    -128t\n    -83t\n    -60t\n    89t\n    48t\n    75t\n    -72t\n    -68t\n    5t\n    67t\n    -32t\n    -1t\n    -9t\n    19t\n    46t\n    -66t\n    104t\n    50t\n    87t\n    -73t\n    -56t\n    -4t\n    91t\n    -21t\n    68t\n    -63t\n    -89t\n    -14t\n    -33t\n    114t\n    -31t\n    16t\n    -86t\n    98t\n    -53t\n    -23t\n    -120t\n    83t\n    -49t\n    -78t\n    7t\n    -90t\n    107t\n    89t\n    47t\n    -71t\n    54t\n    74t\n    7t\n    66t\n    9t\n    -39t\n    5t\n    -45t\n    -100t\n    62t\n    21t\n    32t\n    -125t\n    -17t\n    -39t\n    102t\n    -118t\n    -15t\n    13t\n    -85t\n    24t\n    116t\n    93t\n    87t\n    -98t\n    127t\n    -103t\n    103t\n    31t\n    33t\n    -1t\n    28t\n    43t\n    -73t\n    56t\n    15t\n    -44t\n    54t\n    -41t\n    -68t\n    -16t\n    102t\n    -96t\n    -78t\n    6t\n    71t\n    -18t\n    -107t\n    90t\n    37t\n    58t\n    -80t\n    80t\n    84t\n    25t\n    25t\n    -42t\n    55t\n    54t\n    11t\n    -15t\n    9t\n    43t\n    -43t\n    9t\n    125t\n    95t\n    24t\n    -126t\n    -92t\n    -117t\n    13t\n    28t\n    30t\n    -66t\n    -19t\n    100t\n    4t\n    72t\n    -61t\n    70t\n    -43t\n    87t\n    96t\n    36t\n    29t\n    -5t\n    40t\n    -35t\n    113t\n    20t\n    -19t\n    46t\n    45t\n    6t\n    -73t\n    -106t\n    -87t\n    75t\n    49t\n    -45t\n    35t\n    108t\n    82t\n    -115t\n    -62t\n    105t\n    -2t\n    -60t\n    7t\n    -106t\n    53t\n    -40t\n    -46t\n    -40t\n    -102t\n    -57t\n    25t\n    -64t\n    -92t\n    62t\n    -7t\n    -127t\n    -37t\n    -62t\n    -29t\n    92t\n    5t\n    42t\n    -115t\n    -3t\n    -51t\n    50t\n    -69t\n    126t\n    14t\n    -93t\n    -104t\n    73t\n    59t\n    27t\n    86t\n    71t\n    75t\n    -9t\n    27t\n    70t\n    -44t\n    43t\n    94t\n    -86t\n    54t\n    110t\n    69t\n    18t\n    23t\n    0t\n    -15t\n    105t\n    -82t\n    16t\n    66t\n    -76t\n    -109t\n    28t\n    42t\n    42t\n    -58t\n    -42t\n    0t\n    -49t\n    75t\n    -98t\n    36t\n    -8t\n    23t\n    -58t\n    -21t\n    47t\n    74t\n    60t\n    114t\n    -36t\n    -30t\n    63t\n    -29t\n    71t\n    60t\n    -23t\n    -35t\n    -128t\n    37t\n    125t\n    67t\n    31t\n    10t\n    -118t\n    102t\n    8t\n    101t\n    -53t\n    -58t\n    -92t\n    54t\n    -7t\n    105t\n    -31t\n    77t\n    -126t\n    -4t\n    19t\n    31t\n    -125t\n    94t\n    16t\n    -116t\n    73t\n    97t\n    78t\n    -4t\n    -54t\n    -35t\n    -126t\n    35t\n    65t\n    5t\n    97t\n    37t\n    -45t\n    16t\n    80t\n    3t\n    -63t\n    114t\n    10t\n    44t\n    3t\n    126t\n    90t\n    -104t\n    88t\n    -114t\n    5t\n    -60t\n    127t\n    4t\n    -11t\n    -34t\n    107t\n    47t\n    -2t\n    49t\n    65t\n    -119t\n    127t\n    5t\n    86t\n    73t\n    -22t\n    -12t\n    -63t\n    18t\n    47t\n    -42t\n    1t\n    -87t\n    -46t\n    -26t\n    -113t\n    121t\n    119t\n    -32t\n    118t\n    -17t\n    67t\n    60t\n    -23t\n    -97t\n    65t\n    37t\n    -112t\n    85t\n    0t\n    -35t\n    3t\n    112t\n    10t\n    -70t\n    38t\n    52t\n    -111t\n    -53t\n    -106t\n    88t\n    -71t\n    -124t\n    -120t\n    -92t\n    -123t\n    -76t\n    -33t\n    61t\n    -96t\n    39t\n    57t\n    -108t\n    10t\n    9t\n    -58t\n    30t\n    -107t\n    -114t\n    -33t\n    68t\n    51t\n    -100t\n    95t\n    -67t\n    -111t\n    96t\n    111t\n    18t\n    44t\n    -3t\n    48t\n    94t\n    -102t\n    -127t\n    13t\n    -32t\n    2t\n    -125t\n    -62t\n    80t\n    3t\n    -10t\n    29t\n    -79t\n    8t\n    -68t\n    -105t\n    100t\n    -52t\n    -99t\n    -14t\n    -15t\n    -28t\n    -36t\n    -20t\n    95t\n    -114t\n    -66t\n    15t\n    -15t\n    44t\n    97t\n    -107t\n    -10t\n    77t\n    -111t\n    34t\n    85t\n    101t\n    82t\n    126t\n    -95t\n    -126t\n    -41t\n    62t\n    -124t\n    27t\n    -83t\n    76t\n    93t\n    3t\n    76t\n    87t\n    35t\n    -33t\n    -73t\n    109t\n    109t\n    8t\n    -76t\n    79t\n    57t\n    57t\n    -92t\n    4t\n    117t\n    -97t\n    98t\n    -79t\n    62t\n    39t\n    119t\n    101t\n    97t\n    -12t\n    32t\n    61t\n    71t\n    14t\n    -9t\n    35t\n    76t\n    39t\n    -23t\n    93t\n    50t\n    24t\n    -42t\n    2t\n    -90t\n    -20t\n    -75t\n    -102t\n    -75t\n    -45t\n    -16t\n    110t\n    87t\n    25t\n    33t\n    -24t\n    9t\n    -15t\n    12t\n    -33t\n    99t\n    14t\n    -121t\n    -69t\n    19t\n    69t\n    -13t\n    28t\n    50t\n    -30t\n    -91t\n    -92t\n    127t\n    -114t\n    -29t\n    -28t\n    -111t\n    -99t\n    -32t\n    -73t\n    -90t\n    31t\n    -108t\n    -18t\n    127t\n    89t\n    -36t\n    9t\n    -107t\n    70t\n    94t\n    -18t\n    -100t\n    96t\n    -97t\n    -5t\n    -108t\n    -34t\n    -56t\n    -20t\n    -9t\n    -92t\n    -46t\n    -109t\n    13t\n    -40t\n    -68t\n    -11t\n    103t\n    13t\n    31t\n    -46t\n    4t\n    -38t\n    -66t\n    57t\n    -42t\n    49t\n    -123t\n    59t\n    -39t\n    -56t\n    -91t\n    87t\n    -37t\n    -39t\n    75t\n    34t\n    -73t\n    109t\n    -33t\n    -48t\n    -71t\n    74t\n    65t\n    39t\n    103t\n    86t\n    -1t\n    -24t\n    -99t\n    114t\n    12t\n    106t\n    39t\n    -58t\n    89t\n    -13t\n    77t\n    -21t\n    33t\n    -118t\n    66t\n    -88t\n    95t\n    -119t\n    111t\n    81t\n    -58t\n    71t\n    -76t\n    -1t\n    51t\n    23t\n    -82t\n    31t\n    84t\n    -61t\n    -10t\n    127t\n    107t\n    16t\n    -38t\n    -59t\n    27t\n    -70t\n    -77t\n    -23t\n    -52t\n    -59t\n    16t\n    26t\n    18t\n    5t\n    66t\n    -37t\n    112t\n    -73t\n    -120t\n    -55t\n    -3t\n    36t\n    24t\n    -30t\n    92t\n    -94t\n    -69t\n    30t\n    -57t\n    -5t\n    92t\n    42t\n    -108t\n    33t\n    -87t\n    45t\n    98t\n    -27t\n    19t\n    20t\n    71t\n    -86t\n    25t\n    -66t\n    -108t\n    25t\n    55t\n    -56t\n    90t\n    -99t\n    104t\n    90t\n    -64t\n    -121t\n    57t\n    -75t\n    89t\n    -47t\n    36t\n    -62t\n    122t\n    -60t\n    -118t\n    -123t\n    86t\n    74t\n    -90t\n    85t\n    1t\n    112t\n    -111t\n    69t\n    71t\n    -37t\n    -52t\n    22t\n    -105t\n    5t\n    -123t\n    24t\n    121t\n    72t\n    -66t\n    3t\n    76t\n    52t\n    -50t\n    -16t\n    102t\n    49t\n    -128t\n    33t\n    120t\n    -60t\n    -26t\n    -40t\n    93t\n    -118t\n    -72t\n    15t\n    111t\n    104t\n    -7t\n    -115t\n    -32t\n    48t\n    -82t\n    -39t\n    -66t\n    -121t\n    72t\n    -17t\n    75t\n    -68t\n    73t\n    82t\n    30t\n    -52t\n    -123t\n    7t\n    112t\n    28t\n    64t\n    -91t\n    -111t\n    -59t\n    -50t\n    -33t\n    78t\n    82t\n    52t\n    78t\n    98t\n    -77t\n    93t\n    -103t\n    -56t\n    39t\n    -94t\n    -13t\n    97t\n    104t\n    90t\n    20t\n    46t\n    -11t\n    -30t\n    10t\n    124t\n    -60t\n    -71t\n    68t\n    -77t\n    -34t\n    69t\n    -93t\n    103t\n    41t\n    28t\n    98t\n    78t\n    -63t\n    -24t\n    -103t\n    84t\n    99t\n    -116t\n    -123t\n    79t\n    109t\n    -125t\n    104t\n    8t\n    39t\n    17t\n    -101t\n    -90t\n    2t\n    58t\n    92t\n    -31t\n    -68t\n    50t\n    -22t\n    12t\n    93t\n    57t\n    24t\n    -123t\n    95t\n    -65t\n    -128t\n    -54t\n    57t\n    -43t\n    -108t\n    115t\n    62t\n    -110t\n    -72t\n    -12t\n    -71t\n    -29t\n    -96t\n    -26t\n    -42t\n    44t\n    -78t\n    -122t\n    51t\n    -74t\n    -57t\n    -102t\n    106t\n    60t\n    11t\n    31t\n    71t\n    60t\n    44t\n    -103t\n    -57t\n    -48t\n    117t\n    -34t\n    78t\n    115t\n    77t\n    -20t\n    -91t\n    90t\n    -72t\n    11t\n    17t\n    -36t\n    -117t\n    57t\n    -96t\n    -11t\n    -128t\n    -15t\n    -110t\n    -116t\n    -9t\n    -18t\n    -72t\n    87t\n    67t\n    29t\n    15t\n    -12t\n    -31t\n    -79t\n    39t\n    107t\n    38t\n    11t\n    -122t\n    -121t\n    28t\n    -10t\n    86t\n    -8t\n    -51t\n    42t\n    -116t\n    -40t\n    -53t\n    -23t\n    85t\n    124t\n    -95t\n    111t\n    93t\n    -99t\n    -48t\n    74t\n    -123t\n    97t\n    93t\n    77t\n    74t\n    -124t\n    -58t\n    43t\n    -35t\n    -9t\n    34t\n    64t\n    -35t\n    -12t\n    14t\n    59t\n    3t\n    97t\n    -48t\n    -45t\n    -37t\n    58t\n    -61t\n    -46t\n    49t\n    -97t\n    49t\n    -19t\n    50t\n    -114t\n    101t\n    -24t\n    -61t\n    -76t\n    -40t\n    60t\n    -4t\n    -107t\n    101t\n    -127t\n    -32t\n    -53t\n    109t\n    -76t\n    4t\n    98t\n    115t\n    16t\n    -56t\n    -67t\n    45t\n    113t\n    -118t\n    -86t\n    45t\n    108t\n    2t\n    -121t\n    116t\n    87t\n    -14t\n    99t\n    -67t\n    -73t\n    1t\n    -45t\n    84t\n    -88t\n    -84t\n    116t\n    51t\n    -76t\n    -122t\n    -68t\n    -95t\n    32t\n    -25t\n    9t\n    82t\n    -92t\n    -91t\n    -19t\n    72t\n    56t\n    64t\n    39t\n    80t\n    46t\n    58t\n    98t\n    -43t\n    102t\n    -106t\n    113t\n    116t\n    -46t\n    -18t\n    -11t\n    24t\n    85t\n    -36t\n    -39t\n    -120t\n    73t\n    65t\n    -116t\n    74t\n    -43t\n    -53t\n    90t\n    -63t\n    94t\n    31t\n    -6t\n    -17t\n    -49t\n    14t\n    -74t\n    125t\n    -15t\n    13t\n    76t\n    -108t\n    -103t\n    2t\n    82t\n    -80t\n    -101t\n    32t\n    -118t\n    52t\n    123t\n    -84t\n    19t\n    -92t\n    -24t\n    35t\n    79t\n    64t\n    -97t\n    106t\n    114t\n    19t\n    50t\n    -27t\n    96t\n    -46t\n    -127t\n    -90t\n    -21t\n    7t\n    -26t\n    -78t\n    91t\n    88t\n    -83t\n    45t\n    30t\n    5t\n    11t\n    -109t\n    -117t\n    -55t\n    -69t\n    125t\n    102t\n    91t\n    -108t\n    69t\n    62t\n    -31t\n    -113t\n    -85t\n    50t\n    -39t\n    -1t\n    48t\n    -60t\n    66t\n    -124t\n    -89t\n    1t\n    -26t\n    -60t\n    103t\n    26t\n    14t\n    27t\n    -124t\n    -80t\n    22t\n    110t\n    -90t\n    54t\n    112t\n    116t\n    -65t\n    -93t\n    99t\n    61t\n    -83t\n    52t\n    -122t\n    -36t\n    -8t\n    -116t\n    -25t\n    -47t\n    80t\n    -94t\n    102t\n    119t\n    28t\n    11t\n    39t\n    -21t\n    47t\n    -57t\n    54t\n    -89t\n    -16t\n    -85t\n    -59t\n    88t\n    55t\n    -61t\n    71t\n    -15t\n    88t\n    -58t\n    44t\n    -102t\n    63t\n    -103t\n    -44t\n    -93t\n    63t\n    23t\n    120t\n    38t\n    44t\n    -63t\n    0t\n    -73t\n    -27t\n    63t\n    -40t\n    91t\n    -12t\n    20t\n    -39t\n    97t\n    -21t\n    94t\n    -25t\n    -6t\n    106t\n    -97t\n    49t\n    -4t\n    -108t\n    103t\n    -60t\n    62t\n    -70t\n    -61t\n    14t\n    -77t\n    96t\n    -38t\n    21t\n    59t\n    36t\n    -50t\n    90t\n    -25t\n    -92t\n    114t\n    89t\n    103t\n    -96t\n    -5t\n    100t\n    41t\n    -3t\n    36t\n    -11t\n    103t\n    -67t\n    37t\n    -46t\n    127t\n    -70t\n    113t\n    -15t\n    -67t\n    76t\n    -78t\n    37t\n    -90t\n    -23t\n    2t\n    54t\n    -89t\n    105t\n    -21t\n    -79t\n    -5t\n    29t\n    -30t\n    -49t\n    116t\n    3t\n    58t\n    66t\n    65t\n    -54t\n    79t\n    84t\n    6t\n    55t\n    -6t\n    -22t\n    -40t\n    -101t\n    32t\n    -124t\n    78t\n    55t\n    100t\n    101t\n    -16t\n    -102t\n    -37t\n    2t\n    108t\n    -123t\n    -46t\n    77t\n    112t\n    25t\n    -31t\n    16t\n    -21t\n    -90t\n    125t\n    -74t\n    29t\n    -113t\n    -76t\n    118t\n    27t\n    -80t\n    -86t\n    16t\n    -7t\n    64t\n    6t\n    12t\n    -101t\n    -128t\n    110t\n    -50t\n    9t\n    67t\n    52t\n    -96t\n    -38t\n    -21t\n    67t\n    94t\n    -95t\n    -69t\n    -54t\n    -109t\n    -9t\n    62t\n    -32t\n    -54t\n    -67t\n    -78t\n    29t\n    121t\n    90t\n    -114t\n    -54t\n    75t\n    38t\n    91t\n    -1t\n    83t\n    -114t\n    -124t\n    107t\n    64t\n    -62t\n    -85t\n    -127t\n    -119t\n    -104t\n    63t\n    5t\n    -70t\n    18t\n    66t\n    95t\n    -61t\n    7t\n    38t\n    -116t\n    55t\n    -95t\n    46t\n    -18t\n    55t\n    100t\n    42t\n    89t\n    -112t\n    -126t\n    6t\n    -17t\n    15t\n    120t\n    -121t\n    99t\n    -109t\n    78t\n    -102t\n    8t\n    -77t\n    28t\n    92t\n    112t\n    90t\n    -18t\n    -52t\n    65t\n    28t\n    95t\n    29t\n    -121t\n    -90t\n    1t\n    -64t\n    38t\n    8t\n    49t\n    0t\n    97t\n    -115t\n    -24t\n    94t\n    94t\n    -58t\n    -35t\n    110t\n    61t\n    -98t\n    -107t\n    -89t\n    44t\n    -32t\n    -123t\n    42t\n    108t\n    77t\n    108t\n    2t\n    -54t\n    98t\n    -53t\n    40t\n    -121t\n    62t\n    33t\n    42t\n    57t\n    122t\n    -119t\n    -39t\n    105t\n    -45t\n    45t\n    -106t\n    -74t\n    47t\n    -36t\n    -86t\n    -64t\n    86t\n    -74t\n    -23t\n    49t\n    122t\n    55t\n    -111t\n    -92t\n    34t\n    -112t\n    -33t\n    125t\n    -95t\n    -34t\n    -104t\n    1t\n    74t\n    -43t\n    -10t\n    69t\n    81t\n    17t\n    -125t\n    -118t\n    -44t\n    -113t\n    84t\n    -17t\n    26t\n    -122t\n    45t\n    -30t\n    30t\n    -17t\n    19t\n    63t\n    94t\n    -26t\n    -55t\n    101t\n    24t\n    -44t\n    -74t\n    54t\n    -46t\n    107t\n    90t\n    32t\n    -84t\n    -81t\n    15t\n    -35t\n    82t\n    -22t\n    103t\n    -77t\n    -65t\n    65t\n    47t\n    1t\n    -122t\n    10t\n    -20t\n    -23t\n    13t\n    33t\n    -1t\n    84t\n    14t\n    82t\n    68t\n    112t\n    -76t\n    -25t\n    61t\n    -69t\n    -2t\n    112t\n    -127t\n    -115t\n    121t\n    110t\n    -70t\n    35t\n    -9t\n    15t\n    19t\n    96t\n    76t\n    106t\n    63t\n    90t\n    118t\n    -43t\n    24t\n    -64t\n    2t\n    -75t\n    125t\n    -100t\n    -12t\n    76t\n    -69t\n    -114t\n    -111t\n    29t\n    0t\n    24t\n    25t\n    26t\n    71t\n    123t\n    10t\n    44t\n    -1t\n    -64t\n    -60t\n    -49t\n    33t\n    -48t\n    9t\n    107t\n    37t\n    119t\n    55t\n    -85t\n    43t\n    -76t\n    -95t\n    4t\n    83t\n    49t\n    35t\n    20t\n    21t\n    -37t\n    66t\n    92t\n    85t\n    -93t\n    -3t\n    -44t\n    73t\n    -92t\n    73t\n    -69t\n    111t\n    -118t\n    -63t\n    118t\n    49t\n    28t\n    -127t\n    -20t\n    38t\n    42t\n    78t\n    -95t\n    108t\n    77t\n    123t\n    117t\n    80t\n    -87t\n    -42t\n    -21t\n    -72t\n    69t\n    -56t\n    -124t\n    47t\n    -49t\n    -2t\n    -95t\n    -70t\n    112t\n    -78t\n    -5t\n    98t\n    47t\n    68t\n    -27t\n    -12t\n    102t\n    85t\n    125t\n    100t\n    -36t\n    105t\n    85t\n    -95t\n    -96t\n    36t\n    9t\n    120t\n    -62t\n    -51t\n    -45t\n    48t\n    26t\n    77t\n    -56t\n    -86t\n    110t\n    -52t\n    101t\n    -41t\n    -115t\n    36t\n    -6t\n    -32t\n    -15t\n    121t\n    -3t\n    21t\n    79t\n    48t\n    -32t\n    -86t\n    -99t\n    58t\n    119t\n    93t\n    39t\n    62t\n    -57t\n    76t\n    -44t\n    117t\n    86t\n    -14t\n    -34t\n    89t\n    105t\n    -33t\n    -119t\n    -88t\n    -118t\n    22t\n    86t\n    10t\n    -62t\n    -36t\n    -119t\n    -104t\n    16t\n    117t\n    -80t\n    79t\n    -67t\n    -37t\n    -14t\n    -75t\n    12t\n    58t\n    10t\n    11t\n    97t\n    19t\n    -97t\n    -21t\n    -6t\n    33t\n    -109t\n    108t\n    36t\n    49t\n    -99t\n    -66t\n    -124t\n    107t\n    -24t\n    76t\n    -5t\n    12t\n    -65t\n    18t\n    98t\n    92t\n    73t\n    -27t\n    -105t\n    117t\n    -67t\n    -126t\n    -124t\n    94t\n    -82t\n    -41t\n    39t\n    -85t\n    119t\n    -118t\n    -98t\n    -91t\n    74t\n    -125t\n    -79t\n    -85t\n    -71t\n    -49t\n    -121t\n    -81t\n    -103t\n    -128t\n    -19t\n    -38t\n    124t\n    -48t\n    13t\n    -97t\n    -82t\n    -110t\n    -34t\n    -65t\n    53t\n    103t\n    16t\n    101t\n    -16t\n    29t\n    -104t\n    -116t\n    -9t\n    -74t\n    -22t\n    103t\n    -60t\n    -54t\n  .end array-data\n  :L156\n  .array-data 1\n    106t\n    97t\n    118t\n    97t\n    47t\n    108t\n    97t\n    110t\n    103t\n    47t\n    73t\n    110t\n    116t\n    101t\n    103t\n    101t\n    114t\n    113t\n    -35t\n    114t\n    99t\n    -38t\n    -44t\n    16t\n    22t\n    98t\n    -74t\n    -51t\n    -83t\n    57t\n    -1t\n    -108t\n    22t\n    98t\n    -43t\n    58t\n    -102t\n    25t\n    -4t\n    -58t\n    -14t\n    19t\n    -78t\n    -72t\n    -34t\n    -11t\n    124t\n    -126t\n    33t\n    68t\n    48t\n    62t\n    -120t\n    -28t\n    -83t\n    -86t\n    77t\n    -40t\n    -87t\n    -106t\n    -77t\n    119t\n    99t\n    -65t\n    97t\n    18t\n    60t\n    92t\n    -76t\n    126t\n    -125t\n    26t\n    -47t\n    -10t\n    -103t\n    -102t\n    -41t\n    19t\n    99t\n    15t\n    -51t\n    66t\n    39t\n    7t\n    93t\n    31t\n    112t\n    98t\n    -127t\n    50t\n    -95t\n    -11t\n    46t\n    -6t\n    -72t\n    -73t\n    58t\n    71t\n    68t\n    8t\n    -30t\n    -17t\n    -45t\n    -28t\n    -9t\n    -81t\n    11t\n    69t\n    1t\n    -95t\n    7t\n    -99t\n    -53t\n    113t\n    10t\n    124t\n    -6t\n    117t\n    124t\n    -91t\n    -89t\n    24t\n    62t\n    -52t\n    104t\n    -24t\n    18t\n    -113t\n    79t\n    60t\n    -20t\n    20t\n    114t\n    -46t\n    -125t\n    111t\n    93t\n    107t\n    -27t\n    44t\n    15t\n    -101t\n    -32t\n    52t\n    24t\n    52t\n    61t\n    55t\n    -63t\n    -37t\n    -45t\n    -39t\n    93t\n    -44t\n    10t\n    115t\n    -34t\n    -32t\n    -12t\n    74t\n    89t\n    54t\n    -102t\n    124t\n    -52t\n    27t\n    -81t\n    -112t\n    12t\n    92t\n    20t\n    101t\n    45t\n    43t\n    -102t\n    -47t\n    -83t\n    -100t\n    5t\n    85t\n    -78t\n    -30t\n    -7t\n    -20t\n    -80t\n    118t\n    95t\n    -71t\n    108t\n    27t\n    118t\n    35t\n    96t\n    42t\n    -48t\n    10t\n    84t\n    -50t\n    0t\n    5t\n    39t\n    -95t\n    -111t\n    -63t\n    47t\n    14t\n    31t\n    36t\n    7t\n    -38t\n    41t\n    -4t\n    -8t\n    -71t\n    78t\n    -6t\n    -94t\n    -68t\n    9t\n    47t\n    -104t\n    90t\n    -56t\n    -10t\n    -60t\n    41t\n    -7t\n    -106t\n    -59t\n    -88t\n    2t\n    20t\n    69t\n    105t\n    2t\n    112t\n    111t\n    -78t\n    -67t\n    -13t\n    18t\n    33t\n    -30t\n    101t\n    125t\n    72t\n    103t\n    -42t\n    -13t\n    -20t\n    -52t\n    62t\n    119t\n    -12t\n    -9t\n    -6t\n    106t\n    -78t\n    -104t\n    25t\n    64t\n    -6t\n    -117t\n    -40t\n    -114t\n    -122t\n    -8t\n    122t\n    -13t\n    -102t\n    -123t\n    55t\n    -66t\n    32t\n    -56t\n    118t\n    -105t\n    -107t\n    -32t\n    103t\n    96t\n    -52t\n    13t\n    19t\n    -103t\n    85t\n    78t\n    -30t\n    -79t\n    -18t\n    -107t\n    -68t\n    61t\n    -124t\n    9t\n    20t\n    28t\n    53t\n    19t\n    -74t\n    56t\n    -78t\n    119t\n    -111t\n    -61t\n    -83t\n    -98t\n    -21t\n    -115t\n    -68t\n    -48t\n    -86t\n    27t\n    -52t\n    -53t\n    115t\n    74t\n    39t\n    90t\n    -126t\n    112t\n    -88t\n    29t\n    -5t\n    39t\n    1t\n    -73t\n    74t\n    38t\n    -45t\n    96t\n    117t\n    81t\n    -28t\n    107t\n    52t\n    -47t\n    87t\n    105t\n    -127t\n    3t\n    -76t\n    39t\n    4t\n    124t\n    -79t\n    57t\n    117t\n    16t\n    6t\n    -83t\n    -61t\n    25t\n    32t\n    -53t\n    101t\n    -102t\n    89t\n    -27t\n    -6t\n    -99t\n    38t\n    -26t\n    83t\n    20t\n    -42t\n    88t\n    -86t\n    91t\n    -22t\n    65t\n    -22t\n    120t\n    41t\n    -104t\n    -55t\n    -91t\n    95t\n    51t\n    97t\n    -115t\n    40t\n    79t\n    10t\n    10t\n    82t\n    120t\n    -119t\n    25t\n    125t\n    94t\n    -18t\n    88t\n    -7t\n    -30t\n    22t\n    -35t\n    71t\n    101t\n    22t\n    -3t\n    -91t\n    -123t\n    -7t\n    106t\n    8t\n    -54t\n    -101t\n    91t\n    70t\n    10t\n    38t\n    46t\n    -45t\n    54t\n    -100t\n    6t\n    48t\n    -110t\n    65t\n    85t\n    -66t\n    85t\n    7t\n    -38t\n    92t\n    -120t\n    22t\n    49t\n    -47t\n    -71t\n    -102t\n    -100t\n    -118t\n    51t\n    2t\n    36t\n    -103t\n    -42t\n    27t\n    -113t\n    20t\n    27t\n    24t\n    -6t\n    -23t\n    -36t\n    -29t\n    45t\n    87t\n    101t\n    -54t\n    109t\n    12t\n    37t\n    106t\n    67t\n    114t\n    22t\n    -19t\n    59t\n    -64t\n    6t\n    30t\n    91t\n    -104t\n    -36t\n    -98t\n    38t\n    83t\n    72t\n    16t\n    -50t\n    -29t\n    87t\n    87t\n    -84t\n    65t\n    -60t\n    10t\n    -5t\n    -52t\n    114t\n    54t\n    -111t\n    -112t\n    -106t\n    -82t\n    -16t\n    12t\n    -96t\n    -30t\n    -122t\n    70t\n    14t\n    51t\n    -59t\n    109t\n    -120t\n    109t\n    125t\n    -66t\n    -49t\n    14t\n    50t\n    63t\n    -14t\n    -67t\n    104t\n    115t\n    101t\n    -109t\n    74t\n    76t\n    -78t\n    -111t\n    49t\n    -10t\n    11t\n    10t\n    -67t\n    -5t\n    -94t\n    76t\n    -116t\n    -20t\n    -22t\n    108t\n    116t\n    -114t\n    -119t\n    118t\n    57t\n    45t\n    75t\n    -46t\n    -4t\n    113t\n    -30t\n    -110t\n    -69t\n    -40t\n    -16t\n    6t\n    30t\n    124t\n    -61t\n    16t\n    -51t\n    -69t\n    -63t\n    -23t\n    23t\n    -26t\n    100t\n    54t\n    -92t\n    84t\n    -48t\n    20t\n    39t\n    41t\n    -65t\n    -21t\n    117t\n    53t\n    40t\n    43t\n    -81t\n    -50t\n    -10t\n    4t\n    53t\n    -14t\n    -123t\n    108t\n    -47t\n    56t\n    107t\n    -11t\n    98t\n    79t\n    107t\n    108t\n    -90t\n    78t\n    -17t\n    -7t\n    120t\n    87t\n    8t\n    -82t\n    -89t\n    -84t\n    -106t\n    -81t\n    81t\n    -82t\n    72t\n    102t\n    -107t\n    32t\n    -6t\n    -36t\n    -1t\n    -76t\n    19t\n    -101t\n    -1t\n    -89t\n    59t\n    61t\n    59t\n    -125t\n    121t\n    -8t\n    -20t\n    100t\n    -12t\n    92t\n    -23t\n    -50t\n    20t\n    -10t\n    -26t\n    -45t\n    -99t\n    99t\n    -86t\n    77t\n    -111t\n    -48t\n    -121t\n    -93t\n    96t\n    28t\n    79t\n    76t\n    13t\n    68t\n    -97t\n    -49t\n    37t\n    99t\n    -3t\n    -62t\n    -67t\n    -11t\n    -46t\n    -103t\n    118t\n    -24t\n    -120t\n    -34t\n    88t\n    -40t\n    -66t\n    -37t\n    112t\n    15t\n    28t\n    34t\n    23t\n    -73t\n    97t\n    65t\n    56t\n    -74t\n    -15t\n    -100t\n    85t\n    -71t\n    97t\n    14t\n    60t\n    -126t\n    49t\n    122t\n    5t\n    -40t\n    -41t\n    18t\n    -85t\n    -99t\n    120t\n    67t\n    -123t\n    70t\n    20t\n    -61t\n    -46t\n    35t\n    116t\n    -40t\n    -108t\n    85t\n    -114t\n    88t\n    33t\n    87t\n    -25t\n    39t\n    107t\n    60t\n    -108t\n    84t\n    2t\n    -80t\n    -47t\n    -30t\n    117t\n    -19t\n    -75t\n    78t\n    -11t\n    24t\n    -125t\n    68t\n    -127t\n    44t\n    18t\n    -85t\n    -72t\n    22t\n    1t\n    -25t\n    -125t\n    -53t\n    -107t\n    -15t\n    -29t\n    93t\n    -127t\n    21t\n    -122t\n    -77t\n    26t\n    84t\n    -105t\n    -21t\n    -115t\n    72t\n    -110t\n    79t\n    104t\n    28t\n    -108t\n    29t\n    -1t\n    102t\n    4t\n    85t\n    -121t\n    91t\n    -113t\n    122t\n    115t\n    -29t\n    53t\n    -108t\n    -81t\n    29t\n    -86t\n    96t\n    17t\n    -105t\n    -97t\n    98t\n    11t\n    -61t\n    32t\n    -105t\n    39t\n    8t\n    -22t\n    84t\n    127t\n    7t\n    8t\n    6t\n    9t\n    -66t\n    8t\n    -119t\n    -62t\n    -14t\n    80t\n    31t\n    126t\n    -90t\n    -122t\n    52t\n    -118t\n    55t\n    31t\n    -95t\n    50t\n    87t\n    -73t\n    -75t\n    11t\n    -76t\n    76t\n    -90t\n    -72t\n    -34t\n    -77t\n    94t\n    -121t\n    -107t\n    -81t\n    72t\n    -109t\n    22t\n    100t\n    114t\n    -105t\n    36t\n    19t\n    96t\n    -94t\n    27t\n    -59t\n    87t\n    87t\n    106t\n    -105t\n    -84t\n    -104t\n    20t\n    -83t\n    29t\n    63t\n    56t\n    -75t\n    123t\n    -80t\n    -30t\n    121t\n    -30t\n    -125t\n    104t\n    -61t\n    -80t\n    88t\n    -97t\n    73t\n    -125t\n    112t\n    -7t\n    110t\n    6t\n    103t\n    -30t\n    13t\n    89t\n    -5t\n    61t\n    -24t\n    -83t\n    62t\n    -10t\n    -68t\n    -85t\n    25t\n    -62t\n    -85t\n    -21t\n    99t\n    -40t\n    123t\n    12t\n    70t\n    -102t\n    -125t\n    -107t\n    120t\n    -5t\n    -42t\n    80t\n    99t\n    29t\n    -106t\n    126t\n    5t\n    102t\n    -18t\n    -38t\n    -59t\n    9t\n    -17t\n    -74t\n    -47t\n    -7t\n    31t\n    83t\n    -80t\n    -74t\n    -79t\n    -56t\n    -8t\n    -112t\n    74t\n    -13t\n    -7t\n    96t\n    100t\n    1t\n    -56t\n    -23t\n    47t\n    38t\n    85t\n    47t\n    -52t\n    5t\n    35t\n    -91t\n    23t\n    -66t\n    -17t\n    50t\n    115t\n    100t\n    34t\n    -26t\n    102t\n    19t\n    -54t\n    -5t\n    -56t\n    -127t\n    -23t\n    -30t\n    -108t\n    106t\n    -17t\n    54t\n    -125t\n    61t\n    -35t\n    88t\n    39t\n    -35t\n    -12t\n    97t\n    -128t\n    -14t\n    69t\n    118t\n    98t\n    116t\n    -69t\n    66t\n    -101t\n    -82t\n    -14t\n    -14t\n    43t\n    -47t\n    -79t\n    -82t\n    -45t\n    -99t\n    99t\n    -29t\n    -20t\n    -95t\n    -16t\n    -35t\n    112t\n    115t\n    86t\n    -119t\n    -117t\n    -6t\n    70t\n    -38t\n    -36t\n    44t\n    90t\n    -54t\n    103t\n    -22t\n    -32t\n    -112t\n    -65t\n    110t\n    -47t\n    -71t\n    -25t\n    -43t\n    83t\n    89t\n    119t\n    -91t\n    -66t\n    118t\n    92t\n    120t\n    89t\n    -79t\n    -126t\n    67t\n    -94t\n    -53t\n    44t\n    -127t\n    34t\n    -14t\n    98t\n    -110t\n    7t\n    15t\n    25t\n    16t\n    -15t\n    9t\n    -105t\n    -123t\n    -53t\n    91t\n    -124t\n    120t\n    -115t\n    119t\n    86t\n    20t\n    -54t\n    72t\n    21t\n    13t\n    -26t\n    104t\n    64t\n    119t\n    123t\n    72t\n    -124t\n    -33t\n    -118t\n    57t\n    -71t\n    12t\n    -71t\n    79t\n    -60t\n    91t\n    -7t\n    -122t\n    -109t\n    109t\n    36t\n    -69t\n    -38t\n    -10t\n    -98t\n    -38t\n    102t\n    -106t\n    -33t\n    123t\n    -40t\n    -15t\n    16t\n    17t\n    14t\n    -121t\n    -122t\n    5t\n    -115t\n    5t\n    -16t\n    -30t\n    63t\n    -18t\n    34t\n    -2t\n    -8t\n    82t\n    38t\n    18t\n    117t\n    -43t\n    25t\n    69t\n    -121t\n    76t\n    -37t\n    29t\n    111t\n    -106t\n    -83t\n    -34t\n    -50t\n    -105t\n    127t\n    69t\n    -112t\n    15t\n    -37t\n    -49t\n    41t\n    58t\n    -53t\n    -95t\n    110t\n    -103t\n    109t\n    115t\n    12t\n    48t\n    -110t\n    15t\n    -105t\n    -56t\n    -56t\n    87t\n    71t\n    -108t\n    -11t\n    -37t\n    118t\n    -112t\n    74t\n    -65t\n    -89t\n    -78t\n    -87t\n    -26t\n    -107t\n    -115t\n    -52t\n    92t\n    -34t\n    -61t\n    -51t\n    -115t\n    -25t\n    -117t\n    67t\n    73t\n    -63t\n    1t\n    -113t\n    17t\n    -32t\n    119t\n    94t\n    -55t\n    92t\n    -119t\n    -1t\n    -18t\n    -109t\n    -40t\n    -90t\n    -81t\n    -5t\n    25t\n    113t\n    -66t\n    11t\n    -97t\n    -77t\n    -33t\n    126t\n    5t\n    30t\n    93t\n    52t\n    -24t\n    103t\n    -114t\n    114t\n    -43t\n    61t\n    -103t\n    -121t\n    60t\n    104t\n    74t\n    -22t\n    25t\n    122t\n    -101t\n    125t\n    -5t\n    61t\n    47t\n    10t\n    113t\n    -118t\n    68t\n    96t\n    -40t\n    13t\n    111t\n    90t\n    63t\n    71t\n    -38t\n    1t\n    35t\n    83t\n    52t\n    -38t\n    74t\n    -71t\n    56t\n    57t\n    89t\n    -33t\n    -57t\n    113t\n    109t\n    -50t\n    78t\n    15t\n    -79t\n    -90t\n    -4t\n    11t\n    -128t\n    -121t\n    33t\n    -4t\n    -105t\n    -115t\n    -54t\n    -102t\n    -8t\n    38t\n    45t\n    8t\n    -45t\n    101t\n    11t\n    -12t\n    50t\n    -59t\n    42t\n    39t\n    -77t\n    -57t\n    45t\n    -66t\n    -69t\n    -49t\n    75t\n    -69t\n    122t\n    -56t\n    117t\n    102t\n    106t\n    -24t\n    3t\n    26t\n    -126t\n    -102t\n    67t\n    -109t\n    -19t\n    -41t\n    116t\n    100t\n    100t\n    -92t\n    -124t\n    71t\n    18t\n    -8t\n    115t\n    111t\n    14t\n    9t\n    120t\n    4t\n    33t\n    86t\n    31t\n    -120t\n    127t\n    30t\n    85t\n    60t\n    -7t\n    68t\n    -18t\n    22t\n    3t\n    -73t\n    -75t\n    14t\n    116t\n    -97t\n    -32t\n    29t\n    -7t\n    52t\n    -61t\n    -47t\n    -80t\n    50t\n    -111t\n    92t\n    4t\n    104t\n    87t\n    -16t\n    99t\n    117t\n    68t\n    21t\n    40t\n    -45t\n    -99t\n    61t\n    -20t\n    20t\n    19t\n    117t\n    64t\n    9t\n    16t\n    -8t\n    34t\n    -64t\n    -113t\n    -89t\n    122t\n    -7t\n    68t\n    89t\n    54t\n    -15t\n    -109t\n    -65t\n    -84t\n    -29t\n    89t\n    5t\n    27t\n    95t\n    39t\n    -19t\n    77t\n    -4t\n    -72t\n    96t\n    -47t\n    -30t\n    100t\n    24t\n    15t\n    -69t\n    -22t\n    47t\n    51t\n    63t\n    105t\n    -102t\n    -21t\n    80t\n    -125t\n    73t\n    34t\n    -11t\n    6t\n    -65t\n    -32t\n    -87t\n    96t\n    -80t\n    -31t\n    47t\n    6t\n    -63t\n    -34t\n    -26t\n    58t\n    -54t\n    -17t\n    -64t\n    -25t\n    114t\n    10t\n    103t\n    12t\n    69t\n    -128t\n    -113t\n    36t\n    -111t\n    -51t\n    -26t\n    57t\n    -103t\n    5t\n    -40t\n    87t\n    123t\n    123t\n    -6t\n    1t\n    87t\n    -28t\n    64t\n    11t\n    74t\n    -47t\n    -79t\n    -110t\n    -70t\n    31t\n    90t\n    57t\n    46t\n    34t\n    -4t\n    -104t\n    35t\n    -117t\n    102t\n    20t\n    14t\n    102t\n    5t\n    -124t\n    -116t\n    -8t\n    52t\n    -39t\n    126t\n    -118t\n    123t\n    90t\n    -124t\n    -113t\n    -107t\n    91t\n    -48t\n    1t\n    13t\n    -5t\n    -27t\n    67t\n    79t\n    -103t\n    -93t\n    0t\n    -95t\n    -37t\n    -34t\n    106t\n    -17t\n    9t\n    79t\n    -53t\n    -18t\n    14t\n    111t\n    -31t\n    44t\n    95t\n    -1t\n    -48t\n    -54t\n    -124t\n    11t\n    75t\n    16t\n    -123t\n    97t\n    100t\n    -66t\n    7t\n    -4t\n    -117t\n    -121t\n    -8t\n    -124t\n    -126t\n    -56t\n    91t\n    93t\n    72t\n    83t\n    93t\n    124t\n    53t\n    -83t\n    80t\n    -16t\n    -117t\n    -1t\n    -127t\n    33t\n    80t\n    44t\n    40t\n    -1t\n    -87t\n    71t\n    7t\n    -14t\n    -1t\n    82t\n    76t\n    32t\n    -113t\n    -54t\n    -72t\n    11t\n    -43t\n    -6t\n    112t\n    -104t\n    -34t\n    -37t\n    -3t\n    63t\n    125t\n    0t\n    -103t\n    -22t\n    91t\n    -42t\n    -21t\n    49t\n    70t\n    -16t\n    -85t\n    31t\n    78t\n    28t\n    4t\n    67t\n    37t\n    24t\n    -73t\n    100t\n    94t\n    -111t\n    -18t\n    81t\n    -30t\n    -27t\n    70t\n    -13t\n    119t\n    -89t\n    40t\n    -114t\n    82t\n    -49t\n    -102t\n    37t\n    -84t\n    75t\n    -55t\n    -54t\n    -66t\n    124t\n    117t\n    121t\n    -14t\n    -114t\n    98t\n    62t\n    -61t\n    55t\n    51t\n    52t\n    -66t\n    81t\n    -75t\n    86t\n    -76t\n    100t\n    33t\n    65t\n    -32t\n    11t\n    -65t\n    92t\n    -16t\n    -7t\n    124t\n    -121t\n    -126t\n    27t\n    79t\n    -38t\n    -7t\n    19t\n    30t\n    -100t\n    -29t\n    44t\n    30t\n    -79t\n    126t\n    -47t\n    85t\n    -27t\n    -64t\n    -60t\n    125t\n    -91t\n    -81t\n    -119t\n    -123t\n    -14t\n    16t\n    -60t\n    -74t\n    83t\n    94t\n    -71t\n    -25t\n    3t\n    -89t\n    -115t\n    118t\n    -21t\n    -83t\n    -110t\n    -70t\n    -127t\n    -39t\n    -110t\n    71t\n    64t\n    -38t\n    -52t\n    -75t\n    -42t\n    24t\n    -90t\n    -64t\n    -36t\n    38t\n    87t\n    -114t\n    63t\n    16t\n    37t\n    -106t\n    -61t\n    45t\n    -39t\n    75t\n    31t\n    22t\n    90t\n    -75t\n    -72t\n    33t\n    -42t\n    -50t\n    13t\n    107t\n    4t\n    -122t\n    3t\n    75t\n    13t\n    108t\n    -47t\n    -26t\n    7t\n    -11t\n    53t\n    91t\n    -116t\n    -118t\n    40t\n    -87t\n    -84t\n    21t\n    117t\n    -33t\n    49t\n    -28t\n    108t\n    78t\n    12t\n    64t\n    -124t\n    94t\n    3t\n    101t\n    57t\n    96t\n    86t\n    -37t\n    86t\n    29t\n    -29t\n    61t\n    -108t\n    84t\n    -39t\n    -107t\n    17t\n    107t\n    -127t\n    -59t\n    -32t\n    -33t\n    -45t\n    -17t\n    21t\n    -39t\n    -94t\n    -56t\n    43t\n    -107t\n    -41t\n    125t\n    -59t\n    -16t\n    6t\n    -95t\n    4t\n    -111t\n    -72t\n    -120t\n    -23t\n    -108t\n    -120t\n    81t\n    -86t\n    -118t\n    -2t\n    -33t\n    81t\n    -16t\n    38t\n    -87t\n    -12t\n    68t\n    -10t\n    22t\n    114t\n    80t\n    13t\n    122t\n    -76t\n    35t\n    -68t\n    -19t\n    -58t\n    -109t\n    -103t\n    115t\n    -70t\n    54t\n    -67t\n    -108t\n    101t\n    15t\n    -66t\n    -117t\n    74t\n    40t\n    82t\n    -59t\n    23t\n    -120t\n    88t\n    -115t\n    116t\n    -6t\n    -51t\n    84t\n    26t\n    -39t\n    -59t\n    -7t\n    -123t\n    93t\n    -20t\n    70t\n    104t\n    126t\n    -5t\n    -81t\n    -30t\n    -60t\n    -116t\n    -62t\n    -31t\n    -20t\n    27t\n    59t\n    -56t\n    28t\n    74t\n    69t\n    46t\n    -1t\n    -96t\n    -57t\n    7t\n    -47t\n    -22t\n    98t\n    -91t\n    23t\n    -86t\n    111t\n    -87t\n    -55t\n    25t\n    -127t\n    127t\n    118t\n    -103t\n    -9t\n    -75t\n    -86t\n    71t\n    -96t\n    27t\n    28t\n    2t\n    -69t\n    -45t\n    -112t\n    -75t\n    81t\n    -80t\n    98t\n    110t\n    95t\n    39t\n    104t\n    -92t\n    6t\n    16t\n    -113t\n    -20t\n    95t\n    -39t\n    27t\n    -81t\n    52t\n    109t\n    35t\n    -57t\n    -10t\n    -34t\n    3t\n    -46t\n    -16t\n    -64t\n    42t\n    -63t\n    -86t\n    -2t\n    84t\n    71t\n    49t\n    -56t\n    -80t\n    16t\n    -111t\n    122t\n    28t\n    89t\n    55t\n    14t\n    -72t\n    -20t\n    0t\n    -49t\n    50t\n    82t\n    113t\n    -53t\n    -119t\n    49t\n    77t\n    80t\n    66t\n    127t\n    -100t\n    -114t\n    116t\n    -97t\n    43t\n    22t\n    104t\n    -110t\n    -61t\n    52t\n    51t\n    -104t\n    -59t\n    39t\n    -93t\n    9t\n    -14t\n    -18t\n    73t\n    71t\n    -36t\n    91t\n    67t\n    103t\n    -4t\n    -38t\n    -87t\n    -81t\n    -79t\n    93t\n    -6t\n    58t\n    -118t\n    -57t\n    88t\n    54t\n    11t\n    -86t\n    -119t\n    -42t\n    104t\n    -29t\n    -96t\n    -108t\n    -78t\n    50t\n    -21t\n    -74t\n    -122t\n    109t\n    -52t\n    -103t\n    62t\n    77t\n    -98t\n    -65t\n    92t\n    -12t\n    70t\n    16t\n    124t\n    -95t\n    -55t\n    -104t\n    33t\n    -96t\n    -6t\n    105t\n    -16t\n    6t\n    41t\n    92t\n    -42t\n    -100t\n    48t\n    -64t\n    41t\n    85t\n    91t\n    -67t\n    18t\n    -35t\n    66t\n    5t\n    -120t\n    83t\n    -16t\n    -37t\n    1t\n    101t\n    -21t\n    -104t\n    -67t\n    -120t\n    42t\n    -96t\n    49t\n    88t\n    17t\n    -102t\n    41t\n    -36t\n    6t\n    72t\n    4t\n    73t\n    73t\n    58t\n    -79t\n    29t\n    -102t\n    30t\n    -117t\n    -61t\n    108t\n    -76t\n    -28t\n    -47t\n    47t\n    -115t\n    44t\n    -16t\n    -89t\n    23t\n    18t\n    -40t\n    -103t\n    36t\n    97t\n    -12t\n    113t\n    -72t\n    -90t\n    -113t\n    21t\n    -106t\n    -81t\n    56t\n    -70t\n    62t\n    7t\n    -100t\n    -100t\n    113t\n    -112t\n    54t\n    -55t\n    -11t\n    72t\n    -49t\n    -117t\n    104t\n    -46t\n    -91t\n    52t\n    -126t\n    -35t\n    -3t\n    39t\n    51t\n    -34t\n    -33t\n    20t\n    68t\n    26t\n    39t\n    -83t\n    -52t\n    -109t\n    67t\n    105t\n    48t\n    1t\n    69t\n    96t\n    -107t\n    105t\n    87t\n    14t\n    -106t\n    -37t\n    -103t\n    75t\n    44t\n    101t\n    -45t\n    19t\n    -112t\n    -62t\n    -26t\n    -118t\n    -19t\n    19t\n    62t\n    -91t\n    -89t\n    -90t\n    -122t\n    -128t\n    -84t\n    -126t\n    -115t\n    8t\n    -73t\n    -126t\n    -26t\n    5t\n    112t\n    -74t\n    -74t\n    -2t\n    9t\n    18t\n    -112t\n    -53t\n    12t\n    -6t\n    -55t\n    4t\n    -60t\n    43t\n    1t\n    93t\n    40t\n    56t\n    104t\n    -39t\n    118t\n    46t\n    -98t\n    -38t\n    -47t\n    -12t\n    0t\n    116t\n    76t\n    112t\n    -63t\n    42t\n    -83t\n    88t\n    -125t\n    -64t\n    50t\n    -64t\n    -21t\n    56t\n    -118t\n    6t\n    113t\n    -25t\n    -83t\n    -65t\n    -7t\n    105t\n    75t\n    -102t\n    117t\n    24t\n    110t\n    86t\n    96t\n    43t\n    26t\n    -4t\n    29t\n    -117t\n    -23t\n    11t\n    118t\n    -36t\n    -66t\n    65t\n    -113t\n    -119t\n    -93t\n    -34t\n    -66t\n    -67t\n    -23t\n    76t\n    -89t\n    7t\n    -69t\n    -49t\n    -11t\n    -2t\n    -37t\n    83t\n    20t\n    113t\n    -7t\n    29t\n    74t\n    -75t\n    44t\n    71t\n    75t\n    61t\n    101t\n    -22t\n    21t\n    -3t\n    -86t\n    57t\n    -86t\n    58t\n    116t\n    -128t\n    -6t\n    26t\n    39t\n    72t\n    4t\n    -28t\n    12t\n    -61t\n    86t\n    47t\n    73t\n    -68t\n    65t\n    -62t\n    89t\n    31t\n    41t\n    23t\n    30t\n    54t\n    11t\n    117t\n    -91t\n    122t\n    50t\n    -127t\n    21t\n    -27t\n    -1t\n    -27t\n    50t\n    52t\n    -65t\n    -88t\n    -31t\n    -29t\n    -81t\n    67t\n    98t\n    97t\n    76t\n    68t\n    -53t\n    -97t\n    -33t\n    3t\n    -115t\n    -1t\n    83t\n    70t\n    -47t\n    28t\n    25t\n    -112t\n    -64t\n    -53t\n    60t\n    -7t\n    31t\n    57t\n    -2t\n    -47t\n    -95t\n    -4t\n    -121t\n    -16t\n    -43t\n    0t\n    -123t\n    64t\n    44t\n    81t\n    46t\n    -23t\n    -68t\n    43t\n    29t\n    -29t\n    -53t\n    3t\n    101t\n    53t\n    73t\n    -79t\n    -124t\n    -121t\n    -3t\n    26t\n    101t\n    105t\n    -46t\n    127t\n    -71t\n    39t\n    63t\n    45t\n    56t\n    96t\n    -32t\n    49t\n    111t\n    94t\n    25t\n    64t\n    -44t\n    116t\n    107t\n    -107t\n    -123t\n    72t\n    114t\n    -116t\n    33t\n    -49t\n    92t\n    -105t\n    14t\n    -67t\n    120t\n    -27t\n    -54t\n    -66t\n    -94t\n    -84t\n    -116t\n    14t\n    64t\n    -97t\n    -27t\n    -26t\n    -106t\n    -83t\n    96t\n    -97t\n    27t\n    74t\n    -30t\n    33t\n    -19t\n    53t\n    39t\n    45t\n    -53t\n    38t\n    77t\n    -34t\n    59t\n    -68t\n    -80t\n    -23t\n    126t\n    112t\n    63t\n    52t\n    110t\n    -14t\n    -98t\n    16t\n    88t\n    -121t\n    -59t\n    -124t\n    -62t\n    -56t\n    -34t\n    60t\n    87t\n    36t\n    -16t\n    -9t\n    53t\n    5t\n    69t\n    -37t\n    83t\n    -28t\n    -39t\n    -83t\n    -1t\n    103t\n    -103t\n    -17t\n    -120t\n    -117t\n    104t\n    61t\n    113t\n    -73t\n    108t\n    110t\n    -7t\n    51t\n    40t\n    -42t\n    113t\n    -67t\n    105t\n    4t\n    -118t\n    34t\n    58t\n    48t\n    62t\n    -93t\n    -41t\n    -109t\n    59t\n    95t\n    -13t\n    1t\n    22t\n    53t\n    104t\n    -23t\n    -89t\n    -115t\n    58t\n    75t\n    87t\n    71t\n    -73t\n    65t\n    -127t\n    -11t\n    -2t\n    -39t\n    106t\n    117t\n    122t\n    -24t\n    70t\n    -8t\n    73t\n    92t\n    49t\n    -119t\n    103t\n    -96t\n    45t\n    -128t\n    -126t\n    121t\n    35t\n    -120t\n    -21t\n    -92t\n    74t\n    16t\n    -49t\n    74t\n    -11t\n    -123t\n    -84t\n    28t\n    72t\n    -91t\n    9t\n    117t\n    -25t\n    44t\n    -120t\n    -73t\n    -71t\n    -47t\n    -7t\n    127t\n    25t\n    100t\n    53t\n    -32t\n    -20t\n    57t\n    -71t\n    38t\n    -62t\n    15t\n    -99t\n    124t\n    -15t\n    -109t\n    111t\n    -99t\n    -124t\n    99t\n    121t\n    74t\n    52t\n    21t\n    50t\n    17t\n    -71t\n    54t\n    -13t\n    -97t\n    6t\n    116t\n    95t\n    92t\n    -117t\n    -60t\n    -35t\n    -80t\n    -47t\n    19t\n    118t\n    82t\n    -111t\n    -20t\n    103t\n    12t\n    84t\n    77t\n    4t\n    40t\n    29t\n    -40t\n    98t\n    105t\n    62t\n    -121t\n    93t\n    -112t\n    28t\n    84t\n    14t\n    21t\n    -99t\n    -67t\n    -62t\n    62t\n    22t\n    -88t\n    48t\n    -110t\n    -44t\n    -67t\n    -106t\n    20t\n    -122t\n    39t\n    27t\n    110t\n    -3t\n    -69t\n    52t\n    -128t\n    -101t\n    -57t\n    66t\n    74t\n    -14t\n    35t\n    86t\n    99t\n    100t\n    -10t\n    -16t\n    -4t\n    -84t\n    -62t\n    13t\n    -2t\n    117t\n    11t\n    -55t\n    14t\n    16t\n    -99t\n    52t\n    0t\n    -96t\n    71t\n    -8t\n    -72t\n    83t\n    -18t\n    32t\n    -125t\n    77t\n    -37t\n    -44t\n    73t\n    122t\n    83t\n    99t\n    -111t\n    -8t\n    -107t\n    58t\n    -113t\n    -77t\n    46t\n    115t\n    -28t\n    61t\n    -99t\n    -104t\n    97t\n    22t\n    -112t\n    113t\n    22t\n    -108t\n    110t\n    96t\n    58t\n    -122t\n    125t\n    35t\n    83t\n    6t\n    72t\n    -33t\n    54t\n    91t\n    -113t\n    -23t\n    -99t\n    -43t\n    -41t\n    -67t\n    -117t\n    94t\n    100t\n    60t\n    120t\n    119t\n    13t\n    8t\n    109t\n    -33t\n    107t\n    7t\n    26t\n    118t\n    46t\n    -106t\n    -122t\n    -115t\n    -30t\n    -45t\n    29t\n    -52t\n    58t\n    104t\n    17t\n    -72t\n    -46t\n    102t\n    69t\n    50t\n    37t\n    -9t\n    -59t\n    -114t\n    -47t\n    -47t\n    -6t\n    -65t\n    -100t\n    -92t\n    109t\n    -108t\n    24t\n    -106t\n    20t\n    -103t\n    -43t\n    71t\n    119t\n    -23t\n    77t\n    123t\n    12t\n    -112t\n    92t\n    -36t\n    -68t\n    34t\n    77t\n    -27t\n    -41t\n    69t\n    102t\n    -116t\n    -127t\n    -48t\n    42t\n    -31t\n    30t\n    38t\n    70t\n    -53t\n    74t\n    125t\n    35t\n    81t\n    26t\n    123t\n    -58t\n    -84t\n    27t\n    110t\n    -31t\n    87t\n    5t\n    -88t\n    -7t\n    -113t\n    -119t\n    -59t\n    -119t\n    -73t\n    -114t\n    -64t\n    88t\n    63t\n    30t\n    -77t\n    -91t\n    -58t\n    2t\n    79t\n    -29t\n    -11t\n    63t\n    26t\n    -12t\n    -64t\n    -68t\n    -68t\n    114t\n    -18t\n    -2t\n    72t\n    -33t\n    -98t\n    -23t\n    -12t\n    -13t\n    -119t\n    -82t\n    -103t\n    121t\n    90t\n    -46t\n    -43t\n    -83t\n    76t\n    2t\n    -41t\n    -12t\n    110t\n    -50t\n    0t\n    67t\n    5t\n    -113t\n    89t\n    78t\n    19t\n    108t\n    1t\n    73t\n    30t\n    1t\n    -46t\n    72t\n    52t\n    -34t\n    -64t\n    75t\n    -88t\n    58t\n    -127t\n    -120t\n    52t\n    -124t\n    -103t\n    -2t\n    -9t\n    -30t\n    -52t\n    -112t\n    80t\n    92t\n    -47t\n    116t\n    21t\n    13t\n    -6t\n    -79t\n    -124t\n    -80t\n    54t\n    -112t\n    -52t\n    125t\n    -28t\n    -61t\n    -61t\n    35t\n    -29t\n    -119t\n    39t\n    -43t\n    -69t\n    -48t\n    51t\n    49t\n    31t\n    29t\n    96t\n    122t\n    38t\n    64t\n    -39t\n    -23t\n    95t\n    100t\n    39t\n    -88t\n    62t\n    -76t\n    -84t\n    64t\n    -69t\n    -11t\n    97t\n    -18t\n    59t\n    -117t\n    48t\n    17t\n    99t\n    -55t\n    -40t\n    7t\n    94t\n    -12t\n    8t\n    87t\n    -78t\n    95t\n    -92t\n    122t\n    96t\n    7t\n    -80t\n    9t\n    112t\n    5t\n    -29t\n    -117t\n    70t\n    97t\n    17t\n    52t\n    88t\n    110t\n    -3t\n    69t\n    -74t\n    116t\n    124t\n    -89t\n    95t\n    -60t\n    47t\n    -17t\n    -123t\n    89t\n    -85t\n    -115t\n    117t\n    -40t\n    50t\n    40t\n    -53t\n    118t\n    57t\n    -54t\n    -40t\n    87t\n    95t\n    -33t\n    126t\n    -73t\n    46t\n    32t\n    -121t\n    8t\n    -100t\n    -60t\n    17t\n    -113t\n    83t\n    -89t\n    32t\n    99t\n    -58t\n    -11t\n    -75t\n    -13t\n    37t\n    105t\n    90t\n    117t\n    -89t\n    102t\n    -104t\n    91t\n    -96t\n    10t\n    -121t\n    19t\n    -86t\n    -76t\n    -107t\n    -104t\n    53t\n    -19t\n    -9t\n    -99t\n    71t\n    -71t\n    -25t\n    -29t\n    -43t\n    64t\n    77t\n    -32t\n    25t\n    -7t\n    -49t\n    -4t\n    -115t\n    -54t\n    -117t\n    125t\n    -69t\n    -23t\n    120t\n    47t\n    -34t\n    17t\n    -43t\n    -83t\n    -3t\n    58t\n    45t\n    15t\n    18t\n    54t\n    -125t\n    93t\n    -100t\n    -104t\n    -26t\n    -107t\n    -39t\n    116t\n    91t\n    68t\n    65t\n    35t\n    71t\n    63t\n    -6t\n    -101t\n    31t\n    -93t\n    76t\n    2t\n    -75t\n    -112t\n    -105t\n    51t\n    109t\n    62t\n    -20t\n    24t\n    -25t\n    22t\n    115t\n    82t\n    -11t\n    -47t\n    103t\n    -53t\n    -20t\n    113t\n    101t\n    -9t\n    -108t\n    20t\n    65t\n    63t\n    -8t\n    -61t\n    43t\n    -88t\n    -125t\n    -108t\n    37t\n    80t\n    -63t\n    118t\n    -114t\n    97t\n    96t\n    3t\n    -35t\n    30t\n    119t\n    8t\n    -104t\n    31t\n    -63t\n    47t\n    -28t\n    -91t\n    -109t\n    99t\n    70t\n    0t\n    13t\n    102t\n    -67t\n    95t\n    -13t\n    12t\n    115t\n    -72t\n    116t\n    -24t\n    -28t\n    -81t\n    -26t\n    29t\n    -123t\n    33t\n    77t\n    24t\n    46t\n    17t\n    -42t\n    -10t\n    3t\n    -120t\n    -116t\n    69t\n    8t\n    -36t\n    41t\n    -102t\n    100t\n    -125t\n    78t\n    26t\n    -83t\n    -102t\n    -121t\n    -70t\n    70t\n    76t\n    -35t\n    120t\n    9t\n    -44t\n    74t\n    -78t\n    -118t\n    26t\n    123t\n    -41t\n    -60t\n    -53t\n    -1t\n    76t\n    -123t\n    119t\n    -68t\n    107t\n    -5t\n    -115t\n    -11t\n    39t\n    52t\n    -52t\n    41t\n    33t\n    116t\n    33t\n    -79t\n    103t\n    59t\n    104t\n    30t\n    22t\n    -113t\n    92t\n    -101t\n    79t\n    -101t\n    40t\n    28t\n    60t\n    -26t\n    36t\n    105t\n    19t\n    40t\n    90t\n    102t\n    -128t\n    -38t\n    -24t\n    108t\n    36t\n    -3t\n    -76t\n    -119t\n    -123t\n    87t\n    87t\n    -18t\n    -15t\n    -118t\n    -9t\n    86t\n    56t\n    74t\n    -92t\n    -115t\n    98t\n    7t\n    98t\n    72t\n    37t\n    74t\n    -20t\n    -14t\n    -126t\n    30t\n    26t\n    -54t\n    -79t\n    -72t\n    53t\n    14t\n    -81t\n    72t\n    61t\n    74t\n    -27t\n    -1t\n    19t\n    -23t\n    100t\n    96t\n    16t\n    123t\n    -23t\n    -109t\n    -79t\n    -85t\n    119t\n    27t\n    26t\n    100t\n    11t\n    39t\n    56t\n    6t\n    -61t\n    34t\n    -63t\n    67t\n    -4t\n    67t\n    32t\n    -61t\n    82t\n    -79t\n    -56t\n    -83t\n    9t\n    -9t\n    -85t\n    62t\n    -38t\n    -50t\n    55t\n    106t\n    -30t\n    20t\n    -103t\n    -20t\n    69t\n    33t\n    -97t\n    91t\n    -72t\n    -64t\n    78t\n    -106t\n    25t\n    76t\n    13t\n    93t\n    -87t\n    -4t\n    3t\n    4t\n    -60t\n    61t\n    96t\n    -116t\n    126t\n    104t\n    59t\n    17t\n    -76t\n    99t\n    -86t\n    -9t\n    21t\n    125t\n    52t\n    4t\n    -35t\n    118t\n    -100t\n    8t\n    121t\n    -11t\n    -126t\n    -75t\n    -34t\n    65t\n    24t\n    -52t\n    71t\n    31t\n    78t\n    -98t\n    61t\n    -46t\n    -68t\n    -105t\n    121t\n    124t\n    37t\n    0t\n    61t\n    -11t\n    101t\n    21t\n    125t\n    27t\n    -18t\n    -108t\n    66t\n    -42t\n    -5t\n    -5t\n    12t\n    109t\n    6t\n    -63t\n    -118t\n    60t\n    -28t\n    93t\n    110t\n    73t\n    33t\n    -90t\n    23t\n    -67t\n    89t\n    90t\n    -76t\n    -96t\n    -95t\n    -30t\n    -49t\n    116t\n    -118t\n    -125t\n    -77t\n    -80t\n    3t\n    83t\n    -91t\n    -6t\n    126t\n    25t\n    -53t\n    97t\n    111t\n    45t\n    92t\n    -43t\n    56t\n    -96t\n    68t\n    -104t\n    83t\n    46t\n    116t\n    66t\n    123t\n    -23t\n    -105t\n    43t\n    76t\n    103t\n    -111t\n    37t\n    53t\n    -25t\n    66t\n    -45t\n    109t\n    -25t\n    22t\n    20t\n    -76t\n    -58t\n    68t\n    -23t\n    -95t\n    -126t\n    -84t\n    24t\n    24t\n    -67t\n    -99t\n    -14t\n    -11t\n    -25t\n    17t\n    3t\n    76t\n    126t\n    7t\n    91t\n    0t\n    78t\n    -63t\n    -78t\n    117t\n    31t\n    -37t\n    79t\n    88t\n    -112t\n    -97t\n    -71t\n    0t\n    70t\n    -21t\n    91t\n    70t\n    11t\n    60t\n    -66t\n    59t\n    -97t\n    -19t\n    28t\n    -64t\n    65t\n    8t\n    22t\n    77t\n    62t\n    -98t\n    -21t\n    61t\n    110t\n    36t\n    -28t\n    86t\n    18t\n    -127t\n    -25t\n    117t\n    84t\n    -72t\n    -76t\n    3t\n    88t\n    45t\n    -97t\n    37t\n    -76t\n    -93t\n    72t\n    52t\n    -116t\n    -11t\n    -114t\n    60t\n    32t\n    -54t\n    9t\n    -72t\n    -115t\n    53t\n    92t\n    -113t\n    -82t\n    -64t\n    -33t\n    87t\n    102t\n    -63t\n    -88t\n    108t\n    -17t\n    4t\n    -14t\n    45t\n    -77t\n    72t\n    -82t\n    32t\n    -70t\n    115t\n    -43t\n    40t\n    120t\n    -31t\n    15t\n    -57t\n    -34t\n    101t\n    -77t\n    42t\n    -89t\n    -11t\n    -39t\n    -112t\n    -47t\n    -22t\n    16t\n    -39t\n    79t\n    -108t\n    -3t\n    -88t\n    118t\n    53t\n    41t\n    37t\n    54t\n    71t\n    -119t\n    102t\n    91t\n    -32t\n    13t\n    -101t\n    -109t\n    71t\n    34t\n    -106t\n    -100t\n    -77t\n    13t\n    101t\n    91t\n    -54t\n    -5t\n    -63t\n    -71t\n    -121t\n    48t\n    -63t\n    22t\n    66t\n    -125t\n    -13t\n    110t\n    109t\n    -43t\n    61t\n    81t\n    99t\n    82t\n    -5t\n    -96t\n    -6t\n    -107t\n    -97t\n    -81t\n    0t\n    68t\n    -96t\n    49t\n    1t\n    84t\n    -59t\n    56t\n    -31t\n    92t\n    71t\n    -58t\n    11t\n    82t\n    -18t\n    -114t\n    -39t\n    -127t\n    40t\n    -42t\n    44t\n    -75t\n    104t\n    16t\n    88t\n    -13t\n    73t\n    -101t\n    -105t\n    58t\n    -15t\n    -57t\n    -39t\n    114t\n    -2t\n    -66t\n    -82t\n    45t\n    -14t\n    117t\n    -4t\n    108t\n    -115t\n    -122t\n    -46t\n    52t\n    1t\n    72t\n    120t\n    -86t\n    103t\n    -109t\n    -69t\n    64t\n    117t\n    38t\n    102t\n    105t\n    6t\n    69t\n    -24t\n    -3t\n    -106t\n    29t\n    -73t\n    -72t\n    -2t\n    54t\n    -114t\n    120t\n    0t\n    57t\n    -27t\n    29t\n    28t\n    36t\n    -57t\n    126t\n    23t\n    114t\n    10t\n    -86t\n    -3t\n    -11t\n    43t\n    86t\n    -122t\n    -93t\n    -29t\n    -49t\n    -72t\n    43t\n    103t\n    -22t\n    10t\n    -112t\n    111t\n    -85t\n    110t\n    -37t\n    46t\n    -107t\n    -121t\n    8t\n    51t\n    -73t\n    40t\n    -109t\n    80t\n    -127t\n    -125t\n    127t\n    63t\n    -51t\n    -12t\n    -19t\n    -37t\n    73t\n    -126t\n    55t\n    -81t\n    36t\n    -45t\n    46t\n    -57t\n    125t\n    -104t\n    36t\n    -121t\n    57t\n    59t\n    -45t\n    121t\n    -12t\n    75t\n    -74t\n    -36t\n    36t\n    -37t\n    -73t\n    12t\n    57t\n    -63t\n    89t\n    -93t\n    -26t\n    84t\n    112t\n    97t\n    125t\n    111t\n    47t\n    86t\n    22t\n    65t\n    -118t\n    -114t\n    80t\n    115t\n    107t\n    82t\n    -91t\n    47t\n    -99t\n    113t\n    -9t\n    -97t\n    37t\n    63t\n    53t\n    -55t\n    127t\n    -112t\n    45t\n    62t\n    -80t\n    -1t\n    45t\n    -106t\n    57t\n    57t\n    -87t\n    -6t\n    90t\n    64t\n    38t\n    -51t\n    -75t\n    46t\n    -100t\n    19t\n    24t\n    -13t\n    31t\n    -16t\n    -10t\n    -32t\n    7t\n    -99t\n    -32t\n    -77t\n    -49t\n    62t\n    -69t\n    103t\n    -28t\n    70t\n    105t\n    96t\n    -11t\n    -100t\n    34t\n    -49t\n    50t\n    -96t\n    118t\n    -47t\n    12t\n    58t\n    -117t\n    -96t\n    8t\n    127t\n    87t\n    33t\n    25t\n    -123t\n    67t\n    -37t\n    -118t\n    107t\n    -117t\n    93t\n    30t\n    -41t\n    -95t\n    -77t\n    -57t\n    -102t\n    -44t\n    62t\n    -111t\n    -55t\n    28t\n    -42t\n    -33t\n    -63t\n    -19t\n    -63t\n    -44t\n    -117t\n    -15t\n    -108t\n    81t\n    11t\n    7t\n    -70t\n    106t\n    57t\n    -67t\n    14t\n    -67t\n    -79t\n    -64t\n    -114t\n    -97t\n    -19t\n    25t\n    -1t\n    106t\n    -112t\n    -105t\n    79t\n    -126t\n    35t\n    -98t\n    0t\n    -43t\n    -89t\n    91t\n    -93t\n    -21t\n    68t\n    -7t\n    -29t\n    109t\n    -44t\n    116t\n    -69t\n    103t\n    -85t\n    116t\n    -122t\n    53t\n    -8t\n    119t\n    -85t\n    104t\n    -107t\n    52t\n    107t\n    -62t\n    109t\n    77t\n    -2t\n    110t\n    -96t\n    -46t\n    63t\n    -84t\n    -45t\n    120t\n    15t\n    85t\n    -1t\n    -89t\n    -83t\n    -60t\n    93t\n    -92t\n    108t\n    52t\n    -96t\n    -113t\n    2t\n    111t\n    47t\n    49t\n    22t\n    116t\n    -115t\n    -10t\n    -25t\n    -45t\n    -43t\n    91t\n    -59t\n    -58t\n    -86t\n    99t\n    -25t\n    -86t\n    -93t\n    -115t\n    -95t\n    -93t\n    114t\n    122t\n    -108t\n    -96t\n    15t\n    64t\n    -5t\n    103t\n    71t\n    45t\n    -99t\n    -82t\n    -15t\n    -120t\n    42t\n    107t\n    64t\n    -95t\n    -53t\n    -60t\n    -1t\n    -118t\n    -27t\n    5t\n    -17t\n    106t\n    -128t\n    63t\n    -63t\n    71t\n    -19t\n    51t\n    23t\n    97t\n    16t\n    -101t\n    88t\n    -68t\n    22t\n    -99t\n    -108t\n    117t\n    46t\n    -32t\n    99t\n    7t\n    -113t\n    118t\n    92t\n    117t\n    -98t\n    -27t\n    41t\n    114t\n    7t\n    86t\n    2t\n    43t\n    -67t\n    -108t\n    -45t\n    24t\n    -101t\n    35t\n    -98t\n    -61t\n    44t\n    13t\n    67t\n    -46t\n    -68t\n    -19t\n    -88t\n    -114t\n    -15t\n    87t\n    40t\n    99t\n    -119t\n    -54t\n    37t\n    -110t\n    -17t\n    31t\n    -39t\n    -11t\n    -61t\n    39t\n    -72t\n    -18t\n    68t\n    59t\n    -20t\n    -72t\n    -85t\n    -84t\n    117t\n    -94t\n    37t\n    97t\n    82t\n    96t\n    -92t\n    -73t\n    -87t\n    -26t\n    124t\n    -14t\n    -35t\n    -7t\n    52t\n    80t\n    19t\n    66t\n    -30t\n    24t\n    86t\n    -17t\n    91t\n    -60t\n    -81t\n    66t\n    -62t\n    -16t\n    -68t\n    32t\n    57t\n    27t\n    92t\n    105t\n    -53t\n    50t\n    86t\n    105t\n    -10t\n    -91t\n    127t\n    47t\n    -22t\n    98t\n    -114t\n    -26t\n    -4t\n    -85t\n    -103t\n    -10t\n    60t\n    -10t\n    -118t\n    81t\n    27t\n    -92t\n    -65t\n    99t\n    33t\n    -4t\n    74t\n    -61t\n    -19t\n    127t\n    -87t\n    108t\n    93t\n    115t\n    -90t\n    0t\n    -101t\n    65t\n    89t\n    68t\n    -32t\n    40t\n    -18t\n    6t\n    11t\n    114t\n    -116t\n    67t\n    119t\n    60t\n    6t\n    -88t\n    -84t\n    -10t\n    120t\n    116t\n    -119t\n    39t\n    72t\n    -16t\n    -52t\n    60t\n    85t\n    -38t\n    117t\n    -6t\n    125t\n    -85t\n    103t\n    29t\n    41t\n    -115t\n    -74t\n    -64t\n    117t\n    -128t\n    -4t\n    77t\n    -22t\n    112t\n    45t\n    58t\n    71t\n    -69t\n    -125t\n    49t\n    94t\n    -57t\n    -4t\n    25t\n    115t\n    51t\n    5t\n    -13t\n    -27t\n    14t\n    104t\n    80t\n    48t\n    -14t\n    108t\n    89t\n    -61t\n    -85t\n    -16t\n    -25t\n    63t\n    -70t\n    83t\n    -89t\n    -119t\n    -107t\n    127t\n    -86t\n    43t\n    -41t\n    75t\n    -65t\n    95t\n    63t\n    -79t\n    -122t\n    -25t\n    -58t\n    45t\n    58t\n    18t\n    88t\n    25t\n    5t\n    -69t\n    -68t\n    14t\n    -12t\n    -53t\n    -127t\n    -78t\n    -122t\n    87t\n    70t\n    -59t\n    -69t\n    -60t\n    90t\n    -19t\n    -70t\n    -60t\n    -104t\n    -81t\n    102t\n    -65t\n    -60t\n    18t\n    -5t\n    31t\n    54t\n    -28t\n    92t\n    38t\n    27t\n    -19t\n    -76t\n    -48t\n    -87t\n    16t\n    -59t\n    58t\n    55t\n    -35t\n    43t\n    -119t\n    81t\n    -93t\n    117t\n    94t\n    -62t\n    -106t\n    41t\n    23t\n    76t\n    75t\n    -13t\n    -23t\n    -3t\n    101t\n    71t\n    -31t\n    38t\n    -82t\n    40t\n    16t\n    -93t\n    -18t\n    41t\n    97t\n    4t\n    -30t\n    97t\n    105t\n    -73t\n    125t\n    -5t\n    -4t\n    93t\n    -17t\n    127t\n    -80t\n    -51t\n    127t\n    52t\n    -7t\n    12t\n    -73t\n    29t\n    118t\n    -126t\n    8t\n    -57t\n    80t\n    -28t\n    -63t\n    12t\n    -60t\n    -123t\n    -26t\n    -74t\n    2t\n    64t\n    -25t\n    27t\n    -18t\n    -74t\n    -74t\n    -103t\n    -103t\n    -70t\n    -11t\n    -67t\n    -54t\n    48t\n    -105t\n    89t\n    111t\n    -27t\n    -37t\n    -92t\n    68t\n    -73t\n    23t\n    -87t\n    -15t\n    68t\n    78t\n    -69t\n    45t\n    106t\n    -122t\n    108t\n    102t\n    -84t\n    74t\n    -84t\n    27t\n    -99t\n    -104t\n    0t\n    49t\n    43t\n    -2t\n    -3t\n    54t\n    -82t\n    115t\n    -80t\n    -84t\n    -27t\n    17t\n    62t\n    -59t\n    -125t\n    104t\n    60t\n    -110t\n    119t\n    123t\n    88t\n    -12t\n    81t\n    95t\n    -40t\n    -70t\n    126t\n    -60t\n    58t\n    -3t\n    14t\n    93t\n    -33t\n    107t\n    -97t\n    -43t\n    -29t\n    4t\n    102t\n    -123t\n    14t\n    89t\n    -34t\n    -70t\n    32t\n    117t\n    -69t\n    110t\n    47t\n    38t\n    -4t\n    121t\n    -119t\n    -51t\n    56t\n    -46t\n    -93t\n    -41t\n    -80t\n    79t\n    46t\n    -74t\n    61t\n    -103t\n    110t\n    52t\n    126t\n    76t\n    122t\n    -49t\n    96t\n    113t\n    -24t\n    54t\n    65t\n    -92t\n    2t\n    -125t\n    -101t\n    -101t\n    97t\n    110t\n    -5t\n    -76t\n    87t\n    -20t\n    -2t\n    -90t\n    36t\n    22t\n    105t\n    29t\n    -80t\n    -64t\n    -109t\n    14t\n    82t\n    -117t\n    66t\n    -127t\n    -124t\n    -58t\n    -97t\n    22t\n    -44t\n    89t\n    75t\n    115t\n    -19t\n    -98t\n    -102t\n    -25t\n    -99t\n    122t\n    -29t\n    72t\n    -30t\n    -40t\n    -13t\n    80t\n    -79t\n    -21t\n    -102t\n    41t\n    -93t\n    97t\n    112t\n    53t\n    -50t\n    -54t\n    -41t\n    -120t\n    -116t\n    -20t\n    -99t\n    11t\n    65t\n    -1t\n    -42t\n    14t\n    -41t\n    -118t\n    109t\n    -17t\n    -110t\n    15t\n    104t\n    67t\n    96t\n    100t\n    -98t\n    -38t\n    -46t\n    104t\n    -46t\n    48t\n    51t\n    -65t\n    -16t\n    -115t\n    64t\n    37t\n    -89t\n    117t\n    8t\n    -34t\n    74t\n    -37t\n    -106t\n    -90t\n    52t\n    78t\n    57t\n    -77t\n    -89t\n    113t\n    -37t\n    -118t\n    72t\n    -12t\n    19t\n    -62t\n    -94t\n    121t\n    -30t\n    49t\n    124t\n    59t\n    -33t\n    -87t\n    120t\n    75t\n    -92t\n    49t\n    3t\n    -91t\n    -3t\n    26t\n    75t\n    -68t\n    -61t\n    112t\n    -75t\n    21t\n    -80t\n    -30t\n    -54t\n    -69t\n    9t\n    18t\n    -124t\n    -113t\n    -61t\n    -90t\n    -118t\n    118t\n    -46t\n    91t\n    31t\n    -49t\n    17t\n    -98t\n    -124t\n    -39t\n    100t\n    -113t\n    -27t\n    6t\n    0t\n    63t\n    -63t\n    118t\n    16t\n    -122t\n    98t\n    -62t\n    112t\n    -93t\n    -115t\n    23t\n    90t\n    19t\n    88t\n    11t\n    121t\n    -117t\n    95t\n    43t\n    74t\n    -75t\n    75t\n    30t\n    -92t\n    91t\n    116t\n    52t\n    47t\n    125t\n    -50t\n    -28t\n    -46t\n    -73t\n    84t\n    -101t\n    111t\n    101t\n    43t\n    75t\n    -110t\n    87t\n    -61t\n    5t\n    -84t\n    58t\n    -112t\n    68t\n    41t\n    29t\n    83t\n    -49t\n    -90t\n    -106t\n    -70t\n    84t\n    118t\n    -127t\n    16t\n    -83t\n    -106t\n    -96t\n    -7t\n    -57t\n    94t\n    16t\n    -71t\n    -8t\n    -88t\n    112t\n    17t\n    -36t\n    -50t\n    58t\n    -116t\n    43t\n    61t\n    -64t\n    -95t\n    78t\n    17t\n    112t\n    -36t\n    -6t\n    -121t\n    -61t\n    23t\n    88t\n    76t\n    -97t\n    -51t\n    -119t\n    109t\n    119t\n    -107t\n    -21t\n    -55t\n    -55t\n    101t\n    -16t\n    87t\n    -29t\n    119t\n    -80t\n    96t\n    46t\n    -65t\n    -3t\n    -90t\n    105t\n    98t\n    -48t\n    -126t\n    -118t\n    104t\n    -67t\n    68t\n    45t\n    -74t\n    -59t\n    52t\n    16t\n    -50t\n    -128t\n    -7t\n    -91t\n    -36t\n    109t\n    -19t\n    51t\n    126t\n    51t\n    -113t\n    -86t\n    -36t\n    44t\n    48t\n    106t\n    -2t\n    53t\n    -108t\n    10t\n    -25t\n    87t\n    53t\n    75t\n    105t\n    -94t\n    1t\n    -65t\n    44t\n    66t\n    -77t\n    112t\n    0t\n    2t\n    56t\n    80t\n    38t\n    -83t\n    74t\n    30t\n    81t\n    0t\n    -123t\n    104t\n    -22t\n    44t\n    -79t\n    81t\n    77t\n    -32t\n    49t\n    -39t\n    121t\n    -81t\n    107t\n    106t\n    -72t\n    -98t\n    -44t\n    -81t\n    -110t\n    -98t\n    -72t\n    105t\n    -1t\n    -125t\n    -20t\n    -19t\n    -84t\n    65t\n    -58t\n    -54t\n    -115t\n    93t\n    51t\n    -78t\n    30t\n    -111t\n    1t\n    45t\n    -10t\n    103t\n    47t\n    -43t\n    -71t\n    -17t\n    75t\n    63t\n    -112t\n    27t\n    -83t\n    -105t\n    -22t\n    64t\n    91t\n    121t\n    48t\n    91t\n    42t\n    -47t\n    -44t\n    1t\n    104t\n    93t\n    124t\n    65t\n    -4t\n    -95t\n    94t\n    120t\n    109t\n    52t\n    73t\n    26t\n    92t\n    50t\n    64t\n    -76t\n    -62t\n    -9t\n    87t\n    -120t\n    -116t\n    110t\n    -104t\n    -109t\n    -102t\n    -23t\n    -78t\n    -38t\n    -22t\n    50t\n    -96t\n    -108t\n    -113t\n    -107t\n    -76t\n    18t\n    -15t\n    -46t\n    -17t\n    -33t\n    -90t\n    38t\n    -82t\n    -102t\n    -127t\n    -80t\n    86t\n    -44t\n    75t\n    -109t\n    61t\n    -102t\n    55t\n    75t\n    -16t\n    -86t\n    -5t\n    -63t\n    -58t\n    41t\n    -92t\n    -53t\n    36t\n    -96t\n    109t\n    108t\n    -36t\n    -100t\n    83t\n    10t\n    -87t\n    78t\n    12t\n    69t\n    -94t\n    -120t\n    -3t\n    42t\n    12t\n    -74t\n    60t\n    -18t\n    117t\n    101t\n    -62t\n    -93t\n    24t\n    -93t\n    13t\n    104t\n    -72t\n    -116t\n    10t\n    83t\n    43t\n    104t\n    -52t\n    -78t\n    -63t\n    -25t\n    62t\n    124t\n    -57t\n    107t\n    -127t\n    -89t\n    122t\n    -104t\n    -51t\n    99t\n    40t\n    -126t\n    -84t\n    -102t\n    -33t\n    -15t\n    11t\n    50t\n    102t\n    -118t\n    100t\n    33t\n    -82t\n    77t\n    -47t\n    0t\n    62t\n    -88t\n    27t\n    -35t\n    -66t\n    118t\n    -97t\n    -4t\n    113t\n    -15t\n    -40t\n    57t\n    5t\n    25t\n    -65t\n    75t\n    79t\n    104t\n    80t\n    95t\n    12t\n    119t\n    -49t\n    -74t\n    -66t\n    -72t\n    57t\n    -35t\n    -3t\n    52t\n    15t\n    6t\n    65t\n    -16t\n    -8t\n    -89t\n    -64t\n    35t\n    -33t\n    69t\n    -106t\n    106t\n    29t\n    94t\n    88t\n    9t\n    115t\n    -73t\n    56t\n    7t\n    -87t\n    -117t\n    -13t\n    -18t\n    -42t\n    112t\n    98t\n    -24t\n    -66t\n    -75t\n    118t\n    -8t\n    -74t\n    30t\n    -92t\n    -125t\n    -115t\n    93t\n    17t\n    71t\n    -46t\n    121t\n    -82t\n    86t\n    119t\n    64t\n    -54t\n    51t\n    98t\n    -69t\n    -97t\n    56t\n    117t\n    -39t\n    -6t\n    25t\n    96t\n    30t\n    125t\n    9t\n    39t\n    9t\n    -110t\n    -69t\n    -109t\n    -61t\n    -10t\n    -57t\n    87t\n    -22t\n    -37t\n    -67t\n    64t\n    2t\n    -10t\n    -83t\n    -126t\n    -116t\n    74t\n    34t\n    47t\n    -83t\n    -117t\n    -56t\n    82t\n    -4t\n    -100t\n    32t\n    -30t\n    34t\n    -81t\n    -64t\n    31t\n    -68t\n    124t\n    22t\n    52t\n    109t\n    8t\n    35t\n    60t\n    103t\n    -110t\n    70t\n    6t\n    36t\n    -79t\n    13t\n    24t\n    -22t\n    75t\n    -112t\n    -62t\n    58t\n    -63t\n    58t\n    10t\n    115t\n    54t\n    57t\n    123t\n    46t\n    -22t\n    -115t\n    -68t\n    44t\n    98t\n    -115t\n    43t\n    86t\n    115t\n    63t\n    -109t\n    -89t\n    102t\n    41t\n    67t\n    77t\n    -27t\n    97t\n    93t\n    -76t\n    -63t\n    45t\n    -94t\n    62t\n    -82t\n    -56t\n    -26t\n    106t\n    -123t\n    27t\n    55t\n    2t\n    122t\n    126t\n    18t\n    67t\n    -1t\n    111t\n    -27t\n    122t\n    69t\n    -10t\n    54t\n    -86t\n    -103t\n    -14t\n    83t\n    -58t\n    -49t\n    2t\n    -57t\n    -89t\n    -115t\n    -108t\n    -125t\n    -73t\n    112t\n    113t\n    -78t\n    25t\n    -16t\n    -121t\n    18t\n    92t\n    -1t\n    -103t\n    101t\n    74t\n    112t\n    -36t\n    -114t\n    122t\n    -119t\n    -1t\n    -118t\n    -54t\n    -36t\n    -111t\n    -101t\n    30t\n    7t\n    -50t\n    -13t\n    -103t\n    23t\n    -119t\n    -83t\n    -105t\n    31t\n    119t\n    -123t\n    85t\n    58t\n    13t\n    -51t\n    95t\n    126t\n    69t\n    83t\n    -30t\n    34t\n    10t\n    -2t\n    -52t\n    -82t\n    15t\n    -60t\n    67t\n    45t\n    99t\n    23t\n    7t\n    16t\n    -10t\n    -36t\n    24t\n    44t\n    2t\n    -4t\n    -56t\n    64t\n    82t\n    -79t\n    -97t\n    -30t\n    81t\n    95t\n    44t\n    76t\n    51t\n    -21t\n    -33t\n    90t\n    11t\n    21t\n    81t\n    112t\n    92t\n    45t\n    49t\n    -116t\n    0t\n    99t\n    -19t\n    -18t\n    82t\n    41t\n    -11t\n    -51t\n    -78t\n    -41t\n    -51t\n    109t\n    93t\n    96t\n    -31t\n    108t\n    25t\n    59t\n    43t\n    -61t\n    94t\n    -113t\n    120t\n    111t\n    107t\n    -77t\n    -23t\n    89t\n    -120t\n    -25t\n    62t\n    -114t\n    95t\n    -50t\n    -108t\n    -49t\n    -13t\n    -48t\n    -83t\n    -103t\n    -68t\n    -106t\n    -106t\n    118t\n    -59t\n    127t\n    -9t\n    41t\n    9t\n    -47t\n    -76t\n    67t\n    -43t\n    17t\n    -108t\n    -126t\n    -2t\n    -100t\n    66t\n    116t\n    -50t\n    80t\n    -73t\n    87t\n    39t\n    -67t\n    24t\n    32t\n    23t\n    -37t\n    -101t\n    -64t\n    40t\n    -109t\n    27t\n    116t\n    -20t\n    2t\n    -122t\n    -47t\n    63t\n    -20t\n    -46t\n    -13t\n    41t\n    28t\n    70t\n    -122t\n    -127t\n    -15t\n    -40t\n    48t\n    -13t\n    70t\n    66t\n    13t\n    58t\n    0t\n    94t\n    72t\n    44t\n    -21t\n    -65t\n    72t\n    -97t\n    -13t\n    101t\n    78t\n    4t\n    -72t\n    -12t\n    -38t\n    -112t\n    55t\n    115t\n    6t\n    -29t\n    78t\n    97t\n    43t\n    -105t\n    -87t\n    -34t\n    102t\n    53t\n    -55t\n    -56t\n    73t\n    101t\n    21t\n    47t\n    -8t\n    44t\n    26t\n    79t\n    76t\n    -101t\n    -92t\n    -99t\n    -113t\n    49t\n    63t\n    5t\n    -81t\n    -28t\n    -82t\n    13t\n    -85t\n    7t\n    113t\n    -60t\n    -82t\n    -61t\n    -114t\n    -31t\n    75t\n    13t\n    -43t\n    -21t\n    44t\n    -34t\n    -23t\n    41t\n    103t\n    54t\n    51t\n    39t\n    -71t\n    -7t\n    -128t\n    -121t\n    -123t\n    -16t\n    32t\n    -95t\n    78t\n    24t\n    33t\n    41t\n    86t\n    -41t\n    -6t\n    -21t\n    -118t\n    -116t\n    36t\n    47t\n    -93t\n    69t\n    66t\n    -90t\n    95t\n    119t\n    94t\n    44t\n    116t\n    20t\n    33t\n    -16t\n    -70t\n    -120t\n    -15t\n    126t\n    -56t\n    93t\n    16t\n    -3t\n    96t\n    57t\n    56t\n    -58t\n    7t\n    0t\n    -54t\n    -52t\n    58t\n    -18t\n    -65t\n    -71t\n    -19t\n    -65t\n    -42t\n    6t\n    -59t\n    22t\n    -33t\n    -119t\n    25t\n    -39t\n    116t\n    14t\n    111t\n    -95t\n    -60t\n    72t\n    -6t\n    -7t\n    -17t\n    12t\n    -82t\n    40t\n    -103t\n    -101t\n    101t\n    -58t\n    117t\n    55t\n    103t\n    -82t\n    -124t\n    15t\n    111t\n    20t\n    87t\n    -99t\n    -125t\n    -117t\n    -96t\n    18t\n    45t\n    117t\n    81t\n    18t\n    -90t\n    102t\n    98t\n    75t\n    -123t\n    39t\n    -33t\n    116t\n    26t\n    26t\n    -77t\n    -35t\n    48t\n    8t\n    -123t\n    -101t\n    -96t\n    61t\n    -15t\n    87t\n    101t\n    -61t\n    -4t\n    105t\n    -100t\n    112t\n    -39t\n    99t\n    -10t\n    -25t\n    85t\n    49t\n    120t\n    80t\n    94t\n    59t\n    59t\n    80t\n    21t\n    -126t\n    21t\n    98t\n    83t\n    105t\n    -105t\n    46t\n    -56t\n    -25t\n    -63t\n    -3t\n    28t\n    19t\n    -34t\n    -3t\n    -65t\n    24t\n    -41t\n    -96t\n    -44t\n    104t\n    89t\n    27t\n    -128t\n    -38t\n    69t\n    23t\n    -76t\n    -29t\n    -31t\n    95t\n    -80t\n    -101t\n    104t\n    -70t\n    -8t\n    -100t\n    104t\n    -88t\n    2t\n    -50t\n    -30t\n    -8t\n    -32t\n    -128t\n    -32t\n    -82t\n    -71t\n    -82t\n    85t\n    -115t\n    -108t\n    16t\n    -85t\n    109t\n    -51t\n    55t\n    -45t\n    -2t\n    0t\n    -28t\n    -43t\n    -97t\n    -122t\n    -45t\n    76t\n    -87t\n    -25t\n    -127t\n    81t\n    -103t\n    75t\n    -65t\n    74t\n    72t\n    -39t\n    41t\n    -55t\n    90t\n    120t\n    0t\n    1t\n    125t\n    95t\n    -62t\n    105t\n    -44t\n    4t\n    79t\n    -74t\n    92t\n    14t\n    55t\n    97t\n    -51t\n    105t\n    49t\n    33t\n    -56t\n    -69t\n    98t\n    0t\n    -81t\n    -108t\n    -62t\n    45t\n    -121t\n    17t\n    -38t\n    -128t\n    -79t\n    105t\n    -128t\n    -57t\n    -118t\n    36t\n    -40t\n    -79t\n    112t\n    109t\n    7t\n    -105t\n    -92t\n    110t\n    71t\n    122t\n    -97t\n    43t\n    -44t\n    -59t\n    49t\n    26t\n    65t\n    -105t\n    96t\n    -3t\n    -120t\n    44t\n    19t\n    -93t\n    7t\n    25t\n    -48t\n    -16t\n    41t\n    -44t\n    -60t\n    -78t\n    14t\n    -22t\n    -4t\n    46t\n    -88t\n    13t\n    -126t\n    107t\n    10t\n    62t\n    11t\n    78t\n    -111t\n    -7t\n    -60t\n    87t\n    11t\n    48t\n    53t\n    -9t\n    74t\n    -5t\n    79t\n    91t\n    39t\n    -125t\n    41t\n    -86t\n    115t\n    -23t\n    -74t\n    79t\n    121t\n    -64t\n    106t\n    -30t\n    40t\n    -32t\n    -20t\n    -21t\n    -32t\n    6t\n    105t\n    57t\n    -110t\n    -95t\n    81t\n    88t\n    -120t\n    118t\n    -80t\n    -4t\n    125t\n    -105t\n    76t\n    117t\n    -86t\n    26t\n    79t\n    -8t\n    -69t\n    62t\n    91t\n    -20t\n    118t\n    -111t\n    84t\n    77t\n    47t\n    -78t\n    -109t\n    102t\n    -19t\n    39t\n    38t\n    88t\n    94t\n    -85t\n    -88t\n    -81t\n    -122t\n    -15t\n    -1t\n    89t\n    -85t\n    125t\n    -121t\n    -95t\n    29t\n    35t\n    52t\n    -64t\n    14t\n    116t\n    -63t\n    -4t\n    -76t\n    83t\n    -122t\n    -19t\n    -109t\n    107t\n    35t\n    -35t\n    -39t\n    -39t\n    -60t\n    -29t\n    71t\n    -29t\n    113t\n    -39t\n    8t\n    63t\n    -114t\n    -128t\n    16t\n    -122t\n    48t\n    -19t\n    -89t\n    101t\n    59t\n    -110t\n    36t\n    -89t\n    -110t\n    -35t\n    -20t\n    -73t\n    72t\n    -57t\n    -56t\n    -127t\n    -87t\n    21t\n    60t\n    -119t\n    -75t\n    115t\n    120t\n    -118t\n    15t\n    -3t\n    33t\n    -122t\n    45t\n    105t\n    92t\n    -29t\n    104t\n    88t\n    7t\n    -87t\n    43t\n    -87t\n    -86t\n    68t\n    -2t\n    -114t\n    36t\n    -85t\n    51t\n    -120t\n    -61t\n    -26t\n    -2t\n    121t\n    96t\n    20t\n    15t\n    -60t\n    -55t\n    97t\n    -100t\n    100t\n    -15t\n    -85t\n    -4t\n    -107t\n    -91t\n    59t\n    -94t\n    -48t\n    71t\n    39t\n    -69t\n    29t\n    19t\n    -90t\n    39t\n    -95t\n    -17t\n    33t\n    47t\n    -37t\n    -121t\n    -23t\n    13t\n    -31t\n    -70t\n    -80t\n    -83t\n    15t\n    -88t\n    9t\n    -3t\n    -101t\n    -111t\n    67t\n    -8t\n    115t\n    -20t\n    -70t\n    17t\n    -21t\n    30t\n    62t\n    -97t\n    66t\n    90t\n    4t\n    34t\n    -65t\n    -83t\n    -56t\n    -17t\n    97t\n    12t\n    16t\n    -80t\n    80t\n    -117t\n    54t\n    79t\n    -77t\n    66t\n    -108t\n    6t\n    -96t\n    9t\n    4t\n    110t\n    52t\n    -89t\n    119t\n    -99t\n    -13t\n    -65t\n    116t\n    -28t\n    82t\n    -24t\n    101t\n    1t\n    104t\n    52t\n    8t\n    -15t\n    122t\n    10t\n    22t\n    -21t\n    -60t\n    -128t\n    -64t\n    -100t\n    44t\n    -11t\n    -94t\n    94t\n    -116t\n    -80t\n    -83t\n    -72t\n    -84t\n    -117t\n    1t\n    -115t\n    -100t\n    125t\n    -39t\n    -35t\n    -16t\n    110t\n    39t\n    -43t\n    -113t\n    64t\n    -70t\n    -24t\n    -55t\n    22t\n    106t\n    76t\n    97t\n    -95t\n    38t\n    69t\n    -119t\n    -104t\n    2t\n    -111t\n    89t\n    -84t\n    97t\n    -102t\n    32t\n    81t\n    105t\n    -47t\n    19t\n    102t\n    -87t\n    48t\n    47t\n    -17t\n    81t\n    116t\n    70t\n    124t\n    -20t\n    127t\n    -99t\n    -56t\n    1t\n    45t\n    61t\n    -30t\n    -100t\n    107t\n    7t\n    -117t\n    -65t\n    -86t\n    107t\n    112t\n    -85t\n    -127t\n    98t\n    -26t\n    -109t\n    -4t\n    -48t\n    -60t\n    38t\n    -9t\n    63t\n    81t\n    14t\n    65t\n    -70t\n    -59t\n    -48t\n    -101t\n    54t\n    61t\n    112t\n    -16t\n    -70t\n    -38t\n    -88t\n    100t\n    -8t\n    8t\n    -54t\n    -43t\n    6t\n    -41t\n    -105t\n    -31t\n    121t\n    79t\n    -122t\n    63t\n    63t\n    -64t\n    -73t\n    122t\n    115t\n    -3t\n    118t\n    -115t\n    97t\n    -21t\n    24t\n    29t\n    34t\n    -68t\n    -30t\n    24t\n    111t\n    36t\n    93t\n    70t\n    26t\n    -84t\n    -127t\n    -50t\n    11t\n    -62t\n    50t\n    78t\n    75t\n    -92t\n    108t\n    -54t\n    86t\n    31t\n    -19t\n    -34t\n    61t\n    -106t\n    64t\n    44t\n    -110t\n    -56t\n    -117t\n    -40t\n    -87t\n    121t\n    -68t\n    51t\n    81t\n    26t\n    27t\n    112t\n    44t\n    -121t\n    73t\n    31t\n    126t\n    -62t\n    97t\n    18t\n    -24t\n    -77t\n    -120t\n    21t\n    22t\n    7t\n    -14t\n    102t\n    15t\n    -13t\n    -123t\n    104t\n    -93t\n    -69t\n    95t\n    -79t\n    -30t\n    -100t\n    -46t\n    -118t\n    -103t\n    21t\n    42t\n    76t\n    -56t\n    -9t\n    -33t\n    26t\n    -39t\n    -95t\n    38t\n    -7t\n    -56t\n    -126t\n    -45t\n    -107t\n    -91t\n    34t\n    -126t\n    -43t\n    -114t\n    36t\n    -76t\n    78t\n    22t\n    80t\n    66t\n    100t\n    -5t\n    -12t\n    121t\n    119t\n    -31t\n    19t\n    -17t\n    89t\n    -73t\n    104t\n    103t\n    -38t\n    -113t\n    64t\n    -108t\n    -28t\n    -115t\n    91t\n    -105t\n    15t\n    -45t\n    47t\n    114t\n    66t\n    -117t\n    29t\n    -87t\n    -126t\n    119t\n    11t\n    -82t\n    57t\n    -86t\n    11t\n    29t\n    -104t\n    75t\n    90t\n    -21t\n    85t\n    13t\n    48t\n    88t\n    -75t\n    -87t\n    117t\n    92t\n    105t\n    -60t\n    -47t\n    106t\n    -58t\n    19t\n    -59t\n    41t\n    23t\n    19t\n    -118t\n    22t\n    -8t\n    -61t\n    118t\n    -30t\n    75t\n    -97t\n    58t\n    61t\n    -55t\n    -90t\n    -48t\n    -75t\n    -37t\n    2t\n    -84t\n    -62t\n    -66t\n    -83t\n    -16t\n    31t\n    42t\n    125t\n    31t\n    32t\n    -13t\n    106t\n    -100t\n    26t\n    102t\n    13t\n    -60t\n    86t\n    -91t\n    -106t\n    -71t\n    -20t\n    43t\n    70t\n    -85t\n    -50t\n    -114t\n    -101t\n    102t\n    -94t\n    -31t\n    109t\n    103t\n    -88t\n    35t\n    28t\n    103t\n    -115t\n    -66t\n    63t\n    103t\n    89t\n    -26t\n    46t\n    39t\n    -80t\n    0t\n    -68t\n    30t\n    -19t\n    -96t\n    -84t\n    -89t\n    107t\n    74t\n    38t\n    -91t\n    -42t\n    -65t\n    84t\n    47t\n    4t\n    -53t\n    -6t\n    -106t\n    77t\n    -48t\n    -44t\n    102t\n    30t\n    -101t\n    75t\n    -67t\n    50t\n    61t\n    -62t\n    -32t\n    -7t\n    -19t\n    9t\n    -39t\n    -117t\n    113t\n    -12t\n    115t\n    -22t\n    58t\n    64t\n    20t\n    84t\n    73t\n    25t\n    -32t\n    117t\n    -8t\n    -28t\n    73t\n    49t\n    -94t\n    28t\n    -80t\n    -86t\n    -34t\n    111t\n    26t\n    -31t\n    -52t\n    109t\n    -33t\n    127t\n    15t\n    80t\n    66t\n    118t\n    86t\n    1t\n    -93t\n    -53t\n    30t\n    -70t\n    -56t\n    -1t\n    85t\n    -62t\n    -40t\n    116t\n    -127t\n    -11t\n    -18t\n    57t\n    -84t\n    -20t\n    67t\n    -94t\n    118t\n    107t\n    24t\n    -126t\n    -76t\n    -116t\n    116t\n    -30t\n    -61t\n    -111t\n    -84t\n    -35t\n    -69t\n    -82t\n    75t\n    -123t\n    8t\n    -123t\n    -1t\n    37t\n    34t\n    -27t\n    6t\n    -103t\n    114t\n    -78t\n    -87t\n    70t\n    -88t\n    -68t\n    116t\n    -1t\n    110t\n    70t\n    105t\n    -5t\n    98t\n    -47t\n    -13t\n    41t\n    61t\n    -84t\n    74t\n    99t\n    28t\n    -62t\n    33t\n    91t\n    -58t\n    37t\n    -12t\n    -101t\n    -68t\n    59t\n    66t\n    -4t\n    27t\n    36t\n    119t\n    -128t\n    122t\n    40t\n    -64t\n    -11t\n    127t\n    -121t\n    -61t\n    14t\n    -6t\n    -78t\n    -111t\n    34t\n    -89t\n    -117t\n    -12t\n    101t\n    -98t\n    65t\n    -128t\n    123t\n    -46t\n    -119t\n    9t\n    -64t\n    -7t\n    113t\n    -47t\n    106t\n    39t\n    -82t\n    13t\n    -2t\n    -88t\n    -79t\n    72t\n    -117t\n    -9t\n    74t\n    -94t\n    -110t\n    -21t\n    117t\n    70t\n    59t\n    110t\n    -8t\n    69t\n    90t\n    -19t\n    66t\n    85t\n    -114t\n    92t\n    34t\n    79t\n    41t\n    60t\n    39t\n    33t\n    -49t\n    39t\n    -85t\n    -66t\n    98t\n    -69t\n    88t\n    118t\n    -66t\n    -109t\n    -93t\n    -32t\n    51t\n    -104t\n    -111t\n    -101t\n    -40t\n    -69t\n    -45t\n    78t\n    -126t\n    92t\n    -23t\n    -55t\n    87t\n    88t\n    98t\n    2t\n    76t\n    -10t\n    -87t\n    5t\n    -91t\n    67t\n    78t\n    -102t\n    -126t\n    8t\n    96t\n    -76t\n    3t\n    -111t\n    -93t\n    37t\n    67t\n    -6t\n    28t\n    -32t\n    -11t\n    -7t\n    45t\n    -21t\n    -60t\n    89t\n    23t\n    3t\n    -104t\n    21t\n    -50t\n    84t\n    -112t\n    43t\n    -121t\n    44t\n    58t\n    -88t\n    -10t\n    23t\n    -95t\n    -88t\n    12t\n    9t\n    36t\n    -7t\n    17t\n    -74t\n    -53t\n    -114t\n    -92t\n    126t\n    -39t\n    -77t\n    -98t\n    18t\n    84t\n    28t\n    41t\n    30t\n    16t\n    -95t\n    59t\n    -51t\n    88t\n    -60t\n    -97t\n    -116t\n    37t\n    -50t\n    -97t\n    123t\n    -95t\n    -118t\n    6t\n    -97t\n    20t\n    64t\n    49t\n    -37t\n    29t\n    48t\n    64t\n    4t\n    67t\n    -84t\n    -95t\n    88t\n    16t\n    99t\n    -91t\n    92t\n    103t\n    8t\n    -89t\n    120t\n    28t\n    -45t\n    -9t\n    -128t\n    -50t\n    2t\n    43t\n    21t\n    -118t\n    -108t\n    78t\n    -63t\n    -126t\n    -100t\n    49t\n    -52t\n    37t\n    114t\n    50t\n    87t\n    61t\n    29t\n    98t\n    118t\n    32t\n    99t\n    76t\n    -4t\n    -116t\n    25t\n    -30t\n    -64t\n    105t\n    3t\n    47t\n    9t\n    -61t\n    109t\n    37t\n    83t\n    118t\n    65t\n    71t\n    85t\n    -87t\n    21t\n    -28t\n    3t\n    2t\n    99t\n    54t\n    -79t\n    -125t\n    -62t\n    61t\n    124t\n    114t\n    -105t\n    54t\n    32t\n    -6t\n    -23t\n    -63t\n    86t\n    22t\n    -31t\n    78t\n    21t\n    -70t\n    -44t\n    -82t\n    -37t\n    125t\n    42t\n    -15t\n    111t\n    -65t\n    91t\n    -68t\n    23t\n    -88t\n    111t\n    -126t\n    -55t\n    118t\n    89t\n    59t\n    96t\n    -95t\n    -38t\n    -81t\n    8t\n    31t\n    39t\n    -88t\n    24t\n    -29t\n    51t\n    16t\n    -42t\n    64t\n    -73t\n    -66t\n    14t\n    89t\n    -28t\n    17t\n    -26t\n    48t\n    48t\n    38t\n    -33t\n    35t\n    46t\n    -126t\n    -68t\n    -95t\n    120t\n    73t\n    -16t\n    -85t\n    -120t\n    113t\n    109t\n    -82t\n    15t\n    122t\n    -89t\n    109t\n    17t\n    -47t\n    67t\n    -126t\n    48t\n    -43t\n    -98t\n    21t\n    -1t\n    -11t\n    -7t\n    -77t\n    -83t\n    -88t\n    73t\n    44t\n    94t\n    99t\n    -77t\n    -110t\n    59t\n    96t\n    56t\n    30t\n    2t\n    117t\n    -108t\n    84t\n    -116t\n    -27t\n    71t\n    18t\n    -8t\n    -86t\n    -105t\n    -74t\n    -113t\n    -78t\n    67t\n    -96t\n    -125t\n    22t\n    -124t\n    -119t\n    -26t\n    43t\n    90t\n    -6t\n    -118t\n    61t\n    52t\n    84t\n    -66t\n    47t\n    -107t\n    108t\n    -107t\n    -9t\n    -56t\n    28t\n    34t\n    -70t\n    -98t\n    -21t\n    66t\n    89t\n    104t\n    125t\n    -88t\n    -54t\n    67t\n    81t\n    6t\n    -91t\n    -126t\n    105t\n    109t\n    -47t\n    63t\n    120t\n    -91t\n    1t\n    -24t\n    -88t\n    101t\n    -127t\n    -25t\n    -122t\n    40t\n    -12t\n    95t\n    20t\n    90t\n    77t\n    -25t\n    -92t\n    18t\n    -105t\n    -68t\n    82t\n    -37t\n    46t\n    59t\n    -58t\n    -99t\n    -91t\n    79t\n    -7t\n    -6t\n    -85t\n    89t\n    102t\n    40t\n    -20t\n    -35t\n    -37t\n    -74t\n    44t\n    -104t\n    73t\n    -127t\n    -51t\n    107t\n    87t\n    16t\n    -125t\n    87t\n    112t\n    -37t\n    89t\n    111t\n    71t\n    -107t\n    39t\n    122t\n    95t\n    97t\n    71t\n    -60t\n    69t\n    -123t\n    -98t\n    4t\n    60t\n    -1t\n    84t\n    -79t\n    -32t\n    78t\n    92t\n    -37t\n    -14t\n    120t\n    -111t\n    54t\n    40t\n    76t\n    123t\n    -113t\n    88t\n    -59t\n    64t\n    98t\n    8t\n    -54t\n    77t\n    33t\n    124t\n    19t\n    -2t\n    -98t\n    41t\n    118t\n    120t\n    31t\n    -36t\n    -85t\n    -70t\n    -127t\n    -120t\n    -91t\n    -71t\n    -103t\n    -63t\n    70t\n    75t\n    61t\n    -78t\n    126t\n    70t\n    -51t\n    -23t\n    58t\n    124t\n    -20t\n    -95t\n    65t\n    -8t\n    11t\n    -74t\n    -77t\n    -34t\n    -46t\n    -85t\n    96t\n    -46t\n    60t\n    -60t\n    -122t\n    125t\n    -66t\n    83t\n    -82t\n    -27t\n    -95t\n    115t\n    46t\n    74t\n    -118t\n    -73t\n    52t\n    87t\n    -77t\n    -38t\n    -105t\n    -31t\n    -76t\n    -91t\n    69t\n    -84t\n    -47t\n    37t\n    -88t\n    -60t\n    -88t\n    53t\n    23t\n    -93t\n    14t\n    9t\n    -8t\n    -127t\n    121t\n    -68t\n    92t\n    30t\n    33t\n    69t\n    -27t\n    88t\n    5t\n    100t\n    30t\n    -62t\n    60t\n    6t\n    118t\n    -32t\n    38t\n    59t\n    -117t\n    -26t\n    -104t\n    -25t\n    114t\n    54t\n    -26t\n    -84t\n    -120t\n    104t\n    -78t\n    62t\n    107t\n    126t\n    54t\n    -59t\n    -75t\n    63t\n    -75t\n    -16t\n    -85t\n    -44t\n    31t\n    110t\n    -70t\n    114t\n    -118t\n    74t\n    -5t\n    31t\n    12t\n    -80t\n    78t\n    12t\n    88t\n    97t\n    93t\n    52t\n    -118t\n    -72t\n    -41t\n    38t\n    96t\n    31t\n    -116t\n    15t\n    -12t\n    101t\n    50t\n    118t\n    124t\n    -100t\n    74t\n    67t\n    -122t\n    49t\n    67t\n    97t\n    -114t\n    59t\n    -88t\n    121t\n    -32t\n    122t\n    -72t\n    -95t\n    39t\n    -98t\n    -34t\n    -18t\n    -68t\n    -25t\n    -92t\n    -104t\n    -36t\n    36t\n    82t\n    -24t\n    112t\n    -100t\n    71t\n    30t\n    -90t\n    83t\n    76t\n    96t\n    -39t\n    54t\n    104t\n    27t\n    -2t\n    -62t\n    70t\n    -64t\n    70t\n    70t\n    126t\n    -11t\n    -126t\n    -59t\n    -34t\n    -92t\n    38t\n    -109t\n    -93t\n    -66t\n    -108t\n    102t\n    -12t\n    90t\n    24t\n    -54t\n    -20t\n    103t\n    13t\n    -67t\n    67t\n    -2t\n    -27t\n    -110t\n    104t\n    48t\n    -66t\n    93t\n    110t\n    -60t\n    -50t\n    -50t\n    73t\n    17t\n    25t\n    -8t\n    -109t\n    16t\n    -87t\n    32t\n    50t\n    26t\n    -9t\n    -92t\n    -12t\n    -93t\n    -72t\n    110t\n    -12t\n    -81t\n    -117t\n    -118t\n    112t\n    -57t\n    98t\n    15t\n    121t\n    -64t\n    -102t\n    102t\n    116t\n    114t\n    81t\n    56t\n    42t\n    111t\n    -7t\n    26t\n    48t\n    -80t\n    -125t\n    -36t\n    23t\n    -128t\n    42t\n    -69t\n    -16t\n    68t\n    -62t\n    -101t\n    103t\n    122t\n    118t\n    -111t\n    98t\n    -61t\n    0t\n    113t\n    -53t\n    -20t\n    -31t\n    -103t\n    87t\n    116t\n    86t\n    97t\n    87t\n    69t\n    -110t\n    -14t\n    -80t\n    -124t\n    -28t\n    -128t\n    -68t\n    -56t\n    83t\n    29t\n    -34t\n    -45t\n    -40t\n    110t\n    126t\n    21t\n    -63t\n    -85t\n    55t\n    -35t\n    -39t\n    -76t\n    54t\n    -102t\n    -24t\n    -114t\n    -120t\n    -3t\n    15t\n    -22t\n    -98t\n    107t\n    28t\n    12t\n    -107t\n    -89t\n    -85t\n    63t\n    -67t\n    25t\n    124t\n    -110t\n    -107t\n    27t\n    -125t\n    -74t\n    -62t\n    92t\n    -54t\n    -22t\n    -118t\n    35t\n    61t\n    -30t\n    -6t\n    115t\n    94t\n    18t\n    -69t\n    -9t\n    -69t\n    7t\n    113t\n    49t\n    -16t\n    94t\n    28t\n    61t\n    -29t\n    -65t\n    101t\n    -14t\n    51t\n    -95t\n    68t\n    -126t\n    38t\n    -85t\n    -58t\n    -69t\n    117t\n    78t\n    -122t\n    -64t\n    102t\n    -40t\n    118t\n    -115t\n    116t\n    16t\n    97t\n    -97t\n    79t\n    44t\n    70t\n    -42t\n    107t\n    -13t\n    26t\n    -85t\n    -73t\n    22t\n    -116t\n    -51t\n    15t\n    60t\n    74t\n    75t\n    41t\n    -93t\n    -53t\n    80t\n    50t\n    56t\n    25t\n    60t\n    103t\n    -86t\n    91t\n    75t\n    89t\n    -37t\n    -63t\n    -29t\n    -1t\n    -21t\n    -62t\n    109t\n    103t\n    88t\n    83t\n    -82t\n    -115t\n    -33t\n    99t\n    -86t\n    6t\n    61t\n    4t\n    -94t\n    -7t\n    42t\n    73t\n    97t\n    -29t\n    -68t\n    19t\n    -32t\n    -107t\n    63t\n    -24t\n    -123t\n    -65t\n    20t\n    -33t\n    11t\n    47t\n    18t\n    -109t\n    5t\n    43t\n    -8t\n    84t\n    122t\n    -20t\n    3t\n    40t\n    -31t\n    -111t\n    -9t\n    124t\n    -30t\n    34t\n    -85t\n    -36t\n    58t\n    93t\n    92t\n    -28t\n    -87t\n    -8t\n    86t\n    -111t\n    80t\n    65t\n    -123t\n    30t\n    67t\n    70t\n    31t\n    -70t\n    -82t\n    47t\n    -79t\n    -12t\n    104t\n    112t\n    -69t\n    -108t\n    -88t\n    44t\n    119t\n    98t\n    20t\n    -97t\n    77t\n    -93t\n    8t\n    6t\n    -58t\n    -75t\n    -112t\n    -32t\n    -73t\n    104t\n    -123t\n    -29t\n    5t\n    109t\n    6t\n    -117t\n    -116t\n    -94t\n    12t\n    -53t\n    7t\n    -98t\n    -79t\n    -106t\n    38t\n    90t\n    104t\n    -116t\n    -90t\n    -79t\n    61t\n    2t\n    92t\n    53t\n    -73t\n    -119t\n    -36t\n    70t\n    -115t\n    -24t\n    -55t\n    81t\n    91t\n    42t\n    -81t\n    92t\n    97t\n    -88t\n    47t\n    1t\n    104t\n    -101t\n    41t\n    -110t\n    -30t\n    -46t\n    9t\n    25t\n    53t\n    65t\n    20t\n    111t\n    32t\n    13t\n    110t\n    93t\n    63t\n    126t\n    18t\n    96t\n    -72t\n    -76t\n    -63t\n    5t\n    36t\n    -115t\n    71t\n    16t\n    -114t\n    38t\n    24t\n    77t\n    12t\n    0t\n    48t\n    -16t\n    21t\n    -33t\n    -17t\n    38t\n    119t\n    -39t\n    -60t\n    -89t\n    -119t\n    39t\n    29t\n    -53t\n    -3t\n    27t\n    66t\n    67t\n    -3t\n    -55t\n    98t\n    -9t\n    -112t\n    -69t\n    106t\n    -116t\n    42t\n    121t\n    -6t\n    42t\n    -13t\n    -57t\n    119t\n    -92t\n    51t\n    115t\n    21t\n    95t\n    20t\n    -69t\n    -19t\n    -26t\n    -92t\n    22t\n    -9t\n    -38t\n    -79t\n    90t\n    -71t\n    99t\n    59t\n    -60t\n    116t\n    72t\n    46t\n    -56t\n    -11t\n    -58t\n    21t\n    -103t\n    -9t\n    -26t\n    31t\n    55t\n    4t\n    71t\n    -100t\n    -65t\n    -32t\n    86t\n    79t\n    -87t\n    53t\n    73t\n    -25t\n    2t\n    84t\n    -12t\n    -31t\n    115t\n    24t\n    -7t\n    -42t\n    -7t\n    -72t\n    -4t\n    21t\n    43t\n    61t\n    1t\n    -38t\n    -39t\n    118t\n    85t\n    -9t\n    -27t\n    108t\n    -127t\n    110t\n    -41t\n    45t\n    20t\n    13t\n    -120t\n    52t\n    -8t\n    110t\n    -16t\n    -80t\n    90t\n    126t\n    -42t\n    -60t\n    42t\n    47t\n    -117t\n    118t\n    -128t\n    -38t\n    84t\n    85t\n    -105t\n    -8t\n    97t\n    92t\n    -4t\n    -91t\n    -84t\n    -70t\n    24t\n    21t\n    -36t\n    12t\n    21t\n    -104t\n    91t\n    -4t\n    91t\n    119t\n    70t\n    -117t\n    -71t\n    27t\n    -83t\n    -18t\n    77t\n    27t\n    28t\n    -102t\n    -113t\n    -88t\n    50t\n    119t\n    19t\n    -58t\n    -25t\n    -109t\n    36t\n    66t\n    -52t\n    93t\n    30t\n    -101t\n    -47t\n    -43t\n    87t\n    -18t\n    -44t\n    127t\n    -78t\n    35t\n    82t\n    28t\n    54t\n    -53t\n    -30t\n    111t\n    -35t\n    123t\n    10t\n    -94t\n    118t\n    46t\n    -33t\n    -12t\n    -20t\n    -19t\n    -33t\n    -100t\n    -107t\n    111t\n    127t\n    116t\n    -82t\n    -114t\n    91t\n    61t\n    125t\n    -87t\n    90t\n    117t\n    -80t\n    -93t\n    -58t\n    -123t\n    81t\n    32t\n    -74t\n    79t\n    -79t\n    117t\n    -101t\n    -66t\n    -86t\n    73t\n    -15t\n    49t\n    -33t\n    -14t\n    86t\n    34t\n    20t\n    -54t\n    1t\n    58t\n    11t\n    -36t\n    -5t\n    -64t\n    -59t\n    -21t\n    -3t\n    -67t\n    116t\n    2t\n    76t\n    -31t\n    36t\n    -14t\n    64t\n    -49t\n    -38t\n    -54t\n    86t\n    105t\n    41t\n    -28t\n    -30t\n    -4t\n    -101t\n    116t\n    12t\n    -86t\n    44t\n    80t\n    16t\n    -70t\n    46t\n    -92t\n    82t\n    -87t\n    5t\n    72t\n    57t\n    -46t\n    -19t\n    103t\n    12t\n    74t\n    -107t\n    115t\n    -113t\n    -29t\n    103t\n    -122t\n    -91t\n    55t\n    95t\n    -126t\n    -110t\n    61t\n    -36t\n    -14t\n    -15t\n    -18t\n    -33t\n    -46t\n    63t\n    -66t\n    111t\n    79t\n    -78t\n    79t\n    100t\n    122t\n    95t\n    7t\n    58t\n    -112t\n    2t\n    75t\n    106t\n    -42t\n    -45t\n    112t\n    -106t\n    33t\n    21t\n    -93t\n    -26t\n    94t\n    -104t\n    -28t\n    -78t\n    -15t\n    -76t\n    -111t\n    41t\n    -38t\n    -35t\n    38t\n    -94t\n    -33t\n    45t\n    -44t\n    -40t\n    40t\n    -13t\n    27t\n    38t\n    -9t\n    74t\n    55t\n    -123t\n    -53t\n    78t\n    -6t\n    121t\n    -28t\n    43t\n    -48t\n    -61t\n    -39t\n    -99t\n    -26t\n    -113t\n    27t\n    -71t\n    119t\n    80t\n    -117t\n    101t\n    83t\n    21t\n    -8t\n    -42t\n    15t\n    -63t\n    68t\n    54t\n    2t\n    -6t\n    75t\n    -103t\n    -71t\n    121t\n    -47t\n    -58t\n    -22t\n    77t\n    8t\n    123t\n    -119t\n    108t\n    92t\n    126t\n    -76t\n    29t\n    -42t\n    12t\n    -119t\n    -40t\n    0t\n    33t\n    46t\n    44t\n    121t\n    -83t\n    76t\n    -4t\n    41t\n    -55t\n    -82t\n    -84t\n    55t\n    39t\n    -2t\n    118t\n    5t\n    20t\n    21t\n    51t\n    -47t\n    89t\n    119t\n    16t\n    -126t\n    -25t\n    11t\n    -13t\n    -60t\n    107t\n    -66t\n    -86t\n    75t\n    32t\n    -113t\n    -83t\n    -55t\n    -6t\n    -82t\n    -40t\n    -108t\n    -100t\n    -50t\n    -66t\n    -119t\n    -61t\n    -110t\n    -118t\n    95t\n    -95t\n    -70t\n    9t\n    -110t\n    43t\n    -35t\n    -76t\n    61t\n    105t\n    -25t\n    -66t\n    33t\n    25t\n    94t\n    -49t\n    13t\n    -71t\n    119t\n    8t\n    89t\n    44t\n    21t\n    -48t\n    3t\n    96t\n    38t\n    17t\n    -54t\n    -10t\n    -13t\n    -106t\n    34t\n    -72t\n    85t\n    46t\n    -84t\n    19t\n    46t\n    -14t\n    -95t\n    48t\n    -96t\n    111t\n    -96t\n    71t\n    78t\n    -25t\n    18t\n    115t\n    7t\n    10t\n    -89t\n    82t\n    70t\n    67t\n    43t\n    -33t\n    -71t\n    0t\n    97t\n    58t\n    -95t\n    71t\n    0t\n    68t\n    -48t\n    -92t\n    -97t\n    38t\n    -77t\n    60t\n    -50t\n    -43t\n    -32t\n    -64t\n    -33t\n    25t\n    73t\n    -27t\n    56t\n    -29t\n    -127t\n    96t\n    86t\n    -45t\n    -16t\n    -89t\n    -94t\n    -71t\n    -52t\n    -65t\n    26t\n    32t\n    -69t\n    -97t\n    31t\n    40t\n    -7t\n    15t\n    -33t\n    83t\n    18t\n    9t\n    -60t\n    70t\n    -77t\n    28t\n    -56t\n    75t\n    22t\n    19t\n    39t\n    55t\n    104t\n    46t\n    25t\n    -43t\n    82t\n    -14t\n    118t\n    -31t\n    -95t\n    109t\n    -126t\n    -29t\n    103t\n    19t\n    -38t\n    -103t\n    108t\n    -25t\n    -102t\n    49t\n    43t\n    -97t\n    -35t\n    -5t\n    24t\n    12t\n    97t\n    35t\n    -34t\n    -19t\n    -32t\n    73t\n    -27t\n    -37t\n    -63t\n    -71t\n    55t\n    -71t\n    -128t\n    -65t\n    91t\n    -101t\n    76t\n    -9t\n    101t\n    -66t\n    -61t\n    -64t\n    75t\n    65t\n    -12t\n    -55t\n    -54t\n    92t\n    28t\n    105t\n    -122t\n    -8t\n    112t\n    86t\n    -88t\n    -122t\n    125t\n    -76t\n    -46t\n    107t\n    -10t\n    -37t\n    -95t\n    110t\n    18t\n    -24t\n    49t\n    -83t\n    -123t\n    -3t\n    -16t\n    -111t\n    97t\n    -51t\n    -42t\n    39t\n    5t\n    -126t\n    57t\n    125t\n    98t\n    -86t\n    -28t\n    -104t\n    91t\n    33t\n    67t\n    40t\n    103t\n    -53t\n    37t\n    -48t\n    127t\n    -47t\n    43t\n    65t\n    86t\n    28t\n    -20t\n    52t\n    105t\n    -28t\n    -118t\n    -17t\n    13t\n    79t\n    -68t\n    2t\n    110t\n    83t\n    121t\n    34t\n    -111t\n    -10t\n    -72t\n    -66t\n    -86t\n    -55t\n    -18t\n    25t\n    -118t\n    -7t\n    120t\n    -53t\n    1t\n    -68t\n    -43t\n    73t\n    -69t\n    -33t\n    9t\n    16t\n    -61t\n    46t\n    53t\n    25t\n    -33t\n    2t\n    68t\n    -30t\n    -38t\n    -113t\n    -65t\n    112t\n    -88t\n    27t\n    -78t\n    -54t\n    63t\n    -4t\n    -37t\n    -40t\n    -62t\n    74t\n    119t\n    -90t\n    77t\n    93t\n    96t\n    40t\n    77t\n    108t\n    -54t\n    34t\n    -120t\n    62t\n    -126t\n    -65t\n    64t\n    81t\n    -44t\n    -109t\n    -4t\n    -19t\n    4t\n    76t\n    115t\n    -79t\n    -98t\n    -98t\n    37t\n    91t\n    -27t\n    26t\n    -45t\n    -119t\n    -88t\n    47t\n    77t\n    -4t\n    -42t\n    109t\n    10t\n    1t\n    -103t\n    -108t\n    90t\n    16t\n    -112t\n    -83t\n    -74t\n    110t\n    -79t\n    33t\n    -92t\n    73t\n    -66t\n    108t\n    6t\n    -35t\n    61t\n    94t\n    110t\n    8t\n    -27t\n    -31t\n    86t\n    -64t\n    57t\n    21t\n    -77t\n    -98t\n    -100t\n    111t\n    100t\n    98t\n    102t\n    1t\n    -117t\n    55t\n    57t\n    2t\n    -46t\n    -57t\n    59t\n    37t\n    -18t\n    49t\n    -103t\n    -52t\n    -124t\n    51t\n    32t\n    -47t\n    -47t\n    -25t\n    76t\n    65t\n    48t\n    -98t\n    16t\n    -65t\n    -110t\n    -117t\n    117t\n    -73t\n    -21t\n    11t\n    38t\n    72t\n    107t\n    -17t\n    -116t\n    115t\n    86t\n    -101t\n    -64t\n    -92t\n    26t\n    96t\n    -43t\n    122t\n    70t\n    84t\n    64t\n    -2t\n    -14t\n    -30t\n    66t\n    -11t\n    55t\n    23t\n    123t\n    -124t\n    -107t\n    -66t\n    -108t\n    4t\n    -47t\n    74t\n    -1t\n    74t\n    12t\n    10t\n    15t\n    98t\n    -99t\n    -16t\n    -77t\n    -46t\n    59t\n    -23t\n    56t\n    23t\n    -56t\n    2t\n    -53t\n    -26t\n    -127t\n    -35t\n    -31t\n    90t\n    58t\n    -43t\n    67t\n    -34t\n    -4t\n    49t\n    52t\n    99t\n    -102t\n    -76t\n    -4t\n    -30t\n    102t\n    18t\n    101t\n    -6t\n    -118t\n    -127t\n    -100t\n    -3t\n    56t\n    110t\n    61t\n    -44t\n    -26t\n    -73t\n    -69t\n    37t\n    -52t\n    -82t\n    76t\n    8t\n    -77t\n    -75t\n    54t\n    34t\n    -58t\n    -90t\n    34t\n    -84t\n    96t\n    -87t\n    -22t\n    -68t\n    68t\n    119t\n    17t\n    -45t\n    -51t\n    -50t\n    27t\n    -106t\n    13t\n    59t\n    -104t\n    72t\n    84t\n    -85t\n    -56t\n    -12t\n    35t\n    33t\n    78t\n    44t\n    7t\n    -94t\n    -56t\n    67t\n    -36t\n    105t\n    45t\n    63t\n    23t\n    -46t\n    55t\n    -24t\n    -105t\n    2t\n    68t\n    -60t\n    -13t\n    -96t\n    81t\n    -22t\n    -44t\n    12t\n    106t\n    18t\n    73t\n    -77t\n    20t\n    -22t\n    -106t\n    80t\n    97t\n    111t\n    20t\n    115t\n    -46t\n    50t\n    -24t\n    -60t\n    -120t\n    -101t\n    -87t\n    126t\n    -97t\n    -97t\n    15t\n    -115t\n    65t\n    -99t\n    58t\n    97t\n    82t\n    -104t\n    -103t\n    -67t\n    49t\n    87t\n    104t\n    -41t\n    30t\n    -29t\n    -111t\n    73t\n    19t\n    -116t\n    -125t\n    -6t\n    39t\n    71t\n    102t\n    -128t\n    74t\n    -116t\n    -100t\n    -101t\n    -119t\n    117t\n    -120t\n    -20t\n    45t\n    27t\n    41t\n    37t\n    -33t\n    98t\n    -84t\n    -28t\n    -27t\n    5t\n    13t\n    27t\n    -96t\n    -77t\n    -48t\n    -112t\n    -87t\n    -17t\n    -49t\n    -27t\n    115t\n    107t\n    -101t\n    102t\n    84t\n    -123t\n    -97t\n    41t\n    93t\n    68t\n    8t\n    79t\n    -71t\n    60t\n    73t\n    74t\n    -71t\n    -34t\n    121t\n    98t\n    68t\n    94t\n    113t\n    -60t\n    -57t\n    107t\n    -46t\n    -40t\n    -34t\n    90t\n    -92t\n    -31t\n    -61t\n    119t\n    104t\n    -87t\n    13t\n    -11t\n    -91t\n    123t\n    4t\n    -15t\n    -45t\n    -110t\n    124t\n    85t\n    -115t\n    93t\n    -81t\n    -90t\n    -112t\n    -123t\n    72t\n    -58t\n    -104t\n    -98t\n    69t\n    91t\n    -15t\n    -88t\n    116t\n    92t\n    25t\n    -27t\n    15t\n    -75t\n    -78t\n    68t\n    125t\n    96t\n    -8t\n    -9t\n    78t\n    55t\n    31t\n    16t\n    -45t\n    14t\n    70t\n    -91t\n    -24t\n    121t\n    71t\n    -92t\n    27t\n    114t\n    -111t\n    -65t\n    -125t\n    28t\n    47t\n    120t\n    -52t\n    111t\n    -43t\n    122t\n    114t\n    -72t\n    50t\n    15t\n    5t\n    117t\n    -88t\n    -8t\n    -55t\n    8t\n    125t\n    91t\n    -89t\n    -68t\n    -95t\n    -39t\n    21t\n    46t\n    77t\n    -85t\n    91t\n    -44t\n    50t\n    18t\n    -87t\n    -50t\n    -12t\n    9t\n    115t\n    -84t\n    -126t\n    -125t\n    17t\n    -58t\n    115t\n    -25t\n    -74t\n    -63t\n    -16t\n    21t\n    31t\n    96t\n    54t\n    66t\n    -87t\n    -37t\n    -111t\n    -101t\n    99t\n    111t\n    61t\n    -16t\n    -61t\n    -72t\n    -1t\n    -56t\n    110t\n    90t\n    -90t\n    -2t\n    -17t\n    -111t\n    -30t\n    -17t\n    -31t\n    -121t\n    -62t\n    -124t\n    82t\n    76t\n    -18t\n    82t\n    33t\n    -93t\n    26t\n    9t\n    -37t\n    87t\n    -48t\n    -118t\n    72t\n    2t\n    -14t\n    -101t\n    71t\n    107t\n    -66t\n    -113t\n    30t\n    -24t\n    51t\n    -8t\n    39t\n    30t\n    45t\n    -18t\n    11t\n    54t\n    -19t\n    -19t\n    95t\n    35t\n    108t\n    -40t\n    64t\n    -63t\n    9t\n    84t\n    -100t\n    61t\n    24t\n    79t\n    -49t\n    -70t\n    -128t\n    77t\n    67t\n    -56t\n    -5t\n    125t\n    -118t\n    113t\n    61t\n    126t\n    -49t\n    -109t\n    86t\n    -115t\n    63t\n    -36t\n    -35t\n    -106t\n    85t\n    90t\n    65t\n    -44t\n    -89t\n    94t\n    78t\n    81t\n    89t\n    76t\n    82t\n    -94t\n    -103t\n    -12t\n    -75t\n    -88t\n    57t\n    -42t\n    -95t\n    122t\n    6t\n    117t\n    -60t\n    78t\n    -38t\n    111t\n    -37t\n    -100t\n    107t\n    -94t\n    44t\n    -81t\n    -119t\n    122t\n    86t\n    -41t\n    -95t\n    3t\n    84t\n    -67t\n    -123t\n    120t\n    -68t\n    -8t\n    -11t\n    -59t\n    -117t\n    -63t\n    94t\n    60t\n    26t\n    -115t\n    -78t\n    -15t\n    86t\n    127t\n    39t\n    43t\n    65t\n    -69t\n    74t\n    -70t\n    86t\n    101t\n    72t\n    -80t\n    77t\n    93t\n    -44t\n    -69t\n    30t\n    72t\n    -59t\n    109t\n    91t\n    48t\n    50t\n    -44t\n    -36t\n    74t\n    -37t\n    -92t\n    122t\n    116t\n    -8t\n    80t\n    84t\n    104t\n    111t\n    48t\n    124t\n    72t\n    69t\n    -126t\n    -10t\n    -76t\n    53t\n    17t\n    45t\n    71t\n    -38t\n    -40t\n    -124t\n    -90t\n    13t\n    -111t\n    124t\n    -51t\n    -41t\n    -42t\n    3t\n    14t\n    102t\n    87t\n    77t\n    10t\n    -58t\n    -5t\n    26t\n    8t\n    112t\n    -4t\n    19t\n    -102t\n    21t\n    -111t\n    46t\n    -4t\n    27t\n    9t\n    -17t\n    -13t\n    -6t\n    1t\n    9t\n    -94t\n    -45t\n    -7t\n    76t\n    -127t\n    -36t\n    -25t\n    -72t\n    -40t\n    -125t\n    -16t\n    -20t\n    71t\n    -66t\n    118t\n    81t\n    90t\n    -42t\n    107t\n    -108t\n    57t\n    84t\n    126t\n    96t\n    -16t\n    87t\n    15t\n    -118t\n    -22t\n    106t\n    -21t\n    -115t\n    59t\n    109t\n    -125t\n    -75t\n    55t\n    36t\n    127t\n    60t\n    -25t\n    45t\n    115t\n    122t\n    -106t\n    77t\n    16t\n    -65t\n    64t\n    -100t\n    -5t\n    87t\n    89t\n    -12t\n    57t\n    125t\n    -25t\n    16t\n    79t\n    115t\n    22t\n    -116t\n    -29t\n    -79t\n    -61t\n    117t\n    53t\n    -22t\n    -117t\n    47t\n    45t\n    25t\n    -106t\n    -80t\n    -107t\n    -86t\n    80t\n    -68t\n    -103t\n    97t\n    -75t\n    116t\n    -8t\n    26t\n    36t\n    6t\n    -128t\n    127t\n    -103t\n    37t\n    78t\n    67t\n    -124t\n    -92t\n    -66t\n    65t\n    -40t\n    -113t\n    -98t\n    56t\n    -49t\n    6t\n    71t\n    122t\n    126t\n    118t\n    -56t\n    -18t\n    -116t\n    65t\n    111t\n    -113t\n    -101t\n    72t\n    -50t\n    -93t\n    -124t\n    44t\n    40t\n    -50t\n    55t\n    -112t\n    -79t\n    -63t\n    89t\n    27t\n    -75t\n    85t\n    -38t\n    -10t\n    47t\n    -33t\n    22t\n    17t\n    57t\n    122t\n    -55t\n    -18t\n    -103t\n    -22t\n    -36t\n    62t\n    121t\n    30t\n    -17t\n    21t\n    -56t\n    -127t\n    -117t\n    -102t\n    49t\n    -44t\n    72t\n    53t\n    84t\n    -52t\n    22t\n    -33t\n    -75t\n    -60t\n    44t\n    103t\n    -6t\n    -91t\n    -10t\n    -90t\n    2t\n    10t\n    -64t\n    -114t\n    -34t\n    -112t\n    -38t\n    -40t\n    103t\n    7t\n    74t\n    -13t\n    -22t\n    15t\n    -110t\n    -60t\n    -34t\n    41t\n    81t\n    -78t\n    112t\n    -4t\n    -126t\n    52t\n    100t\n    -128t\n    96t\n    49t\n    125t\n    108t\n    126t\n    80t\n    54t\n    93t\n    63t\n    96t\n    -13t\n    85t\n    111t\n    -88t\n    -114t\n    82t\n    -112t\n    -96t\n    -64t\n    -90t\n    -53t\n    72t\n    86t\n    -80t\n    43t\n    -8t\n    -124t\n    -37t\n    70t\n    116t\n    -62t\n    82t\n    -6t\n    -101t\n    -66t\n    -78t\n    84t\n    -25t\n    -56t\n    35t\n    -101t\n    -108t\n    64t\n    -63t\n    18t\n    -101t\n    91t\n    -30t\n    108t\n    -71t\n    -77t\n    -22t\n    -23t\n    -88t\n    -83t\n    6t\n    -85t\n    -79t\n    -116t\n    -110t\n    -64t\n    -97t\n    -24t\n    35t\n    58t\n    -92t\n    28t\n    108t\n    62t\n    -27t\n    -78t\n    -63t\n    -90t\n    56t\n    -33t\n    0t\n    90t\n    -16t\n    66t\n    -105t\n    79t\n    -57t\n    -127t\n    101t\n    -25t\n    -107t\n    -85t\n    7t\n    105t\n    115t\n    4t\n    -103t\n    94t\n    12t\n    -24t\n    2t\n    -122t\n    -53t\n    -35t\n    34t\n    -44t\n    -41t\n    102t\n    -42t\n    20t\n    91t\n    -120t\n    -22t\n    -90t\n    -105t\n    -51t\n    -69t\n    -49t\n    25t\n    -123t\n    -36t\n    121t\n    -81t\n    -44t\n    -48t\n    125t\n    44t\n    -42t\n    -15t\n    -126t\n    72t\n    49t\n    -72t\n    -11t\n    43t\n    18t\n    19t\n    -61t\n    -55t\n    -12t\n    10t\n    -88t\n    34t\n    52t\n    -10t\n    -27t\n    -105t\n    -11t\n    43t\n    76t\n    91t\n    48t\n    121t\n    48t\n    -61t\n    -78t\n    -46t\n    -50t\n    111t\n    -122t\n    -2t\n    60t\n    8t\n    125t\n    38t\n    100t\n    38t\n    -67t\n    40t\n    31t\n    124t\n    -36t\n    43t\n    77t\n    8t\n    -105t\n    -107t\n    -33t\n    32t\n    98t\n    -62t\n    87t\n    6t\n    -85t\n    -78t\n    105t\n    2t\n    121t\n    -4t\n    -89t\n    -39t\n    -116t\n    1t\n    88t\n    45t\n    -27t\n    -39t\n    -7t\n    109t\n    -18t\n    24t\n    101t\n    -27t\n    -19t\n    50t\n    -10t\n    -33t\n    -61t\n    -125t\n    122t\n    -119t\n    78t\n    -85t\n    0t\n    -8t\n    39t\n    -78t\n    1t\n    15t\n    84t\n    -78t\n    3t\n    -9t\n    -76t\n    -58t\n    -87t\n    -27t\n    -102t\n    125t\n    -111t\n    76t\n    -80t\n    -119t\n    -69t\n    38t\n    -31t\n    116t\n    68t\n    -54t\n    -55t\n    98t\n    -47t\n    24t\n    -68t\n    6t\n    73t\n    -120t\n    80t\n    90t\n    -127t\n    -61t\n    66t\n    61t\n    -59t\n    -80t\n    -27t\n    116t\n    -30t\n    -47t\n    61t\n    -42t\n    -66t\n    41t\n    102t\n    -15t\n    2t\n    7t\n    20t\n    -4t\n    125t\n    55t\n    97t\n    93t\n    44t\n    -28t\n    60t\n    91t\n    71t\n    -68t\n    123t\n    -99t\n    -15t\n    3t\n    85t\n    -35t\n    105t\n    83t\n    14t\n    106t\n    21t\n    -28t\n    -5t\n    -123t\n    24t\n    37t\n    28t\n    -127t\n    -73t\n    -44t\n    -36t\n    -50t\n    -91t\n    -68t\n    -33t\n    -38t\n    -102t\n    55t\n    -59t\n    124t\n    -9t\n    75t\n    94t\n    87t\n    45t\n    -67t\n    -53t\n    16t\n    124t\n    84t\n    -113t\n    83t\n    88t\n    -62t\n    -1t\n    -77t\n    -126t\n    -20t\n    -72t\n    113t\n    44t\n    82t\n    -101t\n    28t\n    113t\n    -5t\n    -60t\n    -120t\n    45t\n    -101t\n    103t\n    28t\n    -79t\n    95t\n    -41t\n    -99t\n    -111t\n    -70t\n    -17t\n    -41t\n    -52t\n    6t\n    22t\n    -53t\n    26t\n    68t\n    -50t\n    -82t\n    67t\n    14t\n    15t\n    -61t\n    119t\n    -97t\n    -123t\n    -113t\n    -123t\n    -105t\n    -80t\n    -111t\n    43t\n    -37t\n    10t\n    -69t\n    -83t\n    45t\n    22t\n    83t\n    124t\n    -117t\n    124t\n    31t\n    52t\n    -9t\n    -103t\n    -45t\n    53t\n    -8t\n    34t\n    -23t\n    -68t\n    87t\n    23t\n    89t\n    31t\n    -124t\n    21t\n    -8t\n    85t\n    -104t\n    7t\n    96t\n    -94t\n    -16t\n    -3t\n    -55t\n    -44t\n    20t\n    18t\n    100t\n    -91t\n    9t\n    -116t\n    54t\n    -30t\n    111t\n    -71t\n    -52t\n    28t\n    -26t\n    -77t\n    -67t\n    -63t\n    31t\n    30t\n    -9t\n    0t\n    -100t\n    -57t\n    125t\n    39t\n    -106t\n    -77t\n    32t\n    94t\n    -91t\n    81t\n    40t\n    120t\n    68t\n    -5t\n    -112t\n    -23t\n    49t\n    -22t\n    66t\n    -12t\n    -45t\n    27t\n    -10t\n    118t\n    -67t\n    -5t\n    8t\n    126t\n    -109t\n    -17t\n    7t\n    -17t\n    48t\n    -31t\n    52t\n    -20t\n    -24t\n    100t\n    94t\n    100t\n    -25t\n    24t\n    26t\n    4t\n    -112t\n    101t\n    -6t\n    42t\n    -61t\n    -32t\n    -64t\n    -125t\n    -66t\n    115t\n    -80t\n    23t\n    -83t\n    -40t\n    27t\n    63t\n    -122t\n    -110t\n    -87t\n    -18t\n    -125t\n    -37t\n    14t\n    2t\n    17t\n    -8t\n    -33t\n    105t\n    -55t\n    59t\n    14t\n    -4t\n    -107t\n    44t\n    -43t\n    -65t\n    113t\n    121t\n    -24t\n    18t\n    76t\n    -128t\n    82t\n    108t\n    71t\n    -95t\n    42t\n    -99t\n    -113t\n    -128t\n    112t\n    -47t\n    83t\n    -118t\n    -8t\n    -64t\n    -9t\n    -21t\n    21t\n    68t\n    -23t\n    111t\n    95t\n    -126t\n    -34t\n    124t\n    -57t\n    78t\n    23t\n    -15t\n    -82t\n    -47t\n    20t\n    -85t\n    76t\n    -124t\n    -2t\n    36t\n    17t\n    -108t\n    121t\n    60t\n    50t\n    103t\n    112t\n    21t\n    81t\n    -22t\n    -117t\n    21t\n    88t\n    123t\n    -19t\n    13t\n    -116t\n    40t\n    23t\n    -71t\n    91t\n    91t\n    122t\n    -103t\n    16t\n    -28t\n    120t\n    87t\n    62t\n    -102t\n    -12t\n    -67t\n    -59t\n    67t\n    -55t\n    3t\n    19t\n    67t\n    53t\n    -121t\n    71t\n    -57t\n    -70t\n    -83t\n    108t\n    -76t\n    12t\n    -122t\n    52t\n    100t\n    39t\n    -120t\n    50t\n    67t\n    108t\n    -114t\n    -91t\n    -89t\n    -36t\n    91t\n    32t\n    14t\n    -58t\n    -112t\n    45t\n    -83t\n    -62t\n    -98t\n    101t\n    15t\n    68t\n    -99t\n    -94t\n    9t\n    82t\n    83t\n    18t\n    -73t\n    -18t\n    -85t\n    -120t\n    -63t\n    -14t\n    -10t\n    -99t\n    104t\n    59t\n    -62t\n    27t\n    -88t\n    -31t\n    101t\n    -99t\n    -115t\n    -35t\n    -121t\n    -82t\n    -116t\n    -64t\n    10t\n    -17t\n    -125t\n    -80t\n    -85t\n    -23t\n    -41t\n    -11t\n    -28t\n    94t\n    -100t\n    -17t\n    95t\n    91t\n    -41t\n    -26t\n    97t\n    -117t\n    -69t\n    -47t\n    -28t\n    41t\n    -115t\n    -54t\n    36t\n    75t\n    -112t\n    102t\n    -123t\n    -66t\n    79t\n    -29t\n    -63t\n    121t\n    -13t\n    33t\n    59t\n    -43t\n    -52t\n    17t\n    -23t\n    -115t\n    -18t\n    -78t\n    50t\n    125t\n    16t\n    4t\n    44t\n    -112t\n    -88t\n    80t\n    -59t\n    -24t\n    71t\n    116t\n    -95t\n    -97t\n    62t\n    65t\n    5t\n    26t\n    -64t\n    -52t\n    42t\n    90t\n    73t\n    50t\n    -103t\n    -128t\n    96t\n    -46t\n    -35t\n    56t\n    -95t\n    -11t\n    109t\n    88t\n    -13t\n    64t\n    -24t\n    -3t\n    110t\n    59t\n    11t\n    116t\n    -7t\n    8t\n    -89t\n    -108t\n    16t\n    98t\n    41t\n    -27t\n    52t\n    -95t\n    -58t\n    -94t\n    60t\n    -48t\n    7t\n    -98t\n    8t\n    -15t\n    -41t\n    49t\n    -95t\n    11t\n    -18t\n    -4t\n    61t\n    -80t\n    -89t\n    102t\n    -44t\n    -108t\n    92t\n    4t\n    -122t\n    -23t\n    127t\n    -103t\n    -50t\n    116t\n    86t\n    -10t\n    114t\n    -56t\n    -38t\n    -120t\n    45t\n    -47t\n    62t\n    110t\n    -9t\n    -18t\n    -46t\n    -8t\n    -74t\n    -106t\n    92t\n    -67t\n    -50t\n    32t\n    -45t\n    -52t\n    -59t\n    -56t\n    -70t\n    92t\n    32t\n    -19t\n    27t\n    -100t\n    -51t\n    80t\n    30t\n    29t\n    9t\n    -87t\n    14t\n    76t\n    -60t\n    36t\n    -16t\n    36t\n    -13t\n    -22t\n    33t\n    4t\n    72t\n    59t\n    67t\n    -62t\n    -127t\n    109t\n    -11t\n    27t\n    -68t\n    76t\n    -65t\n    48t\n    4t\n    104t\n    -55t\n    -19t\n    122t\n    -71t\n    -57t\n    -110t\n    66t\n    18t\n    24t\n    77t\n    67t\n    -77t\n    61t\n    -105t\n    -38t\n    -112t\n    108t\n    -40t\n    48t\n    78t\n    -39t\n    31t\n    -81t\n    103t\n    -76t\n    -15t\n    14t\n    -118t\n    127t\n    -25t\n    -64t\n    22t\n    51t\n    -18t\n    -71t\n    112t\n    -114t\n    76t\n    82t\n    -58t\n    59t\n    -99t\n    12t\n    0t\n    -108t\n    -90t\n    -24t\n    22t\n    -10t\n    112t\n    39t\n    -46t\n    72t\n    -48t\n    -14t\n    -12t\n    116t\n    11t\n    5t\n    57t\n    91t\n    -37t\n    91t\n    8t\n    -122t\n    -109t\n    -32t\n    -20t\n    90t\n    11t\n    -125t\n    -27t\n    6t\n    93t\n    83t\n    -54t\n    -51t\n    -27t\n    78t\n    -59t\n    15t\n    78t\n    89t\n    -23t\n    -30t\n    118t\n    97t\n    33t\n    20t\n    -41t\n    -49t\n    -37t\n    64t\n    -122t\n    -107t\n    -69t\n    -31t\n    -17t\n    -35t\n    40t\n    -101t\n    68t\n    58t\n    -114t\n    -102t\n    -55t\n    -46t\n    111t\n    -53t\n    -1t\n    53t\n    14t\n    50t\n    -34t\n    16t\n    117t\n    116t\n    108t\n    93t\n    -91t\n    62t\n    -31t\n    46t\n    -116t\n    4t\n    85t\n    -59t\n    92t\n    -115t\n    43t\n    116t\n    114t\n    -23t\n    -99t\n    -4t\n    28t\n    115t\n    83t\n    -10t\n    -120t\n    -94t\n    108t\n    -79t\n    121t\n    -118t\n    118t\n    -43t\n    108t\n    126t\n    58t\n    56t\n    108t\n    -99t\n    -60t\n    -7t\n    -110t\n    127t\n    93t\n    -74t\n    14t\n    70t\n    -14t\n    -49t\n    52t\n    18t\n    116t\n    29t\n    -75t\n    84t\n    62t\n    64t\n    -8t\n    -53t\n    -48t\n    -108t\n    -28t\n    5t\n    -117t\n    110t\n    60t\n    59t\n    -102t\n    -13t\n    49t\n    112t\n    -111t\n    -54t\n    87t\n    -36t\n    63t\n    85t\n    31t\n    -8t\n    -27t\n    -95t\n    -55t\n    -21t\n    115t\n    78t\n    -27t\n    -105t\n    -92t\n    92t\n    -89t\n    -31t\n    35t\n    91t\n    -8t\n    71t\n    75t\n    -105t\n    94t\n    -69t\n    41t\n    -118t\n    25t\n    -105t\n    -60t\n    -4t\n    -86t\n    -19t\n    -13t\n    26t\n    64t\n    114t\n    -119t\n    119t\n    -87t\n    -23t\n    -90t\n    116t\n    106t\n    123t\n    121t\n    -63t\n    69t\n    16t\n    84t\n    -99t\n    123t\n    -79t\n    62t\n    -59t\n    -112t\n    111t\n    -106t\n    35t\n    95t\n    -18t\n    -45t\n    -70t\n    -45t\n    39t\n    18t\n    37t\n    -96t\n    -109t\n    81t\n    -65t\n    -35t\n    105t\n    -76t\n    126t\n    -119t\n    -2t\n    -33t\n    35t\n    30t\n    -13t\n    44t\n    -47t\n    -83t\n    53t\n    -51t\n    -104t\n    -128t\n    -41t\n    31t\n    -95t\n    15t\n    -15t\n    -124t\n    -108t\n    -94t\n    22t\n    -122t\n    -95t\n    -85t\n    5t\n    -52t\n    89t\n    -76t\n    -4t\n    -22t\n    -33t\n    111t\n    80t\n    -51t\n    -85t\n    33t\n    113t\n    -68t\n    90t\n    124t\n    0t\n    -41t\n    -22t\n    15t\n    9t\n    26t\n    121t\n    -100t\n    -62t\n    -77t\n    46t\n    -108t\n    -123t\n    23t\n    -122t\n    25t\n    -27t\n    28t\n    -97t\n    -56t\n    -66t\n    -81t\n    48t\n    -63t\n    -26t\n    -66t\n    21t\n    -87t\n    -86t\n    85t\n    -121t\n    -107t\n    85t\n    -109t\n    127t\n    -29t\n    88t\n    -9t\n    -53t\n    -104t\n    -49t\n    29t\n    -115t\n    -124t\n    94t\n    20t\n    -101t\n    -104t\n    -22t\n    123t\n    -54t\n    -70t\n    -91t\n    121t\n    -75t\n    -66t\n    72t\n    108t\n    -64t\n    -40t\n    97t\n    -35t\n    108t\n    26t\n    -90t\n    35t\n    -111t\n    78t\n    51t\n    37t\n    78t\n    -26t\n    -121t\n    38t\n    126t\n    23t\n    -76t\n    46t\n    97t\n    32t\n    -26t\n    35t\n    14t\n    87t\n    79t\n    118t\n    -27t\n    -2t\n    77t\n    -38t\n    74t\n    -94t\n    -28t\n    90t\n    -17t\n    69t\n    47t\n    -79t\n    91t\n    -120t\n    -9t\n    38t\n    -72t\n    63t\n    -35t\n    73t\n    65t\n    36t\n    30t\n    -11t\n    88t\n    46t\n    76t\n    29t\n    63t\n    65t\n    102t\n    -15t\n    106t\n    24t\n    69t\n    104t\n    -109t\n    9t\n    -120t\n    -4t\n    -71t\n    43t\n    65t\n    -73t\n    -40t\n    1t\n    99t\n    72t\n    -96t\n    39t\n    109t\n    37t\n    62t\n    -88t\n    -116t\n    52t\n    -69t\n    119t\n    29t\n    -52t\n    8t\n    -58t\n    64t\n    -40t\n    29t\n    -120t\n    -94t\n    49t\n    108t\n    57t\n    26t\n    -54t\n    68t\n    -11t\n    -125t\n    43t\n    11t\n    -119t\n    -42t\n    77t\n    -55t\n    -84t\n    -3t\n    26t\n    -24t\n    -100t\n    -66t\n    118t\n    33t\n    -73t\n    -86t\n    41t\n    35t\n    84t\n    40t\n    15t\n    -118t\n    127t\n    -36t\n    -6t\n    -65t\n    99t\n    -40t\n    -13t\n    102t\n    126t\n    -82t\n    -21t\n    109t\n    -95t\n    -114t\n    -79t\n    -48t\n    81t\n    121t\n    -27t\n    81t\n    -118t\n    32t\n    -39t\n    -77t\n    100t\n    -113t\n    -5t\n    -115t\n    58t\n    50t\n    -69t\n    -127t\n    -39t\n    -117t\n    -36t\n    20t\n    -62t\n    -96t\n    96t\n    -100t\n    -109t\n    98t\n    -94t\n    82t\n    95t\n    98t\n    93t\n    11t\n    -121t\n    -5t\n    5t\n    94t\n    -114t\n    38t\n    -80t\n    82t\n    36t\n    -46t\n    85t\n    118t\n    -33t\n    44t\n    110t\n    28t\n    17t\n    120t\n    16t\n    -40t\n    -87t\n    -4t\n    -49t\n    72t\n    -82t\n    113t\n    -1t\n    14t\n    92t\n    -65t\n    80t\n    -14t\n    124t\n    -120t\n    25t\n    121t\n    29t\n    63t\n    8t\n    -34t\n    105t\n    -101t\n    -38t\n    11t\n    114t\n    -30t\n    67t\n    -34t\n    32t\n    -41t\n    -99t\n    35t\n    6t\n    23t\n    56t\n    110t\n    12t\n    -12t\n    -29t\n    -62t\n    107t\n    125t\n    -108t\n    -38t\n    62t\n    -22t\n    93t\n    -28t\n    -65t\n    -87t\n    -53t\n    71t\n    37t\n    -30t\n    -93t\n    112t\n    113t\n    -4t\n    107t\n    33t\n    -101t\n    -65t\n    104t\n    -43t\n    -119t\n    -3t\n    119t\n    101t\n    -17t\n    -81t\n    -119t\n    -9t\n    -62t\n    24t\n    -126t\n    -124t\n    -87t\n    107t\n    123t\n    -100t\n    -30t\n    27t\n    113t\n    -15t\n    -63t\n    -67t\n    -72t\n    -2t\n    84t\n    -63t\n    -86t\n    -58t\n    69t\n    -106t\n    -63t\n    -45t\n    23t\n    -42t\n    123t\n    -23t\n    -83t\n    113t\n    -107t\n    39t\n    -76t\n    107t\n    60t\n    23t\n    -26t\n    63t\n    -41t\n    42t\n    -20t\n    -94t\n    91t\n    97t\n    -127t\n    -7t\n    -85t\n    -17t\n    107t\n    124t\n    22t\n    -39t\n    53t\n    -90t\n    120t\n    -104t\n    -120t\n    -59t\n    112t\n    96t\n    19t\n    92t\n    65t\n    -60t\n    -119t\n    -10t\n    -94t\n    -95t\n    -88t\n    -38t\n    10t\n    102t\n    -37t\n    124t\n    4t\n    81t\n    -119t\n    113t\n    43t\n    52t\n    63t\n    -7t\n    -88t\n    -48t\n    -53t\n    -123t\n    103t\n    -74t\n    -92t\n    -28t\n    70t\n    -86t\n    8t\n    -28t\n    117t\n    -107t\n    -55t\n    -23t\n    23t\n    7t\n    44t\n    127t\n    66t\n    -46t\n    7t\n    64t\n    32t\n    -113t\n    -83t\n    60t\n    71t\n    3t\n    -5t\n    -73t\n    -14t\n    -14t\n    -42t\n    -44t\n    49t\n    -17t\n    74t\n    -102t\n    115t\n    -50t\n    66t\n    87t\n    -44t\n    85t\n    2t\n    23t\n    -97t\n    52t\n    4t\n    -19t\n    -52t\n    -112t\n    26t\n    123t\n    -47t\n    45t\n    -121t\n    99t\n    -9t\n    -90t\n    -39t\n    68t\n    86t\n    -63t\n    25t\n    9t\n    -98t\n    -52t\n    76t\n    116t\n    -118t\n    95t\n    -55t\n    0t\n    28t\n    -66t\n    -12t\n    -87t\n    2t\n    17t\n    18t\n    -81t\n    56t\n    106t\n    -5t\n    57t\n    -30t\n    117t\n    71t\n    92t\n    0t\n    -48t\n    13t\n    -68t\n    -61t\n    -57t\n    122t\n    40t\n    120t\n    77t\n    117t\n    -116t\n    -108t\n    34t\n    103t\n    94t\n    64t\n    -53t\n    44t\n    123t\n    -14t\n    -68t\n    -33t\n    50t\n    106t\n    -60t\n    54t\n    -83t\n    35t\n    -62t\n    -8t\n    -15t\n    13t\n    111t\n    -118t\n    69t\n    93t\n    26t\n    44t\n    36t\n    73t\n    -14t\n    -56t\n    -118t\n    59t\n    70t\n    117t\n    -11t\n    -74t\n    -127t\n    -127t\n    -6t\n    -93t\n    -48t\n    88t\n    -74t\n    41t\n    21t\n    -10t\n    -49t\n    114t\n    63t\n    -37t\n    62t\n    70t\n    39t\n    -26t\n    73t\n    58t\n    125t\n    -7t\n    -81t\n    -79t\n    -13t\n    102t\n    -36t\n    -1t\n    -10t\n    -46t\n    48t\n    -122t\n    73t\n    36t\n    -5t\n    42t\n    80t\n    -62t\n    -52t\n    31t\n    88t\n    100t\n    -7t\n    96t\n    36t\n    -119t\n    -37t\n    -119t\n    48t\n    -2t\n    -73t\n    95t\n    83t\n    -3t\n    105t\n    -22t\n    -28t\n    -52t\n    26t\n    22t\n    -70t\n    -126t\n    54t\n    17t\n    99t\n    -2t\n    -123t\n    -15t\n    -23t\n    -39t\n    -20t\n    -46t\n    127t\n    -99t\n    8t\n    64t\n    75t\n    -84t\n    -115t\n    23t\n    -27t\n    92t\n    -77t\n    -11t\n    52t\n    42t\n    73t\n    -99t\n    11t\n    1t\n    -54t\n    -128t\n    67t\n    15t\n    -121t\n    49t\n    -18t\n    57t\n    -124t\n    -85t\n    -29t\n    1t\n    -53t\n    1t\n    101t\n    95t\n    60t\n    115t\n    -95t\n    44t\n    -5t\n    119t\n    -117t\n    83t\n    -114t\n    -24t\n    -38t\n    -55t\n    85t\n    -72t\n    -57t\n    36t\n    8t\n    91t\n    -101t\n    -13t\n    59t\n    4t\n    40t\n    -102t\n    -23t\n    -8t\n    -47t\n    -27t\n    -89t\n    23t\n    109t\n    -30t\n    -119t\n    87t\n    96t\n    78t\n    -96t\n    -22t\n    41t\n    16t\n    0t\n    91t\n    100t\n    115t\n    8t\n    77t\n    51t\n    119t\n    124t\n    -52t\n    -50t\n    -99t\n    -16t\n    69t\n    54t\n    -127t\n    113t\n    -104t\n    72t\n    109t\n    31t\n    26t\n    -71t\n    -59t\n    -87t\n    50t\n    -125t\n    69t\n    68t\n    74t\n    -105t\n    0t\n    -51t\n    1t\n    -2t\n    -75t\n    102t\n    22t\n    -89t\n    -120t\n    50t\n    -60t\n    -9t\n    -76t\n    -32t\n    -14t\n    122t\n    102t\n    -113t\n    -23t\n    116t\n    -2t\n    119t\n    -56t\n    12t\n    -8t\n    -32t\n    82t\n    116t\n    -80t\n    13t\n    -65t\n    96t\n    -65t\n    28t\n    -41t\n    72t\n    73t\n    -33t\n    -119t\n    124t\n    -118t\n    25t\n    -6t\n    -76t\n    -55t\n    -125t\n    57t\n    6t\n    52t\n    110t\n    -38t\n    -69t\n    36t\n    19t\n    -117t\n    39t\n    117t\n    85t\n    12t\n    112t\n    79t\n    -105t\n    75t\n    -25t\n    -8t\n    56t\n    -9t\n    -40t\n    -96t\n    13t\n    -27t\n    122t\n    -119t\n    -53t\n    -88t\n    -125t\n    73t\n    -20t\n    110t\n    43t\n    101t\n    19t\n    123t\n    43t\n    -90t\n    31t\n    61t\n    -13t\n    84t\n    -45t\n    95t\n    -61t\n    -55t\n    37t\n    -13t\n    -44t\n    113t\n    106t\n    64t\n    -66t\n    -53t\n    48t\n    -78t\n    108t\n    -33t\n    43t\n    59t\n    -100t\n    -9t\n    -108t\n    122t\n    -9t\n    -7t\n    127t\n    -54t\n    -77t\n    53t\n    111t\n    -127t\n    -85t\n    66t\n    78t\n    -10t\n    -103t\n    106t\n    -98t\n    124t\n    85t\n    -23t\n    -84t\n    6t\n    -88t\n    96t\n    35t\n    -56t\n    -23t\n    110t\n    -64t\n    -114t\n    -41t\n    50t\n    -33t\n    59t\n    76t\n    -26t\n    -35t\n    103t\n    -43t\n    -77t\n    -6t\n    -41t\n    46t\n    127t\n    81t\n    25t\n    82t\n    60t\n    -85t\n    -83t\n    56t\n    121t\n    -112t\n    -59t\n    -45t\n    -36t\n    -122t\n    13t\n    -128t\n    -103t\n    -24t\n    62t\n    21t\n    29t\n    -121t\n    -97t\n    54t\n    25t\n    -34t\n    -23t\n    21t\n    -22t\n    -52t\n    43t\n    33t\n    -105t\n    -111t\n    -31t\n    93t\n    27t\n    39t\n    38t\n    117t\n    -9t\n    -106t\n    77t\n    -75t\n    -88t\n    -52t\n    -17t\n    -49t\n    -30t\n    22t\n    -24t\n    85t\n    32t\n    -10t\n    87t\n    9t\n    122t\n    -53t\n    -82t\n    -128t\n    121t\n    63t\n    31t\n    -93t\n    70t\n    -87t\n    49t\n    110t\n    -105t\n    -21t\n    -71t\n    79t\n    -40t\n    -82t\n    10t\n    117t\n    -121t\n    59t\n    19t\n    -50t\n    46t\n    -119t\n    -75t\n    54t\n    9t\n    -45t\n    32t\n    -102t\n    -28t\n    111t\n    -94t\n    73t\n    -15t\n    114t\n    -24t\n    127t\n    41t\n    21t\n    -39t\n    -58t\n    80t\n    91t\n    111t\n    38t\n    24t\n    84t\n    17t\n    61t\n    -17t\n    -78t\n    -108t\n    -7t\n    15t\n    -24t\n    2t\n    -81t\n    -127t\n    97t\n    -98t\n    -121t\n    -91t\n    -17t\n    61t\n    -78t\n    -84t\n    -88t\n    46t\n    101t\n    127t\n    16t\n    -19t\n    49t\n    -108t\n    1t\n    -14t\n    -95t\n    26t\n    55t\n    41t\n    33t\n    -74t\n    76t\n    -45t\n    -108t\n    35t\n    -9t\n    39t\n    -87t\n    -25t\n    113t\n    -65t\n    98t\n    -90t\n    114t\n    -120t\n    44t\n    -57t\n    52t\n    -36t\n    49t\n    -114t\n    -119t\n    61t\n    82t\n    58t\n    -28t\n    -109t\n    15t\n    -59t\n    82t\n    65t\n    29t\n    -107t\n    43t\n    48t\n    86t\n    24t\n    -104t\n    28t\n    127t\n    -54t\n    -59t\n    1t\n    122t\n    121t\n    68t\n    102t\n    -118t\n    95t\n    -121t\n    97t\n    90t\n    -49t\n    -105t\n    82t\n    10t\n    -95t\n    25t\n    -29t\n    15t\n    -128t\n    -121t\n    93t\n    -115t\n    -128t\n    -126t\n    26t\n    106t\n    111t\n    90t\n    -18t\n    114t\n    123t\n    86t\n    -62t\n    37t\n    96t\n    81t\n    -32t\n    35t\n    106t\n    -36t\n    -47t\n    -117t\n    91t\n    1t\n    32t\n    0t\n    -41t\n    82t\n    23t\n    -19t\n    -126t\n    46t\n    118t\n    51t\n    -85t\n    53t\n    124t\n    42t\n    -19t\n    7t\n    -61t\n    -14t\n    44t\n    -23t\n    -121t\n    19t\n    -108t\n    73t\n    -9t\n    4t\n    -13t\n    114t\n    35t\n    -33t\n    46t\n    16t\n    122t\n    -89t\n    119t\n    51t\n    -120t\n    113t\n    8t\n    -35t\n    29t\n    5t\n    63t\n    -30t\n    -52t\n    39t\n    -25t\n    -65t\n    29t\n    -78t\n    -48t\n    -20t\n    79t\n    87t\n    -45t\n    4t\n    125t\n    -82t\n    -53t\n    88t\n    122t\n    -13t\n    -79t\n    122t\n    68t\n    93t\n    13t\n    114t\n    -100t\n    -88t\n    -112t\n    83t\n    -107t\n    8t\n    -76t\n    114t\n    -58t\n    -98t\n    -9t\n    114t\n    -3t\n    -31t\n    76t\n    -15t\n    122t\n    90t\n    39t\n    55t\n    -16t\n    -47t\n    32t\n    117t\n    -105t\n    -68t\n    -117t\n    25t\n    -75t\n    98t\n    -92t\n    74t\n    -95t\n    -45t\n    10t\n    -69t\n    94t\n    -59t\n    -111t\n    92t\n    24t\n    -42t\n    88t\n    4t\n    -20t\n    -25t\n    -86t\n    24t\n    -62t\n    75t\n    102t\n    -122t\n    -53t\n    95t\n    20t\n    -73t\n    10t\n    2t\n    60t\n    15t\n    -40t\n    -108t\n    59t\n    56t\n    86t\n    -8t\n    39t\n    -128t\n    19t\n    -107t\n    81t\n    16t\n    -31t\n    26t\n    120t\n    25t\n    113t\n    -98t\n    127t\n    -93t\n    -50t\n    82t\n    67t\n    26t\n    16t\n    16t\n    -66t\n    -22t\n    -118t\n    58t\n    12t\n    -88t\n    -25t\n    -112t\n    101t\n    32t\n    52t\n    90t\n    124t\n    81t\n    -80t\n    65t\n    8t\n    47t\n    -29t\n    -124t\n    43t\n    -92t\n    -24t\n    44t\n    32t\n    -91t\n    -64t\n    -21t\n    117t\n    41t\n    115t\n    76t\n    -27t\n    -11t\n    -9t\n    -123t\n    42t\n    110t\n    89t\n    5t\n    120t\n    -72t\n    67t\n    59t\n    89t\n    -118t\n    50t\n    -125t\n    71t\n    -62t\n    48t\n    19t\n    96t\n    -128t\n    98t\n    56t\n    50t\n    17t\n    4t\n    112t\n    -68t\n    75t\n    53t\n    86t\n    -103t\n    -21t\n    -25t\n    44t\n    25t\n    -125t\n    -74t\n    -63t\n    121t\n    2t\n    3t\n    -96t\n    -12t\n    121t\n    -32t\n    -122t\n    58t\n    56t\n    69t\n    -122t\n    87t\n    68t\n    28t\n    94t\n    -37t\n    -88t\n    65t\n    24t\n    116t\n    -83t\n    -118t\n    -28t\n    -70t\n    -109t\n    -28t\n    109t\n    -76t\n    -128t\n    -101t\n    64t\n    58t\n    87t\n    14t\n    119t\n    -67t\n    -87t\n    -4t\n    -75t\n    127t\n    -127t\n    -13t\n    115t\n    -81t\n    77t\n    -121t\n    75t\n    37t\n    -86t\n    -1t\n    -46t\n    18t\n    68t\n    -113t\n    -66t\n    -45t\n    -84t\n    94t\n    -87t\n    27t\n    -95t\n    -54t\n    11t\n    31t\n    49t\n    -40t\n    2t\n    -101t\n    -1t\n    -82t\n    -87t\n    0t\n    118t\n    1t\n    8t\n    -54t\n    -9t\n    -63t\n    55t\n    -53t\n    -73t\n    94t\n    52t\n    -25t\n    72t\n    51t\n    28t\n    -18t\n    89t\n    96t\n    23t\n    97t\n    5t\n    66t\n    48t\n    8t\n    43t\n    8t\n    -27t\n    -109t\n    -9t\n    -9t\n    -41t\n    113t\n    76t\n    -57t\n    22t\n    95t\n    -100t\n    -51t\n    -2t\n    -52t\n    -55t\n    -88t\n    110t\n    -38t\n    64t\n    -51t\n    105t\n    122t\n    22t\n    107t\n    -105t\n    -74t\n    -1t\n    -106t\n    106t\n    -119t\n    -103t\n    -58t\n    7t\n    81t\n    53t\n    25t\n    111t\n    -67t\n    -25t\n    -122t\n    -68t\n    -7t\n    63t\n    78t\n    -117t\n    -32t\n    -50t\n    -116t\n    -13t\n    -3t\n    -47t\n    -83t\n    -28t\n    118t\n    55t\n    123t\n    -117t\n    89t\n    -78t\n    -70t\n    -28t\n    -30t\n    99t\n    -100t\n    70t\n    103t\n    81t\n    46t\n    65t\n    -81t\n    100t\n    -110t\n    -19t\n    -20t\n    60t\n    30t\n    -2t\n    -50t\n    -62t\n    8t\n    61t\n    -93t\n    46t\n    -81t\n    5t\n    42t\n    -63t\n    97t\n    83t\n    43t\n    98t\n    11t\n    29t\n    16t\n    -97t\n    -74t\n    -69t\n    -10t\n    -86t\n    26t\n    -98t\n    -110t\n    -9t\n    48t\n    -35t\n    103t\n    -26t\n    20t\n    -109t\n    -67t\n    -78t\n    -34t\n    -38t\n    -26t\n    -94t\n    -14t\n    -85t\n    -18t\n    88t\n    -120t\n    -49t\n    -52t\n    -37t\n    -45t\n    81t\n    -121t\n    -69t\n    -65t\n    -85t\n    86t\n    -117t\n    -71t\n    48t\n    101t\n    -106t\n    -13t\n    51t\n    81t\n    14t\n    -84t\n    -6t\n    77t\n    -6t\n    28t\n    88t\n    69t\n    -81t\n    104t\n    122t\n    -16t\n    79t\n    -87t\n    112t\n    -47t\n    -74t\n    -11t\n    14t\n    90t\n    -126t\n    -78t\n    97t\n    -102t\n    -76t\n    100t\n    29t\n    109t\n    122t\n    102t\n    59t\n    -29t\n    117t\n    -31t\n    -106t\n    61t\n    4t\n    -3t\n    -10t\n    -102t\n    -56t\n    91t\n    15t\n    -116t\n    -83t\n    -27t\n    26t\n    -110t\n    -44t\n    67t\n    14t\n    101t\n    113t\n    -88t\n    69t\n    -30t\n    -93t\n    -107t\n    -125t\n    -73t\n    8t\n    73t\n    70t\n    97t\n    118t\n    104t\n    -20t\n    -53t\n    -80t\n    71t\n    93t\n    2t\n    90t\n    -19t\n    40t\n    57t\n    -3t\n    105t\n    -46t\n    54t\n    -81t\n    -59t\n    -64t\n    29t\n    42t\n    44t\n    -103t\n    42t\n    -67t\n    -79t\n    -82t\n    100t\n    93t\n    62t\n    -8t\n    15t\n    -84t\n    47t\n    89t\n    0t\n    99t\n    -77t\n    64t\n    -74t\n    -46t\n    -26t\n    102t\n    64t\n    41t\n    -5t\n    -14t\n    -26t\n    106t\n    -37t\n    17t\n    -53t\n    -25t\n    -99t\n    95t\n    77t\n    105t\n    118t\n    3t\n    123t\n    -103t\n    -127t\n    89t\n    89t\n    -109t\n    -81t\n    27t\n    100t\n    67t\n    92t\n    122t\n    5t\n    102t\n    -34t\n    65t\n    118t\n    121t\n    -21t\n    -44t\n    34t\n    52t\n    78t\n    81t\n    -109t\n    123t\n    -11t\n    -127t\n    39t\n    114t\n    -123t\n    0t\n    54t\n    -19t\n    -22t\n    90t\n    50t\n    113t\n    92t\n    -116t\n    13t\n    42t\n    117t\n    112t\n    19t\n    -27t\n    -117t\n    -64t\n    -53t\n    -69t\n    -70t\n    -128t\n    -75t\n    -10t\n    0t\n    89t\n    78t\n    42t\n    28t\n    50t\n    -25t\n    69t\n    1t\n    97t\n    -51t\n    -84t\n    27t\n    4t\n    91t\n    17t\n    3t\n    -108t\n    94t\n    -41t\n    78t\n    26t\n    98t\n    -5t\n    116t\n    -25t\n    -73t\n    5t\n    -122t\n    -112t\n    -21t\n    -65t\n    -53t\n    127t\n    -77t\n    59t\n    -97t\n    15t\n    58t\n    28t\n    -121t\n    -113t\n    -80t\n    115t\n    -57t\n    -76t\n    -4t\n    -71t\n    106t\n    103t\n    -63t\n    29t\n    32t\n    15t\n    -108t\n    118t\n    9t\n    -38t\n    122t\n    -54t\n    47t\n    85t\n    10t\n    59t\n    14t\n    63t\n    -44t\n    92t\n    -63t\n    76t\n    60t\n    -9t\n    53t\n    -86t\n    -46t\n    -58t\n    -75t\n    98t\n    24t\n    -67t\n    107t\n    -79t\n    65t\n    -58t\n    24t\n    102t\n    -63t\n    50t\n    -36t\n    31t\n    66t\n    -75t\n    -110t\n    113t\n    -55t\n    -15t\n    -39t\n    66t\n    18t\n    -101t\n    -78t\n    -109t\n    -22t\n    96t\n    -51t\n    68t\n    111t\n    41t\n    14t\n    30t\n    123t\n    49t\n    89t\n    -46t\n    -105t\n    31t\n    102t\n    19t\n    -45t\n    -88t\n    -43t\n    86t\n    121t\n    -64t\n    50t\n    -75t\n    -71t\n    31t\n    -110t\n    13t\n    -101t\n    59t\n    14t\n    101t\n    41t\n    111t\n    -17t\n    20t\n    -46t\n    70t\n    116t\n    -43t\n    -90t\n    -111t\n    -85t\n    53t\n    52t\n    17t\n    -65t\n    -111t\n    68t\n    -70t\n    124t\n    -66t\n    -76t\n    122t\n    -1t\n    68t\n    112t\n    -9t\n    -27t\n    -92t\n    79t\n    116t\n    -53t\n    88t\n    28t\n    -94t\n    -103t\n    -86t\n    -66t\n    -32t\n    75t\n    -124t\n    -52t\n    3t\n    -69t\n    83t\n    -87t\n    -25t\n    -104t\n    -61t\n    -79t\n    8t\n    40t\n    86t\n    -122t\n    -53t\n    -77t\n    -3t\n    105t\n    102t\n    -19t\n    -54t\n    58t\n    -20t\n    -70t\n    -73t\n    -125t\n    -106t\n    101t\n    62t\n    -63t\n    -100t\n    82t\n    42t\n    22t\n    70t\n    76t\n    37t\n    -90t\n    125t\n    -21t\n    119t\n    62t\n    99t\n    40t\n    -15t\n    63t\n    116t\n    46t\n    50t\n    -115t\n    -122t\n    84t\n    -50t\n    -4t\n    18t\n    110t\n    -81t\n    3t\n    66t\n    22t\n    78t\n    75t\n    11t\n    107t\n    117t\n    95t\n    26t\n    -94t\n    3t\n    -5t\n    89t\n    5t\n    88t\n    -33t\n    -122t\n    -83t\n    -31t\n    -90t\n    -78t\n    104t\n    -86t\n    -46t\n    116t\n    28t\n    -120t\n    64t\n    -66t\n    89t\n    -39t\n    84t\n    -6t\n    -76t\n    57t\n    -11t\n    -100t\n    -2t\n    73t\n    27t\n    -107t\n    -52t\n    -96t\n    107t\n    -48t\n    -66t\n    -9t\n    103t\n    98t\n    50t\n    -71t\n    111t\n    -35t\n    -47t\n    123t\n    92t\n    7t\n    -66t\n    -99t\n    34t\n    -32t\n    124t\n    -73t\n    -78t\n    116t\n    -123t\n    -39t\n    -33t\n    77t\n    64t\n    -39t\n    7t\n    15t\n    -55t\n    -105t\n    36t\n    -115t\n    -93t\n    71t\n    7t\n    14t\n    13t\n    45t\n    32t\n    -112t\n    -96t\n    -35t\n    110t\n    35t\n    -118t\n    -85t\n    98t\n    28t\n    82t\n    89t\n    -47t\n    34t\n    -86t\n    12t\n    111t\n    -18t\n    -114t\n    30t\n    -99t\n    62t\n    -53t\n    127t\n    -1t\n    -55t\n    -126t\n    -80t\n    0t\n    31t\n    -37t\n    110t\n    -111t\n    11t\n    -119t\n    104t\n    105t\n    -13t\n    42t\n    -71t\n    32t\n    -37t\n    43t\n    -96t\n    -97t\n    100t\n    -84t\n    -76t\n    -83t\n    82t\n    57t\n    -40t\n    -33t\n    86t\n    -74t\n    -48t\n    51t\n    -69t\n    -89t\n    26t\n    -115t\n    -104t\n    121t\n    84t\n    -81t\n    122t\n    -95t\n    126t\n    -15t\n    57t\n    30t\n    -29t\n    -83t\n    -89t\n    -25t\n    91t\n    87t\n    59t\n    86t\n    -126t\n    -81t\n    34t\n    34t\n    63t\n    -83t\n    116t\n    -23t\n    -60t\n    -14t\n    105t\n    -17t\n    -94t\n    98t\n    -15t\n    41t\n    -58t\n    -94t\n    25t\n    100t\n    -49t\n    -67t\n    60t\n    58t\n    7t\n    55t\n    20t\n    30t\n    -116t\n    67t\n    -125t\n    -81t\n    -43t\n    -36t\n    89t\n    -30t\n    114t\n    119t\n    79t\n    -89t\n    50t\n    115t\n    36t\n    -35t\n    -26t\n    -40t\n    25t\n    -60t\n    65t\n    101t\n    -73t\n    112t\n    -17t\n    -73t\n    11t\n    -82t\n    -58t\n    -32t\n    45t\n    -26t\n    -10t\n    -50t\n    -18t\n    -49t\n    -38t\n    -24t\n    18t\n    76t\n    75t\n    117t\n    110t\n    125t\n    53t\n    -37t\n    -125t\n    -108t\n    10t\n    -41t\n    -79t\n    73t\n    9t\n    44t\n    78t\n    -27t\n    -64t\n    -124t\n    112t\n    -90t\n    -19t\n    -29t\n    -74t\n    -107t\n    -17t\n    14t\n    -112t\n    116t\n    -93t\n    -90t\n    8t\n    -13t\n    -40t\n    36t\n    -119t\n    -78t\n    63t\n    -91t\n    24t\n    114t\n    116t\n    22t\n    28t\n    30t\n    -49t\n    48t\n    70t\n    -41t\n    -126t\n    21t\n    108t\n    -98t\n    45t\n    -63t\n    -98t\n    -28t\n    81t\n    85t\n    -74t\n    78t\n    -127t\n    89t\n    56t\n    -103t\n    -126t\n    43t\n    -128t\n    -76t\n    123t\n    59t\n    -67t\n    65t\n    -26t\n    3t\n    -113t\n    34t\n    24t\n    -24t\n    -9t\n    68t\n    1t\n    -115t\n    46t\n    -48t\n    -119t\n    41t\n    -40t\n    -11t\n    -67t\n    103t\n    -52t\n    126t\n    -4t\n    88t\n    -85t\n    -69t\n    -7t\n    -76t\n    71t\n    19t\n    122t\n    98t\n    121t\n    -3t\n    -4t\n    -25t\n    106t\n    34t\n    -125t\n    62t\n    113t\n    -62t\n    -116t\n    71t\n    -30t\n    117t\n    64t\n    127t\n    -124t\n    -1t\n    102t\n    126t\n    82t\n    34t\n    -94t\n    79t\n    -66t\n    88t\n    7t\n    -123t\n    120t\n    -92t\n    122t\n    -103t\n    22t\n    98t\n    -97t\n    96t\n    5t\n    -87t\n    -9t\n    -128t\n    113t\n    -116t\n    -61t\n    7t\n    -22t\n    8t\n    -59t\n    20t\n    27t\n    -34t\n    0t\n    -71t\n    -27t\n    -62t\n    85t\n    -105t\n    -126t\n    57t\n    16t\n    55t\n    -11t\n    -22t\n    -66t\n    -30t\n    1t\n    -93t\n    -121t\n    -85t\n    66t\n    -81t\n    27t\n    103t\n    92t\n    16t\n    102t\n    -71t\n    43t\n    111t\n    -46t\n    -44t\n    -125t\n    105t\n    -98t\n    -110t\n    -8t\n    21t\n    -36t\n    -107t\n    -85t\n    118t\n    -83t\n    -67t\n    70t\n    7t\n    -64t\n    -113t\n    117t\n    114t\n    -104t\n    36t\n    -76t\n    41t\n    -14t\n    -52t\n    98t\n    65t\n    -81t\n    -107t\n    63t\n    -29t\n    42t\n    52t\n    115t\n    29t\n    -113t\n    -71t\n    117t\n    -105t\n    101t\n    76t\n    33t\n    97t\n    80t\n    -88t\n    -126t\n    116t\n    -113t\n    49t\n    58t\n    -46t\n    -117t\n    32t\n    -89t\n    114t\n    -86t\n    -95t\n    -91t\n    64t\n    58t\n    20t\n    87t\n    60t\n    -10t\n    41t\n    -128t\n    -125t\n    20t\n    -85t\n    -51t\n    91t\n    53t\n    -42t\n    18t\n    -106t\n    -38t\n    97t\n    -58t\n    -71t\n    -57t\n    22t\n    -113t\n    -49t\n    -80t\n    -63t\n    93t\n    60t\n    61t\n    -70t\n    70t\n    -24t\n    34t\n    49t\n    -40t\n    -21t\n    -73t\n    -117t\n    12t\n    -122t\n    26t\n    15t\n    -8t\n    102t\n    -82t\n    75t\n    -9t\n    -74t\n    -71t\n    25t\n    103t\n    -53t\n    -23t\n    89t\n    106t\n    -65t\n    14t\n    126t\n    52t\n    124t\n    86t\n    -92t\n    -12t\n    -9t\n    119t\n    -116t\n    -71t\n    -21t\n    103t\n    -59t\n    41t\n    53t\n    -18t\n    17t\n    67t\n    -114t\n    106t\n    -46t\n    -2t\n    35t\n    -59t\n    74t\n    95t\n    87t\n    64t\n    73t\n    -52t\n    -43t\n    -35t\n    -95t\n    54t\n    -3t\n    56t\n    -15t\n    -49t\n    20t\n    10t\n    22t\n    -67t\n    113t\n    -112t\n    111t\n    98t\n    -14t\n    -28t\n    109t\n    119t\n    -120t\n    -90t\n    -32t\n    -89t\n    46t\n    -65t\n    78t\n    106t\n    -75t\n    -108t\n    -97t\n    103t\n    -86t\n    -128t\n    -28t\n    -42t\n    -72t\n    80t\n    -52t\n    39t\n    -101t\n    -127t\n    -22t\n    12t\n    -74t\n    89t\n    45t\n    70t\n    -44t\n    -70t\n    43t\n    -6t\n    -91t\n    -108t\n    125t\n    -58t\n    68t\n    117t\n    40t\n    83t\n    -28t\n    115t\n    -102t\n    -81t\n    108t\n    111t\n    -118t\n    -101t\n    98t\n    -56t\n    102t\n    -14t\n    -18t\n    9t\n    -92t\n    -126t\n    108t\n    -78t\n    -93t\n    -75t\n    -49t\n    95t\n    13t\n    56t\n    78t\n    26t\n    67t\n    -83t\n    -71t\n    64t\n    -85t\n    -109t\n    -98t\n    -78t\n    -3t\n    -127t\n    -67t\n    -96t\n    121t\n    -5t\n    73t\n    -102t\n    121t\n    -39t\n    -4t\n    30t\n    -65t\n    -99t\n    84t\n    -45t\n    -84t\n    43t\n    100t\n    -106t\n    -8t\n    59t\n    -78t\n    18t\n    -86t\n    30t\n    -63t\n    97t\n    58t\n    -125t\n    -96t\n    -97t\n    84t\n    6t\n    -13t\n    86t\n    -2t\n    -121t\n    119t\n    -90t\n    -7t\n    113t\n    -24t\n    56t\n    55t\n    87t\n    102t\n    84t\n    66t\n    52t\n    110t\n    -14t\n    118t\n    42t\n    -104t\n    38t\n    -119t\n    60t\n    -103t\n    -121t\n    -10t\n    -84t\n    85t\n    59t\n    111t\n    -102t\n    -9t\n    50t\n    70t\n    111t\n    -116t\n    23t\n    23t\n    54t\n    20t\n    -73t\n    -64t\n    30t\n    -105t\n    -107t\n    -31t\n    93t\n    -23t\n    -102t\n    94t\n    15t\n    -26t\n    11t\n    -109t\n    -22t\n    90t\n    -34t\n    30t\n    -123t\n    117t\n    -62t\n    -20t\n    12t\n    -35t\n    7t\n    -70t\n    -7t\n    57t\n    -31t\n    -76t\n    -76t\n    -118t\n    21t\n    -90t\n    -102t\n    -89t\n    81t\n    -50t\n    89t\n    -22t\n    -9t\n    -53t\n    17t\n    -10t\n    49t\n    40t\n    -113t\n    -114t\n    41t\n    -62t\n    91t\n    23t\n    -126t\n    -76t\n    67t\n    -25t\n    -85t\n    -32t\n    117t\n    -79t\n    -112t\n    50t\n    122t\n    79t\n    12t\n    32t\n    -12t\n    -102t\n    109t\n    -18t\n    -116t\n    -58t\n    -80t\n    30t\n    57t\n    -84t\n    -52t\n    -117t\n    114t\n    67t\n    -71t\n    16t\n    51t\n    99t\n    -77t\n    -29t\n    -40t\n    -23t\n    -55t\n    -11t\n    50t\n    127t\n    95t\n    92t\n    61t\n    84t\n    -107t\n    -111t\n    38t\n    -20t\n    46t\n    -109t\n    63t\n    -108t\n    18t\n    24t\n    -18t\n    -59t\n    -85t\n    -77t\n    -102t\n    61t\n    50t\n    86t\n    102t\n    127t\n    34t\n    -122t\n    29t\n    -67t\n    87t\n    54t\n    53t\n    43t\n    53t\n    113t\n    -1t\n    30t\n    18t\n    -18t\n    -117t\n    117t\n    -94t\n    19t\n    78t\n    -75t\n    -66t\n    41t\n    38t\n    78t\n    118t\n    46t\n    76t\n    93t\n    -72t\n    -118t\n    77t\n    -18t\n    -114t\n    96t\n    -89t\n    -12t\n    54t\n    -77t\n    -67t\n    111t\n    -75t\n    91t\n    77t\n    15t\n    -116t\n    -102t\n    -79t\n    28t\n    50t\n    30t\n    66t\n    18t\n    -90t\n    -112t\n    -14t\n    22t\n    91t\n    64t\n    98t\n    -96t\n    -106t\n    -88t\n    127t\n    85t\n    -8t\n    26t\n    13t\n    84t\n    -62t\n    44t\n    27t\n    -3t\n    46t\n    100t\n    70t\n    -23t\n    -7t\n    18t\n    70t\n    106t\n    6t\n    15t\n    13t\n    -115t\n    20t\n    -28t\n    114t\n    -120t\n    28t\n    120t\n    -34t\n    -70t\n    -25t\n    -65t\n    4t\n    39t\n    127t\n    117t\n    -84t\n    12t\n    64t\n    -67t\n    7t\n    31t\n    -4t\n    -109t\n    -127t\n    108t\n    -80t\n    -93t\n    79t\n    102t\n    -12t\n    24t\n    -21t\n    25t\n    104t\n    -28t\n    93t\n    -101t\n    -15t\n    -96t\n    -30t\n    85t\n    -96t\n    -43t\n    26t\n    117t\n    102t\n    99t\n    105t\n    123t\n    -46t\n    81t\n    -120t\n    -64t\n    -74t\n    -3t\n    -56t\n    -114t\n    23t\n    45t\n    18t\n    -9t\n    -76t\n    -22t\n    21t\n    -24t\n    -68t\n    25t\n    8t\n    69t\n    -103t\n    17t\n    123t\n    4t\n    49t\n    60t\n    38t\n    -97t\n    120t\n    90t\n    -115t\n    85t\n    -23t\n    -115t\n    -11t\n    -90t\n    -23t\n    -35t\n    59t\n    37t\n    -120t\n    69t\n    39t\n    68t\n    -76t\n    -101t\n    123t\n    -83t\n    95t\n    20t\n    -127t\n    84t\n    -35t\n    116t\n    42t\n    -41t\n    -75t\n    11t\n    -21t\n    -89t\n    -7t\n    -82t\n    -73t\n    125t\n    124t\n    66t\n    104t\n    -66t\n    38t\n    -103t\n    27t\n    86t\n    17t\n    7t\n    -12t\n    21t\n    -100t\n    -44t\n    25t\n    100t\n    -44t\n    113t\n    90t\n    -29t\n    28t\n    36t\n    109t\n    -76t\n    -6t\n    55t\n    -7t\n    55t\n    -49t\n    -40t\n    71t\n    109t\n    57t\n    45t\n    48t\n    39t\n    55t\n    -65t\n    -108t\n    -78t\n    -19t\n    -82t\n    55t\n    7t\n    5t\n    102t\n    89t\n    -52t\n    -123t\n    -46t\n    -71t\n    75t\n    -113t\n    80t\n    -103t\n    -107t\n    78t\n    13t\n    101t\n    124t\n    37t\n    6t\n    -117t\n    -124t\n    -82t\n    -67t\n    -38t\n    -125t\n    -82t\n    -42t\n    -105t\n    116t\n    -86t\n    127t\n    34t\n    -88t\n    26t\n    -77t\n    26t\n    10t\n    -39t\n    -14t\n    84t\n    -23t\n    -81t\n    102t\n    30t\n    -106t\n    65t\n    -95t\n    -93t\n    17t\n    61t\n    81t\n    -73t\n    -82t\n    -27t\n    28t\n    -63t\n    55t\n    105t\n    -22t\n    108t\n    67t\n    111t\n    -5t\n    10t\n    32t\n    -91t\n    -61t\n    43t\n    -34t\n    -23t\n    38t\n    -120t\n    112t\n    57t\n    -1t\n    39t\n    58t\n    -99t\n    -79t\n    24t\n    113t\n    -71t\n    95t\n    -51t\n    -31t\n    -63t\n    -74t\n    -28t\n    -110t\n    38t\n    -7t\n    45t\n    -12t\n    -27t\n    63t\n    28t\n    -13t\n    110t\n    89t\n    -44t\n    -106t\n    40t\n    -13t\n    87t\n    -81t\n    69t\n    13t\n    125t\n    53t\n    -70t\n    -44t\n    -101t\n    102t\n    26t\n    117t\n    123t\n    71t\n    -26t\n    87t\n    22t\n    -93t\n    78t\n    -50t\n    56t\n    -20t\n    111t\n    -21t\n    52t\n    -56t\n    -85t\n    -42t\n    120t\n    3t\n    -53t\n    8t\n    38t\n    -15t\n    -6t\n    -96t\n    30t\n    109t\n    -58t\n    29t\n    -120t\n    -9t\n    -84t\n    -50t\n    57t\n    111t\n    6t\n    15t\n    14t\n    111t\n    125t\n    88t\n    -93t\n    37t\n    45t\n    -11t\n    23t\n    19t\n    105t\n    -27t\n    -50t\n    47t\n    9t\n    -34t\n    -8t\n    53t\n    -13t\n    105t\n    54t\n    126t\n    9t\n    -95t\n    59t\n    62t\n    -122t\n    -106t\n    65t\n    46t\n    7t\n    18t\n    -13t\n    -48t\n    -126t\n    -12t\n    -64t\n    -94t\n    98t\n    71t\n    34t\n    -45t\n    46t\n    53t\n    -58t\n    -83t\n    17t\n    111t\n    113t\n    -16t\n    9t\n    16t\n    11t\n    76t\n    80t\n    -23t\n    -79t\n    103t\n    -89t\n    120t\n    60t\n    109t\n    -72t\n    8t\n    -84t\n    50t\n    72t\n    -103t\n    -15t\n    -114t\n    -35t\n    105t\n    15t\n    -96t\n    11t\n    -88t\n    67t\n    -74t\n    1t\n    62t\n    102t\n    126t\n    88t\n    -19t\n    122t\n    -73t\n    124t\n    -121t\n    9t\n    -74t\n    45t\n    -14t\n    124t\n    66t\n    -70t\n    -78t\n    -1t\n    69t\n    64t\n    -33t\n    95t\n    -63t\n    43t\n    -117t\n    122t\n    97t\n    6t\n    85t\n    -106t\n    -76t\n    -20t\n    -127t\n    -116t\n    6t\n    33t\n    -23t\n    71t\n    36t\n    33t\n    -45t\n    -30t\n    63t\n    24t\n    -47t\n    -29t\n    -53t\n    -3t\n    -24t\n    36t\n    -36t\n    80t\n    100t\n    82t\n    4t\n    113t\n    48t\n    -17t\n    -49t\n    -66t\n    93t\n    79t\n    3t\n    47t\n    -30t\n    49t\n    -118t\n    -64t\n    2t\n    106t\n    116t\n    -20t\n    -72t\n    72t\n    39t\n    50t\n    -95t\n    94t\n    106t\n    18t\n    114t\n    -42t\n    -116t\n    -123t\n    -91t\n    -76t\n    105t\n    -93t\n    50t\n    32t\n    106t\n    -52t\n    93t\n    -96t\n    -40t\n    46t\n    99t\n    77t\n    -71t\n    -127t\n    29t\n    -29t\n    20t\n    -103t\n    -2t\n    -44t\n    103t\n    2t\n    0t\n    21t\n    79t\n    -93t\n    43t\n    -8t\n    1t\n    -32t\n    -72t\n    -98t\n    9t\n    36t\n    -81t\n    7t\n    114t\n    38t\n    3t\n    90t\n    -41t\n    -16t\n    -72t\n    -104t\n    8t\n    9t\n    26t\n    36t\n    39t\n    112t\n    -82t\n    47t\n    -16t\n    86t\n    -18t\n    -57t\n    109t\n    105t\n    62t\n    -94t\n    57t\n    5t\n    -86t\n    99t\n    117t\n    110t\n    37t\n    -120t\n    -41t\n    118t\n    -66t\n    -108t\n    60t\n    -120t\n    12t\n    104t\n    -70t\n    56t\n    -52t\n    16t\n    43t\n    -96t\n    60t\n    41t\n    124t\n    57t\n    -103t\n    125t\n    103t\n    25t\n    -117t\n    83t\n    59t\n    95t\n    112t\n    -55t\n    90t\n    91t\n    -69t\n    0t\n    -104t\n    -105t\n    91t\n    -26t\n    77t\n    26t\n    29t\n    -109t\n    -65t\n    53t\n    -1t\n    -82t\n    118t\n    -80t\n    17t\n    -5t\n    -17t\n    -11t\n    114t\n    -43t\n    -7t\n    96t\n    23t\n    32t\n    119t\n    2t\n    114t\n    -90t\n    -4t\n    34t\n    12t\n    -85t\n    112t\n    -82t\n    73t\n    -105t\n    -62t\n    62t\n    -79t\n    -46t\n    -41t\n    97t\n    -126t\n    -43t\n    22t\n    -61t\n    -62t\n    -106t\n    10t\n    81t\n    85t\n    65t\n    18t\n    99t\n    -39t\n    -119t\n    -23t\n    -73t\n    -96t\n    114t\n    55t\n    -54t\n    11t\n    -66t\n    19t\n    82t\n    51t\n    25t\n    -14t\n    12t\n    49t\n    42t\n    -60t\n    126t\n    -2t\n    23t\n    -19t\n    -79t\n    -31t\n    0t\n    -122t\n    122t\n    -111t\n    -12t\n    53t\n    -39t\n    22t\n    96t\n    -31t\n    96t\n    -58t\n    -13t\n    74t\n    40t\n    47t\n    -79t\n    118t\n    -105t\n    -108t\n    -54t\n    -95t\n    21t\n    -12t\n    -87t\n    104t\n    -104t\n    77t\n    45t\n    40t\n    -42t\n    -120t\n    61t\n    -126t\n    -22t\n    -98t\n    -103t\n    61t\n    100t\n    63t\n    -104t\n    -87t\n    -5t\n    93t\n    23t\n    -11t\n    -27t\n    -20t\n    36t\n    -105t\n    -14t\n    75t\n    -4t\n    -114t\n    -3t\n    23t\n    86t\n    -108t\n    112t\n    15t\n    100t\n    -33t\n    25t\n    -128t\n    98t\n    -1t\n    84t\n    96t\n    -116t\n    28t\n    -94t\n    0t\n    121t\n    -83t\n    111t\n    122t\n    76t\n    -80t\n    116t\n    8t\n    12t\n    123t\n    72t\n    -81t\n    127t\n    82t\n    6t\n    57t\n    98t\n    92t\n    57t\n    82t\n    -120t\n    -23t\n    114t\n    21t\n    99t\n    -128t\n    -128t\n    96t\n    -113t\n    -74t\n    -21t\n    61t\n    62t\n    3t\n    -14t\n    -2t\n    95t\n    -21t\n    -53t\n    102t\n    111t\n    -87t\n    28t\n    26t\n    75t\n    -6t\n    65t\n    -53t\n    -72t\n    -34t\n    90t\n    -77t\n    113t\n    -40t\n    11t\n    94t\n    -1t\n    -80t\n    -54t\n    29t\n    43t\n    108t\n    38t\n    -10t\n    5t\n    36t\n    -91t\n    21t\n    40t\n    -82t\n    44t\n    109t\n    -54t\n    105t\n    6t\n    66t\n    77t\n    11t\n    110t\n    64t\n    20t\n    82t\n    46t\n    91t\n    8t\n    82t\n    79t\n    -116t\n    -22t\n    20t\n    -13t\n    117t\n    -14t\n    -44t\n    78t\n    -33t\n    102t\n    57t\n    -114t\n    -54t\n    -20t\n    102t\n    -35t\n    36t\n    -72t\n    17t\n    -106t\n    -39t\n    79t\n    -120t\n    109t\n    -48t\n    68t\n    -36t\n    72t\n    -115t\n    -6t\n    43t\n    -108t\n    -77t\n    -88t\n    100t\n    68t\n    25t\n    -98t\n    -85t\n    -73t\n    -52t\n    -3t\n    29t\n    -116t\n    114t\n    -9t\n    15t\n    48t\n    -20t\n    29t\n    103t\n    58t\n    -54t\n    -27t\n    -71t\n    98t\n    -48t\n    -22t\n    -48t\n    -64t\n    28t\n    -94t\n    -39t\n    -106t\n    -99t\n    123t\n    23t\n    117t\n    -122t\n    30t\n    12t\n    -4t\n    -98t\n    -97t\n    -66t\n    -20t\n    -118t\n    46t\n    -37t\n    123t\n    18t\n    -103t\n    14t\n    70t\n    117t\n    -28t\n    81t\n    24t\n    -43t\n    -82t\n    39t\n    84t\n    -55t\n    -43t\n    6t\n    83t\n    24t\n    -43t\n    -38t\n    107t\n    82t\n    115t\n    56t\n    116t\n    -76t\n    57t\n    -53t\n    -107t\n    43t\n    93t\n    -10t\n    -39t\n    -126t\n    -101t\n    -105t\n    64t\n    57t\n    52t\n    84t\n    10t\n    113t\n    66t\n    0t\n    -54t\n    -48t\n    123t\n    -84t\n    122t\n    8t\n    -66t\n    60t\n    17t\n    98t\n    69t\n    -46t\n    -72t\n    -59t\n    -102t\n    60t\n    -82t\n    53t\n    -102t\n    85t\n    72t\n    4t\n    -101t\n    118t\n    -104t\n    -20t\n    18t\n    48t\n    87t\n    -54t\n    -87t\n    4t\n    60t\n    76t\n    51t\n    -40t\n    -62t\n    -59t\n    -104t\n    -31t\n    -118t\n    99t\n    -123t\n    25t\n    -106t\n    -24t\n    -13t\n    -67t\n    0t\n    19t\n    -95t\n    -38t\n    118t\n    -52t\n    -98t\n    -107t\n    119t\n    -55t\n    -84t\n    -46t\n    -89t\n    -9t\n    -93t\n    -119t\n    -104t\n    95t\n    103t\n    113t\n    -68t\n    -5t\n    35t\n    126t\n    -112t\n    -83t\n    123t\n    88t\n    -27t\n    92t\n    -9t\n    -30t\n    37t\n    5t\n    -96t\n    -38t\n    -64t\n    -104t\n    -2t\n    6t\n    -66t\n    -53t\n    -75t\n    -51t\n    -2t\n    -1t\n    19t\n    -46t\n    -44t\n    27t\n    66t\n    41t\n    -73t\n    -29t\n    -9t\n    -37t\n    119t\n    17t\n    -105t\n    19t\n    -111t\n    48t\n    6t\n    33t\n    94t\n    -16t\n    1t\n    -42t\n    80t\n    50t\n    114t\n    3t\n    41t\n    39t\n    -120t\n    -77t\n    37t\n    -108t\n    -70t\n    10t\n    48t\n    -75t\n    -111t\n    43t\n    60t\n    -117t\n    -109t\n    9t\n    100t\n    -16t\n    48t\n    101t\n    -33t\n    -91t\n    -46t\n    -2t\n    7t\n    -96t\n    127t\n    37t\n    71t\n    -114t\n    -61t\n    -100t\n    44t\n    25t\n    82t\n    -71t\n    114t\n    116t\n    -61t\n    -107t\n    -78t\n    -24t\n    -109t\n    -84t\n    6t\n    -16t\n    -117t\n    -70t\n    24t\n    -70t\n    118t\n    31t\n    -119t\n    -22t\n    -74t\n    -102t\n    -125t\n    97t\n    17t\n    -33t\n    7t\n    -68t\n    127t\n    -113t\n    33t\n    122t\n    85t\n    68t\n    21t\n    -39t\n    82t\n    83t\n    97t\n    81t\n    5t\n    26t\n    116t\n    -34t\n    83t\n    70t\n    -112t\n    41t\n    83t\n    -19t\n    -124t\n    -101t\n    77t\n    123t\n    82t\n    -73t\n    -60t\n    -97t\n    33t\n    124t\n    5t\n    9t\n    22t\n    -29t\n    -122t\n    53t\n    -114t\n    100t\n    123t\n    79t\n    58t\n    122t\n    -53t\n    -63t\n    -65t\n    -102t\n    116t\n    -116t\n    14t\n    -109t\n    38t\n    8t\n    -112t\n    82t\n    -59t\n    -85t\n    35t\n    -121t\n    -97t\n    -50t\n    -31t\n    -63t\n    1t\n    85t\n    -114t\n    -1t\n    104t\n    -51t\n    71t\n    68t\n    -30t\n    19t\n    -43t\n    -64t\n    84t\n    66t\n    13t\n    -96t\n    -116t\n    -91t\n    109t\n    23t\n    77t\n    115t\n    73t\n    5t\n    63t\n    -117t\n    -72t\n    94t\n    -120t\n    88t\n    125t\n    88t\n    116t\n    -81t\n    -35t\n    -29t\n    -55t\n    -50t\n    -26t\n    120t\n    116t\n    24t\n    -93t\n    124t\n    -94t\n    100t\n    -90t\n    -69t\n    -90t\n    -82t\n    112t\n    -103t\n    -114t\n    -112t\n    104t\n    46t\n    -100t\n    -62t\n    -4t\n    6t\n    105t\n    -22t\n    113t\n    42t\n    -78t\n    -96t\n    -10t\n    -96t\n    -14t\n    77t\n    6t\n    28t\n    -69t\n    -29t\n    59t\n    -126t\n    13t\n    118t\n    83t\n    123t\n    -86t\n    -15t\n    117t\n    67t\n    4t\n    -101t\n    4t\n    -88t\n    -39t\n    122t\n    -67t\n    8t\n    64t\n    -69t\n    20t\n    -30t\n    80t\n    88t\n    -87t\n    -108t\n    -113t\n    -78t\n    -31t\n    63t\n    15t\n    46t\n    81t\n    27t\n    114t\n    61t\n    8t\n    -26t\n    -17t\n    -23t\n    -47t\n    -71t\n    57t\n    -50t\n    94t\n    -9t\n    -103t\n    -93t\n    10t\n    110t\n    -31t\n    -37t\n    -100t\n    80t\n    77t\n    23t\n    69t\n    31t\n    21t\n    -39t\n    97t\n    -70t\n    118t\n    -6t\n    -38t\n    -16t\n    31t\n    -96t\n    14t\n    -55t\n    41t\n    -66t\n    -5t\n    -83t\n    -64t\n    96t\n    -82t\n    -27t\n    -65t\n    -68t\n    -95t\n    64t\n    81t\n    108t\n    -99t\n    64t\n    -17t\n    91t\n    -59t\n    91t\n    -20t\n    -44t\n    85t\n    76t\n    121t\n    35t\n    127t\n    -62t\n    108t\n    -113t\n    -83t\n    -98t\n    20t\n    -32t\n    -4t\n    95t\n    -102t\n    -59t\n    47t\n    -97t\n    19t\n    88t\n    -128t\n    60t\n    -84t\n    -110t\n    -31t\n    78t\n    125t\n    24t\n    94t\n    -62t\n    78t\n    98t\n    -126t\n    -48t\n    84t\n    -4t\n    55t\n    125t\n    -115t\n    -112t\n    57t\n    34t\n    86t\n    84t\n    38t\n    53t\n    120t\n    -110t\n    -21t\n    -14t\n    -111t\n    -86t\n    79t\n    -47t\n    38t\n    -15t\n    -21t\n    12t\n    43t\n    22t\n    -62t\n    59t\n    109t\n    -100t\n    34t\n    40t\n    102t\n    -46t\n    -12t\n    6t\n    56t\n    86t\n    35t\n    -12t\n    0t\n    92t\n    -122t\n    -82t\n    -104t\n    99t\n    -88t\n    -8t\n    8t\n    99t\n    -88t\n    -73t\n    95t\n    -105t\n    74t\n    34t\n    -19t\n    34t\n    125t\n    -26t\n    -8t\n    -127t\n    20t\n    -30t\n    48t\n    -83t\n    19t\n    -86t\n    103t\n    -80t\n    66t\n    -21t\n    -104t\n    116t\n    -78t\n    50t\n    99t\n    -120t\n    -68t\n    115t\n    -59t\n    -106t\n    -97t\n    -86t\n    26t\n    -62t\n    -120t\n    57t\n    31t\n    -78t\n    104t\n    20t\n    51t\n    72t\n    88t\n    1t\n    -17t\n    56t\n    101t\n    -116t\n    -59t\n    54t\n    -58t\n    72t\n    -1t\n    -118t\n    -21t\n    -34t\n    -76t\n    -122t\n    -32t\n    -36t\n    -109t\n    60t\n    -75t\n    32t\n    2t\n    -77t\n    19t\n    19t\n    -121t\n    -95t\n    -68t\n    -1t\n    40t\n    -93t\n    42t\n    -65t\n    -107t\n    7t\n    58t\n    75t\n    31t\n    3t\n    -125t\n    -101t\n    47t\n    -48t\n    49t\n    -72t\n    47t\n    -6t\n    -102t\n    108t\n    121t\n    40t\n    30t\n    9t\n    74t\n    -24t\n    -11t\n    -128t\n    -51t\n    47t\n    13t\n    -43t\n    50t\n    96t\n    126t\n    -65t\n    111t\n    102t\n    -1t\n    30t\n    81t\n    -109t\n    -20t\n    -21t\n    -117t\n    -111t\n    -36t\n    81t\n    -1t\n    -3t\n    -82t\n    70t\n    -32t\n    -80t\n    -63t\n    -110t\n    86t\n    -107t\n    20t\n    -120t\n    42t\n    119t\n    19t\n    -119t\n    -90t\n    -50t\n    -75t\n    116t\n    111t\n    -90t\n    -12t\n    -96t\n    -103t\n    107t\n    106t\n    -108t\n    105t\n    -102t\n    61t\n    68t\n    -34t\n    -72t\n    -90t\n    13t\n    76t\n    120t\n    -98t\n    67t\n    78t\n    -42t\n    20t\n    100t\n    55t\n    -125t\n    -59t\n    100t\n    -98t\n    -121t\n    -84t\n    81t\n    -75t\n    -54t\n    97t\n    117t\n    -93t\n    92t\n    122t\n    -125t\n    -14t\n    -18t\n    36t\n    -88t\n    64t\n    96t\n    75t\n    79t\n    -67t\n    6t\n    -90t\n    -33t\n    -33t\n    45t\n    2t\n    -18t\n    -56t\n    -81t\n    77t\n    85t\n    55t\n    43t\n    68t\n    123t\n    -39t\n    -106t\n    -45t\n    47t\n    -78t\n    -92t\n    -127t\n    -45t\n    -122t\n    -128t\n    -73t\n    -104t\n    25t\n    -8t\n    26t\n    97t\n    126t\n    -21t\n    -68t\n    91t\n    35t\n    9t\n    84t\n    -53t\n    114t\n    -128t\n    -36t\n    102t\n    -37t\n    37t\n    67t\n    -69t\n    42t\n    -73t\n    109t\n    -39t\n    -49t\n    -22t\n    86t\n    -41t\n    23t\n    76t\n    -94t\n    -76t\n    -59t\n    5t\n    -82t\n    -77t\n    -46t\n    -73t\n    -68t\n    84t\n    80t\n    -61t\n    50t\n    66t\n    33t\n    -39t\n    24t\n    71t\n    27t\n    104t\n    -62t\n    94t\n    18t\n    123t\n    -101t\n    46t\n    -104t\n    43t\n    -48t\n    -39t\n    76t\n    -11t\n    72t\n    -61t\n    117t\n    -105t\n    -98t\n    -13t\n    127t\n    -86t\n    54t\n    -1t\n    -14t\n    46t\n    -11t\n    -92t\n    62t\n    -115t\n    -63t\n    74t\n    -4t\n    57t\n    107t\n    -51t\n    65t\n    52t\n    -8t\n    7t\n    -1t\n    -25t\n    -68t\n    -113t\n    96t\n    -128t\n    -100t\n    38t\n    36t\n    -83t\n    44t\n    102t\n    31t\n    -35t\n    -110t\n    -52t\n    99t\n    -44t\n    -89t\n    -14t\n    81t\n    87t\n    15t\n    -106t\n    -92t\n    79t\n    22t\n    -23t\n    -89t\n    -115t\n    112t\n    -52t\n    -122t\n    115t\n    -15t\n    -27t\n    -32t\n    92t\n    10t\n    33t\n    -74t\n    92t\n    -94t\n    -128t\n    77t\n    -81t\n    14t\n    -69t\n    -70t\n    120t\n    76t\n    52t\n    123t\n    28t\n    111t\n    19t\n    -123t\n    84t\n    114t\n    -29t\n    -128t\n    64t\n    -9t\n    79t\n    56t\n    -94t\n    111t\n    -54t\n    43t\n    -64t\n    29t\n    -26t\n    67t\n    -60t\n    -28t\n    54t\n    96t\n    20t\n    -44t\n    -16t\n    105t\n    103t\n    -118t\n    -5t\n    20t\n    110t\n    -69t\n    20t\n    120t\n    -51t\n    62t\n    60t\n    21t\n    -119t\n    -60t\n    25t\n    -43t\n    -112t\n    -121t\n    85t\n    7t\n    -96t\n    87t\n    -123t\n    104t\n    -68t\n    104t\n    -10t\n    -109t\n    60t\n    82t\n    -42t\n    1t\n    -104t\n    82t\n    -16t\n    -21t\n    -56t\n    67t\n    -69t\n    63t\n    94t\n    105t\n    81t\n    90t\n    -5t\n    88t\n    41t\n    -109t\n    61t\n    -118t\n    39t\n    55t\n    10t\n    -57t\n    -107t\n    126t\n    45t\n    59t\n    -108t\n    48t\n    25t\n    63t\n    -119t\n    108t\n    115t\n    68t\n    24t\n    25t\n    112t\n    72t\n    -96t\n    3t\n    33t\n    -126t\n    111t\n    49t\n    112t\n    -83t\n    -62t\n    -35t\n    98t\n    20t\n    -22t\n    -24t\n    -38t\n    -125t\n    95t\n    -70t\n    -33t\n    20t\n    53t\n    46t\n    76t\n    -83t\n    59t\n    38t\n    98t\n    119t\n    37t\n    -105t\n    51t\n    -76t\n    18t\n    -14t\n    -46t\n    43t\n    12t\n    86t\n    -94t\n    115t\n    -52t\n    50t\n    66t\n    -70t\n    12t\n    49t\n    72t\n    120t\n    -125t\n    83t\n    67t\n    69t\n    93t\n    10t\n    126t\n    116t\n    -126t\n    107t\n    -9t\n    -106t\n    -84t\n    -37t\n    -79t\n    -94t\n    116t\n    -35t\n    -30t\n    6t\n    92t\n    -108t\n    13t\n    -18t\n    -90t\n    100t\n    -88t\n    119t\n    -3t\n    -124t\n    -46t\n    -61t\n    -17t\n    84t\n    35t\n    7t\n    -111t\n    113t\n    -125t\n    95t\n    -84t\n    98t\n    42t\n    -19t\n    30t\n    11t\n    119t\n    -25t\n    79t\n    87t\n    -103t\n    -65t\n    -57t\n    95t\n    -125t\n    6t\n    100t\n    96t\n    52t\n    78t\n    95t\n    -108t\n    -128t\n    -109t\n    -48t\n    -84t\n    22t\n    -33t\n    -75t\n    -23t\n    -21t\n    -84t\n    -80t\n    102t\n    39t\n    -75t\n    114t\n    29t\n    -36t\n    3t\n    -9t\n    69t\n    -119t\n    7t\n    -114t\n    65t\n    120t\n    -31t\n    28t\n    8t\n    18t\n    -99t\n    -104t\n    55t\n    57t\n    48t\n    106t\n    122t\n    94t\n    -117t\n    -108t\n    31t\n    -13t\n    56t\n    7t\n    -72t\n    17t\n    25t\n    30t\n    71t\n    -102t\n    -54t\n    71t\n    -36t\n    -57t\n    -40t\n    56t\n    55t\n    -39t\n    -122t\n    51t\n    -109t\n    -9t\n    -31t\n    -127t\n    -85t\n    -101t\n    -4t\n    -51t\n    29t\n    78t\n    22t\n    -128t\n    -22t\n    71t\n    -76t\n    105t\n    -85t\n    -71t\n    85t\n    52t\n    117t\n    43t\n    8t\n    31t\n    -127t\n    103t\n    -50t\n    45t\n    -116t\n    48t\n    66t\n    2t\n    -100t\n    -18t\n    99t\n    -80t\n    -108t\n    120t\n    -121t\n    40t\n    -17t\n    -61t\n    -10t\n    109t\n    126t\n    76t\n    94t\n    75t\n    -1t\n    19t\n    28t\n    87t\n    -88t\n    112t\n    -110t\n    -127t\n    37t\n    79t\n    -107t\n    -46t\n    -115t\n    55t\n    -74t\n    24t\n    28t\n    -48t\n    -101t\n    -100t\n    68t\n    -53t\n    32t\n    118t\n    -33t\n    -110t\n    -13t\n    -71t\n    -104t\n    111t\n    96t\n    76t\n    -32t\n    118t\n    99t\n    -15t\n    -82t\n    -100t\n    -20t\n    -27t\n    -72t\n    -3t\n    -46t\n    -91t\n    121t\n    -18t\n    -115t\n    11t\n    -2t\n    -101t\n    -38t\n    103t\n    110t\n    -9t\n    18t\n    35t\n    20t\n    27t\n    -59t\n    -69t\n    117t\n    53t\n    -61t\n    -113t\n    -66t\n    -76t\n    -3t\n    121t\n    97t\n    -96t\n    66t\n    -83t\n    -111t\n    -128t\n    -26t\n    0t\n    114t\n    -82t\n    29t\n    77t\n    -8t\n    1t\n    -77t\n    -44t\n    -88t\n    -112t\n    32t\n    110t\n    -124t\n    -67t\n    -71t\n    12t\n    86t\n    -38t\n    4t\n    -119t\n    -9t\n    -54t\n    28t\n    87t\n    -121t\n    -108t\n    -15t\n    38t\n    -38t\n    62t\n    -72t\n    -3t\n    117t\n    80t\n    34t\n    102t\n    -4t\n    -54t\n    19t\n    27t\n    127t\n    -2t\n    -20t\n    58t\n    -80t\n    115t\n    -30t\n    -112t\n    100t\n    -14t\n    112t\n    -67t\n    118t\n    -113t\n    108t\n    -101t\n    -94t\n    -19t\n    22t\n    69t\n    -2t\n    46t\n    10t\n    -81t\n    82t\n    56t\n    -6t\n    62t\n    74t\n    7t\n    -20t\n    -14t\n    -105t\n    -37t\n    -86t\n    88t\n    55t\n    -127t\n    93t\n    116t\n    81t\n    -39t\n    5t\n    104t\n    105t\n    14t\n    -9t\n    122t\n    -56t\n    13t\n    -6t\n    -36t\n    -111t\n    -97t\n    -44t\n    25t\n    -104t\n    15t\n    -69t\n    -108t\n    -117t\n    -111t\n    41t\n    -23t\n    113t\n    81t\n    124t\n    -101t\n    -73t\n    -102t\n    -3t\n    120t\n    -56t\n    38t\n    -17t\n    36t\n    -75t\n    -72t\n    -24t\n    -23t\n    -100t\n    -47t\n    115t\n    18t\n    -89t\n    103t\n    20t\n    112t\n    -125t\n    -23t\n    -82t\n    -5t\n    85t\n    62t\n    53t\n    -69t\n    -91t\n    -44t\n    -32t\n    25t\n    71t\n    -92t\n    3t\n    -83t\n    3t\n    73t\n    96t\n    31t\n    69t\n    24t\n    -106t\n    -64t\n    -38t\n    -40t\n    80t\n    -49t\n    24t\n    83t\n    116t\n    79t\n    73t\n    15t\n    -42t\n    104t\n    14t\n    44t\n    120t\n    32t\n    83t\n    124t\n    41t\n    61t\n    21t\n    -82t\n    78t\n    114t\n    126t\n    56t\n    63t\n    62t\n    -58t\n    -46t\n    -65t\n    -13t\n    34t\n    -48t\n    96t\n    118t\n    -54t\n    -6t\n    92t\n    -90t\n    -46t\n    74t\n    -28t\n    -98t\n    3t\n    26t\n    59t\n    -34t\n    68t\n    -23t\n    -78t\n    -74t\n    -1t\n    -32t\n    -34t\n    -86t\n    49t\n    43t\n    -125t\n    93t\n    111t\n    127t\n    -120t\n    120t\n    75t\n    85t\n    90t\n    109t\n    -30t\n    -39t\n    44t\n    34t\n    110t\n    48t\n    71t\n    101t\n    87t\n    8t\n    41t\n    74t\n    65t\n    51t\n    -115t\n    93t\n    -110t\n    20t\n    106t\n    -95t\n    106t\n    127t\n    -38t\n    124t\n    -45t\n    -63t\n    -117t\n    -54t\n    -53t\n    -38t\n    -42t\n    110t\n    -18t\n    127t\n    -68t\n    126t\n    -113t\n    113t\n    99t\n    51t\n    -40t\n    -106t\n    29t\n    38t\n    -73t\n    -81t\n    -36t\n    -48t\n    -108t\n    -25t\n    -21t\n    -80t\n    20t\n    -111t\n    -25t\n    -94t\n    -56t\n    -83t\n    105t\n    37t\n    -6t\n    97t\n    -1t\n    -75t\n    -128t\n    -43t\n    22t\n    -48t\n    -3t\n    -42t\n    9t\n    50t\n    75t\n    64t\n    51t\n    -19t\n    -125t\n    119t\n    -128t\n    -127t\n    -61t\n    70t\n    20t\n    -70t\n    -1t\n    -29t\n    -92t\n    65t\n    125t\n    -55t\n    -110t\n    9t\n    98t\n    -21t\n    95t\n    -72t\n    -121t\n    21t\n    -28t\n    -64t\n    51t\n    -111t\n    -125t\n    -2t\n    -94t\n    82t\n    -62t\n    -73t\n    73t\n    -44t\n    86t\n    17t\n    -112t\n    34t\n    17t\n    -41t\n    -117t\n    39t\n    59t\n    -62t\n    126t\n    73t\n    125t\n    58t\n    -40t\n    116t\n    -19t\n    -40t\n    0t\n    -109t\n    -5t\n    113t\n    11t\n    -88t\n    34t\n    -39t\n    79t\n    -77t\n    -99t\n    -118t\n    -40t\n    85t\n    49t\n    119t\n    -46t\n    90t\n    -86t\n    88t\n    -71t\n    -66t\n    -65t\n    36t\n    40t\n    32t\n    -27t\n    127t\n    -22t\n    -20t\n    -69t\n    -94t\n    -62t\n    -13t\n    79t\n    111t\n    66t\n    -26t\n    106t\n    -108t\n    -39t\n    -104t\n    -67t\n    -108t\n    60t\n    -95t\n    -65t\n    -30t\n    -20t\n    -9t\n    83t\n    -18t\n    -102t\n    -49t\n    75t\n    45t\n    105t\n    56t\n    -66t\n    120t\n    -21t\n    -14t\n    -69t\n    -23t\n    54t\n    36t\n    117t\n    -100t\n    -86t\n    -82t\n    -96t\n    -113t\n    -26t\n    108t\n    47t\n    -70t\n    0t\n    -112t\n    -44t\n    -57t\n    -62t\n    -76t\n    -68t\n    -96t\n    -102t\n    -32t\n    74t\n    78t\n    31t\n    113t\n    127t\n    -1t\n    -65t\n    86t\n    -25t\n    39t\n    -74t\n    -26t\n    -48t\n    -30t\n    28t\n    92t\n    -39t\n    73t\n    -32t\n    101t\n    -8t\n    -44t\n    6t\n    -61t\n    -112t\n    96t\n    -45t\n    120t\n    96t\n    -112t\n    95t\n    -91t\n    78t\n    23t\n    76t\n    -114t\n    65t\n    -100t\n    79t\n    30t\n    -105t\n    -24t\n    104t\n    94t\n    70t\n    -12t\n    -102t\n    -19t\n    -29t\n    -117t\n    -117t\n    -65t\n    -99t\n    -64t\n    -77t\n    40t\n    -108t\n    31t\n    107t\n    19t\n    91t\n    74t\n    -112t\n    -127t\n    28t\n    -2t\n    73t\n    -36t\n    11t\n    57t\n    72t\n    28t\n    118t\n    -69t\n    92t\n    -9t\n    -41t\n    -93t\n    52t\n    -125t\n    43t\n    17t\n    80t\n    80t\n    -60t\n    -17t\n    -28t\n    74t\n    -15t\n    95t\n    2t\n    -18t\n    -21t\n    -18t\n    -6t\n    121t\n    101t\n    102t\n    -70t\n    -76t\n    87t\n    48t\n    -56t\n    -109t\n    50t\n    126t\n    -115t\n    41t\n    47t\n    -103t\n    0t\n    -6t\n    46t\n    -28t\n    -11t\n    -58t\n    27t\n    82t\n    97t\n    120t\n    52t\n    23t\n    91t\n    121t\n    59t\n    -100t\n    18t\n    80t\n    79t\n    64t\n    90t\n    48t\n    91t\n    -97t\n    -115t\n    -8t\n    -43t\n    -23t\n    -66t\n    -78t\n    22t\n    4t\n    -26t\n    -85t\n    -2t\n    80t\n    -5t\n    -27t\n    111t\n    65t\n    104t\n    -17t\n    64t\n    -23t\n    -127t\n    99t\n    61t\n    -26t\n    -112t\n    52t\n    -36t\n    116t\n    98t\n    -61t\n    48t\n    -19t\n    102t\n    -47t\n    -53t\n    -52t\n    90t\n    64t\n    -40t\n    27t\n    -27t\n    -57t\n    -36t\n    21t\n    -53t\n    81t\n    31t\n    -7t\n    99t\n    -93t\n    -45t\n    108t\n    60t\n    32t\n    49t\n    -98t\n    65t\n    117t\n    -76t\n    68t\n    -82t\n    98t\n    76t\n    49t\n    -68t\n    111t\n    -43t\n    48t\n    -126t\n    -36t\n    -86t\n    8t\n    -90t\n    -55t\n    -127t\n    29t\n    67t\n    76t\n    47t\n    -126t\n    -76t\n    -96t\n    52t\n    6t\n    -59t\n    -1t\n    -20t\n    80t\n    -40t\n    -73t\n    -120t\n    -42t\n    -6t\n    -21t\n    -42t\n    -67t\n    -78t\n    26t\n    58t\n    64t\n    -58t\n    -117t\n    100t\n    -78t\n    -32t\n    67t\n    -28t\n    69t\n    -59t\n    20t\n    -93t\n    -2t\n    15t\n    -2t\n    32t\n    -45t\n    -35t\n    -73t\n    14t\n    -25t\n    -63t\n    -105t\n    -96t\n    -78t\n    -35t\n    -93t\n    48t\n    24t\n    15t\n    125t\n    -85t\n    21t\n    52t\n    -38t\n    108t\n    -21t\n    -26t\n    -102t\n    -85t\n    23t\n    -40t\n    -2t\n    45t\n    -128t\n    -22t\n    -103t\n    -126t\n    49t\n    19t\n    -68t\n    -9t\n    -65t\n    -121t\n    -120t\n    -10t\n    105t\n    -6t\n    104t\n    59t\n    -6t\n    9t\n    -108t\n    100t\n    -14t\n    104t\n    90t\n    109t\n    -83t\n    -85t\n    -17t\n    -107t\n    -73t\n    101t\n    -12t\n    39t\n    -24t\n    58t\n    57t\n    -118t\n    61t\n    88t\n    95t\n    -118t\n    -60t\n    70t\n    -88t\n    50t\n    -34t\n    67t\n    4t\n    -101t\n    -37t\n    69t\n    -96t\n    82t\n    -123t\n    58t\n    111t\n    -78t\n    11t\n    -125t\n    -43t\n    -1t\n    -97t\n    124t\n    -120t\n    -83t\n    -106t\n    97t\n    -47t\n    -98t\n    98t\n    -99t\n    59t\n    -46t\n    80t\n    -59t\n    -63t\n    65t\n    -17t\n    66t\n    6t\n    71t\n    112t\n    100t\n    -77t\n    88t\n    -72t\n    -104t\n    -66t\n    -28t\n    17t\n    -77t\n    111t\n    -99t\n    111t\n    26t\n    47t\n    64t\n    -33t\n    10t\n    -38t\n    -19t\n    118t\n    123t\n    -92t\n    82t\n    -103t\n    -87t\n    81t\n    -56t\n    57t\n    -26t\n    92t\n    70t\n    39t\n    -112t\n    -29t\n    49t\n    97t\n    -77t\n    13t\n    108t\n    115t\n    57t\n    -91t\n    40t\n    -89t\n    -6t\n    56t\n    84t\n    110t\n    8t\n    70t\n    -17t\n    -31t\n    83t\n    43t\n    86t\n    33t\n    39t\n    -43t\n    1t\n    44t\n    72t\n    -34t\n    -87t\n    35t\n    95t\n    -55t\n    45t\n    -91t\n    -17t\n    -27t\n    86t\n    117t\n    -10t\n    17t\n    82t\n    -58t\n    81t\n    -77t\n    52t\n    57t\n    -78t\n    64t\n    -90t\n    73t\n    -5t\n    -33t\n    -97t\n    -42t\n    70t\n    -9t\n    -51t\n    -109t\n    11t\n    13t\n    -57t\n    101t\n    120t\n    15t\n    50t\n    -64t\n    -44t\n    65t\n    -35t\n    26t\n    17t\n    79t\n    122t\n    56t\n    52t\n    112t\n    47t\n    -39t\n    -94t\n    -96t\n    -54t\n    90t\n    123t\n    23t\n    91t\n    86t\n    -53t\n    97t\n    45t\n    107t\n    -43t\n    97t\n    -97t\n    113t\n    3t\n    -110t\n    -90t\n    -27t\n    -120t\n    42t\n    48t\n    109t\n    -83t\n    -30t\n    -128t\n    7t\n    -58t\n    121t\n    -33t\n    125t\n    43t\n    50t\n    53t\n    46t\n    6t\n    10t\n    7t\n    -20t\n    -83t\n    -124t\n    -39t\n    -61t\n    74t\n    56t\n    -117t\n    -76t\n    54t\n    -15t\n    39t\n    -31t\n    -1t\n    66t\n    -95t\n    -53t\n    24t\n    109t\n    39t\n    13t\n    -31t\n    80t\n    -16t\n    120t\n    57t\n    83t\n    27t\n    -70t\n    -31t\n    23t\n    108t\n    -56t\n    -112t\n    111t\n    63t\n    -67t\n    -51t\n    61t\n    41t\n    7t\n    76t\n    -122t\n    45t\n    94t\n    104t\n    -39t\n    -95t\n    -56t\n    -70t\n    -115t\n    -121t\n    -98t\n    -22t\n    63t\n    -28t\n    -74t\n    103t\n    120t\n    122t\n    -105t\n    -23t\n    -68t\n    68t\n    46t\n    -108t\n    -116t\n    71t\n    98t\n    -78t\n    -10t\n    76t\n    122t\n    -6t\n    24t\n    -16t\n    -16t\n    -43t\n    39t\n    63t\n    36t\n    106t\n    -79t\n    65t\n    118t\n    57t\n    102t\n    -112t\n    -65t\n    -46t\n    -22t\n    -6t\n    -49t\n    -108t\n    34t\n    22t\n    29t\n    -49t\n    77t\n    16t\n    94t\n    -9t\n    -106t\n    -36t\n    94t\n    -81t\n    -127t\n    -39t\n    -17t\n    47t\n    -1t\n    -20t\n    3t\n    -37t\n    -104t\n    50t\n    76t\n    -81t\n    -46t\n    49t\n    110t\n    91t\n    -102t\n    -84t\n    -49t\n    111t\n    26t\n    -63t\n    40t\n    62t\n    -49t\n    -21t\n    -44t\n    106t\n    -31t\n    -58t\n    90t\n    -100t\n    11t\n    127t\n    -85t\n    5t\n    73t\n    75t\n    59t\n    -95t\n    -13t\n    -103t\n    -7t\n    85t\n    -69t\n    -124t\n    36t\n    80t\n    -82t\n    10t\n    -33t\n    31t\n    -41t\n    -43t\n    -68t\n    -99t\n    -45t\n    -55t\n    -128t\n    -58t\n    81t\n    -68t\n    -1t\n    -42t\n    -123t\n    -97t\n    -65t\n    -56t\n    111t\n    -69t\n    117t\n    -87t\n    78t\n    -118t\n    91t\n    25t\n    -19t\n    -27t\n    34t\n    -39t\n    30t\n    -45t\n    105t\n    19t\n    -71t\n    -91t\n    -50t\n    -77t\n    87t\n    116t\n    -99t\n    94t\n    -49t\n    -98t\n    -36t\n    -115t\n    -79t\n    38t\n    82t\n    -14t\n    -104t\n    -74t\n    31t\n    -15t\n    -59t\n    -17t\n    -94t\n    35t\n    91t\n    -81t\n    -3t\n    122t\n    120t\n    -18t\n    17t\n    34t\n    -56t\n    -66t\n    54t\n    -56t\n    96t\n    -44t\n    -95t\n    42t\n    -21t\n    -13t\n    60t\n    -109t\n    49t\n    -19t\n    -75t\n    75t\n    47t\n    110t\n    105t\n    20t\n    -98t\n    -88t\n    100t\n    -103t\n    -31t\n    126t\n    -48t\n    123t\n    -106t\n    34t\n    18t\n    81t\n    113t\n    -67t\n    18t\n    111t\n    -9t\n    -127t\n    -79t\n    -92t\n    4t\n    25t\n    -13t\n    58t\n    63t\n    48t\n    -81t\n    -42t\n    18t\n    100t\n    -84t\n    -30t\n    -96t\n    -119t\n    65t\n    -126t\n    49t\n    -28t\n    -14t\n    -50t\n    35t\n    46t\n    -100t\n    -15t\n    -10t\n    -34t\n    -55t\n    -47t\n    92t\n    -41t\n    -2t\n    112t\n    84t\n    -8t\n    -76t\n    125t\n    90t\n    -78t\n    -125t\n    -114t\n    20t\n    -66t\n    -82t\n    -57t\n    -106t\n    0t\n    54t\n    115t\n    -90t\n    -82t\n    84t\n    34t\n    -96t\n    -101t\n    -64t\n    -90t\n    80t\n    -61t\n    -107t\n    57t\n    -127t\n    -79t\n    108t\n    -5t\n    95t\n    32t\n    79t\n    -110t\n    48t\n    58t\n    14t\n    34t\n    -29t\n    27t\n    13t\n    -102t\n    -75t\n    72t\n    -64t\n    -18t\n    -21t\n    95t\n    -43t\n    31t\n    58t\n    115t\n    96t\n    -36t\n    -121t\n    63t\n    -98t\n    20t\n    50t\n    -75t\n    -125t\n    111t\n    -52t\n    93t\n    101t\n    24t\n    -71t\n    -122t\n    -36t\n    111t\n    66t\n    109t\n    7t\n    13t\n    -117t\n    88t\n    -7t\n    110t\n    63t\n    -51t\n    95t\n    13t\n    68t\n    -76t\n    1t\n    14t\n    -101t\n    -38t\n    66t\n    112t\n    -3t\n    -126t\n    -20t\n    -71t\n    122t\n    44t\n    -54t\n    -105t\n    40t\n    -108t\n    40t\n    -28t\n    -68t\n    10t\n    -58t\n    44t\n    124t\n    55t\n    122t\n    64t\n    -13t\n    -109t\n    -12t\n    -9t\n    -96t\n    -104t\n    -9t\n    -25t\n    6t\n    -50t\n    -54t\n    104t\n    -44t\n    -116t\n    85t\n    4t\n    92t\n    49t\n    7t\n    37t\n    39t\n    -70t\n    121t\n    -26t\n    -93t\n    -80t\n    -8t\n    59t\n    -93t\n    -80t\n    94t\n    -75t\n    -121t\n    -6t\n    -108t\n    86t\n    -35t\n    69t\n    125t\n    -84t\n    115t\n    -99t\n    -60t\n    69t\n    -84t\n    19t\n    109t\n    61t\n    107t\n    39t\n    111t\n    -113t\n    -82t\n    -49t\n    41t\n    4t\n    94t\n    84t\n    -58t\n    60t\n    -63t\n    54t\n    12t\n    38t\n    -68t\n    -37t\n    50t\n    126t\n    39t\n    115t\n    -44t\n    19t\n    -107t\n    -13t\n    -8t\n    -12t\n    -123t\n    45t\n    -13t\n    5t\n    -20t\n    -96t\n    -1t\n    27t\n    70t\n    53t\n    99t\n    63t\n    -16t\n    -124t\n    -126t\n    -58t\n    22t\n    -8t\n    -114t\n    0t\n    -64t\n    114t\n    14t\n    33t\n    -106t\n    110t\n    126t\n    37t\n    -120t\n    20t\n    -6t\n    -119t\n    23t\n    41t\n    112t\n    -104t\n    -100t\n    -19t\n    -52t\n    5t\n    97t\n    1t\n    -17t\n    84t\n    -10t\n    29t\n    62t\n    30t\n    104t\n    -104t\n    -101t\n    26t\n    124t\n    125t\n    -8t\n    116t\n    111t\n    42t\n    -55t\n    -32t\n    109t\n    -7t\n    92t\n    -78t\n    54t\n    -13t\n    115t\n    100t\n    -39t\n    -38t\n    67t\n    38t\n    115t\n    -54t\n    -70t\n    63t\n    104t\n    -62t\n    -76t\n    67t\n    -35t\n    -91t\n    28t\n    73t\n    5t\n    2t\n    46t\n    -110t\n    -92t\n    -29t\n    109t\n    -38t\n    122t\n    -28t\n    -112t\n    -39t\n    -31t\n    -25t\n    -62t\n    -96t\n    -73t\n    -71t\n    -93t\n    64t\n    6t\n    -89t\n    -70t\n    24t\n    52t\n    -51t\n    -79t\n    71t\n    7t\n    -26t\n    41t\n    54t\n    43t\n    -82t\n    -121t\n    119t\n    -12t\n    108t\n    -104t\n    -47t\n    -49t\n    14t\n    -112t\n    89t\n    -112t\n    77t\n    2t\n    -83t\n    -125t\n    64t\n    97t\n    -65t\n    -41t\n    103t\n    116t\n    -120t\n    67t\n    109t\n    -36t\n    -20t\n    -22t\n    -106t\n    61t\n    69t\n    49t\n    47t\n    88t\n    95t\n    -61t\n    -14t\n    -83t\n    95t\n    42t\n    106t\n    78t\n    35t\n    -90t\n    -116t\n    -80t\n    94t\n    -101t\n    -43t\n    -35t\n    44t\n    56t\n    97t\n    -8t\n    -105t\n    96t\n    95t\n    92t\n    90t\n    -125t\n    -56t\n    -63t\n    123t\n    10t\n    -87t\n    -14t\n    32t\n    79t\n    97t\n    -83t\n    6t\n    -28t\n    -43t\n    -29t\n    116t\n    126t\n    -14t\n    72t\n    -50t\n    41t\n    -5t\n    18t\n    36t\n    60t\n    12t\n    113t\n    -3t\n    -79t\n    46t\n    7t\n    -83t\n    11t\n    -73t\n    -47t\n    -83t\n    -74t\n    -31t\n    37t\n    -52t\n    9t\n    -98t\n    -39t\n    -105t\n    19t\n    62t\n    -72t\n    24t\n    -106t\n    80t\n    18t\n    79t\n    5t\n    -109t\n    -97t\n    -83t\n    -126t\n    28t\n    104t\n    8t\n    -66t\n    -73t\n    -66t\n    -100t\n    97t\n    96t\n    -34t\n    -25t\n    11t\n    60t\n    3t\n    28t\n    86t\n    -125t\n    -57t\n    -35t\n    -123t\n    -67t\n    75t\n    -18t\n    32t\n    19t\n    -94t\n    125t\n    76t\n    -20t\n    97t\n    -27t\n    74t\n    -10t\n    14t\n    71t\n    -88t\n    -48t\n    57t\n    38t\n    -15t\n    -125t\n    -109t\n    105t\n    44t\n    110t\n    13t\n    52t\n    -25t\n    28t\n    -7t\n    23t\n    103t\n    84t\n    33t\n    64t\n    -36t\n    -43t\n    -115t\n    -74t\n    34t\n    2t\n    12t\n    -92t\n    107t\n    41t\n    75t\n    85t\n    -20t\n    -50t\n    24t\n    -22t\n    78t\n    10t\n    8t\n    -56t\n    41t\n    -123t\n    -41t\n    -53t\n    24t\n    23t\n    118t\n    54t\n    81t\n    76t\n    56t\n    -44t\n    -113t\n    105t\n    59t\n    -120t\n    7t\n    -93t\n    22t\n    28t\n    -108t\n    -14t\n    18t\n    75t\n    2t\n    3t\n    -125t\n    -85t\n    11t\n    -40t\n    95t\n    -122t\n    104t\n    46t\n    58t\n    25t\n    -97t\n    -31t\n    67t\n    -80t\n    16t\n    123t\n    -118t\n    46t\n    -30t\n    17t\n    -122t\n    5t\n    69t\n    -21t\n    36t\n    -111t\n    69t\n    38t\n    -19t\n    30t\n    55t\n    -101t\n    127t\n    -39t\n    109t\n    33t\n    -93t\n    -96t\n    88t\n    -49t\n    22t\n    82t\n    35t\n    99t\n    89t\n    11t\n    -70t\n    79t\n    -81t\n    -116t\n    -15t\n    68t\n    89t\n    126t\n    14t\n    -33t\n    19t\n    53t\n    21t\n    15t\n    -1t\n    97t\n    99t\n    -31t\n    -10t\n    101t\n    65t\n    102t\n    -124t\n    12t\n    75t\n    77t\n    -77t\n    6t\n    -68t\n    -85t\n    -112t\n    -99t\n    -43t\n    -111t\n    116t\n    78t\n    -104t\n    28t\n    23t\n    -14t\n    9t\n    -61t\n    -10t\n    -66t\n    6t\n    122t\n    82t\n    -51t\n    -23t\n    -77t\n    122t\n    -115t\n    95t\n    7t\n    -40t\n    -109t\n    -119t\n    20t\n    8t\n    61t\n    72t\n    -17t\n    -105t\n    37t\n    -87t\n    86t\n    76t\n    -85t\n    72t\n    -108t\n    104t\n    -86t\n    99t\n    -113t\n    -127t\n    27t\n    39t\n    -9t\n    119t\n    46t\n    108t\n    12t\n    86t\n    50t\n    -12t\n    -109t\n    52t\n    56t\n    107t\n    89t\n    95t\n    71t\n    36t\n    -77t\n    72t\n    94t\n    99t\n    33t\n    -90t\n    -74t\n    26t\n    -109t\n    3t\n    -19t\n    44t\n    69t\n    -62t\n    -107t\n    95t\n    -15t\n    -89t\n    16t\n    41t\n    -124t\n    78t\n    -76t\n    -55t\n    -26t\n    -18t\n    -41t\n    28t\n    90t\n    -6t\n    26t\n    -106t\n    -51t\n    -86t\n    123t\n    -87t\n    -55t\n    70t\n    -73t\n    -41t\n    -6t\n    53t\n    68t\n    -4t\n    36t\n    -28t\n    -101t\n    -91t\n    -110t\n    -79t\n    50t\n    -27t\n    78t\n    62t\n    -24t\n    105t\n    84t\n    -96t\n    -100t\n    -100t\n    -67t\n    -120t\n    30t\n    -6t\n    -66t\n    -73t\n    -62t\n    121t\n    -4t\n    61t\n    49t\n    -126t\n    44t\n    -89t\n    -58t\n    65t\n    40t\n    -101t\n    -74t\n    5t\n    111t\n    -95t\n    -74t\n    -37t\n    96t\n    -52t\n    -31t\n    7t\n    41t\n    -73t\n    14t\n    -73t\n    46t\n    -56t\n    -119t\n    122t\n    -101t\n    121t\n    81t\n    -70t\n    15t\n    122t\n    71t\n    63t\n    93t\n    45t\n    -37t\n    -16t\n    74t\n    11t\n    125t\n    -7t\n    -99t\n    42t\n    -44t\n    -124t\n    58t\n    -70t\n    13t\n    -42t\n    73t\n    60t\n    17t\n    11t\n    -86t\n    -99t\n    -16t\n    23t\n    -6t\n    -115t\n    -39t\n    108t\n    9t\n    -43t\n    7t\n    25t\n    119t\n    -75t\n    -2t\n    -25t\n    -102t\n    21t\n    75t\n    111t\n    40t\n    73t\n    69t\n    105t\n    -66t\n    -2t\n    -116t\n    -59t\n    -97t\n    -90t\n    -99t\n    -53t\n    -37t\n    39t\n    35t\n    36t\n    -87t\n    -24t\n    94t\n    46t\n    14t\n    43t\n    104t\n    45t\n    16t\n    -127t\n    111t\n    -100t\n    -57t\n    120t\n    -66t\n    -60t\n    64t\n    -51t\n    -46t\n    33t\n    -82t\n    -106t\n    39t\n    75t\n    -16t\n    107t\n    -36t\n    68t\n    93t\n    -28t\n    106t\n    103t\n    52t\n    2t\n    3t\n    -5t\n    20t\n    -21t\n    47t\n    52t\n    117t\n    -80t\n    -123t\n    -36t\n    -67t\n    -27t\n    110t\n    124t\n    87t\n    50t\n    -31t\n    -29t\n    -113t\n    6t\n    37t\n    33t\n    29t\n    -127t\n    -106t\n    -68t\n    110t\n    -88t\n    34t\n    -111t\n    75t\n    -62t\n    -106t\n    -87t\n    -48t\n    -31t\n    99t\n    35t\n    -50t\n    -53t\n    -57t\n    -16t\n    -105t\n    -35t\n    -68t\n    -42t\n    46t\n    51t\n    92t\n    -123t\n    -105t\n    7t\n    73t\n    -35t\n    54t\n    99t\n    -125t\n    -29t\n    -119t\n    52t\n    99t\n    76t\n    52t\n    11t\n    90t\n    -85t\n    -89t\n    -43t\n    23t\n    111t\n    -44t\n    96t\n    101t\n    -101t\n    -52t\n    94t\n    95t\n    116t\n    -110t\n    40t\n    60t\n    -36t\n    10t\n    54t\n    -10t\n    84t\n    104t\n    23t\n    -110t\n    -101t\n    -116t\n    -127t\n    -51t\n    121t\n    -84t\n    0t\n    19t\n    118t\n    48t\n    33t\n    -95t\n    -14t\n    -86t\n    -83t\n    -105t\n    112t\n    -28t\n    56t\n    -95t\n    55t\n    -94t\n    -96t\n    -6t\n    60t\n    -107t\n    122t\n    6t\n    -97t\n    48t\n    -67t\n    -120t\n    11t\n    -21t\n    87t\n    85t\n    91t\n    2t\n    -98t\n    47t\n    -44t\n    127t\n    4t\n    -26t\n    -50t\n    -70t\n    -32t\n    -128t\n    45t\n    -128t\n    -120t\n    88t\n    -38t\n    -112t\n    31t\n    79t\n    -38t\n    68t\n    60t\n    57t\n    32t\n    91t\n    -13t\n    -68t\n    2t\n    -120t\n    -87t\n    42t\n    -76t\n    52t\n    -65t\n    122t\n    -13t\n    -24t\n    41t\n    69t\n    90t\n    21t\n    12t\n    -27t\n    -40t\n    65t\n    -106t\n    103t\n    -126t\n    -15t\n    57t\n    61t\n    127t\n    118t\n    124t\n    102t\n    -59t\n    -50t\n    -75t\n    78t\n    -24t\n    -114t\n    -106t\n    -118t\n    -56t\n    62t\n    -18t\n    -39t\n    -61t\n    -82t\n    21t\n    33t\n    -1t\n    -124t\n    -79t\n    41t\n    22t\n    -108t\n    -29t\n    -93t\n    -127t\n    -98t\n    109t\n    73t\n    -44t\n    110t\n    126t\n    -1t\n    94t\n    -112t\n    39t\n    46t\n    -94t\n    44t\n    110t\n    -103t\n    -51t\n    111t\n    4t\n    -70t\n    -78t\n    68t\n    -104t\n    -99t\n    44t\n    99t\n    -88t\n    116t\n    118t\n    -103t\n    -47t\n    -57t\n    -105t\n    -62t\n    92t\n    -65t\n    -18t\n    56t\n    122t\n    -12t\n    -9t\n    22t\n    -66t\n    45t\n    100t\n    28t\n    87t\n    53t\n    -9t\n    109t\n    -111t\n    110t\n    88t\n    -92t\n    -76t\n    -66t\n    75t\n    19t\n    -45t\n    44t\n    32t\n    48t\n    119t\n    20t\n    101t\n    56t\n    -117t\n    89t\n    89t\n    98t\n    107t\n    13t\n    67t\n    -122t\n    -72t\n    -28t\n    29t\n    101t\n    82t\n    -48t\n    93t\n    -110t\n    -71t\n    -106t\n    -54t\n    -61t\n    -18t\n    -74t\n    90t\n    106t\n    -72t\n    -58t\n    -91t\n    69t\n    -107t\n    -63t\n    106t\n    -70t\n    -128t\n    -63t\n    84t\n    -47t\n    56t\n    121t\n    14t\n    0t\n    -85t\n    -1t\n    -1t\n    -10t\n    -86t\n    -120t\n    -57t\n    -81t\n    16t\n    115t\n    -85t\n    -28t\n    -13t\n    19t\n    20t\n    49t\n    73t\n    73t\n    21t\n    30t\n    78t\n    -7t\n    105t\n    -107t\n    -105t\n    -112t\n    -32t\n    -121t\n    2t\n    29t\n    4t\n    -11t\n    117t\n    -29t\n    -3t\n    -16t\n    39t\n    -1t\n    -6t\n    8t\n    81t\n    26t\n    -106t\n    -11t\n    12t\n    18t\n    -66t\n    90t\n    72t\n    63t\n    122t\n    -128t\n    -106t\n    -74t\n    42t\n    10t\n    -39t\n    -75t\n    -24t\n    80t\n    22t\n    77t\n    -127t\n    105t\n    -120t\n    126t\n    -58t\n    -107t\n    -47t\n    43t\n    -11t\n    -32t\n    -34t\n    67t\n    -106t\n    52t\n    -18t\n    -20t\n    -11t\n    -92t\n    48t\n    106t\n    21t\n    23t\n    -65t\n    73t\n    -36t\n    -27t\n    67t\n    -34t\n    39t\n    35t\n    0t\n    -48t\n    -12t\n    -68t\n    -9t\n    114t\n    -36t\n    18t\n    94t\n    -41t\n    -74t\n    86t\n    -125t\n    -118t\n    -85t\n    -34t\n    21t\n    88t\n    -113t\n    56t\n    -48t\n    -56t\n    68t\n    -72t\n    -20t\n    -37t\n    -108t\n    104t\n    -90t\n    -9t\n    30t\n    -69t\n    8t\n    98t\n    -42t\n    -71t\n    36t\n    -39t\n    100t\n    70t\n    -89t\n    118t\n    25t\n    -65t\n    -69t\n    -100t\n    33t\n    53t\n    -110t\n    62t\n    87t\n    -92t\n    -3t\n    -18t\n    34t\n    -112t\n    117t\n    -13t\n    -91t\n    -73t\n    52t\n    -83t\n    -11t\n    40t\n    49t\n    -1t\n    87t\n    -1t\n    119t\n    -110t\n    31t\n    81t\n    84t\n    9t\n    87t\n    84t\n    -100t\n    -51t\n    -7t\n    -30t\n    100t\n    -1t\n    -1t\n    124t\n    110t\n    -21t\n    89t\n    -46t\n    -102t\n    -80t\n    -119t\n    42t\n    -42t\n    -39t\n    -10t\n    -77t\n    -64t\n    -96t\n    -1t\n    83t\n    -96t\n    -12t\n    68t\n    -39t\n    -45t\n    113t\n    -97t\n    114t\n    16t\n    -33t\n    15t\n    75t\n    -51t\n    118t\n    22t\n    -39t\n    -116t\n    -115t\n    119t\n    51t\n    0t\n    26t\n    -6t\n    -115t\n    -23t\n    81t\n    108t\n    -96t\n    -120t\n    -12t\n    -100t\n    12t\n    33t\n    -121t\n    14t\n    35t\n    -112t\n    81t\n    115t\n    2t\n    -69t\n    -104t\n    90t\n    123t\n    -93t\n    -90t\n    -107t\n    -89t\n    13t\n    -28t\n    0t\n    34t\n    126t\n    -2t\n    58t\n    -52t\n    122t\n    111t\n    48t\n    85t\n    73t\n    10t\n    0t\n    -117t\n    -11t\n    -63t\n    66t\n    124t\n    99t\n    89t\n    -73t\n    -111t\n    -35t\n    -60t\n    22t\n    -1t\n    -35t\n    -58t\n    -107t\n    -23t\n    15t\n    88t\n    -3t\n    -103t\n    -2t\n    -112t\n    36t\n    97t\n    -104t\n    92t\n    1t\n    110t\n    -19t\n    16t\n    -121t\n    -69t\n    39t\n    -105t\n    70t\n    -18t\n    73t\n    -81t\n    -30t\n    106t\n    -38t\n    -43t\n    60t\n    26t\n    77t\n    25t\n    15t\n    -126t\n    105t\n    -62t\n    -109t\n    -86t\n    53t\n    -115t\n    66t\n    42t\n    33t\n    -97t\n    78t\n    59t\n    -5t\n    -108t\n    55t\n    4t\n    -106t\n    -48t\n    -7t\n    43t\n    -90t\n    -108t\n    16t\n    -49t\n    -14t\n    -68t\n    5t\n    18t\n    80t\n    -61t\n    62t\n    8t\n    109t\n    13t\n    29t\n    18t\n    112t\n    49t\n    -101t\n    87t\n    -103t\n    82t\n    58t\n    60t\n    -36t\n    69t\n    83t\n    -99t\n    40t\n    -90t\n    -10t\n    85t\n    18t\n    -115t\n    73t\n    -33t\n    -7t\n    -11t\n    41t\n    35t\n    20t\n    -51t\n    4t\n    87t\n    59t\n    55t\n    -105t\n    -118t\n    -126t\n    -5t\n    21t\n    122t\n    -88t\n    53t\n    26t\n    -127t\n    104t\n    80t\n    31t\n    120t\n    57t\n    121t\n    58t\n    -19t\n    39t\n    -1t\n    -78t\n    -56t\n    8t\n    -32t\n    -19t\n    -52t\n    80t\n    -73t\n    -94t\n    12t\n    -63t\n    50t\n    78t\n    -120t\n    62t\n    74t\n    54t\n    81t\n    121t\n    -15t\n    95t\n    -28t\n    -122t\n    87t\n    11t\n    -53t\n    63t\n    3t\n    -127t\n    -48t\n    -39t\n    -103t\n    -40t\n    17t\n    -27t\n    76t\n    82t\n    46t\n    110t\n    121t\n    43t\n    34t\n    -112t\n    -2t\n    26t\n    37t\n    40t\n    -42t\n    6t\n    12t\n    66t\n    -38t\n    0t\n    -52t\n    -7t\n    -86t\n    0t\n    75t\n    -9t\n    74t\n    23t\n    -103t\n    123t\n    -82t\n    21t\n    100t\n    95t\n    -87t\n    -9t\n    18t\n    66t\n    -61t\n    -85t\n    -80t\n    7t\n    73t\n    -20t\n    -3t\n    -74t\n    -72t\n    -111t\n    -59t\n    25t\n    109t\n    121t\n    69t\n    53t\n    64t\n    113t\n    -78t\n    -88t\n    -104t\n    -30t\n    42t\n    -48t\n    -22t\n    74t\n    104t\n    -51t\n    49t\n    -55t\n    102t\n    -97t\n    -105t\n    91t\n    -69t\n    -57t\n    -47t\n    -100t\n    -64t\n    -49t\n    -32t\n    52t\n    -62t\n    49t\n    42t\n    -73t\n    9t\n    9t\n    91t\n    -12t\n    -7t\n    -81t\n    80t\n    114t\n    94t\n    -51t\n    -86t\n    -25t\n    101t\n    -78t\n    127t\n    -8t\n    -95t\n    78t\n    85t\n    7t\n    47t\n    60t\n    54t\n    112t\n    7t\n    -2t\n    118t\n    -125t\n    -107t\n    -49t\n    111t\n    -103t\n    -67t\n    -3t\n    38t\n    -15t\n    -96t\n    100t\n    43t\n    101t\n    100t\n    -45t\n    96t\n    -18t\n    -14t\n    42t\n    71t\n    -111t\n    26t\n    49t\n    -20t\n    -66t\n    -33t\n    -86t\n    103t\n    -28t\n    -37t\n    -91t\n    -52t\n    74t\n    101t\n    16t\n    96t\n    116t\n    36t\n    24t\n    -5t\n    -36t\n    122t\n    -79t\n    -24t\n    86t\n    76t\n    -89t\n    91t\n    -34t\n    58t\n    -109t\n    -15t\n    -122t\n    -114t\n    104t\n    39t\n    53t\n    12t\n    -50t\n    -34t\n    26t\n    11t\n    119t\n    57t\n    -79t\n    -101t\n    124t\n    73t\n    34t\n    -20t\n    83t\n    -102t\n    37t\n    -7t\n    43t\n    45t\n    56t\n    83t\n    65t\n    110t\n    -93t\n    -9t\n    85t\n    38t\n    -89t\n    -43t\n    124t\n    59t\n    93t\n    -25t\n    -9t\n    -113t\n    -82t\n    113t\n    28t\n    10t\n    -17t\n    96t\n    -79t\n    119t\n    -26t\n    -87t\n    -63t\n    -1t\n    -92t\n    23t\n    -68t\n    56t\n    42t\n    26t\n    -11t\n    -1t\n    92t\n    -59t\n    -111t\n    -18t\n    50t\n    -55t\n    -5t\n    -2t\n    -43t\n    -7t\n    72t\n    114t\n    -72t\n    -122t\n    18t\n    47t\n    102t\n    62t\n    -7t\n    -27t\n    41t\n    66t\n    -51t\n    -75t\n    81t\n    111t\n    97t\n    -119t\n    -8t\n    71t\n    18t\n    49t\n    -123t\n    35t\n    96t\n    -20t\n    33t\n    -57t\n    109t\n    -87t\n    -86t\n    49t\n    59t\n    28t\n    -7t\n    -72t\n    -2t\n    -54t\n    31t\n    79t\n    -56t\n    -13t\n    22t\n    13t\n    38t\n    67t\n    -18t\n    9t\n    -35t\n    -128t\n    54t\n    -121t\n    -104t\n    -118t\n    84t\n    112t\n    -124t\n    -57t\n    -30t\n    -48t\n    -88t\n    -54t\n    -81t\n    111t\n    55t\n    97t\n    -24t\n    96t\n    95t\n    13t\n    17t\n    123t\n    -27t\n    -109t\n    116t\n    112t\n    94t\n    106t\n    92t\n    -116t\n    -85t\n    99t\n    -72t\n    89t\n    71t\n    18t\n    -75t\n    118t\n    -38t\n    -13t\n    -69t\n    -16t\n    123t\n    34t\n    103t\n    -46t\n    104t\n    -87t\n    53t\n    102t\n    -9t\n    116t\n    -56t\n    -114t\n    28t\n    -118t\n    -97t\n    105t\n    -49t\n    7t\n    -76t\n    -70t\n    -81t\n    52t\n    -53t\n    -62t\n    21t\n    41t\n    -41t\n    -26t\n    124t\n    -31t\n    63t\n    -110t\n    86t\n    -74t\n    -2t\n    9t\n    -104t\n    111t\n    93t\n    -70t\n    -127t\n    -9t\n    16t\n    -14t\n    -79t\n    68t\n    -38t\n    106t\n    -118t\n    12t\n    -2t\n    -17t\n    -43t\n    -55t\n    -56t\n    -56t\n    1t\n    -122t\n    85t\n    -85t\n    -31t\n    -125t\n    -1t\n    -25t\n    -93t\n    -25t\n    120t\n    -5t\n    -128t\n    79t\n    -78t\n    118t\n    -32t\n    -33t\n    -41t\n    112t\n    -102t\n    62t\n    -21t\n    -41t\n    56t\n    -112t\n    -11t\n    -26t\n    115t\n    -46t\n    -31t\n    -34t\n    -105t\n    -24t\n    61t\n    55t\n    121t\n    34t\n    60t\n    101t\n    38t\n    88t\n    -1t\n    -43t\n    50t\n    49t\n    66t\n    4t\n    -50t\n    -39t\n    102t\n    -128t\n    29t\n    -7t\n    -104t\n    -90t\n    49t\n    -30t\n    -45t\n    -45t\n    99t\n    76t\n    -76t\n    101t\n    -37t\n    8t\n    -3t\n    81t\n    110t\n    -37t\n    -92t\n    85t\n    -88t\n    -18t\n    -82t\n    -43t\n    -14t\n    -35t\n    4t\n    92t\n    24t\n    -31t\n    -123t\n    -31t\n    -50t\n    -72t\n    -110t\n    44t\n    -75t\n    94t\n    24t\n    60t\n    27t\n    -20t\n    118t\n    -123t\n    -27t\n    8t\n    -106t\n    15t\n    -70t\n    82t\n    60t\n    44t\n    24t\n    5t\n    126t\n    68t\n    119t\n    46t\n    -67t\n    -127t\n    -6t\n    109t\n    52t\n    -31t\n    -30t\n    -53t\n    25t\n    -10t\n    121t\n    97t\n    123t\n    84t\n    -25t\n    -109t\n    85t\n    -9t\n    49t\n    70t\n    23t\n    28t\n    19t\n    21t\n    -39t\n    -8t\n    -56t\n    105t\n    -35t\n    97t\n    -111t\n    53t\n    4t\n    -47t\n    72t\n    -37t\n    -61t\n    -10t\n    -25t\n    31t\n    -115t\n    -48t\n    36t\n    -72t\n    33t\n    65t\n    81t\n    71t\n    -40t\n    127t\n    60t\n    120t\n    72t\n    -111t\n    -62t\n    -20t\n    -120t\n    22t\n    69t\n    112t\n    124t\n    -32t\n    -13t\n    100t\n    -92t\n    -72t\n    5t\n    6t\n    -97t\n    -85t\n    -88t\n    -91t\n    -120t\n    47t\n    110t\n    33t\n    67t\n    36t\n    -35t\n    27t\n    52t\n    -71t\n    -3t\n    122t\n    21t\n    -1t\n    57t\n    79t\n    66t\n    51t\n    68t\n    -61t\n    -46t\n    15t\n    65t\n    106t\n    -68t\n    2t\n    -36t\n    57t\n    65t\n    91t\n    -11t\n    8t\n    31t\n    -2t\n    -74t\n    -48t\n    -126t\n    -61t\n    49t\n    46t\n    43t\n    -36t\n    -61t\n    -61t\n    63t\n    -126t\n    -17t\n    62t\n    -105t\n    49t\n    35t\n    108t\n    -72t\n    -24t\n    108t\n    3t\n    -77t\n    120t\n    41t\n    -65t\n    115t\n    16t\n    77t\n    53t\n    1t\n    -41t\n    35t\n    46t\n    -107t\n    45t\n    -109t\n    -117t\n    -74t\n    43t\n    -105t\n    -98t\n    103t\n    79t\n    -80t\n    113t\n    -25t\n    30t\n    -2t\n    120t\n    51t\n    109t\n    64t\n    38t\n    -63t\n    -127t\n    39t\n    -8t\n    -6t\n    105t\n    -101t\n    -45t\n    -88t\n    -50t\n    -9t\n    42t\n    -121t\n    -20t\n    -93t\n    126t\n    -94t\n    104t\n    -125t\n    -44t\n    -57t\n    -40t\n    69t\n    107t\n    -30t\n    -72t\n    -2t\n    68t\n    87t\n    -114t\n    -102t\n    -110t\n    28t\n    21t\n    106t\n    -112t\n    -122t\n    -73t\n    18t\n    89t\n    89t\n    -47t\n    -6t\n    -99t\n    104t\n    -94t\n    -73t\n    -50t\n    -74t\n    -71t\n    -25t\n    0t\n    -76t\n    -96t\n    -55t\n    57t\n    9t\n    -80t\n    -4t\n    -122t\n    106t\n    -2t\n    95t\n    46t\n    82t\n    -118t\n    -117t\n    -101t\n    -123t\n    -89t\n    81t\n    -17t\n    90t\n    52t\n    44t\n    102t\n    -77t\n    -70t\n    -105t\n    102t\n    90t\n    -66t\n    2t\n    -4t\n    63t\n    77t\n    -8t\n    18t\n    56t\n    -78t\n    -25t\n    -29t\n    122t\n    -110t\n    -71t\n    -1t\n    80t\n    112t\n    -73t\n    -31t\n    -77t\n    72t\n    92t\n    -110t\n    -28t\n    -29t\n    83t\n    77t\n    12t\n    124t\n    -67t\n    26t\n    -26t\n    36t\n    -11t\n    -15t\n    -106t\n    -83t\n    -1t\n    88t\n    -54t\n    -93t\n    -7t\n    69t\n    40t\n    50t\n    -80t\n    92t\n    19t\n    -107t\n    54t\n    16t\n    79t\n    12t\n    94t\n    -78t\n    -18t\n    23t\n    -72t\n    -16t\n    92t\n    62t\n    71t\n    114t\n    -82t\n    -115t\n    109t\n    -32t\n    1t\n    -37t\n    -11t\n    -91t\n    71t\n    -126t\n    119t\n    63t\n    -67t\n    23t\n    -32t\n    67t\n    81t\n    -45t\n    24t\n    -50t\n    66t\n    -26t\n    -55t\n    -32t\n    -87t\n    -24t\n    113t\n    6t\n    72t\n    -85t\n    -115t\n    43t\n    12t\n    56t\n    -105t\n    -18t\n    -121t\n    -45t\n    -64t\n    -107t\n    72t\n    60t\n    -109t\n    63t\n    -18t\n    123t\n    -36t\n    -102t\n    124t\n    61t\n    -119t\n    -47t\n    -47t\n    -119t\n    28t\n    32t\n    30t\n    -37t\n    -122t\n    83t\n    -62t\n    -22t\n    64t\n    -73t\n    -94t\n    -33t\n    51t\n    -45t\n    -82t\n    57t\n    11t\n    -85t\n    106t\n    36t\n    119t\n    -39t\n    -85t\n    100t\n    -93t\n    49t\n    69t\n    -51t\n    24t\n    93t\n    119t\n    -38t\n    -10t\n    82t\n    -55t\n    10t\n    -67t\n    71t\n    -126t\n    -42t\n    -31t\n    -46t\n    125t\n    -33t\n    21t\n    72t\n    13t\n    32t\n    -50t\n    47t\n    -88t\n    105t\n    79t\n    -29t\n    -121t\n    70t\n    -90t\n    114t\n    97t\n    34t\n    18t\n    -105t\n    91t\n    -49t\n    -97t\n    -56t\n    -88t\n    -59t\n    120t\n    106t\n    59t\n    -29t\n    80t\n    115t\n    -33t\n    -58t\n    30t\n    112t\n    -92t\n    -88t\n    -5t\n    10t\n    -80t\n    107t\n    64t\n    24t\n    107t\n    32t\n    93t\n    -68t\n    -14t\n    -123t\n    -47t\n    119t\n    -11t\n    84t\n    21t\n    13t\n    -47t\n    72t\n    -82t\n    65t\n    -57t\n    -60t\n    115t\n    34t\n    10t\n    127t\n    -37t\n    120t\n    -69t\n    18t\n    -33t\n    108t\n    -127t\n    74t\n    106t\n    -81t\n    57t\n    100t\n    70t\n    -61t\n    2t\n    88t\n    96t\n    -77t\n    60t\n    43t\n    69t\n    -37t\n    -54t\n    -28t\n    39t\n    38t\n    -11t\n    -92t\n    -40t\n    99t\n    38t\n    -66t\n    -94t\n    -80t\n    -86t\n    97t\n    -122t\n    -59t\n    -3t\n    -10t\n    94t\n    80t\n    -29t\n    -7t\n    86t\n    91t\n    109t\n    -36t\n    38t\n    -33t\n    -99t\n    -98t\n    -26t\n    68t\n    -10t\n    92t\n    75t\n    2t\n    57t\n    32t\n    -103t\n    -44t\n    30t\n    30t\n    13t\n    111t\n    -73t\n    56t\n    121t\n    -35t\n    -119t\n    -22t\n    -58t\n    -54t\n    -125t\n    74t\n    -106t\n    106t\n    -51t\n    -78t\n    89t\n    11t\n    -27t\n    -13t\n    107t\n    123t\n    112t\n    -13t\n    -6t\n    -38t\n    80t\n    59t\n    61t\n    -78t\n    124t\n    -22t\n    57t\n    -93t\n    -24t\n    40t\n    39t\n    -101t\n    71t\n    -27t\n    -100t\n    94t\n    112t\n    20t\n    109t\n    119t\n    80t\n    -23t\n    -81t\n    69t\n    5t\n    -61t\n    -114t\n    89t\n    -121t\n    73t\n    102t\n    58t\n    -58t\n    81t\n    -120t\n    -83t\n    123t\n    -88t\n    18t\n    -109t\n    94t\n    -1t\n    -47t\n    18t\n    -44t\n    126t\n    -61t\n    -78t\n    -92t\n    11t\n    -123t\n    -14t\n    58t\n    -91t\n    -113t\n    125t\n    87t\n    10t\n    26t\n    -46t\n    28t\n    33t\n    71t\n    125t\n    -97t\n    37t\n    64t\n    46t\n    105t\n    5t\n    -38t\n    101t\n    -71t\n    -89t\n    -21t\n    -54t\n    61t\n    77t\n    -29t\n    44t\n    78t\n    122t\n    110t\n    -97t\n    10t\n    115t\n    73t\n    -1t\n    17t\n    -90t\n    54t\n    -19t\n    77t\n    -6t\n    86t\n    96t\n    -89t\n    -57t\n    -87t\n    -99t\n    49t\n    -13t\n    -3t\n    104t\n    -79t\n    -3t\n    -22t\n    -39t\n    -18t\n    109t\n    -79t\n    16t\n    125t\n    -87t\n    48t\n    -44t\n    -19t\n    -30t\n    58t\n    78t\n    -61t\n    57t\n    8t\n    -17t\n    -49t\n    -93t\n    -76t\n    -84t\n    77t\n    54t\n    -26t\n    -125t\n    120t\n    21t\n    101t\n    48t\n    104t\n    -113t\n    -72t\n    106t\n    -27t\n    15t\n    -124t\n    -103t\n    -41t\n    84t\n    19t\n    -106t\n    17t\n    10t\n    46t\n    -103t\n    15t\n    68t\n    -62t\n    -39t\n    -66t\n    125t\n    100t\n    -8t\n    99t\n    -107t\n    -80t\n    -112t\n    83t\n    85t\n    31t\n    63t\n    84t\n    -43t\n    -76t\n    -65t\n    -114t\n    -119t\n    -52t\n    37t\n    -110t\n    -100t\n    -75t\n    -126t\n    -20t\n    50t\n    -28t\n    30t\n    -38t\n    13t\n    -14t\n    121t\n    -95t\n    -60t\n    48t\n    -70t\n    -46t\n    -43t\n    32t\n    -127t\n    105t\n    -108t\n    -115t\n    122t\n    24t\n    -77t\n    104t\n    63t\n    -33t\n    -110t\n    -44t\n    26t\n    20t\n    -74t\n    -53t\n    -2t\n    -70t\n    30t\n    -24t\n    -107t\n    58t\n    37t\n    -70t\n    56t\n    -56t\n    72t\n    62t\n    125t\n    103t\n    -98t\n    -62t\n    121t\n    110t\n    -78t\n    114t\n    24t\n    -112t\n    94t\n    6t\n    52t\n    81t\n    21t\n    35t\n    112t\n    77t\n    -117t\n    72t\n    -31t\n    72t\n    -126t\n    92t\n    51t\n    -124t\n    -2t\n    -124t\n    -13t\n    -51t\n    80t\n    -2t\n    -9t\n    -114t\n    55t\n    -28t\n    54t\n    14t\n    71t\n    -29t\n    -47t\n    42t\n    66t\n    -85t\n    118t\n    -23t\n    -74t\n    -35t\n    64t\n    30t\n    -18t\n    17t\n    -6t\n    -32t\n    -40t\n    77t\n    68t\n    82t\n    -76t\n    41t\n    -6t\n    -31t\n    52t\n    31t\n    39t\n    108t\n    -83t\n    118t\n    -80t\n    119t\n    58t\n    91t\n    -126t\n    29t\n    105t\n    9t\n    -7t\n    62t\n    6t\n    120t\n    -122t\n    23t\n    67t\n    -49t\n    43t\n    -22t\n    80t\n    44t\n    -49t\n    98t\n    -128t\n    -82t\n    -45t\n    122t\n    12t\n    81t\n    52t\n    -41t\n    89t\n    46t\n    -78t\n    -123t\n    10t\n    -3t\n    -56t\n    -116t\n    7t\n    -73t\n    -88t\n    42t\n    22t\n    -128t\n    16t\n    46t\n    80t\n    8t\n    -3t\n    -6t\n    -65t\n    123t\n    124t\n    20t\n    -36t\n    -124t\n    -54t\n    -18t\n    11t\n    -77t\n    40t\n    -5t\n    0t\n    94t\n    -15t\n    27t\n    41t\n    -33t\n    81t\n    18t\n    125t\n    113t\n    -35t\n    1t\n    106t\n    11t\n    -123t\n    62t\n    2t\n    -18t\n    55t\n    -2t\n    -46t\n    114t\n    -109t\n    -32t\n    -82t\n    -28t\n    22t\n    86t\n    -21t\n    -26t\n    55t\n    107t\n    38t\n    -27t\n    -38t\n    -4t\n    101t\n    110t\n    -127t\n    -103t\n    14t\n    62t\n    113t\n    -30t\n    -77t\n    119t\n    -67t\n    66t\n    107t\n    95t\n    -100t\n    -92t\n    36t\n    41t\n    61t\n    -104t\n    110t\n    -117t\n    -111t\n    27t\n    100t\n    93t\n    -43t\n    26t\n    4t\n    35t\n    -4t\n    -46t\n    108t\n    100t\n    -114t\n    15t\n    12t\n    -91t\n    92t\n    -15t\n    -34t\n    -24t\n    -10t\n    -39t\n    44t\n    1t\n    -123t\n    19t\n    -43t\n    76t\n    -37t\n    25t\n    -27t\n    -12t\n    118t\n    -88t\n    -99t\n    56t\n    -21t\n    42t\n    -39t\n    69t\n    -76t\n    -54t\n    -16t\n    -123t\n    -93t\n    -19t\n    32t\n    -115t\n    -28t\n    -81t\n    48t\n    76t\n    69t\n    6t\n    -45t\n    -106t\n    -52t\n    -13t\n    -50t\n    37t\n    -72t\n    107t\n    15t\n    -44t\n    90t\n    24t\n    -66t\n    -63t\n    93t\n    41t\n    -39t\n    -97t\n    -27t\n    -3t\n    -2t\n    -96t\n    -40t\n    63t\n    -80t\n    44t\n    84t\n    -94t\n    39t\n    -49t\n    -116t\n    -76t\n    -109t\n    36t\n    -108t\n    -79t\n    46t\n    90t\n    49t\n    13t\n    -78t\n    -29t\n    -75t\n    -36t\n    -58t\n    -22t\n    -110t\n    70t\n    -10t\n    94t\n    -123t\n    -90t\n    -77t\n    -81t\n    -92t\n    -32t\n    -62t\n    -76t\n    -90t\n    -78t\n    -32t\n    -60t\n    57t\n    9t\n    -6t\n    -114t\n    88t\n    78t\n    -63t\n    -18t\n    -72t\n    -50t\n    -70t\n    112t\n    103t\n    -60t\n    -21t\n    -76t\n    0t\n    -33t\n    12t\n    -71t\n    -63t\n    58t\n    13t\n    73t\n    -42t\n    -31t\n    71t\n    36t\n    29t\n    104t\n    31t\n    6t\n    56t\n    -127t\n    -13t\n    -127t\n    103t\n    55t\n    115t\n    13t\n    75t\n    91t\n    47t\n    -91t\n    -123t\n    -22t\n    44t\n    -2t\n    -128t\n    -19t\n    119t\n    28t\n    20t\n    123t\n    66t\n    -126t\n    70t\n    43t\n    15t\n    123t\n    26t\n    86t\n    -49t\n    -78t\n    79t\n    -48t\n    -66t\n    -8t\n    49t\n    -90t\n    6t\n    25t\n    -75t\n    73t\n    -16t\n    -48t\n    -123t\n    -59t\n    -57t\n    -6t\n    77t\n    -60t\n    -65t\n    -32t\n    -111t\n    55t\n    -25t\n    -83t\n    -98t\n    124t\n    81t\n    104t\n    -126t\n    -127t\n    37t\n    70t\n    106t\n    72t\n    -59t\n    93t\n    -45t\n    90t\n    -61t\n    105t\n    -30t\n    -63t\n    -88t\n    -60t\n    76t\n    89t\n    -99t\n    31t\n    -102t\n    -17t\n    -56t\n    114t\n    94t\n    -60t\n    -55t\n    -4t\n    -122t\n    -74t\n    60t\n    124t\n    103t\n    -49t\n    -9t\n    -124t\n    47t\n    -111t\n    -105t\n    24t\n    59t\n    34t\n    -18t\n    -75t\n    99t\n    88t\n    85t\n    114t\n    12t\n    -100t\n    71t\n    78t\n    55t\n    -1t\n    -33t\n    -57t\n    -99t\n    50t\n    102t\n    41t\n    -50t\n    122t\n    27t\n    -37t\n    94t\n    71t\n    -6t\n    43t\n    -110t\n    90t\n    -86t\n    40t\n    -37t\n    -2t\n    95t\n    -72t\n    69t\n    -11t\n    -15t\n    55t\n    -17t\n    10t\n    126t\n    76t\n    -27t\n    -99t\n    -95t\n    113t\n    -56t\n    -29t\n    121t\n    -100t\n    52t\n    -5t\n    18t\n    -76t\n    6t\n    11t\n    -86t\n    -81t\n    -73t\n    -121t\n    -126t\n    -80t\n    -91t\n    81t\n    -113t\n    99t\n    -111t\n    -125t\n    47t\n    -9t\n    62t\n    125t\n    -67t\n    -78t\n    121t\n    -45t\n    9t\n    78t\n    -74t\n    -35t\n    -108t\n    -27t\n    -124t\n    -36t\n    -114t\n    -30t\n    -108t\n    115t\n    -125t\n    98t\n    -106t\n    56t\n    50t\n    -101t\n    52t\n    114t\n    -115t\n    86t\n    77t\n    -30t\n    76t\n    -69t\n    -62t\n    70t\n    83t\n    -61t\n    -81t\n    80t\n    1t\n    72t\n    -72t\n    -109t\n    -93t\n    98t\n    -86t\n    -64t\n    -67t\n    2t\n    2t\n    89t\n    10t\n    114t\n    108t\n    27t\n    -65t\n    5t\n    -22t\n    54t\n    -62t\n    118t\n    -20t\n    -112t\n    -14t\n    -22t\n    -74t\n    59t\n    -16t\n    66t\n    -102t\n    106t\n    -24t\n    -12t\n    34t\n    74t\n    63t\n    -62t\n    -30t\n    -5t\n    1t\n    52t\n    -82t\n    109t\n    -22t\n    -66t\n    119t\n    -5t\n    -112t\n    53t\n    125t\n    -54t\n    15t\n    -4t\n    5t\n    13t\n    -12t\n    -30t\n    -9t\n    110t\n    -57t\n    -23t\n    -107t\n    121t\n    72t\n    -71t\n    36t\n    70t\n    13t\n    -2t\n    97t\n    -120t\n    107t\n    -64t\n    -111t\n    40t\n    47t\n    76t\n    43t\n    -62t\n    -42t\n    -128t\n    33t\n    65t\n    -84t\n    73t\n    -118t\n    -17t\n    11t\n    1t\n    37t\n    -93t\n    99t\n    93t\n    -116t\n    -126t\n    105t\n    -93t\n    -99t\n    -114t\n    90t\n    -47t\n    -11t\n    -90t\n    93t\n    -80t\n    -12t\n    -35t\n    -24t\n    -7t\n    39t\n    37t\n    36t\n    -66t\n    109t\n    -88t\n    -64t\n    -101t\n    -50t\n    -75t\n    -69t\n    -124t\n    40t\n    -110t\n    30t\n    8t\n    121t\n    51t\n    25t\n    46t\n    -117t\n    98t\n    -67t\n    61t\n    96t\n    57t\n    -11t\n    78t\n    65t\n    -93t\n    -127t\n    -10t\n    11t\n    30t\n    5t\n    52t\n    -67t\n    15t\n    -108t\n    -68t\n    -91t\n    -28t\n    -93t\n    59t\n    124t\n    -17t\n    103t\n    17t\n    -41t\n    44t\n    71t\n    51t\n    10t\n    -1t\n    76t\n    57t\n    -54t\n    103t\n    92t\n    -38t\n    78t\n    11t\n    104t\n    80t\n    90t\n    80t\n    45t\n    -7t\n    107t\n    -35t\n    69t\n    -69t\n    89t\n    -15t\n    -6t\n    56t\n    33t\n    9t\n    26t\n    117t\n    -121t\n    87t\n    -108t\n    106t\n    105t\n    -4t\n    -36t\n    -37t\n    22t\n    57t\n    -33t\n    -122t\n    -71t\n    -114t\n    -12t\n    84t\n    -98t\n    105t\n    119t\n    11t\n    12t\n    36t\n    88t\n    -112t\n    72t\n    -40t\n    -40t\n    -50t\n    33t\n    19t\n    -77t\n    118t\n    -79t\n    27t\n    109t\n    32t\n    -122t\n    -103t\n    28t\n    -119t\n    -80t\n    27t\n    -11t\n    9t\n    67t\n    -53t\n    85t\n    -3t\n    118t\n    36t\n    35t\n    18t\n    64t\n    -85t\n    99t\n    -15t\n    -11t\n    -72t\n    125t\n    -89t\n    -36t\n    27t\n    5t\n    104t\n    -41t\n    45t\n    78t\n    67t\n    -74t\n    -66t\n    76t\n    -59t\n    -110t\n    -94t\n    2t\n    -98t\n    88t\n    -53t\n    35t\n    75t\n    -125t\n    0t\n    92t\n    83t\n    -126t\n    -4t\n    -32t\n    35t\n    -18t\n    53t\n    22t\n    -85t\n    -62t\n    86t\n    -103t\n    -42t\n    17t\n    127t\n    105t\n    -120t\n    -41t\n    -124t\n    -86t\n    39t\n    -123t\n    -14t\n    -36t\n    -66t\n    37t\n    -97t\n    -37t\n    125t\n    6t\n    -119t\n    42t\n    110t\n    109t\n    -74t\n    -126t\n    32t\n    12t\n    -79t\n    -128t\n    -52t\n    -4t\n    -87t\n    -126t\n    127t\n    -105t\n    -31t\n    -101t\n    100t\n    54t\n    -42t\n    70t\n    65t\n    50t\n    -19t\n    -66t\n    -93t\n    116t\n    -81t\n    -14t\n    -102t\n    94t\n    28t\n    -12t\n    111t\n    79t\n    124t\n    44t\n    -102t\n    -46t\n    -47t\n    114t\n    82t\n    -116t\n    103t\n    69t\n    42t\n    95t\n    -98t\n    87t\n    -71t\n    -30t\n    -66t\n    -29t\n    73t\n    60t\n    -90t\n    21t\n    -79t\n    71t\n    -72t\n    -61t\n    84t\n    -33t\n    -51t\n    -97t\n    -19t\n    86t\n    -18t\n    -17t\n    115t\n    -38t\n    43t\n    -75t\n    18t\n    34t\n    115t\n    -43t\n    70t\n    21t\n    122t\n    -117t\n    -71t\n    -93t\n    95t\n    -28t\n    70t\n    35t\n    -51t\n    117t\n    -87t\n    76t\n    88t\n    -83t\n    46t\n    -25t\n    39t\n    91t\n    127t\n    -75t\n    -84t\n    9t\n    47t\n    95t\n    83t\n    -18t\n    -13t\n    1t\n    123t\n    -60t\n    20t\n    22t\n    42t\n    -78t\n    77t\n    -39t\n    -80t\n    -8t\n    105t\n    -26t\n    69t\n    70t\n    -7t\n    -47t\n    101t\n    -84t\n    35t\n    -104t\n    -17t\n    73t\n    58t\n    -23t\n    2t\n    -127t\n    52t\n    -80t\n    -48t\n    103t\n    -58t\n    9t\n    83t\n    -29t\n    33t\n    91t\n    3t\n    100t\n    14t\n    35t\n    -48t\n    -14t\n    -32t\n    -36t\n    95t\n    -77t\n    21t\n    -88t\n    0t\n    17t\n    -19t\n    -121t\n    -63t\n    -33t\n    89t\n    50t\n    -95t\n    105t\n    -62t\n    94t\n    -127t\n    -118t\n    -59t\n    1t\n    -6t\n    -71t\n    112t\n    68t\n    100t\n    127t\n    27t\n    78t\n    60t\n    66t\n    13t\n    41t\n    -28t\n    100t\n    -123t\n    18t\n    4t\n    124t\n    -102t\n    61t\n    -119t\n    -30t\n    78t\n    57t\n    43t\n    -70t\n    -17t\n    -45t\n    88t\n    -1t\n    -65t\n    127t\n    -84t\n    4t\n    116t\n    -17t\n    119t\n    -117t\n    21t\n    -123t\n    -76t\n    52t\n    98t\n    79t\n    -57t\n    108t\n    -52t\n    -28t\n    104t\n    75t\n    88t\n    15t\n    74t\n    -109t\n    63t\n    68t\n    -79t\n    -95t\n    -30t\n    -87t\n    -122t\n    -96t\n    -37t\n    0t\n    -121t\n    -47t\n    17t\n    111t\n    32t\n    -80t\n    -18t\n    69t\n    37t\n    -27t\n    19t\n    -5t\n    79t\n    -3t\n    13t\n    -50t\n    -53t\n    -49t\n    45t\n    -120t\n    85t\n    12t\n    -84t\n    119t\n    -115t\n    -72t\n    3t\n    81t\n    122t\n    74t\n    42t\n    82t\n    -10t\n    -89t\n    -115t\n    -8t\n    32t\n    70t\n    49t\n    63t\n    -6t\n    106t\n    -22t\n    -116t\n    -70t\n    97t\n    46t\n    -119t\n    65t\n    118t\n    -98t\n    78t\n    103t\n    44t\n    116t\n    -79t\n    95t\n    -90t\n    -38t\n    74t\n    -106t\n    -60t\n    115t\n    21t\n    -48t\n    22t\n    67t\n    -17t\n    48t\n    68t\n    101t\n    39t\n    61t\n    -45t\n    8t\n    4t\n    66t\n    125t\n    -23t\n    -119t\n    79t\n    52t\n    -35t\n    109t\n    -3t\n    -82t\n    -70t\n    39t\n    40t\n    -126t\n    -126t\n    109t\n    -123t\n    -115t\n    -26t\n    -95t\n    -17t\n    39t\n    -110t\n    -102t\n    -37t\n    -78t\n    81t\n    -96t\n    87t\n    -96t\n    -4t\n    -124t\n    -46t\n    -45t\n    -125t\n    -25t\n    -17t\n    67t\n    -36t\n    107t\n    5t\n    -116t\n    -124t\n    -98t\n    12t\n    -75t\n    72t\n    -55t\n    13t\n    -42t\n    118t\n    -107t\n    -32t\n    67t\n    12t\n    89t\n    13t\n    31t\n    -75t\n    -127t\n    -111t\n    15t\n    21t\n    -36t\n    60t\n    -63t\n    85t\n    39t\n    17t\n    99t\n    4t\n    88t\n    104t\n    -73t\n    -109t\n    -19t\n    -82t\n    -85t\n    42t\n    120t\n    118t\n    20t\n    -1t\n    58t\n    -31t\n    114t\n    -61t\n    -107t\n    -30t\n    -23t\n    17t\n    -69t\n    -110t\n    10t\n    -54t\n    16t\n    12t\n    65t\n    15t\n    100t\n    -125t\n    50t\n    22t\n    118t\n    21t\n    113t\n    -106t\n    2t\n    17t\n    -94t\n    -67t\n    -79t\n    -77t\n    25t\n    87t\n    -46t\n    -108t\n    -87t\n    -55t\n    62t\n    52t\n    123t\n    88t\n    56t\n    68t\n    79t\n    -112t\n    122t\n    23t\n    -8t\n    -112t\n    83t\n    21t\n    105t\n    -113t\n    37t\n    -56t\n    73t\n    6t\n    57t\n    -60t\n    30t\n    -78t\n    86t\n    -1t\n    -69t\n    -96t\n    -33t\n    -73t\n    -43t\n    24t\n    -114t\n    -87t\n    -57t\n    23t\n    36t\n    112t\n    -33t\n    71t\n    -29t\n    120t\n    78t\n    -97t\n    35t\n    122t\n    -106t\n    46t\n    89t\n    23t\n    -98t\n    -35t\n    62t\n    -125t\n    -38t\n    44t\n    28t\n    113t\n    -113t\n    83t\n    119t\n    -26t\n    -19t\n    19t\n    -126t\n    8t\n    -91t\n    106t\n    113t\n    114t\n    84t\n    90t\n    99t\n    65t\n    -41t\n    65t\n    44t\n    -79t\n    -120t\n    -90t\n    -16t\n    -50t\n    -64t\n    64t\n    65t\n    3t\n    72t\n    13t\n    30t\n    8t\n    -120t\n    -122t\n    -54t\n    -56t\n    -124t\n    -115t\n    -12t\n    -45t\n    -69t\n    -60t\n    7t\n    66t\n    122t\n    102t\n    86t\n    -21t\n    6t\n    -113t\n    -33t\n    -25t\n    -112t\n    -87t\n    -91t\n    -53t\n    73t\n    117t\n    -65t\n    40t\n    -91t\n    -75t\n    126t\n    -22t\n    5t\n    102t\n    -87t\n    -10t\n    7t\n    -82t\n    -43t\n    -124t\n    -102t\n    -64t\n    47t\n    -49t\n    -91t\n    -68t\n    -65t\n    83t\n    -55t\n    90t\n    -66t\n    -73t\n    78t\n    46t\n    -116t\n    118t\n    -38t\n    107t\n    97t\n    -99t\n    -91t\n    -108t\n    -48t\n    107t\n    73t\n    -23t\n    68t\n    -128t\n    41t\n    115t\n    -32t\n    -23t\n    -32t\n    -10t\n    -117t\n    31t\n    -77t\n    6t\n    -88t\n    14t\n    70t\n    -102t\n    73t\n    17t\n    102t\n    -92t\n    112t\n    -126t\n    58t\n    82t\n    -19t\n    4t\n    -5t\n    -74t\n    0t\n    86t\n    116t\n    38t\n    121t\n    7t\n    29t\n    124t\n    49t\n    39t\n    -120t\n    45t\n    -38t\n    19t\n    -94t\n    81t\n    0t\n    12t\n    100t\n    -1t\n    89t\n    49t\n    97t\n    34t\n    105t\n    38t\n    56t\n    18t\n    -8t\n    112t\n    -86t\n    118t\n    -37t\n    88t\n    30t\n    -86t\n    9t\n    90t\n    88t\n    121t\n    -107t\n    -86t\n    -58t\n    -13t\n    108t\n    -4t\n    -5t\n    22t\n    -106t\n    -54t\n    -54t\n    107t\n    -20t\n    4t\n    74t\n    -17t\n    100t\n    18t\n    -106t\n    48t\n    -25t\n    91t\n    96t\n    -48t\n    47t\n    -33t\n    36t\n    61t\n    117t\n    67t\n    -90t\n    42t\n    -56t\n    -123t\n    105t\n    67t\n    23t\n    75t\n    39t\n    -13t\n    126t\n    99t\n    15t\n    97t\n    29t\n    -47t\n    94t\n    15t\n    19t\n    3t\n    -66t\n    -89t\n    -11t\n    -31t\n    30t\n    67t\n    40t\n    68t\n    7t\n    -22t\n    -113t\n    -82t\n    94t\n    127t\n    24t\n    -78t\n    109t\n    23t\n    -10t\n    -110t\n    12t\n    35t\n    -18t\n    21t\n    121t\n    97t\n    -93t\n    -8t\n    -117t\n    -124t\n    9t\n    -89t\n    -94t\n    -29t\n    33t\n    -96t\n    49t\n    -120t\n    -98t\n    89t\n    -99t\n    68t\n    53t\n    28t\n    -75t\n    -2t\n    -79t\n    -96t\n    -106t\n    46t\n    -11t\n    97t\n    -23t\n    -76t\n    67t\n    -9t\n    36t\n    101t\n    -123t\n    109t\n    120t\n    2t\n    -51t\n    27t\n    -99t\n    -71t\n    73t\n    -64t\n    99t\n    113t\n    -63t\n    -83t\n    36t\n    -89t\n    -12t\n    -61t\n    -119t\n    24t\n    50t\n    -60t\n    25t\n    -122t\n    -101t\n    -56t\n    -32t\n    78t\n    117t\n    -13t\n    12t\n    51t\n    -12t\n    56t\n    104t\n    -15t\n    62t\n    -109t\n    -74t\n    96t\n    -122t\n    -119t\n    -22t\n    26t\n    -43t\n    -105t\n    -76t\n    39t\n    -27t\n    60t\n    68t\n    31t\n    -77t\n    97t\n    -9t\n    48t\n    -22t\n    10t\n    -50t\n    14t\n    -6t\n    111t\n    -61t\n    8t\n    8t\n    79t\n    103t\n    44t\n    115t\n    84t\n    66t\n    -31t\n    -106t\n    12t\n    -60t\n    -93t\n    -37t\n    -38t\n    30t\n    -94t\n    54t\n    83t\n    10t\n    -20t\n    78t\n    -54t\n    -110t\n    63t\n    -59t\n    12t\n    84t\n    115t\n    10t\n    -2t\n    120t\n    -15t\n    -122t\n    53t\n    57t\n    56t\n    90t\n    -112t\n    91t\n    88t\n    -6t\n    -90t\n    11t\n    -120t\n    -3t\n    -76t\n    -63t\n    86t\n    27t\n    39t\n    42t\n    70t\n    47t\n    -72t\n    -39t\n    55t\n    57t\n    28t\n    44t\n    3t\n    17t\n    55t\n    13t\n    -6t\n    -54t\n    -67t\n    -126t\n    -112t\n    46t\n    -20t\n    -67t\n    43t\n    -27t\n    -11t\n    -11t\n    79t\n    -26t\n    -66t\n    112t\n    92t\n    1t\n    -86t\n    -102t\n    88t\n    56t\n    -89t\n    -93t\n    -120t\n    -35t\n    58t\n    72t\n    11t\n    86t\n    -37t\n    35t\n    -9t\n    69t\n    48t\n    -53t\n    -65t\n    -26t\n    119t\n    5t\n    103t\n    80t\n    -33t\n    -93t\n    -80t\n    -22t\n    -7t\n    93t\n    40t\n    -101t\n    49t\n    52t\n    118t\n    -10t\n    28t\n    -44t\n    -46t\n    -125t\n    -36t\n    -3t\n    -90t\n    3t\n    -92t\n    31t\n    99t\n    -22t\n    30t\n    -24t\n    -33t\n    36t\n    -30t\n    94t\n    -73t\n    -45t\n    -30t\n    16t\n    60t\n    -65t\n    -118t\n    29t\n    104t\n    83t\n    1t\n    112t\n    -71t\n    0t\n    75t\n    -115t\n    -91t\n    78t\n    46t\n    -86t\n    -4t\n    -72t\n    -23t\n    51t\n    -58t\n    123t\n    -87t\n    -81t\n    66t\n    57t\n    -94t\n    -53t\n    24t\n    55t\n    -127t\n    120t\n    -113t\n    65t\n    91t\n    -21t\n    113t\n    12t\n    2t\n    -4t\n    -34t\n    -58t\n    46t\n    -75t\n    -91t\n    -76t\n    -56t\n    100t\n    -30t\n    -26t\n    -103t\n    50t\n    80t\n    92t\n    -8t\n    -28t\n    10t\n    -117t\n    -48t\n    76t\n    56t\n    -117t\n    62t\n    -79t\n    38t\n    118t\n    36t\n    31t\n    -16t\n    -81t\n    0t\n    38t\n    -44t\n    -26t\n    -43t\n    -73t\n    40t\n    74t\n    -48t\n    93t\n    -104t\n    17t\n    -79t\n    103t\n    32t\n    123t\n    -63t\n    86t\n    27t\n    -97t\n    8t\n    -112t\n    -77t\n    16t\n    23t\n    88t\n    83t\n    37t\n    -55t\n    -50t\n    -90t\n    -30t\n    82t\n    69t\n    -67t\n    -111t\n    -29t\n    -27t\n    -109t\n    -8t\n    42t\n    -111t\n    18t\n    -55t\n    10t\n    46t\n    112t\n    -91t\n    48t\n    102t\n    -28t\n    -5t\n    -113t\n    -19t\n    -84t\n    19t\n    -58t\n    79t\n    3t\n    93t\n    -6t\n    -128t\n    -89t\n    12t\n    -47t\n    8t\n    -91t\n    -103t\n    -111t\n    -32t\n    -35t\n    20t\n    -32t\n    113t\n    -122t\n    -61t\n    93t\n    -2t\n    15t\n    -55t\n    -83t\n    -41t\n    35t\n    -80t\n    -39t\n    -26t\n    77t\n    -90t\n    -56t\n    -73t\n    36t\n    29t\n    52t\n    -34t\n    -70t\n    61t\n    -17t\n    -55t\n    114t\n    -24t\n    -45t\n    85t\n    -117t\n    76t\n    -70t\n    121t\n    -38t\n    -72t\n    55t\n    -100t\n    -99t\n    86t\n    21t\n    87t\n    -37t\n    -115t\n    30t\n    -1t\n    33t\n    100t\n    -55t\n    123t\n    -77t\n    113t\n    -128t\n    3t\n    -17t\n    -18t\n    -120t\n    104t\n    -26t\n    93t\n    14t\n    -106t\n    -117t\n    106t\n    -62t\n    3t\n    -20t\n    54t\n    8t\n    60t\n    2t\n    -76t\n    108t\n    10t\n    33t\n    73t\n    -13t\n    -86t\n    -93t\n    -123t\n    -42t\n    67t\n    124t\n    -104t\n    -38t\n    73t\n    107t\n    106t\n    -125t\n    -68t\n    -60t\n    -66t\n    14t\n    -92t\n    95t\n    12t\n    43t\n    54t\n    -30t\n    -31t\n    113t\n    87t\n    112t\n    87t\n    -90t\n    74t\n    51t\n    73t\n    51t\n    84t\n    127t\n    -3t\n    89t\n    -62t\n    0t\n    -105t\n    2t\n    -78t\n    18t\n    51t\n    16t\n    106t\n    76t\n    105t\n    74t\n    -67t\n    79t\n    25t\n    -78t\n    -65t\n    123t\n    -41t\n    55t\n    -100t\n    -79t\n    29t\n    -33t\n    37t\n    -15t\n    -120t\n    54t\n    -107t\n    82t\n    -11t\n    23t\n    113t\n    -104t\n    -122t\n    70t\n    -102t\n    74t\n    113t\n    80t\n    17t\n    -60t\n    -86t\n    -105t\n    -28t\n    94t\n    124t\n    95t\n    116t\n    -77t\n    -39t\n    1t\n    -10t\n    108t\n    -13t\n    -80t\n    -51t\n    45t\n    94t\n    101t\n    17t\n    -105t\n    -90t\n    -93t\n    -16t\n    11t\n    58t\n    21t\n    -90t\n    -44t\n    -33t\n    -24t\n    -58t\n    -39t\n    -64t\n    -49t\n    -45t\n    -12t\n    32t\n    -79t\n    82t\n    -12t\n    -71t\n    10t\n    -58t\n    103t\n    -52t\n    127t\n    110t\n    112t\n    27t\n    100t\n    -64t\n    -30t\n    -50t\n    117t\n    -108t\n    -50t\n    74t\n    82t\n    108t\n    -36t\n    86t\n    28t\n    -103t\n    -102t\n    78t\n    -24t\n    61t\n    -59t\n    30t\n    -4t\n    -86t\n    63t\n    -16t\n    92t\n    89t\n    -106t\n    65t\n    -28t\n    -65t\n    41t\n    -81t\n    -2t\n    -87t\n    72t\n    -38t\n    114t\n    -36t\n    -71t\n    -117t\n    105t\n    20t\n    -128t\n    18t\n    2t\n    -101t\n    11t\n    -72t\n    -103t\n    -53t\n    28t\n    -55t\n    -73t\n    120t\n    -68t\n    -73t\n    53t\n    26t\n    -37t\n    -2t\n    44t\n    -44t\n    -34t\n    23t\n    97t\n    115t\n    65t\n    79t\n    25t\n    54t\n    53t\n    -108t\n    -87t\n    -37t\n    -68t\n    -113t\n    -89t\n    9t\n    124t\n    -102t\n    -62t\n    62t\n    123t\n    90t\n    -89t\n    91t\n    32t\n    -88t\n    -15t\n    88t\n    -62t\n    -96t\n    94t\n    -74t\n    21t\n    114t\n    -30t\n    -52t\n    112t\n    -34t\n    -22t\n    120t\n    113t\n    -77t\n    -93t\n    -2t\n    -82t\n    -80t\n    -128t\n    120t\n    54t\n    -120t\n    112t\n    19t\n    53t\n    83t\n    -55t\n    -18t\n    48t\n    120t\n    95t\n    -60t\n    -123t\n    23t\n    94t\n    -23t\n    81t\n    121t\n    59t\n    -72t\n    122t\n    108t\n    8t\n    46t\n    26t\n    -45t\n    -51t\n    -7t\n    88t\n    77t\n    106t\n    92t\n    104t\n    -52t\n    -73t\n    103t\n    29t\n    -24t\n    10t\n    -88t\n    8t\n    89t\n    57t\n    6t\n    48t\n    71t\n    -59t\n    -73t\n    -54t\n    -26t\n    109t\n    -62t\n    66t\n    -19t\n    93t\n    -79t\n    79t\n    -68t\n    5t\n    -13t\n    -109t\n    -40t\n    32t\n    78t\n    41t\n    63t\n    -41t\n    109t\n    41t\n    -123t\n    -35t\n    -29t\n    19t\n    -74t\n    -75t\n    92t\n    38t\n    -127t\n    -101t\n    99t\n    83t\n    96t\n    108t\n    68t\n    66t\n    116t\n    -42t\n    112t\n    -106t\n    -5t\n    9t\n    -81t\n    80t\n    -93t\n    6t\n    124t\n    47t\n    -20t\n    62t\n    -58t\n    -55t\n    103t\n    9t\n    3t\n    -43t\n    72t\n    -10t\n    82t\n    39t\n    -126t\n    125t\n    -22t\n    38t\n    -65t\n    72t\n    101t\n    -24t\n    36t\n    86t\n    6t\n    42t\n    87t\n    64t\n    107t\n    -101t\n    -119t\n    -43t\n    -3t\n    -35t\n    -102t\n    -35t\n    -108t\n    -119t\n    71t\n    -55t\n    86t\n    -107t\n    -101t\n    90t\n    70t\n    34t\n    83t\n    -1t\n    -119t\n    15t\n    -113t\n    24t\n    124t\n    10t\n    -115t\n    105t\n    93t\n    -78t\n    115t\n    -24t\n    80t\n    12t\n    47t\n    -42t\n    -119t\n    -97t\n    -28t\n    11t\n    -5t\n    -26t\n    -43t\n    -5t\n    16t\n    47t\n    111t\n    -1t\n    -58t\n    108t\n    -77t\n    -8t\n    35t\n    57t\n    26t\n    23t\n    120t\n    20t\n    -55t\n    -95t\n    119t\n    94t\n    -96t\n    31t\n    -42t\n    -5t\n    -103t\n    -46t\n    50t\n    -69t\n    -35t\n    56t\n    -7t\n    -101t\n    119t\n    72t\n    107t\n    107t\n    103t\n    121t\n    104t\n    26t\n    29t\n    84t\n    -1t\n    40t\n    -59t\n    74t\n    90t\n    -39t\n    -29t\n    85t\n    -82t\n    4t\n    -29t\n    88t\n    -59t\n    40t\n    -118t\n    -40t\n    -78t\n    77t\n    -38t\n    -74t\n    -68t\n    -26t\n    42t\n    -65t\n    -19t\n    1t\n    116t\n    -77t\n    62t\n    -14t\n    -62t\n    -127t\n    106t\n    -99t\n    -117t\n    -9t\n    -91t\n    105t\n    58t\n    -75t\n    70t\n    -4t\n    90t\n    32t\n    -90t\n    41t\n    -95t\n    -39t\n    -45t\n    127t\n    42t\n    123t\n    62t\n    89t\n    -64t\n    69t\n    -65t\n    -94t\n    12t\n    -6t\n    95t\n    -85t\n    -71t\n    9t\n    -74t\n    -103t\n    68t\n    49t\n    92t\n    56t\n    -89t\n    97t\n    77t\n    90t\n    65t\n    123t\n    -108t\n    67t\n    -5t\n    124t\n    -104t\n    119t\n    28t\n    -39t\n    109t\n    50t\n    79t\n    21t\n    39t\n    -41t\n    -78t\n    -43t\n    -2t\n    -17t\n    30t\n    106t\n    -117t\n    -102t\n    73t\n    -118t\n    -38t\n    37t\n    -108t\n    -90t\n    28t\n    -22t\n    -88t\n    -21t\n    31t\n    -108t\n    1t\n    75t\n    -94t\n    100t\n    91t\n    -50t\n    -63t\n    84t\n    -89t\n    45t\n    27t\n    -30t\n    59t\n    54t\n    43t\n    -89t\n    -76t\n    -14t\n    -13t\n    -101t\n    19t\n    41t\n    -93t\n    71t\n    -60t\n    15t\n    6t\n    94t\n    -85t\n    46t\n    120t\n    -14t\n    -56t\n    -127t\n    63t\n    -128t\n    2t\n    21t\n    88t\n    2t\n    -101t\n    -14t\n    -92t\n    -42t\n    39t\n    -94t\n    100t\n    -93t\n    -35t\n    -90t\n    -106t\n    80t\n    84t\n    -73t\n    32t\n    -78t\n    28t\n    -101t\n    55t\n    52t\n    -76t\n    51t\n    23t\n    42t\n    61t\n    -40t\n    46t\n    -44t\n    -60t\n    -3t\n    113t\n    19t\n    -71t\n    -48t\n    16t\n    1t\n    41t\n    -69t\n    3t\n    25t\n    -35t\n    55t\n    -94t\n    -17t\n    66t\n    -91t\n    57t\n    -9t\n    94t\n    -30t\n    117t\n    28t\n    62t\n    97t\n    -26t\n    -101t\n    72t\n    23t\n    -57t\n    75t\n    37t\n    28t\n    19t\n    97t\n    43t\n    110t\n    -36t\n    -89t\n    16t\n    114t\n    -100t\n    18t\n    55t\n    -85t\n    -63t\n    -17t\n    -101t\n    49t\n    -15t\n    101t\n    -59t\n    50t\n    -95t\n    82t\n    76t\n    60t\n    32t\n    11t\n    -19t\n    -90t\n    32t\n    -36t\n    -4t\n    -74t\n    123t\n    115t\n    60t\n    112t\n    85t\n    -101t\n    51t\n    11t\n    38t\n    -110t\n    -118t\n    -3t\n    -73t\n    111t\n    -79t\n    63t\n    71t\n    24t\n    59t\n    86t\n    -113t\n    71t\n    74t\n    -33t\n    -122t\n    -68t\n    92t\n    93t\n    -38t\n    -106t\n    -33t\n    -3t\n    -50t\n    106t\n    -120t\n    30t\n    91t\n    39t\n    -94t\n    -111t\n    -68t\n    101t\n    -31t\n    100t\n    -80t\n    -112t\n    72t\n    -60t\n    -46t\n    -108t\n    -14t\n    -82t\n    -4t\n    -40t\n    122t\n    -73t\n    -105t\n    -103t\n    -63t\n    83t\n    84t\n    9t\n    85t\n    57t\n    37t\n    85t\n    1t\n    -112t\n    -77t\n    41t\n    -2t\n    -56t\n    90t\n    21t\n    127t\n    -128t\n    31t\n    106t\n    -27t\n    -52t\n    -51t\n    -88t\n    64t\n    127t\n    -88t\n    21t\n    78t\n    126t\n    -115t\n    39t\n    37t\n    99t\n    32t\n    48t\n    -104t\n    -122t\n    46t\n    -83t\n    85t\n    -95t\n    -102t\n    -33t\n    -70t\n    -44t\n    -93t\n    -71t\n    57t\n    86t\n    -48t\n    93t\n    21t\n    11t\n    -23t\n    61t\n    34t\n    71t\n    102t\n    126t\n    54t\n    70t\n    56t\n    31t\n    79t\n    125t\n    41t\n    84t\n    -98t\n    -111t\n    -32t\n    50t\n    -47t\n    54t\n    -20t\n    -14t\n    26t\n    -48t\n    123t\n    14t\n    -92t\n    78t\n    5t\n    -105t\n    8t\n    32t\n    70t\n    101t\n    -39t\n    -8t\n    -74t\n    -3t\n    39t\n    4t\n    -74t\n    -7t\n    -60t\n    53t\n    -54t\n    49t\n    -40t\n    -16t\n    -82t\n    -102t\n    -6t\n    34t\n    -106t\n    19t\n    -58t\n    54t\n    22t\n    12t\n    11t\n    17t\n    76t\n    -119t\n    114t\n    -97t\n    17t\n    122t\n    -62t\n    32t\n    -64t\n    -47t\n    -76t\n    -100t\n    -49t\n    -93t\n    -116t\n    -9t\n    80t\n    44t\n    -102t\n    105t\n    -124t\n    73t\n    -123t\n    86t\n    -20t\n    -28t\n    -79t\n    28t\n    99t\n    91t\n    -18t\n    59t\n    -128t\n    2t\n    76t\n    2t\n    -66t\n    65t\n    -44t\n    -91t\n    -43t\n    -13t\n    70t\n    -45t\n    72t\n    22t\n    115t\n    52t\n    20t\n    41t\n    -109t\n    -118t\n    127t\n    22t\n    65t\n    39t\n    68t\n    103t\n    -71t\n    -90t\n    -79t\n    -125t\n    -122t\n    -125t\n    55t\n    81t\n    111t\n    -7t\n    99t\n    -79t\n    60t\n    -26t\n    9t\n    37t\n    38t\n    4t\n    29t\n    96t\n    -3t\n    1t\n    12t\n    74t\n    -10t\n    35t\n    -98t\n    65t\n    -103t\n    -115t\n    -79t\n    -4t\n    -98t\n    89t\n    -72t\n    42t\n    -39t\n    59t\n    -21t\n    28t\n    -60t\n    32t\n    -88t\n    -36t\n    98t\n    -116t\n    -69t\n    62t\n    44t\n    94t\n    71t\n    75t\n    14t\n    120t\n    122t\n    -29t\n    36t\n    -63t\n    107t\n    19t\n    0t\n    -18t\n    -9t\n    -90t\n    -70t\n    78t\n    42t\n    -113t\n    -59t\n    113t\n    81t\n    87t\n    -32t\n    4t\n    7t\n    -95t\n    -3t\n    -95t\n    -39t\n    42t\n    12t\n    93t\n    2t\n    -17t\n    -54t\n    -92t\n    -126t\n    20t\n    88t\n    92t\n    2t\n    -105t\n    60t\n    94t\n    -79t\n    -68t\n    -19t\n    -121t\n    -123t\n    -110t\n    61t\n    -87t\n    80t\n    37t\n    -70t\n    -15t\n    65t\n    -103t\n    0t\n    92t\n    107t\n    50t\n    33t\n    -122t\n    -107t\n    31t\n    -121t\n    71t\n    -19t\n    70t\n    30t\n    28t\n    108t\n    92t\n    115t\n    -8t\n    121t\n    -104t\n    -26t\n    76t\n    -114t\n    -45t\n    -60t\n    122t\n    -84t\n    69t\n    20t\n    -37t\n    -78t\n    115t\n    -20t\n    -10t\n    -57t\n    -4t\n    -45t\n    27t\n    56t\n    33t\n    103t\n    -86t\n    31t\n    17t\n    -115t\n    -67t\n    -14t\n    -77t\n    -73t\n    -11t\n    39t\n    91t\n    9t\n    -105t\n    -74t\n    -45t\n    52t\n    84t\n    -26t\n    -1t\n    -115t\n    70t\n    -121t\n    -118t\n    -8t\n    -89t\n    26t\n    101t\n    104t\n    94t\n    -82t\n    40t\n    -37t\n    -31t\n    103t\n    4t\n    115t\n    14t\n    -11t\n    27t\n    68t\n    81t\n    -106t\n    42t\n    -120t\n    -24t\n    14t\n    2t\n    35t\n    -94t\n    87t\n    78t\n    -112t\n    -18t\n    33t\n    -97t\n    1t\n    -101t\n    -33t\n    114t\n    36t\n    -104t\n    -21t\n    -8t\n    -40t\n    -62t\n    108t\n    49t\n    27t\n    9t\n    -110t\n    -50t\n    -16t\n    3t\n    -86t\n    -62t\n    -3t\n    -112t\n    83t\n    56t\n    -47t\n    116t\n    78t\n    85t\n    -38t\n    -32t\n    65t\n    113t\n    99t\n    -32t\n    -91t\n    45t\n    79t\n    71t\n    86t\n    19t\n    -113t\n    -61t\n    -96t\n    -34t\n    57t\n    -40t\n    101t\n    -40t\n    -47t\n    -27t\n    2t\n    -55t\n    44t\n    -23t\n    94t\n    123t\n    -93t\n    117t\n    -116t\n    -6t\n    -43t\n    7t\n    -86t\n    -102t\n    37t\n    81t\n    90t\n    -125t\n    -30t\n    -6t\n    -30t\n    68t\n    8t\n    -36t\n    71t\n    17t\n    24t\n    54t\n    -33t\n    34t\n    -94t\n    46t\n    2t\n    50t\n    97t\n    -79t\n    72t\n    -108t\n    -43t\n    10t\n    -41t\n    -21t\n    -119t\n    17t\n    -115t\n    -112t\n    35t\n    -3t\n    -127t\n    -7t\n    -120t\n    -18t\n    -128t\n    101t\n    21t\n    -63t\n    16t\n    65t\n    32t\n    31t\n    27t\n    126t\n    -41t\n    123t\n    -90t\n    26t\n    -19t\n    66t\n    91t\n    -101t\n    -72t\n    -94t\n    53t\n    -27t\n    -68t\n    28t\n    -21t\n    -15t\n    -49t\n    -40t\n    -61t\n    124t\n    114t\n    -32t\n    -77t\n    64t\n    -29t\n    38t\n    -68t\n    19t\n    -58t\n    -94t\n    -103t\n    -53t\n    64t\n    -69t\n    5t\n    125t\n    53t\n    77t\n    -18t\n    -39t\n    -75t\n    98t\n    64t\n    -102t\n    -57t\n    -54t\n    -124t\n    -104t\n    -51t\n    125t\n    47t\n    -79t\n    -52t\n    20t\n    -81t\n    90t\n    123t\n    119t\n    38t\n    114t\n    4t\n    -1t\n    -48t\n    -25t\n    -86t\n    68t\n    81t\n    5t\n    -99t\n    32t\n    -65t\n    22t\n    69t\n    -71t\n    12t\n    -27t\n    92t\n    27t\n    114t\n    57t\n    53t\n    -32t\n    -11t\n    -49t\n    -23t\n    -64t\n    -27t\n    -68t\n    83t\n    -33t\n    55t\n    -119t\n    65t\n    62t\n    68t\n    113t\n    29t\n    86t\n    84t\n    -122t\n    -96t\n    -118t\n    -43t\n    -88t\n    20t\n    2t\n    -96t\n    -101t\n    -24t\n    -45t\n    6t\n    -37t\n    -110t\n    -58t\n    -54t\n    -72t\n    -57t\n    -2t\n    117t\n    -19t\n    -6t\n    67t\n    106t\n    17t\n    54t\n    88t\n    50t\n    107t\n    94t\n    -121t\n    98t\n    -34t\n    29t\n    20t\n    -20t\n    -42t\n    60t\n    100t\n    94t\n    83t\n    -64t\n    -106t\n    -7t\n    -114t\n    -91t\n    94t\n    -69t\n    -116t\n    83t\n    -127t\n    -108t\n    -31t\n    -123t\n    81t\n    54t\n    78t\n    -15t\n    57t\n    36t\n    -120t\n    44t\n    -6t\n    -44t\n    116t\n    -49t\n    -31t\n    67t\n    -105t\n    66t\n    -98t\n    -78t\n    0t\n    84t\n    43t\n    -115t\n    116t\n    -3t\n    -115t\n    -17t\n    63t\n    -35t\n    -31t\n    -25t\n    -46t\n    -114t\n    -13t\n    99t\n    -68t\n    -106t\n    72t\n    -43t\n    34t\n    -54t\n    119t\n    92t\n    36t\n    -111t\n    27t\n    66t\n    -9t\n    -67t\n    106t\n    -116t\n    108t\n    -117t\n    87t\n    -125t\n    20t\n    35t\n    -100t\n    66t\n    -29t\n    -30t\n    109t\n    -12t\n    54t\n    -41t\n    117t\n    107t\n    28t\n    93t\n    -43t\n    -69t\n    117t\n    -37t\n    16t\n    37t\n    48t\n    88t\n    -42t\n    127t\n    17t\n    -85t\n    22t\n    -93t\n    -109t\n    -5t\n    42t\n    57t\n    49t\n    -77t\n    66t\n    -119t\n    115t\n    15t\n    -3t\n    109t\n    -18t\n    -97t\n    125t\n    -37t\n    9t\n    79t\n    -86t\n    27t\n    -107t\n    22t\n    78t\n    -94t\n    54t\n    6t\n    -64t\n    124t\n    67t\n    105t\n    -106t\n    86t\n    -96t\n    -50t\n    99t\n    79t\n    84t\n    -10t\n    44t\n    -80t\n    -57t\n    -106t\n    8t\n    -98t\n    30t\n    -5t\n    95t\n    -11t\n    -112t\n    -120t\n    -80t\n    54t\n    -16t\n    23t\n    -76t\n    88t\n    95t\n    -2t\n    -60t\n    76t\n    -70t\n    35t\n    116t\n    -104t\n    -96t\n    -73t\n    -31t\n    93t\n    -91t\n    26t\n    95t\n    23t\n    10t\n    -54t\n    75t\n    -38t\n    107t\n    -126t\n    -78t\n    11t\n    81t\n    65t\n    49t\n    93t\n    106t\n    27t\n    2t\n    1t\n    15t\n    -42t\n    -63t\n    -9t\n    108t\n    -126t\n    4t\n    -69t\n    53t\n    113t\n    60t\n    72t\n    35t\n    51t\n    -110t\n    111t\n    -93t\n    -116t\n    2t\n    124t\n    -81t\n    104t\n    42t\n    3t\n    86t\n    113t\n    120t\n    3t\n    -23t\n    85t\n    -27t\n    56t\n    5t\n    -84t\n    -65t\n    -92t\n    41t\n    75t\n    -20t\n    87t\n    -21t\n    36t\n    26t\n    -44t\n    -78t\n    66t\n    -90t\n    48t\n    125t\n    124t\n    -10t\n    -33t\n    9t\n    120t\n    68t\n    7t\n    -22t\n    -79t\n    -120t\n    117t\n    125t\n    -30t\n    -8t\n    -7t\n    98t\n    114t\n    -56t\n    73t\n    -111t\n    -119t\n    68t\n    56t\n    15t\n    -64t\n    92t\n    -104t\n    -94t\n    3t\n    65t\n    88t\n    -25t\n    -76t\n    59t\n    -125t\n    -88t\n    41t\n    -95t\n    53t\n    -31t\n    -38t\n    5t\n    31t\n    -92t\n    -73t\n    68t\n    60t\n    100t\n    54t\n    -121t\n    39t\n    -10t\n    -94t\n    40t\n    104t\n    -19t\n    -77t\n    -101t\n    -120t\n    69t\n    -91t\n    -80t\n    23t\n    78t\n    -32t\n    -90t\n    -76t\n    65t\n    -21t\n    107t\n    93t\n    -27t\n    38t\n    -84t\n    20t\n    43t\n    -123t\n    119t\n    49t\n    7t\n    66t\n    -128t\n    -75t\n    -59t\n    -25t\n    123t\n    8t\n    71t\n    123t\n    106t\n    54t\n    -54t\n    120t\n    54t\n    -125t\n    -70t\n    65t\n    94t\n    120t\n    54t\n    -124t\n    -22t\n    73t\n    -99t\n    -59t\n    124t\n    98t\n    105t\n    103t\n    115t\n    92t\n    0t\n    4t\n    -91t\n    17t\n    -23t\n    102t\n    -89t\n    59t\n    114t\n    -86t\n    21t\n    23t\n    -88t\n    87t\n    -88t\n    0t\n    -44t\n    -28t\n    -91t\n    -113t\n    62t\n    27t\n    102t\n    -1t\n    -123t\n    79t\n    104t\n    68t\n    -45t\n    -110t\n    101t\n    62t\n    120t\n    13t\n    26t\n    -25t\n    -47t\n    79t\n    94t\n    110t\n    -23t\n    -119t\n    -85t\n    48t\n    112t\n    -15t\n    6t\n    -58t\n    -115t\n    -99t\n    61t\n    -56t\n    3t\n    40t\n    -89t\n    -110t\n    -124t\n    -10t\n    98t\n    99t\n    117t\n    88t\n    45t\n    27t\n    -128t\n    -71t\n    62t\n    62t\n    -3t\n    -124t\n    118t\n    51t\n    17t\n    90t\n    -120t\n    -28t\n    -91t\n    88t\n    123t\n    104t\n    49t\n    -121t\n    102t\n    -43t\n    66t\n    51t\n    -2t\n    102t\n    113t\n    71t\n    1t\n    -53t\n    -88t\n    -81t\n    49t\n    59t\n    -60t\n    -53t\n    100t\n    46t\n    -36t\n    20t\n    53t\n    -98t\n    86t\n    119t\n    -46t\n    -24t\n    46t\n    84t\n    91t\n    -101t\n    -96t\n    -36t\n    -127t\n    17t\n    -93t\n    58t\n    -98t\n    -9t\n    -94t\n    90t\n    -91t\n    12t\n    91t\n    122t\n    -29t\n    -42t\n    -6t\n    5t\n    -108t\n    -127t\n    -30t\n    86t\n    54t\n    8t\n    -4t\n    121t\n    1t\n    -11t\n    44t\n    -65t\n    54t\n    112t\n    -40t\n    -122t\n    23t\n    58t\n    -21t\n    -103t\n    123t\n    64t\n    -73t\n    -74t\n    37t\n    100t\n    67t\n    -109t\n    89t\n    15t\n    1t\n    114t\n    -105t\n    102t\n    16t\n    26t\n    34t\n    -95t\n    96t\n    -7t\n    80t\n    60t\n    98t\n    107t\n    64t\n    36t\n    -55t\n    78t\n    -81t\n    26t\n    87t\n    -83t\n    -88t\n    -23t\n    -35t\n    -43t\n    1t\n    124t\n    127t\n    -97t\n    -52t\n    76t\n    82t\n    99t\n    52t\n    -57t\n    37t\n    124t\n    -86t\n    96t\n    48t\n    64t\n    6t\n    113t\n    -120t\n    78t\n    23t\n    99t\n    102t\n    -63t\n    -66t\n    -118t\n    66t\n    94t\n    -2t\n    -68t\n    12t\n    101t\n    -1t\n    -124t\n    111t\n    123t\n    122t\n    108t\n    -78t\n    17t\n    -19t\n    -26t\n    4t\n    -57t\n    -51t\n    -55t\n    -53t\n    -49t\n    -118t\n    -84t\n    19t\n    96t\n    21t\n    21t\n    113t\n    19t\n    30t\n    -79t\n    -23t\n    -86t\n    -89t\n    -76t\n    113t\n    110t\n    14t\n    98t\n    -94t\n    106t\n    -16t\n    47t\n    23t\n    83t\n    69t\n    78t\n    108t\n    -109t\n    -29t\n    -26t\n    8t\n    -128t\n    -100t\n    25t\n    -42t\n    -45t\n    -23t\n    -24t\n    -35t\n    -27t\n    -75t\n    42t\n    -5t\n    18t\n    60t\n    108t\n    95t\n    -71t\n    45t\n    80t\n    116t\n    -82t\n    37t\n    70t\n    109t\n    57t\n    -82t\n    -92t\n    -94t\n    -81t\n    112t\n    110t\n    -45t\n    -87t\n    -55t\n    104t\n    117t\n    -40t\n    108t\n    -97t\n    -90t\n    -88t\n    -98t\n    9t\n    68t\n    -26t\n    -103t\n    -112t\n    -75t\n    72t\n    -100t\n    -84t\n    118t\n    112t\n    -16t\n    -56t\n    -110t\n    34t\n    103t\n    -79t\n    30t\n    73t\n    -112t\n    112t\n    -36t\n    -121t\n    78t\n    -14t\n    -47t\n    30t\n    94t\n    83t\n    -84t\n    117t\n    -83t\n    -31t\n    -14t\n    -46t\n    -14t\n    -25t\n    -94t\n    28t\n    -60t\n    53t\n    10t\n    -70t\n    14t\n    122t\n    51t\n    21t\n    -13t\n    -67t\n    -39t\n    -49t\n    20t\n    83t\n    36t\n    23t\n    17t\n    107t\n    -69t\n    -67t\n    -50t\n    -122t\n    91t\n    79t\n    -74t\n    -57t\n    -26t\n    -105t\n    -40t\n    86t\n    -18t\n    -49t\n    73t\n    -116t\n    16t\n    17t\n    32t\n    -97t\n    90t\n    -91t\n    41t\n    -37t\n    51t\n    -127t\n    87t\n    -106t\n    -69t\n    -10t\n    69t\n    -42t\n    100t\n    77t\n    31t\n    -36t\n    -66t\n    98t\n    110t\n    5t\n    45t\n    -55t\n    -89t\n    -66t\n    -9t\n    126t\n    6t\n    -124t\n    -111t\n    0t\n    122t\n    -62t\n    -54t\n    -109t\n    -91t\n    3t\n    -9t\n    7t\n    -108t\n    23t\n    75t\n    -103t\n    -105t\n    10t\n    55t\n    113t\n    -64t\n    -31t\n    -6t\n    -30t\n    -120t\n    29t\n    49t\n    66t\n    126t\n    -96t\n    -19t\n    -46t\n    -118t\n    7t\n    91t\n    56t\n    46t\n    -103t\n    81t\n    47t\n    69t\n    -83t\n    78t\n    51t\n    -126t\n    35t\n    57t\n    -111t\n    -57t\n    42t\n    -52t\n    78t\n    -21t\n    -25t\n    -39t\n    -61t\n    122t\n    -120t\n    18t\n    71t\n    4t\n    115t\n    13t\n    -89t\n    121t\n    13t\n    109t\n    -49t\n    -104t\n    -7t\n    112t\n    53t\n    44t\n    -42t\n    -126t\n    39t\n    -4t\n    104t\n    119t\n    99t\n    32t\n    123t\n    97t\n    43t\n    -71t\n    -110t\n    -38t\n    84t\n    -97t\n    -111t\n    69t\n    12t\n    22t\n    -80t\n    -51t\n    -2t\n    -39t\n    69t\n    71t\n    55t\n    62t\n    -48t\n    -78t\n    -107t\n    90t\n    21t\n    -108t\n    12t\n    96t\n    74t\n    -116t\n    -99t\n    -42t\n    -92t\n    115t\n    -118t\n    27t\n    -8t\n    -84t\n    126t\n    -82t\n    -33t\n    -68t\n    -66t\n    -96t\n    -115t\n    -52t\n    74t\n    23t\n    15t\n    -85t\n    -40t\n    21t\n    -99t\n    -108t\n    50t\n    -67t\n    33t\n    57t\n    83t\n    -66t\n    -75t\n    -71t\n    -82t\n    34t\n    91t\n    107t\n    -90t\n    35t\n    -75t\n    57t\n    -103t\n    59t\n    -6t\n    -36t\n    115t\n    48t\n    -124t\n    -81t\n    97t\n    61t\n    104t\n    -35t\n    -24t\n    -74t\n    -45t\n    -31t\n    -41t\n    79t\n    72t\n    35t\n    -12t\n    41t\n    116t\n    33t\n    -15t\n    -26t\n    58t\n    -111t\n    -62t\n    -75t\n    40t\n    -1t\n    16t\n    -113t\n    110t\n    111t\n    63t\n    13t\n    -10t\n    -73t\n    65t\n    -31t\n    -64t\n    -33t\n    37t\n    14t\n    72t\n    72t\n    36t\n    105t\n    70t\n    100t\n    77t\n    -119t\n    -25t\n    -64t\n    8t\n    -3t\n    86t\n    -89t\n    -108t\n    -127t\n    55t\n    -86t\n    37t\n    -24t\n    -53t\n    120t\n    124t\n    -92t\n    9t\n    56t\n    54t\n    63t\n    -100t\n    -82t\n    40t\n    14t\n    -44t\n    36t\n    101t\n    37t\n    -109t\n    110t\n    -123t\n    2t\n    -48t\n    28t\n    118t\n    -83t\n    -85t\n    92t\n    21t\n    -126t\n    72t\n    -90t\n    -86t\n    49t\n    -125t\n    111t\n    -111t\n    -108t\n    119t\n    -96t\n    -25t\n    41t\n    45t\n    -11t\n    91t\n    -122t\n    -54t\n    96t\n    26t\n    115t\n    37t\n    -119t\n    64t\n    -84t\n    94t\n    110t\n    -20t\n    -86t\n    -61t\n    72t\n    57t\n    -97t\n    71t\n    6t\n    -12t\n    -47t\n    -93t\n    -44t\n    124t\n    -69t\n    -50t\n    -3t\n    -38t\n    -91t\n    -90t\n    123t\n    -127t\n    -7t\n    16t\n    85t\n    79t\n    106t\n    -69t\n    -92t\n    -99t\n    -64t\n    47t\n    118t\n    -110t\n    -128t\n    -73t\n    68t\n    21t\n    14t\n    -98t\n    -109t\n    99t\n    12t\n    -114t\n    30t\n    63t\n    78t\n    33t\n    -9t\n    -100t\n    -14t\n    -99t\n    -108t\n    -42t\n    -79t\n    -64t\n    92t\n    -90t\n    -42t\n    -32t\n    9t\n    117t\n    -35t\n    31t\n    -34t\n    -96t\n    23t\n    36t\n    4t\n    88t\n    -116t\n    -120t\n    112t\n    67t\n    -122t\n    49t\n    11t\n    -116t\n    99t\n    99t\n    27t\n    15t\n    -44t\n    -86t\n    -81t\n    48t\n    -39t\n    -10t\n    -56t\n    117t\n    -48t\n    23t\n    -89t\n    47t\n    40t\n    -28t\n    58t\n    40t\n    56t\n    65t\n    82t\n    -67t\n    0t\n    -63t\n    -83t\n    108t\n    23t\n    75t\n    -28t\n    -41t\n    86t\n    -95t\n    23t\n    26t\n    -38t\n    -79t\n    -5t\n    -122t\n    -35t\n    -61t\n    16t\n    -102t\n    54t\n    22t\n    3t\n    73t\n    -113t\n    107t\n    -37t\n    106t\n    -89t\n    20t\n    29t\n    120t\n    53t\n    -99t\n    118t\n    58t\n    -121t\n    -93t\n    67t\n    13t\n    119t\n    -43t\n    -24t\n    -105t\n    84t\n    -63t\n    98t\n    -37t\n    -22t\n    -124t\n    90t\n    80t\n    115t\n    -83t\n    -118t\n    64t\n    -64t\n    -122t\n    -40t\n    -91t\n    -91t\n    -15t\n    8t\n    -104t\n    126t\n    -62t\n    -55t\n    -57t\n    -89t\n    70t\n    -76t\n    -69t\n    123t\n    98t\n    101t\n    -114t\n    -46t\n    10t\n    -35t\n    45t\n    13t\n    -92t\n    103t\n    70t\n    -122t\n    -17t\n    114t\n    -75t\n    -42t\n    105t\n    29t\n    42t\n    120t\n    -64t\n    78t\n    -92t\n    -32t\n    64t\n    -64t\n    87t\n    -15t\n    -68t\n    120t\n    -114t\n    115t\n    -49t\n    -19t\n    102t\n    50t\n    74t\n    59t\n    75t\n    70t\n    86t\n    -59t\n    -122t\n    -122t\n    76t\n    -107t\n    64t\n    -11t\n    -54t\n    99t\n    -111t\n    104t\n    -44t\n    -25t\n    -101t\n    -24t\n    90t\n    -102t\n    -21t\n    -2t\n    23t\n    -59t\n    69t\n    27t\n    60t\n    74t\n    -115t\n    110t\n    106t\n    44t\n    90t\n    -88t\n    -33t\n    39t\n    54t\n    122t\n    23t\n    119t\n    -80t\n    -110t\n    -96t\n    13t\n    -43t\n    3t\n    -31t\n    -128t\n    -19t\n    65t\n    39t\n    77t\n    44t\n    60t\n    106t\n    57t\n    -36t\n    78t\n    -22t\n    22t\n    -94t\n    115t\n    -84t\n    36t\n    80t\n    -22t\n    51t\n    38t\n    25t\n    76t\n    -70t\n    60t\n    -22t\n    32t\n    -39t\n    -15t\n    -40t\n    -42t\n    -126t\n    -28t\n    115t\n    57t\n    126t\n    -41t\n    -115t\n    44t\n    -105t\n    -47t\n    -74t\n    123t\n    -96t\n    -42t\n    87t\n    13t\n    -85t\n    107t\n    121t\n    108t\n    -126t\n    -86t\n    -98t\n    -26t\n    105t\n    -123t\n    -5t\n    79t\n    -56t\n    124t\n    66t\n    3t\n    80t\n    68t\n    -86t\n    51t\n    -38t\n    96t\n    100t\n    87t\n    75t\n    66t\n    82t\n    108t\n    50t\n    -33t\n    124t\n    2t\n    -106t\n    126t\n    -32t\n    -26t\n    -62t\n    -66t\n    -117t\n    116t\n    -92t\n    51t\n    71t\n    -91t\n    22t\n    107t\n    3t\n    81t\n    -55t\n    -43t\n    -98t\n    15t\n    16t\n    6t\n    -78t\n    7t\n    56t\n    68t\n    119t\n    50t\n    -97t\n    3t\n    -95t\n    114t\n    -122t\n    101t\n    -99t\n    -22t\n    55t\n    -24t\n    -53t\n    102t\n    66t\n    77t\n    79t\n    -34t\n    -11t\n    -115t\n    -19t\n    -56t\n    23t\n    16t\n    105t\n    87t\n    13t\n    -124t\n    -107t\n    34t\n    -68t\n    85t\n    104t\n    -42t\n    92t\n    18t\n    95t\n    -99t\n    75t\n    -86t\n    -121t\n    -109t\n    88t\n    19t\n    -87t\n    18t\n    86t\n    -94t\n    96t\n    79t\n    -27t\n    -46t\n    -17t\n    50t\n    -105t\n    62t\n    -106t\n    3t\n    -45t\n    -46t\n    35t\n    -20t\n    -78t\n    12t\n    47t\n    -72t\n    109t\n    -81t\n    -40t\n    3t\n    -85t\n    69t\n    12t\n    74t\n    -53t\n    123t\n    -101t\n    -13t\n    -120t\n    -8t\n    27t\n    56t\n    41t\n    -94t\n    -5t\n    -87t\n    -121t\n    115t\n    -28t\n    121t\n    105t\n    94t\n    -83t\n    7t\n    -58t\n    -36t\n    -73t\n    124t\n    -51t\n    117t\n    -85t\n    -50t\n    -68t\n    -21t\n    1t\n    99t\n    90t\n    -71t\n    -5t\n    -123t\n    7t\n    36t\n    36t\n    82t\n    -9t\n    -20t\n    -9t\n    1t\n    -11t\n    29t\n    -27t\n    -71t\n    54t\n    -6t\n    -86t\n    -14t\n    -78t\n    10t\n    119t\n    33t\n    -93t\n    78t\n    24t\n    71t\n    -47t\n    -83t\n    57t\n    30t\n    -48t\n    124t\n    -57t\n    -113t\n    -90t\n    -107t\n    -42t\n    -61t\n    70t\n    40t\n    65t\n    -32t\n    70t\n    -92t\n    108t\n    55t\n    105t\n    93t\n    48t\n    -7t\n    -97t\n    -108t\n    -29t\n    -29t\n    -7t\n    -99t\n    34t\n    125t\n    124t\n    -61t\n    96t\n    66t\n    45t\n    -35t\n    -98t\n    -13t\n    43t\n    111t\n    81t\n    120t\n    -11t\n    119t\n    59t\n    -109t\n    -108t\n    -51t\n    35t\n    -25t\n    81t\n    33t\n    -76t\n    67t\n    -83t\n    36t\n    -91t\n    96t\n    -75t\n    -63t\n    -80t\n    -29t\n    -44t\n    36t\n    107t\n    75t\n    53t\n    -78t\n    -4t\n    113t\n    96t\n    -125t\n    0t\n    110t\n    91t\n    -77t\n    -19t\n    -13t\n    28t\n    -8t\n    33t\n    33t\n    101t\n    -107t\n    -87t\n    -45t\n    -82t\n    114t\n    125t\n    -120t\n    -59t\n    -1t\n    -2t\n    29t\n    12t\n    -5t\n    -17t\n    91t\n    -117t\n    -45t\n    65t\n    -57t\n    -126t\n    -123t\n    127t\n    76t\n    -41t\n    46t\n    123t\n    15t\n    -22t\n    45t\n    -114t\n    -34t\n    48t\n    122t\n    46t\n    127t\n    -3t\n    34t\n    -120t\n    68t\n    -109t\n    67t\n    -60t\n    56t\n    106t\n    -61t\n    -101t\n    119t\n    3t\n    25t\n    5t\n    -46t\n    25t\n    50t\n    81t\n    -60t\n    -25t\n    -113t\n    24t\n    -123t\n    92t\n    -98t\n    -91t\n    -64t\n    27t\n    -57t\n    -65t\n    90t\n    39t\n    -61t\n    -110t\n    103t\n    -22t\n    -97t\n    -117t\n    13t\n    78t\n    31t\n    48t\n    -79t\n    -106t\n    -127t\n    22t\n    52t\n    60t\n    -116t\n    110t\n    -29t\n    66t\n    -58t\n    -13t\n    -104t\n    -63t\n    -125t\n    -43t\n    112t\n    -82t\n    111t\n    -100t\n    -47t\n    98t\n    -105t\n    19t\n    0t\n    -111t\n    115t\n    71t\n    -127t\n    -113t\n    -10t\n    38t\n    -113t\n    120t\n    -26t\n    -42t\n    43t\n    41t\n    -84t\n    -24t\n    108t\n    123t\n    -20t\n    -99t\n    -68t\n    -109t\n    98t\n    105t\n    -62t\n    -33t\n    70t\n    -90t\n    -123t\n    -68t\n    -39t\n    124t\n    -69t\n    82t\n    114t\n    -28t\n    127t\n    20t\n    -57t\n    11t\n    79t\n    85t\n    -58t\n    -26t\n    7t\n    85t\n    60t\n    124t\n    -12t\n    -31t\n    -88t\n    -82t\n    -66t\n    -29t\n    65t\n    -32t\n    80t\n    -100t\n    14t\n    -38t\n    73t\n    26t\n    -16t\n    -125t\n    95t\n    -81t\n    -116t\n    -95t\n    -9t\n    124t\n    42t\n    106t\n    40t\n    60t\n    -3t\n    -100t\n    -112t\n    124t\n    -54t\n    99t\n    -122t\n    -110t\n    -2t\n    95t\n    95t\n    38t\n    78t\n    36t\n    -41t\n    16t\n    25t\n    41t\n    -49t\n    -96t\n    -21t\n    -115t\n    68t\n    121t\n    -6t\n    -81t\n    63t\n    -23t\n    -41t\n    34t\n    -64t\n    122t\n    -124t\n    82t\n    44t\n    31t\n    82t\n    121t\n    93t\n    86t\n    4t\n    107t\n    86t\n    36t\n    88t\n    -55t\n    -30t\n    -25t\n    87t\n    -79t\n    38t\n    -42t\n    -16t\n    -67t\n    0t\n    -29t\n    -13t\n    -104t\n    -123t\n    -57t\n    -102t\n    34t\n    -59t\n    -41t\n    46t\n    -18t\n    -35t\n    44t\n    123t\n    84t\n    -93t\n    -53t\n    -126t\n    -101t\n    -84t\n    -77t\n    118t\n    -55t\n    93t\n    -108t\n    -58t\n    -23t\n    -89t\n    -103t\n    -77t\n    33t\n    77t\n    62t\n    112t\n    93t\n    14t\n    -119t\n    -27t\n    -114t\n    -102t\n    -111t\n    -27t\n    78t\n    7t\n    -77t\n    103t\n    109t\n    -101t\n    55t\n    99t\n    50t\n    -109t\n    58t\n    -111t\n    18t\n    -59t\n    -104t\n    94t\n    -4t\n    87t\n    86t\n    19t\n    24t\n    -109t\n    -41t\n    -61t\n    -97t\n    100t\n    -36t\n    31t\n    81t\n    -78t\n    23t\n    -118t\n    -68t\n    -49t\n    -105t\n    33t\n    105t\n    -55t\n    13t\n    98t\n    -110t\n    -101t\n    24t\n    35t\n    -119t\n    26t\n    60t\n    -83t\n    121t\n    -88t\n    123t\n    42t\n    87t\n    -11t\n    -119t\n    87t\n    -99t\n    54t\n    3t\n    -3t\n    -25t\n    36t\n    60t\n    -51t\n    77t\n    53t\n    -77t\n    40t\n    -127t\n    -18t\n    116t\n    -3t\n    -52t\n    17t\n    67t\n    -27t\n    77t\n    111t\n    96t\n    68t\n    59t\n    -109t\n    113t\n    -82t\n    -11t\n    -71t\n    -119t\n    34t\n    -115t\n    6t\n    80t\n    -103t\n    -63t\n    -77t\n    -90t\n    86t\n    -100t\n    10t\n    64t\n    30t\n    121t\n    64t\n    -33t\n    74t\n    41t\n    46t\n    105t\n    -3t\n    -128t\n    -92t\n    -73t\n    127t\n    -27t\n    -9t\n    43t\n    102t\n    32t\n    15t\n    120t\n    -125t\n    -21t\n    34t\n    42t\n    68t\n    -58t\n    -117t\n    11t\n    27t\n    99t\n    104t\n    -61t\n    -114t\n    -46t\n    9t\n    -7t\n    -115t\n    -12t\n    -58t\n    121t\n    -47t\n    59t\n    -42t\n    -99t\n    -15t\n    -87t\n    100t\n    64t\n    -34t\n    -118t\n    -102t\n    89t\n    58t\n    66t\n    -52t\n    -40t\n    -95t\n    -111t\n    -29t\n    51t\n    1t\n    105t\n    -87t\n    19t\n    -35t\n    -65t\n    -21t\n    54t\n    -53t\n    95t\n    -65t\n    120t\n    -9t\n    -84t\n    -35t\n    62t\n    65t\n    -31t\n    -39t\n    9t\n    -91t\n    7t\n    -40t\n    -42t\n    63t\n    -108t\n    113t\n    13t\n    -49t\n    83t\n    -7t\n    90t\n    -17t\n    12t\n    -1t\n    109t\n    -122t\n    -80t\n    41t\n    -109t\n    -3t\n    -103t\n    -36t\n    -77t\n    27t\n    -24t\n    26t\n    -1t\n    11t\n    11t\n    69t\n    -68t\n    92t\n    -106t\n    111t\n    111t\n    -90t\n    -49t\n    14t\n    -51t\n    69t\n    97t\n    -93t\n    77t\n    116t\n    -11t\n    -74t\n    -27t\n    -126t\n    -40t\n    117t\n    49t\n    67t\n    89t\n    -53t\n    102t\n    81t\n    74t\n    62t\n    -112t\n    -106t\n    -55t\n    13t\n    14t\n    19t\n    113t\n    -94t\n    35t\n    -107t\n    45t\n    -29t\n    94t\n    77t\n    86t\n    95t\n    81t\n    -107t\n    71t\n    0t\n    -104t\n    -18t\n    91t\n    82t\n    -35t\n    126t\n    13t\n    -38t\n    111t\n    113t\n    89t\n    -86t\n    22t\n    -121t\n    -103t\n    12t\n    -115t\n    113t\n    115t\n    -15t\n    119t\n    125t\n    105t\n    62t\n    15t\n    3t\n    14t\n    -96t\n    44t\n    118t\n    -43t\n    7t\n    -86t\n    -25t\n    -20t\n    -26t\n    -87t\n    -50t\n    -56t\n    -50t\n    -83t\n    -92t\n    75t\n    39t\n    -89t\n    -50t\n    93t\n    -40t\n    57t\n    -52t\n    -122t\n    102t\n    79t\n    -124t\n    92t\n    62t\n    53t\n    90t\n    -86t\n    42t\n    -105t\n    -26t\n    112t\n    -128t\n    23t\n    123t\n    -110t\n    -102t\n    57t\n    -93t\n    -122t\n    63t\n    -101t\n    -123t\n    -110t\n    103t\n    -41t\n    90t\n    90t\n    -9t\n    50t\n    83t\n    20t\n    -82t\n    1t\n    -11t\n    1t\n    10t\n    -98t\n    50t\n    -107t\n    -51t\n    -34t\n    127t\n    -8t\n    120t\n    -65t\n    33t\n    -71t\n    -111t\n    -13t\n    33t\n    -77t\n    57t\n    118t\n    34t\n    62t\n    -109t\n    19t\n    -95t\n    -112t\n    -36t\n    -109t\n    -49t\n    90t\n    18t\n    69t\n    118t\n    -18t\n    -104t\n    106t\n    126t\n    -105t\n    -19t\n    -10t\n    -71t\n    -36t\n    57t\n    -59t\n    31t\n    77t\n    -52t\n    33t\n    -41t\n    89t\n    112t\n    28t\n    -66t\n    -85t\n    47t\n    73t\n    56t\n    -90t\n    -39t\n    48t\n    4t\n    -53t\n    20t\n    35t\n    -40t\n    38t\n    65t\n    36t\n    113t\n    -111t\n    -28t\n    123t\n    105t\n    -12t\n    -16t\n    -106t\n    -102t\n    121t\n    -93t\n    -29t\n    -12t\n    -102t\n    -27t\n    68t\n    -115t\n    -41t\n    23t\n    -26t\n    -83t\n    6t\n    111t\n    -23t\n    49t\n    58t\n    111t\n    -27t\n    -126t\n    77t\n    25t\n    -63t\n    106t\n    19t\n    23t\n    70t\n    98t\n    -33t\n    -68t\n    -10t\n    123t\n    4t\n    97t\n    10t\n    41t\n    78t\n    -114t\n    -105t\n    33t\n    52t\n    -55t\n    116t\n    24t\n    -93t\n    -99t\n    39t\n    57t\n    -86t\n    91t\n    41t\n    -89t\n    66t\n    -47t\n    -18t\n    -86t\n    24t\n    87t\n    -4t\n    87t\n    -109t\n    77t\n    72t\n    -18t\n    -95t\n    -57t\n    -27t\n    -71t\n    -88t\n    40t\n    -4t\n    -47t\n    27t\n    119t\n    -34t\n    124t\n    -42t\n    108t\n    107t\n    31t\n    84t\n    -62t\n    92t\n    124t\n    118t\n    10t\n    -43t\n    103t\n    -15t\n    -10t\n    23t\n    -63t\n    11t\n    -66t\n    98t\n    106t\n    68t\n    -26t\n    114t\n    24t\n    52t\n    -119t\n    74t\n    -79t\n    -89t\n    49t\n    35t\n    40t\n    42t\n    37t\n    -23t\n    -100t\n    -19t\n    6t\n    115t\n    -113t\n    118t\n    122t\n    58t\n    -4t\n    -26t\n    99t\n    51t\n    62t\n    -64t\n    -96t\n    5t\n    113t\n    -105t\n    2t\n    80t\n    -28t\n    26t\n    41t\n    5t\n    119t\n    123t\n    26t\n    -114t\n    -82t\n    -20t\n    -3t\n    -54t\n    100t\n    -64t\n    -115t\n    63t\n    44t\n    -101t\n    72t\n    83t\n    84t\n    76t\n    123t\n    27t\n    -91t\n    -22t\n    -77t\n    23t\n    43t\n    -125t\n    21t\n    75t\n    25t\n    -99t\n    -108t\n    94t\n    -112t\n    48t\n    -59t\n    113t\n    -40t\n    82t\n    -107t\n    46t\n    58t\n    -110t\n    82t\n    51t\n    -75t\n    -37t\n    -103t\n    80t\n    26t\n    37t\n    50t\n    64t\n    117t\n    -50t\n    15t\n    64t\n    -24t\n    -108t\n    4t\n    -49t\n    -28t\n    3t\n    32t\n    89t\n    65t\n    -120t\n    84t\n    -109t\n    45t\n    19t\n    -25t\n    -16t\n    103t\n    -57t\n    -60t\n    -91t\n    17t\n    127t\n    77t\n    -28t\n    101t\n    58t\n    48t\n    50t\n    119t\n    64t\n    -89t\n    87t\n    1t\n    44t\n    -65t\n    98t\n    86t\n    -84t\n    69t\n    -105t\n    -16t\n    -20t\n    97t\n    -83t\n    91t\n    -53t\n    57t\n    -29t\n    -13t\n    -27t\n    112t\n    1t\n    57t\n    -125t\n    -38t\n    -15t\n    -103t\n    54t\n    34t\n    -71t\n    120t\n    18t\n    -32t\n    -96t\n    -37t\n    85t\n    -2t\n    -95t\n    -23t\n    8t\n    48t\n    49t\n    36t\n    92t\n    43t\n    19t\n    38t\n    98t\n    -51t\n    116t\n    57t\n    0t\n    -91t\n    -25t\n    -80t\n    -2t\n    122t\n    63t\n    -8t\n    -83t\n    -69t\n    -87t\n    120t\n    -18t\n    -109t\n    36t\n    68t\n    126t\n    125t\n    75t\n    -11t\n    111t\n    118t\n    38t\n    -50t\n    39t\n    110t\n    54t\n    -96t\n    71t\n    81t\n    -120t\n    -93t\n    -51t\n    -21t\n    -73t\n    127t\n    -102t\n    -65t\n    -54t\n    86t\n    -65t\n    -11t\n    -16t\n    -122t\n    62t\n    -82t\n    -95t\n    54t\n    34t\n    -59t\n    59t\n    -49t\n    3t\n    -9t\n    -3t\n    90t\n    73t\n    -21t\n    -44t\n    41t\n    -5t\n    -12t\n    -88t\n    99t\n    -1t\n    15t\n    -71t\n    92t\n    -48t\n    -120t\n    -110t\n    -36t\n    112t\n    -73t\n    61t\n    -78t\n    -44t\n    -73t\n    -76t\n    -89t\n    -42t\n    -117t\n    86t\n    108t\n    60t\n    103t\n    -16t\n    -94t\n    -101t\n    -5t\n    -105t\n    -49t\n    30t\n    125t\n    84t\n    -53t\n    -21t\n    -12t\n    -121t\n    8t\n    121t\n    62t\n    62t\n    -12t\n    28t\n    -95t\n    127t\n    125t\n    79t\n    124t\n    -86t\n    82t\n    79t\n    1t\n    15t\n    -19t\n    -68t\n    -34t\n    -91t\n    15t\n    125t\n    -91t\n    -83t\n    111t\n    61t\n    109t\n    -6t\n    -128t\n    81t\n    -118t\n    10t\n    43t\n    -10t\n    84t\n    123t\n    75t\n    -105t\n    -17t\n    -46t\n    70t\n    103t\n    -72t\n    -93t\n    19t\n    -93t\n    -90t\n    79t\n    66t\n    -71t\n    17t\n    -119t\n    89t\n    -112t\n    1t\n    30t\n    -95t\n    -15t\n    -106t\n    73t\n    82t\n    -84t\n    16t\n    -53t\n    -70t\n    119t\n    8t\n    92t\n    -26t\n    114t\n    -7t\n    -47t\n    46t\n    105t\n    -39t\n    -48t\n    102t\n    -55t\n    -94t\n    107t\n    45t\n    -66t\n    -19t\n    -35t\n    -28t\n    28t\n    -80t\n    -72t\n    22t\n    60t\n    -79t\n    126t\n    -65t\n    95t\n    -99t\n    84t\n    -35t\n    -111t\n    31t\n    0t\n    -81t\n    -122t\n    -44t\n    80t\n    43t\n    -24t\n    73t\n    -85t\n    71t\n    -45t\n    -114t\n    -55t\n    88t\n    -115t\n    51t\n    -98t\n    14t\n    -69t\n    -110t\n    86t\n    120t\n    -57t\n    90t\n    56t\n    -124t\n    -51t\n    -32t\n    86t\n    -81t\n    -1t\n    54t\n    27t\n    106t\n    -45t\n    -94t\n    -45t\n    63t\n    -118t\n    89t\n    79t\n    82t\n    -68t\n    85t\n    72t\n    -37t\n    -88t\n    98t\n    65t\n    -27t\n    9t\n    57t\n    15t\n    -64t\n    -33t\n    -30t\n    -123t\n    75t\n    -24t\n    127t\n    119t\n    54t\n    107t\n    -96t\n    -70t\n    -21t\n    93t\n    -47t\n    -43t\n    -13t\n    -120t\n    -41t\n    -70t\n    -55t\n    55t\n    41t\n    -117t\n    126t\n    26t\n    43t\n    -12t\n    -115t\n    14t\n    94t\n    -93t\n    -58t\n    -1t\n    6t\n    -98t\n    21t\n    -93t\n    -17t\n    -44t\n    98t\n    -30t\n    99t\n    -10t\n    90t\n    125t\n    -15t\n    49t\n    101t\n    -73t\n    -54t\n    90t\n    2t\n    -80t\n    -112t\n    -95t\n    107t\n    92t\n    -112t\n    -8t\n    -92t\n    61t\n    -81t\n    97t\n    -103t\n    30t\n    -54t\n    32t\n    94t\n    -53t\n    75t\n    56t\n    116t\n    36t\n    5t\n    49t\n    125t\n    37t\n    6t\n    -49t\n    -46t\n    117t\n    -113t\n    -84t\n    -84t\n    -48t\n    112t\n    -39t\n    -10t\n    98t\n    54t\n    -62t\n    -73t\n    99t\n    75t\n    18t\n    108t\n    -40t\n    -9t\n    112t\n    -51t\n    -123t\n    -59t\n    1t\n    51t\n    113t\n    -125t\n    19t\n    -48t\n    -119t\n    -10t\n    -105t\n    86t\n    -16t\n    41t\n    38t\n    -64t\n    -38t\n    -36t\n    -88t\n    -114t\n    111t\n    110t\n    -23t\n    -59t\n    13t\n    123t\n    33t\n    -53t\n    3t\n    -78t\n    33t\n    50t\n    87t\n    -120t\n    76t\n    6t\n    -122t\n    -91t\n    95t\n    -58t\n    52t\n    -103t\n    28t\n    87t\n    86t\n    -84t\n    -71t\n    94t\n    55t\n    -125t\n    48t\n    67t\n    -118t\n    -57t\n    106t\n    62t\n    26t\n    20t\n    20t\n    -116t\n    14t\n    38t\n    -56t\n    99t\n    -77t\n    -16t\n    -45t\n    -89t\n    121t\n    113t\n    -120t\n    2t\n    -12t\n    126t\n    -18t\n    -88t\n    89t\n    -22t\n    122t\n    85t\n    94t\n    49t\n    -108t\n    75t\n    -96t\n    106t\n    13t\n    -16t\n    -111t\n    -28t\n    -49t\n    60t\n    -57t\n    -90t\n    -35t\n    -85t\n    82t\n    106t\n    51t\n    -55t\n    17t\n    69t\n    -20t\n    -76t\n    -29t\n    52t\n    25t\n    -128t\n    -2t\n    70t\n    -126t\n    -117t\n    -49t\n    47t\n    -38t\n    -14t\n    -39t\n    -13t\n    105t\n    -47t\n    91t\n    34t\n    26t\n    -47t\n    108t\n    -14t\n    123t\n    -84t\n    -107t\n    -29t\n    -85t\n    5t\n    32t\n    85t\n    112t\n    -58t\n    69t\n    25t\n    115t\n    -86t\n    -116t\n    15t\n    -47t\n    -118t\n    6t\n    -7t\n    33t\n    43t\n    24t\n    49t\n    115t\n    -127t\n    74t\n    -55t\n    -122t\n    -49t\n    22t\n    73t\n    -59t\n    111t\n    -89t\n    23t\n    52t\n    -22t\n    26t\n    -55t\n    51t\n    -54t\n    60t\n    35t\n    42t\n    83t\n    43t\n    77t\n    -30t\n    105t\n    14t\n    -82t\n    -77t\n    -62t\n    122t\n    68t\n    29t\n    104t\n    -76t\n    90t\n    117t\n    -53t\n    -113t\n    -118t\n    -96t\n    -110t\n    -82t\n    -68t\n    11t\n    7t\n    67t\n    36t\n    -40t\n    81t\n    -92t\n    58t\n    -116t\n    -84t\n    -99t\n    55t\n    103t\n    86t\n    49t\n    114t\n    70t\n    -65t\n    123t\n    -120t\n    -21t\n    1t\n    -96t\n    41t\n    -39t\n    -75t\n    -48t\n    54t\n    -109t\n    -12t\n    115t\n    -81t\n    -25t\n    -112t\n    101t\n    84t\n    21t\n    91t\n    -88t\n    -94t\n    -116t\n    53t\n    -109t\n    -23t\n    8t\n    86t\n    111t\n    44t\n    -56t\n    76t\n    -91t\n    -90t\n    53t\n    -103t\n    43t\n    98t\n    -51t\n    -17t\n    8t\n    83t\n    66t\n    -60t\n    -112t\n    -46t\n    18t\n    -104t\n    75t\n    -19t\n    -108t\n    124t\n    -11t\n    84t\n    -53t\n    -23t\n    4t\n    -115t\n    73t\n    -100t\n    106t\n    -111t\n    0t\n    -40t\n    2t\n    -41t\n    -75t\n    -55t\n    -4t\n    10t\n    108t\n    -67t\n    103t\n    -117t\n    -83t\n    7t\n    -49t\n    -121t\n    22t\n    -39t\n    18t\n    -108t\n    81t\n    -30t\n    87t\n    -122t\n    111t\n    115t\n    -20t\n    3t\n    42t\n    50t\n    -66t\n    96t\n    50t\n    -72t\n    123t\n    0t\n    -108t\n    89t\n    70t\n    -38t\n    54t\n    71t\n    39t\n    -31t\n    -34t\n    120t\n    78t\n    -91t\n    -85t\n    22t\n    -50t\n    -101t\n    -87t\n    54t\n    116t\n    -31t\n    55t\n    64t\n    -89t\n    64t\n    -67t\n    -12t\n    14t\n    -108t\n    -83t\n    109t\n    126t\n    40t\n    121t\n    -24t\n    -10t\n    -71t\n    -51t\n    97t\n    70t\n    -29t\n    -110t\n    -68t\n    -103t\n    -109t\n    33t\n    -77t\n    -111t\n    -87t\n    96t\n    89t\n    -50t\n    1t\n    102t\n    111t\n    -92t\n    -45t\n    -6t\n    66t\n    -125t\n    -75t\n    90t\n    -97t\n    22t\n    87t\n    48t\n    27t\n    2t\n    -2t\n    -102t\n    -102t\n    5t\n    5t\n    -117t\n    -12t\n    118t\n    80t\n    28t\n    -64t\n    -70t\n    -101t\n    69t\n    -52t\n    91t\n    -44t\n    -30t\n    -111t\n    29t\n    -24t\n    45t\n    -107t\n    93t\n    -50t\n    -36t\n    120t\n    -58t\n    -29t\n    -102t\n    -17t\n    -62t\n    95t\n    -104t\n    -57t\n    -27t\n    -74t\n    73t\n    -103t\n    80t\n    23t\n    38t\n    77t\n    17t\n    42t\n    52t\n    -63t\n    95t\n    -94t\n    95t\n    26t\n    -62t\n    -43t\n    77t\n    73t\n    -97t\n    5t\n    41t\n    60t\n    29t\n    69t\n    105t\n    20t\n    -12t\n    10t\n    -15t\n    -79t\n    69t\n    -105t\n    -9t\n    84t\n    45t\n    13t\n    -39t\n    107t\n    -66t\n    -55t\n    -121t\n    -95t\n    -46t\n    -40t\n    2t\n    -75t\n    -111t\n    78t\n    -9t\n    -16t\n    123t\n    32t\n    -95t\n    98t\n    54t\n    102t\n    -111t\n    -104t\n    30t\n    102t\n    -80t\n    115t\n    -27t\n    16t\n    94t\n    -7t\n    -85t\n    55t\n    110t\n    -6t\n    -127t\n    5t\n    23t\n    11t\n    27t\n    -65t\n    96t\n    -116t\n    -28t\n    -96t\n    64t\n    -73t\n    22t\n    -67t\n    78t\n    104t\n    -119t\n    4t\n    95t\n    55t\n    18t\n    -122t\n    38t\n    86t\n    3t\n    -107t\n    43t\n    41t\n    92t\n    11t\n    36t\n    -88t\n    105t\n    -83t\n    15t\n    -29t\n    9t\n    -127t\n    74t\n    -51t\n    -121t\n    -21t\n    99t\n    -62t\n    38t\n    -26t\n    48t\n    56t\n    -47t\n    66t\n    -56t\n    108t\n    37t\n    -76t\n    -22t\n    56t\n    -80t\n    101t\n    54t\n    111t\n    38t\n    -18t\n    -90t\n    125t\n    86t\n    -99t\n    -31t\n    105t\n    30t\n    -11t\n    33t\n    25t\n    -96t\n    -40t\n    -87t\n    -120t\n    74t\n    -28t\n    -5t\n    92t\n    85t\n    -39t\n    109t\n    101t\n    112t\n    -125t\n    -13t\n    28t\n    104t\n    -101t\n    -105t\n    75t\n    1t\n    28t\n    -107t\n    48t\n    0t\n    -105t\n    42t\n    -2t\n    20t\n    -115t\n    -72t\n    93t\n    -122t\n    -116t\n    33t\n    -32t\n    82t\n    33t\n    31t\n    4t\n    -72t\n    -91t\n    -30t\n    -22t\n    -116t\n    -24t\n    -108t\n    70t\n    23t\n    -52t\n    -52t\n    120t\n    -101t\n    -109t\n    77t\n    -84t\n    -32t\n    -35t\n    -102t\n    15t\n    120t\n    -74t\n    -91t\n    8t\n    -91t\n    -37t\n    -70t\n    41t\n    -96t\n    -45t\n    55t\n    29t\n    21t\n    -113t\n    38t\n    24t\n    105t\n    70t\n    40t\n    20t\n    -67t\n    -64t\n    -78t\n    -95t\n    4t\n    -39t\n    59t\n    -108t\n    -111t\n    -62t\n    88t\n    8t\n    48t\n    73t\n    44t\n    75t\n    74t\n    -13t\n    62t\n    87t\n    -37t\n    -32t\n    16t\n    0t\n    73t\n    -58t\n    -9t\n    -26t\n    25t\n    103t\n    35t\n    -62t\n    -10t\n    -28t\n    101t\n    -27t\n    -43t\n    65t\n    -107t\n    23t\n    90t\n    -52t\n    19t\n    -12t\n    94t\n    -7t\n    -81t\n    121t\n    123t\n    -25t\n    -36t\n    118t\n    67t\n    16t\n    78t\n    -21t\n    20t\n    -72t\n    90t\n    96t\n    64t\n    -7t\n    8t\n    19t\n    -115t\n    29t\n    13t\n    90t\n    30t\n    30t\n    60t\n    -51t\n    -33t\n    4t\n    72t\n    -53t\n    -104t\n    102t\n    0t\n    -65t\n    103t\n    56t\n    -99t\n    35t\n    -24t\n    29t\n    45t\n    76t\n    87t\n    -116t\n    -95t\n    -31t\n    108t\n    -105t\n    20t\n    -88t\n    -36t\n    -113t\n    10t\n    -24t\n    -58t\n    28t\n    96t\n    -14t\n    -21t\n    -13t\n    71t\n    71t\n    18t\n    70t\n    -111t\n    -78t\n    -35t\n    -94t\n    51t\n    -20t\n    -25t\n    -59t\n    -63t\n    -102t\n    -68t\n    60t\n    -93t\n    71t\n    70t\n    -6t\n    -2t\n    78t\n    -67t\n    19t\n    44t\n    -125t\n    111t\n    -120t\n    -95t\n    -16t\n    53t\n    56t\n    27t\n    64t\n    115t\n    -114t\n    -46t\n    -76t\n    -72t\n    92t\n    26t\n    109t\n    126t\n    -118t\n    -93t\n    26t\n    69t\n    -66t\n    -76t\n    119t\n    109t\n    116t\n    108t\n    -111t\n    -63t\n    -45t\n    -50t\n    -81t\n    -34t\n    -57t\n    -96t\n    -35t\n    -32t\n    -101t\n    -75t\n    -55t\n    66t\n    34t\n    16t\n    -83t\n    43t\n    -21t\n    -87t\n    67t\n    125t\n    98t\n    -45t\n    119t\n    65t\n    -71t\n    -82t\n    59t\n    6t\n    -42t\n    116t\n    64t\n    66t\n    -85t\n    -100t\n    63t\n    72t\n    126t\n    -61t\n    123t\n    23t\n    104t\n    45t\n    -6t\n    90t\n    93t\n    -126t\n    115t\n    -110t\n    -23t\n    49t\n    -102t\n    -58t\n    -18t\n    84t\n    106t\n    100t\n    -43t\n    54t\n    3t\n    -39t\n    25t\n    -70t\n    -34t\n    86t\n    100t\n    -7t\n    -46t\n    -90t\n    -20t\n    -116t\n    -12t\n    -100t\n    -2t\n    -19t\n    107t\n    -125t\n    -13t\n    3t\n    -95t\n    -52t\n    53t\n    -90t\n    41t\n    -56t\n    -67t\n    -124t\n    -10t\n    56t\n    88t\n    -28t\n    -84t\n    114t\n    -72t\n    124t\n    101t\n    105t\n    56t\n    -9t\n    -1t\n    -11t\n    -69t\n    53t\n    123t\n    32t\n    -73t\n    -107t\n    -22t\n    110t\n    69t\n    52t\n    -95t\n    -37t\n    113t\n    -10t\n    92t\n    3t\n    78t\n    -90t\n    49t\n    -84t\n    -87t\n    91t\n    101t\n    -45t\n    -54t\n    -122t\n    73t\n    92t\n    24t\n    -76t\n    0t\n    -121t\n    -94t\n    -6t\n    -100t\n    34t\n    75t\n    14t\n    109t\n    -43t\n    7t\n    -34t\n    -100t\n    -116t\n    10t\n    83t\n    -22t\n    -92t\n    127t\n    -6t\n    -41t\n    -46t\n    57t\n    91t\n    18t\n    46t\n    15t\n    44t\n    -14t\n    55t\n    -92t\n    95t\n    1t\n    -32t\n    -34t\n    40t\n    85t\n    -108t\n    86t\n    104t\n    -64t\n    118t\n    4t\n    71t\n    -105t\n    61t\n    -60t\n    -114t\n    -101t\n    -72t\n    1t\n    62t\n    79t\n    -106t\n    104t\n    -22t\n    27t\n    70t\n    23t\n    -50t\n    -12t\n    -101t\n    -98t\n    -70t\n    -2t\n    50t\n    -77t\n    41t\n    -2t\n    -35t\n    -29t\n    7t\n    -128t\n    92t\n    32t\n    -101t\n    -20t\n    -24t\n    76t\n    120t\n    83t\n    -78t\n    95t\n    -124t\n    108t\n    -87t\n    -52t\n    64t\n    97t\n    93t\n    -95t\n    -74t\n    70t\n    42t\n    105t\n    101t\n    -5t\n    65t\n    -38t\n    99t\n    -19t\n    127t\n    70t\n    -8t\n    -68t\n    -84t\n    -115t\n    50t\n    121t\n    29t\n    109t\n    -79t\n    -78t\n    -72t\n    87t\n    -36t\n    3t\n    -84t\n    46t\n    75t\n    79t\n    95t\n    57t\n    -47t\n    -60t\n    51t\n    -3t\n    -75t\n    -58t\n    87t\n    51t\n    111t\n    -21t\n    -7t\n    -98t\n    -36t\n    111t\n    5t\n    -62t\n    82t\n    84t\n    0t\n    -120t\n    106t\n    90t\n    -125t\n    85t\n    -11t\n    27t\n    -65t\n    69t\n    -58t\n    105t\n    -31t\n    47t\n    -124t\n    -17t\n    99t\n    -12t\n    50t\n    -122t\n    -99t\n    10t\n    79t\n    -109t\n    -65t\n    106t\n    -64t\n    -36t\n    65t\n    -28t\n    -119t\n    112t\n    46t\n    55t\n    25t\n    51t\n    111t\n    33t\n    -19t\n    -73t\n    -49t\n    34t\n    -17t\n    4t\n    99t\n    110t\n    -78t\n    -116t\n    -100t\n    -54t\n    -82t\n    -109t\n    -90t\n    -85t\n    -30t\n    -73t\n    -83t\n    85t\n    -101t\n    -2t\n    33t\n    127t\n    -39t\n    -95t\n    84t\n    46t\n    61t\n    -109t\n    78t\n    17t\n    18t\n    -26t\n    117t\n    -45t\n    -6t\n    -44t\n    -63t\n    60t\n    -21t\n    69t\n    46t\n    -37t\n    40t\n    -110t\n    57t\n    -65t\n    -35t\n    5t\n    -108t\n    -70t\n    -34t\n    -110t\n    -52t\n    117t\n    12t\n    -12t\n    95t\n    -1t\n    102t\n    -21t\n    21t\n    -99t\n    -109t\n    59t\n    -69t\n    35t\n    -88t\n    -56t\n    105t\n    -101t\n    -108t\n    -28t\n    79t\n    -79t\n    106t\n    -100t\n    -44t\n    102t\n    7t\n    -18t\n    70t\n    -118t\n    -90t\n    -47t\n    86t\n    91t\n    -45t\n    113t\n    113t\n    -116t\n    53t\n    8t\n    99t\n    108t\n    24t\n    6t\n    -13t\n    104t\n    30t\n    40t\n    -35t\n    -18t\n    -39t\n    25t\n    -53t\n    63t\n    -82t\n    70t\n    -50t\n    -32t\n    -65t\n    34t\n    -8t\n    -71t\n    116t\n    -58t\n    -21t\n    83t\n    45t\n    15t\n    -16t\n    80t\n    -83t\n    110t\n    -16t\n    47t\n    97t\n    99t\n    82t\n    -77t\n    89t\n    -128t\n    -71t\n    27t\n    -82t\n    -27t\n    -101t\n    -106t\n    -99t\n    92t\n    71t\n    13t\n    24t\n    -13t\n    51t\n    102t\n    -120t\n    -26t\n    -106t\n    15t\n    -7t\n    -28t\n    -83t\n    -100t\n    -127t\n    36t\n    -51t\n    -56t\n    120t\n    -95t\n    -6t\n    -106t\n    81t\n    124t\n    122t\n    51t\n    19t\n    48t\n    73t\n    -124t\n    65t\n    49t\n    -88t\n    -28t\n    -45t\n    -17t\n    43t\n    -8t\n    93t\n    -79t\n    41t\n    -12t\n    -59t\n    -117t\n    0t\n    82t\n    67t\n    -55t\n    -27t\n    -29t\n    -118t\n    83t\n    -115t\n    -101t\n    -112t\n    -124t\n    66t\n    -7t\n    41t\n    -104t\n    -83t\n    19t\n    -35t\n    40t\n    -31t\n    1t\n    -16t\n    4t\n    -95t\n    44t\n    48t\n    -55t\n    -28t\n    -42t\n    14t\n    88t\n    113t\n    24t\n    31t\n    -12t\n    -1t\n    123t\n    69t\n    -39t\n    -71t\n    -2t\n    109t\n    -73t\n    56t\n    105t\n    77t\n    44t\n    83t\n    -110t\n    -108t\n    9t\n    28t\n    17t\n    77t\n    -19t\n    -34t\n    96t\n    12t\n    0t\n    61t\n    -101t\n    57t\n    31t\n    -46t\n    -58t\n    -25t\n    48t\n    -62t\n    93t\n    -20t\n    -76t\n    27t\n    -4t\n    101t\n    17t\n    -127t\n    9t\n    85t\n    15t\n    93t\n    -95t\n    -79t\n    -3t\n    -38t\n    62t\n    -39t\n    102t\n    -117t\n    -24t\n    33t\n    -66t\n    71t\n    53t\n    59t\n    27t\n    -52t\n    11t\n    -45t\n    85t\n    42t\n    107t\n    59t\n    88t\n    54t\n    124t\n    -67t\n    22t\n    25t\n    -36t\n    -19t\n    -35t\n    83t\n    43t\n    -99t\n    35t\n    -83t\n    36t\n    33t\n    99t\n    76t\n    -20t\n    85t\n    -21t\n    -90t\n    119t\n    77t\n    -38t\n    -73t\n    -1t\n    73t\n    0t\n    -40t\n    29t\n    -16t\n    76t\n    -114t\n    41t\n    -75t\n    -117t\n    57t\n    8t\n    -49t\n    -120t\n    -121t\n    -45t\n    105t\n    87t\n    16t\n    -57t\n    108t\n    -74t\n    -32t\n    28t\n    110t\n    -111t\n    -43t\n    107t\n    -115t\n    61t\n    51t\n    -112t\n    -104t\n    -128t\n    59t\n    -60t\n    69t\n    123t\n    78t\n    92t\n    -103t\n    -33t\n    50t\n    -89t\n    114t\n    -11t\n    -57t\n    60t\n    73t\n    30t\n    21t\n    104t\n    -64t\n    -128t\n    -18t\n    107t\n    -88t\n    110t\n    28t\n    38t\n    -48t\n    12t\n    -50t\n    -34t\n    55t\n    24t\n    37t\n    -128t\n    -35t\n    42t\n    -122t\n    -119t\n    127t\n    -40t\n    19t\n    124t\n    -117t\n    -75t\n    -20t\n    115t\n    -91t\n    111t\n    95t\n    30t\n    -74t\n    -126t\n    -59t\n    49t\n    -91t\n    -13t\n    -3t\n    119t\n    28t\n    -113t\n    -19t\n    59t\n    75t\n    95t\n    15t\n    -34t\n    -62t\n    -15t\n    -118t\n    -102t\n    66t\n    -117t\n    -71t\n    87t\n    -123t\n    -119t\n    97t\n    -11t\n    -65t\n    -76t\n    -48t\n    60t\n    109t\n    -13t\n    27t\n    -72t\n    10t\n    -83t\n    -26t\n    87t\n    -115t\n    49t\n    -93t\n    -99t\n    98t\n    69t\n    -120t\n    -107t\n    -28t\n    13t\n    20t\n    -92t\n    22t\n    -42t\n    -54t\n    59t\n    14t\n    29t\n    -29t\n    80t\n    -36t\n    49t\n    -26t\n    -40t\n    95t\n    51t\n    84t\n    34t\n    -23t\n    -21t\n    -78t\n    -64t\n    41t\n    72t\n    27t\n    -60t\n    44t\n    2t\n    -15t\n    -30t\n    -107t\n    -51t\n    111t\n    40t\n    51t\n    36t\n    112t\n    -49t\n    83t\n    124t\n    -37t\n    -9t\n    -21t\n    41t\n    -71t\n    -20t\n    8t\n    -118t\n    30t\n    118t\n    47t\n    -26t\n    -21t\n    33t\n    -103t\n    26t\n    78t\n    -93t\n    -111t\n    -62t\n    -65t\n    -11t\n    -29t\n    41t\n    -128t\n    124t\n    -46t\n    64t\n    -86t\n    -19t\n    13t\n    93t\n    -71t\n    106t\n    -7t\n    15t\n    109t\n    -83t\n    123t\n    51t\n    24t\n    -18t\n    102t\n    -25t\n    20t\n    108t\n    -79t\n    -2t\n    -98t\n    -59t\n    55t\n    -39t\n    -51t\n    116t\n    31t\n    -62t\n    -81t\n    -71t\n    -87t\n    -20t\n    -78t\n    123t\n    -47t\n    127t\n    -82t\n    -33t\n    -77t\n    90t\n    -34t\n    -52t\n    -38t\n    -52t\n    -84t\n    -63t\n    109t\n    -16t\n    89t\n    70t\n    -17t\n    87t\n    86t\n    -6t\n    -5t\n    -51t\n    -53t\n    52t\n    80t\n    -95t\n    35t\n    -88t\n    -28t\n    51t\n    -80t\n    32t\n    115t\n    27t\n    38t\n    83t\n    2t\n    97t\n    34t\n    -22t\n    -63t\n    -125t\n    -49t\n    -118t\n    120t\n    44t\n    98t\n    7t\n    -53t\n    -43t\n    27t\n    65t\n    -25t\n    -37t\n    6t\n    70t\n    111t\n    37t\n    114t\n    -58t\n    5t\n    12t\n    126t\n    63t\n    -17t\n    77t\n    -44t\n    -57t\n    21t\n    -92t\n    68t\n    106t\n    -101t\n    45t\n    108t\n    125t\n    -119t\n    74t\n    -84t\n    -83t\n    36t\n    -41t\n    -123t\n    -42t\n    -95t\n    89t\n    -124t\n    -92t\n    -28t\n    -5t\n    36t\n    -64t\n    -97t\n    118t\n    -57t\n    89t\n    10t\n    -117t\n    -59t\n    5t\n    -65t\n    70t\n    66t\n    -46t\n    119t\n    40t\n    79t\n    4t\n    -75t\n    12t\n    29t\n    78t\n    18t\n    -101t\n    105t\n    105t\n    -63t\n    -8t\n    -127t\n    -88t\n    -13t\n    -103t\n    -30t\n    71t\n    32t\n    122t\n    66t\n    -69t\n    -53t\n    25t\n    96t\n    -39t\n    -90t\n    -20t\n    11t\n    6t\n    -115t\n    -102t\n    103t\n    -58t\n    58t\n    68t\n    45t\n    45t\n    -35t\n    -36t\n    26t\n    -10t\n    48t\n    10t\n    -91t\n    -69t\n    31t\n    -44t\n    -113t\n    53t\n    -35t\n    -45t\n    0t\n    -88t\n    -9t\n    40t\n    101t\n    -38t\n    50t\n    120t\n    62t\n    22t\n    -33t\n    -28t\n    119t\n    -53t\n    -95t\n    127t\n    -54t\n    10t\n    72t\n    -77t\n    12t\n    -79t\n    26t\n    56t\n    -98t\n    27t\n    -95t\n    31t\n    -59t\n    -103t\n    -111t\n    65t\n    -47t\n    -122t\n    -101t\n    -118t\n    92t\n    -10t\n    -110t\n    -97t\n    -12t\n    -125t\n    75t\n    -38t\n    64t\n    -17t\n    -86t\n    60t\n    -115t\n    -77t\n    -28t\n    -126t\n    -8t\n    -54t\n    71t\n    10t\n    -100t\n    34t\n    -98t\n    -120t\n    35t\n    20t\n    70t\n    4t\n    -122t\n    68t\n    18t\n    -56t\n    94t\n    127t\n    -76t\n    34t\n    -98t\n    -120t\n    54t\n    -85t\n    49t\n    74t\n    -18t\n    -93t\n    -81t\n    -126t\n    -115t\n    111t\n    16t\n    -53t\n    -54t\n    -8t\n    -120t\n    -23t\n    36t\n    25t\n    112t\n    -85t\n    -83t\n    -73t\n    -103t\n    96t\n    -22t\n    56t\n    119t\n    -22t\n    5t\n    79t\n    107t\n    126t\n    -123t\n    57t\n    40t\n    -36t\n    81t\n    32t\n    -88t\n    116t\n    -77t\n    -93t\n    -68t\n    -111t\n    101t\n    -21t\n    106t\n    -27t\n    67t\n    44t\n    86t\n    -4t\n    69t\n    -104t\n    -60t\n    -118t\n    -118t\n    119t\n    119t\n    -71t\n    16t\n    116t\n    -77t\n    93t\n    54t\n    -98t\n    -1t\n    10t\n    -121t\n    -65t\n    -68t\n    10t\n    -56t\n    61t\n    103t\n    37t\n    -83t\n    -122t\n    31t\n    64t\n    59t\n    -118t\n    -59t\n    -58t\n    -50t\n    -51t\n    73t\n    111t\n    102t\n    27t\n    -54t\n    75t\n    -97t\n    58t\n    64t\n    -34t\n    -47t\n    -28t\n    -121t\n    63t\n    -108t\n    -91t\n    4t\n    111t\n    39t\n    79t\n    -121t\n    -26t\n    -96t\n    91t\n    80t\n    -108t\n    -54t\n    7t\n    33t\n    39t\n    -2t\n    80t\n    1t\n    15t\n    127t\n    -73t\n    -31t\n    -88t\n    7t\n    -71t\n    26t\n    10t\n    4t\n    0t\n    -37t\n    75t\n    -105t\n    13t\n    46t\n    25t\n    62t\n    -98t\n    -29t\n    -25t\n    48t\n    -29t\n    -10t\n    -42t\n    104t\n    -62t\n    29t\n    88t\n    20t\n    77t\n    110t\n    -36t\n    -8t\n    26t\n    -26t\n    17t\n    -80t\n    11t\n    13t\n    -121t\n    -65t\n    58t\n    -77t\n    -50t\n    29t\n    -47t\n    -12t\n    -126t\n    -99t\n    72t\n    -56t\n    -89t\n    -74t\n    122t\n    5t\n    25t\n    94t\n    18t\n    105t\n    -89t\n    34t\n    5t\n    7t\n    72t\n    -100t\n    -120t\n    59t\n    93t\n    -81t\n    -56t\n    28t\n    31t\n    -128t\n    -111t\n    127t\n    47t\n    -58t\n    39t\n    -67t\n    2t\n    -101t\n    -48t\n    54t\n    39t\n    -51t\n    -44t\n    93t\n    -118t\n    -23t\n    57t\n    116t\n    13t\n    -79t\n    45t\n    32t\n    127t\n    -74t\n    95t\n    -97t\n    -5t\n    100t\n    98t\n    35t\n    2t\n    -98t\n    -17t\n    87t\n    31t\n    -85t\n    35t\n    -40t\n    -25t\n    -83t\n    -83t\n    124t\n    32t\n    -44t\n    14t\n    -44t\n    21t\n    -57t\n    -122t\n    106t\n    18t\n    106t\n    -102t\n    63t\n    -108t\n    62t\n    45t\n    -67t\n    -79t\n    -78t\n    -48t\n    101t\n    -79t\n    -105t\n    -98t\n    10t\n    123t\n    -21t\n    -10t\n    109t\n    -107t\n    -50t\n    85t\n    47t\n    75t\n    66t\n    38t\n    -53t\n    34t\n    56t\n    -94t\n    108t\n    -105t\n    -34t\n    -107t\n    -43t\n    -108t\n    -80t\n    -115t\n    -27t\n    -36t\n    41t\n    -66t\n    -114t\n    -50t\n    57t\n    -26t\n    69t\n    91t\n    -85t\n    56t\n    -89t\n    76t\n    81t\n    -118t\n    -21t\n    118t\n    39t\n    34t\n    114t\n    -5t\n    -11t\n    -27t\n    63t\n    15t\n    32t\n    -22t\n    2t\n    -12t\n    -122t\n    0t\n    54t\n    -43t\n    -68t\n    18t\n    -121t\n    79t\n    47t\n    -8t\n    115t\n    -27t\n    -17t\n    -2t\n    -41t\n    61t\n    -82t\n    68t\n    -60t\n    124t\n    75t\n    24t\n    -75t\n    -59t\n    -3t\n    93t\n    90t\n    -74t\n    92t\n    84t\n    -14t\n    61t\n    64t\n    40t\n    -120t\n    95t\n    -35t\n    65t\n    13t\n    58t\n    -69t\n    23t\n    -15t\n    71t\n    -125t\n    -90t\n    15t\n    38t\n    -33t\n    17t\n    -2t\n    54t\n    -23t\n    23t\n    81t\n    80t\n    -53t\n    -113t\n    -19t\n    -61t\n    -103t\n    -62t\n    56t\n    -114t\n    70t\n    -23t\n    69t\n    53t\n    -91t\n    72t\n    -35t\n    80t\n    69t\n    17t\n    35t\n    74t\n    -79t\n    -119t\n    -22t\n    7t\n    28t\n    6t\n    -107t\n    59t\n    27t\n    -15t\n    76t\n    -27t\n    -72t\n    -65t\n    -111t\n    23t\n    -84t\n    -9t\n    18t\n    61t\n    83t\n    33t\n    -40t\n    43t\n    47t\n    -19t\n    -72t\n    -5t\n    -79t\n    -46t\n    127t\n    72t\n    113t\n    61t\n    -22t\n    -96t\n    45t\n    1t\n    -101t\n    41t\n    -94t\n    68t\n    37t\n    33t\n    -103t\n    -98t\n    -71t\n    -52t\n    94t\n    46t\n    -32t\n    -2t\n    -86t\n    36t\n    114t\n    -83t\n    20t\n    -49t\n    78t\n    51t\n    -45t\n    50t\n    -128t\n    -39t\n    39t\n    -113t\n    -106t\n    86t\n    100t\n    -118t\n    -30t\n    79t\n    107t\n    28t\n    -73t\n    -84t\n    81t\n    -57t\n    -27t\n    -85t\n    104t\n    -18t\n    95t\n    112t\n    -40t\n    95t\n    -108t\n    -82t\n    95t\n    -29t\n    86t\n    -61t\n    21t\n    -111t\n    83t\n    -88t\n    -62t\n    71t\n    37t\n    64t\n    -1t\n    31t\n    7t\n    44t\n    63t\n    53t\n    -83t\n    -120t\n    -52t\n    -11t\n    33t\n    57t\n    -59t\n    71t\n    21t\n    -71t\n    -3t\n    -23t\n    88t\n    -35t\n    -127t\n    -107t\n    -8t\n    63t\n    39t\n    15t\n    34t\n    1t\n    -105t\n    -82t\n    -54t\n    75t\n    32t\n    -95t\n    21t\n    -73t\n    119t\n    -47t\n    -86t\n    -64t\n    -69t\n    94t\n    8t\n    90t\n    18t\n    25t\n    104t\n    101t\n    20t\n    51t\n    -71t\n    -105t\n    -7t\n    14t\n    -99t\n    -125t\n    -37t\n    63t\n    -23t\n    -109t\n    77t\n    122t\n    -127t\n    99t\n    103t\n    50t\n    -106t\n    6t\n    93t\n    -107t\n    -96t\n    89t\n    -60t\n    86t\n    -61t\n    -66t\n    -46t\n    -29t\n    37t\n    -69t\n    -86t\n    -128t\n    51t\n    -43t\n    66t\n    43t\n    8t\n    -91t\n    88t\n    28t\n    -83t\n    55t\n    63t\n    39t\n    -99t\n    70t\n    39t\n    58t\n    -64t\n    -88t\n    -93t\n    12t\n    -115t\n    -78t\n    60t\n    93t\n    115t\n    15t\n    47t\n    -90t\n    -73t\n    93t\n    -61t\n    120t\n    -107t\n    -98t\n    122t\n    100t\n    -52t\n    91t\n    20t\n    -40t\n    37t\n    18t\n    -36t\n    -31t\n    18t\n    75t\n    -27t\n    -64t\n    105t\n    -78t\n    -89t\n    44t\n    -19t\n    -9t\n    -64t\n    8t\n    -123t\n    37t\n    8t\n    -9t\n    -2t\n    -17t\n    -104t\n    43t\n    -123t\n    54t\n    60t\n    67t\n    23t\n    60t\n    102t\n    8t\n    81t\n    47t\n    -41t\n    126t\n    49t\n    84t\n    -37t\n    -114t\n    -114t\n    -53t\n    -35t\n    4t\n    115t\n    -109t\n    -100t\n    -88t\n    68t\n    -13t\n    -92t\n    -10t\n    -24t\n    29t\n    78t\n    -65t\n    -97t\n    107t\n    105t\n    -68t\n    -97t\n    -99t\n    -33t\n    80t\n    73t\n    58t\n    -114t\n    -91t\n    71t\n    92t\n    -21t\n    66t\n    77t\n    -7t\n    -3t\n    55t\n    76t\n    112t\n    -104t\n    69t\n    -120t\n    -126t\n    34t\n    6t\n    -45t\n    -14t\n    -76t\n    -27t\n    78t\n    -7t\n    -73t\n    9t\n    10t\n    4t\n    -118t\n    -106t\n    58t\n    57t\n    -64t\n    58t\n    -63t\n    9t\n    -121t\n    27t\n    -8t\n    -75t\n    76t\n    10t\n    79t\n    -78t\n    97t\n    -105t\n    -111t\n    -69t\n    -28t\n    61t\n    126t\n    -51t\n    122t\n    -111t\n    86t\n    -115t\n    -37t\n    41t\n    -57t\n    -32t\n    67t\n    112t\n    -114t\n    -4t\n    91t\n    -112t\n    127t\n    13t\n    10t\n    -117t\n    93t\n    -106t\n    -6t\n    65t\n    -126t\n    -24t\n    -111t\n    41t\n    87t\n    87t\n    -90t\n    53t\n    -17t\n    104t\n    4t\n    -68t\n    -102t\n    41t\n    89t\n    -38t\n    74t\n    76t\n    -51t\n    -116t\n    -9t\n    -33t\n    49t\n    -36t\n    115t\n    56t\n    123t\n    9t\n    104t\n    -126t\n    -42t\n    93t\n    56t\n    113t\n    113t\n    -100t\n    -112t\n    -103t\n    99t\n    54t\n    29t\n    -75t\n    102t\n    38t\n    28t\n    93t\n    96t\n    -64t\n    -28t\n    69t\n    81t\n    50t\n    67t\n    86t\n    67t\n    111t\n    13t\n    119t\n    62t\n    -108t\n    -109t\n    69t\n    -50t\n    109t\n    124t\n    41t\n    83t\n    124t\n    116t\n    59t\n    103t\n    90t\n    -112t\n    93t\n    42t\n    41t\n    -95t\n    -15t\n    57t\n    72t\n    -60t\n    -125t\n    -30t\n    -19t\n    43t\n    -108t\n    108t\n    -85t\n    -64t\n    73t\n    -24t\n    -115t\n    73t\n    -12t\n    103t\n    -124t\n    -94t\n    -92t\n    41t\n    69t\n    99t\n    -74t\n    -117t\n    -114t\n    41t\n    79t\n    107t\n    -69t\n    -32t\n    -46t\n    60t\n    -45t\n    -88t\n    14t\n    8t\n    -39t\n    42t\n    44t\n    -33t\n    -94t\n    -36t\n    10t\n    -30t\n    38t\n    -45t\n    96t\n    -61t\n    -48t\n    -70t\n    -7t\n    50t\n    23t\n    -121t\n    3t\n    -127t\n    -28t\n    62t\n    -125t\n    -82t\n    -77t\n    22t\n    112t\n    -57t\n    -47t\n    -41t\n    -38t\n    81t\n    100t\n    -122t\n    16t\n    104t\n    -96t\n    -11t\n    -1t\n    113t\n    -35t\n    -1t\n    113t\n    3t\n    125t\n    -46t\n    -102t\n    44t\n    40t\n    -44t\n    67t\n    -35t\n    -48t\n    98t\n    -35t\n    -112t\n    -58t\n    94t\n    -41t\n    48t\n    112t\n    98t\n    -27t\n    -91t\n    31t\n    -44t\n    86t\n    82t\n    -81t\n    -100t\n    -80t\n    81t\n    41t\n    -103t\n    -27t\n    -30t\n    -11t\n    -20t\n    83t\n    111t\n    -17t\n    19t\n    50t\n    43t\n    90t\n    -64t\n    -2t\n    41t\n    15t\n    11t\n    47t\n    77t\n    -49t\n    80t\n    -3t\n    -4t\n    87t\n    25t\n    112t\n    44t\n    -43t\n    -102t\n    -96t\n    6t\n    54t\n    54t\n    -93t\n    -110t\n    60t\n    121t\n    66t\n    -9t\n    -56t\n    59t\n    -57t\n    -4t\n    39t\n    77t\n    118t\n    -8t\n    69t\n    101t\n    11t\n    18t\n    36t\n    102t\n    -5t\n    115t\n    -6t\n    121t\n    -67t\n    40t\n    -15t\n    94t\n    -46t\n    -85t\n    109t\n    -5t\n    -38t\n    -16t\n    124t\n    -118t\n    21t\n    -45t\n    -42t\n    -99t\n    41t\n    -53t\n    124t\n    -128t\n    -17t\n    88t\n    1t\n    6t\n    -55t\n    -20t\n    -24t\n    -117t\n    -52t\n    -26t\n    -62t\n    127t\n    -38t\n    -21t\n    -117t\n    40t\n    -77t\n    -101t\n    117t\n    76t\n    -58t\n    -42t\n    95t\n    70t\n    -42t\n    69t\n    81t\n    108t\n    107t\n    41t\n    -64t\n    -46t\n    51t\n    53t\n    91t\n    59t\n    -104t\n    -116t\n    118t\n    112t\n    62t\n    11t\n    3t\n    -94t\n    -101t\n    -111t\n    77t\n    -109t\n    -38t\n    27t\n    -79t\n    -95t\n    48t\n    -67t\n    102t\n    45t\n    -115t\n    -42t\n    -110t\n    18t\n    -44t\n    -83t\n    19t\n    39t\n    -33t\n    79t\n    11t\n    -16t\n    23t\n    79t\n    48t\n    119t\n    -14t\n    125t\n    -13t\n    -65t\n    -5t\n    -58t\n    -33t\n    -13t\n    36t\n    -80t\n    61t\n    46t\n    -6t\n    107t\n    -57t\n    -30t\n    -117t\n    -58t\n    -128t\n    -73t\n    18t\n    -23t\n    -9t\n    50t\n    78t\n    21t\n    27t\n    -13t\n    -25t\n    -73t\n    -120t\n    -32t\n    103t\n    53t\n    47t\n    28t\n    -124t\n    -5t\n    -46t\n    74t\n    56t\n    61t\n    -44t\n    -26t\n    96t\n    -110t\n    -51t\n    -113t\n    84t\n    95t\n    -64t\n    81t\n    109t\n    -7t\n    -29t\n    -126t\n    -42t\n    -128t\n    -96t\n    -83t\n    -13t\n    54t\n    107t\n    -92t\n    43t\n    46t\n    -54t\n    -122t\n    50t\n    -23t\n    -4t\n    -97t\n    8t\n    38t\n    -29t\n    -87t\n    -114t\n    108t\n    50t\n    -123t\n    -14t\n    -15t\n    -30t\n    3t\n    -87t\n    -113t\n    -4t\n    -36t\n    82t\n    -97t\n    -114t\n    9t\n    33t\n    95t\n    -36t\n    -76t\n    15t\n    -10t\n    -48t\n    59t\n    104t\n    -32t\n    32t\n    83t\n    -41t\n    117t\n    -99t\n    -64t\n    -109t\n    -15t\n    -42t\n    62t\n    -95t\n    -71t\n    -75t\n    -48t\n    -37t\n    -54t\n    36t\n    54t\n    -96t\n    103t\n    -4t\n    116t\n    -97t\n    -15t\n    -54t\n    28t\n    73t\n    80t\n    85t\n    -126t\n    56t\n    32t\n    -117t\n    -26t\n    108t\n    23t\n    -28t\n    -32t\n    -5t\n    21t\n    80t\n    123t\n    -34t\n    94t\n    8t\n    -105t\n    -88t\n    -30t\n    6t\n    -83t\n    81t\n    -95t\n    -8t\n    33t\n    49t\n    -41t\n    68t\n    54t\n    -96t\n    117t\n    -58t\n    -77t\n    89t\n    -73t\n    -103t\n    -110t\n    -27t\n    90t\n    37t\n    -103t\n    25t\n    -61t\n    -19t\n    -36t\n    81t\n    -114t\n    -7t\n    -73t\n    -28t\n    101t\n    73t\n    -5t\n    -92t\n    -59t\n    -119t\n    -73t\n    -108t\n    -44t\n    -97t\n    6t\n    -9t\n    31t\n    71t\n    15t\n    -56t\n    39t\n    60t\n    -23t\n    104t\n    -33t\n    79t\n    82t\n    -15t\n    -103t\n    2t\n    8t\n    39t\n    -50t\n    -35t\n    -59t\n    86t\n    -89t\n    12t\n    -26t\n    -76t\n    -94t\n    52t\n    -76t\n    125t\n    16t\n    -70t\n    72t\n    115t\n    79t\n    71t\n    -109t\n    94t\n    -121t\n    -43t\n    -82t\n    29t\n    11t\n    -62t\n    122t\n    91t\n    107t\n    41t\n    -56t\n    -16t\n    127t\n    -4t\n    -58t\n    -61t\n    29t\n    -5t\n    -19t\n    -25t\n    36t\n    -92t\n    -124t\n    -120t\n    -83t\n    59t\n    51t\n    -12t\n    11t\n    -17t\n    93t\n    16t\n    107t\n    -61t\n    -6t\n    -17t\n    -110t\n    124t\n    60t\n    90t\n    -116t\n    100t\n    19t\n    89t\n    -31t\n    -77t\n    62t\n    126t\n    78t\n    21t\n    -81t\n    -102t\n    76t\n    28t\n    -108t\n    -42t\n    -21t\n    43t\n    -29t\n    -88t\n    97t\n    -49t\n    84t\n    124t\n    117t\n    -30t\n    -93t\n    10t\n    -111t\n    -113t\n    -123t\n    -63t\n    85t\n    -74t\n    -77t\n    -92t\n    49t\n    97t\n    63t\n    -106t\n    30t\n    -17t\n    107t\n    36t\n    -79t\n    34t\n    102t\n    99t\n    -70t\n    -17t\n    -63t\n    70t\n    -74t\n    68t\n    1t\n    -109t\n    67t\n    -110t\n    29t\n    67t\n    37t\n    11t\n    -82t\n    127t\n    -37t\n    -9t\n    104t\n    10t\n    -106t\n    53t\n    -17t\n    3t\n    46t\n    26t\n    -115t\n    -9t\n    -11t\n    13t\n    -55t\n    67t\n    49t\n    82t\n    -65t\n    -115t\n    48t\n    -14t\n    -57t\n    88t\n    0t\n    -110t\n    -73t\n    -119t\n    -36t\n    -73t\n    53t\n    102t\n    -30t\n    126t\n    -102t\n    54t\n    61t\n    -107t\n    -14t\n    100t\n    58t\n    -73t\n    107t\n    -19t\n    -89t\n    -26t\n    -77t\n    -60t\n    9t\n    70t\n    106t\n    98t\n    75t\n    -2t\n    6t\n    -32t\n    42t\n    -76t\n    112t\n    83t\n    -9t\n    -30t\n    21t\n    -122t\n    -104t\n    66t\n    -128t\n    -93t\n    112t\n    -85t\n    96t\n    66t\n    -105t\n    26t\n    -95t\n    -18t\n    53t\n    -125t\n    -47t\n    92t\n    -74t\n    98t\n    -1t\n    -9t\n    113t\n    -31t\n    67t\n    12t\n    121t\n    -73t\n    -116t\n    -61t\n    33t\n    62t\n    -106t\n    22t\n    -105t\n    26t\n    -79t\n    52t\n    -49t\n    -56t\n    20t\n    83t\n    73t\n    -99t\n    1t\n    76t\n    -123t\n    18t\n    30t\n    -39t\n    11t\n    49t\n    30t\n    69t\n    22t\n    -50t\n    -110t\n    -64t\n    7t\n    60t\n    -125t\n    -90t\n    34t\n    -85t\n    95t\n    58t\n    -31t\n    -19t\n    -128t\n    3t\n    36t\n    10t\n    -31t\n    18t\n    3t\n    -90t\n    60t\n    -15t\n    -34t\n    10t\n    119t\n    -94t\n    -49t\n    -98t\n    -42t\n    51t\n    126t\n    85t\n    44t\n    24t\n    107t\n    13t\n    -40t\n    74t\n    -113t\n    84t\n    78t\n    -27t\n    -97t\n    120t\n    22t\n    -67t\n    -34t\n    73t\n    3t\n    -104t\n    -72t\n    -19t\n    -105t\n    55t\n    -92t\n    57t\n    1t\n    105t\n    118t\n    42t\n    -54t\n    -116t\n    61t\n    116t\n    -76t\n    -55t\n    -118t\n    13t\n    -78t\n    -121t\n    -98t\n    -39t\n    -48t\n    -122t\n    -32t\n    -7t\n    -16t\n    -107t\n    1t\n    38t\n    -73t\n    23t\n    52t\n    -95t\n    67t\n    25t\n    -104t\n    33t\n    -46t\n    -50t\n    -128t\n    80t\n    -77t\n    -14t\n    2t\n    -46t\n    -88t\n    -72t\n    20t\n    -75t\n    19t\n    -109t\n    -78t\n    45t\n    109t\n    127t\n    102t\n    -82t\n    -1t\n    -36t\n    -81t\n    -121t\n    104t\n    78t\n    -126t\n    -99t\n    115t\n    -64t\n    29t\n    9t\n    -104t\n    98t\n    -66t\n    -2t\n    -25t\n    52t\n    -106t\n    -27t\n    -121t\n    -108t\n    -85t\n    -127t\n    34t\n    -73t\n    123t\n    6t\n    -9t\n    -2t\n    10t\n    14t\n    81t\n    -4t\n    43t\n    37t\n    88t\n    -25t\n    65t\n    -88t\n    85t\n    34t\n    116t\n    79t\n    121t\n    -17t\n    69t\n    59t\n    -68t\n    2t\n    15t\n    122t\n    -57t\n    12t\n    -12t\n    84t\n    -91t\n    -66t\n    -92t\n    -30t\n    -70t\n    36t\n    -70t\n    -20t\n    -72t\n    -109t\n    -98t\n    -54t\n    -93t\n    -69t\n    89t\n    127t\n    51t\n    13t\n    3t\n    6t\n    -82t\n    -9t\n    25t\n    -26t\n    74t\n    85t\n    45t\n    -110t\n    35t\n    71t\n    -53t\n    -34t\n    88t\n    64t\n    -79t\n    -126t\n    -16t\n    72t\n    25t\n    -16t\n    -111t\n    73t\n    116t\n    -31t\n    -40t\n    55t\n    82t\n    -81t\n    13t\n    -125t\n    41t\n    -97t\n    99t\n    -57t\n    20t\n    -90t\n    0t\n    124t\n    31t\n    18t\n    -36t\n    20t\n    -114t\n    50t\n    -86t\n    -37t\n    127t\n    -2t\n    -18t\n    -106t\n    121t\n    115t\n    -68t\n    -25t\n    90t\n    127t\n    -31t\n    -126t\n    30t\n    107t\n    -50t\n    0t\n    66t\n    60t\n    102t\n    -114t\n    52t\n    56t\n    65t\n    -124t\n    123t\n    -17t\n    -4t\n    -1t\n    83t\n    95t\n    45t\n    -75t\n    -119t\n    -66t\n    122t\n    -118t\n    -124t\n    -122t\n    73t\n    16t\n    75t\n    -105t\n    -96t\n    -94t\n    22t\n    16t\n    -125t\n    -84t\n    52t\n    -7t\n    118t\n    63t\n    -25t\n    -96t\n    76t\n    34t\n    72t\n    -9t\n    120t\n    -22t\n    -81t\n    -110t\n    33t\n    13t\n    3t\n    -124t\n    -63t\n    -33t\n    10t\n    107t\n    118t\n    4t\n    111t\n    118t\n    -118t\n    -61t\n    59t\n    -120t\n    70t\n    59t\n    -69t\n    98t\n    51t\n    74t\n    -59t\n    -93t\n    -24t\n    -70t\n    -81t\n    98t\n    65t\n    -14t\n    108t\n    93t\n    97t\n    111t\n    45t\n    -43t\n    101t\n    -52t\n    -119t\n    -114t\n    -111t\n    45t\n    25t\n    -115t\n    -68t\n    14t\n    -96t\n    -103t\n    113t\n    3t\n    110t\n    102t\n    -79t\n    -80t\n    59t\n    -59t\n    -7t\n    11t\n    -6t\n    127t\n    98t\n    -55t\n    87t\n    80t\n    -56t\n    -104t\n    -12t\n    16t\n    60t\n    -6t\n    -49t\n    -113t\n    21t\n    12t\n    -55t\n    103t\n    19t\n    98t\n    -52t\n    -73t\n    -45t\n    68t\n    -38t\n    -94t\n    98t\n    -90t\n    -14t\n    -22t\n    -121t\n    91t\n    -51t\n    -8t\n    103t\n    64t\n    -106t\n    9t\n    -74t\n    9t\n    74t\n    13t\n    -13t\n    -128t\n    95t\n    -25t\n    -25t\n    -25t\n    49t\n    125t\n    -83t\n    38t\n    65t\n    24t\n    118t\n    0t\n    -82t\n    -61t\n    -36t\n    -108t\n    70t\n    -33t\n    101t\n    -71t\n    -36t\n    98t\n    2t\n    35t\n    -113t\n    88t\n    -104t\n    -65t\n    -37t\n    -113t\n    -17t\n    -2t\n    -73t\n    61t\n    8t\n    -123t\n    88t\n    107t\n    -24t\n    56t\n    42t\n    -88t\n    45t\n    -14t\n    80t\n    88t\n    -76t\n    28t\n    33t\n    38t\n    29t\n    -87t\n    89t\n    -11t\n    15t\n    -37t\n    1t\n    -102t\n    -105t\n    118t\n    -75t\n    12t\n    53t\n    -35t\n    32t\n    -77t\n    -38t\n    -73t\n    -41t\n    117t\n    95t\n    60t\n    13t\n    -2t\n    -73t\n    16t\n    39t\n    -125t\n    126t\n    70t\n    65t\n    45t\n    112t\n    -93t\n    -57t\n    -5t\n    21t\n    -62t\n    66t\n    119t\n    -94t\n    -40t\n    -21t\n    52t\n    25t\n    8t\n    -4t\n    -30t\n    95t\n    77t\n    7t\n    -102t\n    -7t\n    31t\n    -36t\n    -83t\n    2t\n    104t\n    -66t\n    44t\n    111t\n    -103t\n    43t\n    94t\n    95t\n    -127t\n    35t\n    91t\n    -76t\n    37t\n    38t\n    5t\n    20t\n    -31t\n    42t\n    86t\n    113t\n    -33t\n    52t\n    -16t\n    -42t\n    -67t\n    23t\n    -14t\n    49t\n    -55t\n    -46t\n    -38t\n    52t\n    -77t\n    114t\n    -51t\n    125t\n    96t\n    -25t\n    0t\n    -90t\n    50t\n    62t\n    97t\n    55t\n    -97t\n    105t\n    70t\n    62t\n    43t\n    -64t\n    99t\n    -120t\n    31t\n    77t\n    28t\n    76t\n    -83t\n    -52t\n    -114t\n    -23t\n    73t\n    -123t\n    72t\n    -34t\n    -15t\n    59t\n    -113t\n    115t\n    36t\n    -125t\n    -55t\n    -42t\n    -77t\n    -31t\n    -93t\n    -92t\n    -82t\n    -113t\n    99t\n    28t\n    -58t\n    -89t\n    -98t\n    76t\n    -103t\n    -61t\n    113t\n    86t\n    -69t\n    10t\n    -29t\n    87t\n    78t\n    -15t\n    -68t\n    9t\n    -64t\n    -96t\n    64t\n    72t\n    94t\n    -31t\n    0t\n    87t\n    -41t\n    119t\n    110t\n    -74t\n    5t\n    28t\n    -11t\n    14t\n    -73t\n    -49t\n    -103t\n    22t\n    -53t\n    32t\n    53t\n    -17t\n    54t\n    -2t\n    29t\n    -107t\n    69t\n    45t\n    -44t\n    86t\n    -121t\n    110t\n    114t\n    76t\n    1t\n    -70t\n    25t\n    -98t\n    47t\n    -128t\n    -74t\n    -31t\n    97t\n    -100t\n    9t\n    -61t\n    32t\n    43t\n    -84t\n    -48t\n    -57t\n    -68t\n    61t\n    123t\n    56t\n    -108t\n    -6t\n    -22t\n    17t\n    -65t\n    -107t\n    -112t\n    -93t\n    -86t\n    -28t\n    59t\n    47t\n    -51t\n    29t\n    115t\n    49t\n    -120t\n    -31t\n    78t\n    -14t\n    88t\n    125t\n    -63t\n    104t\n    28t\n    89t\n    -114t\n    -94t\n    100t\n    -18t\n    65t\n    -101t\n    7t\n    -76t\n    99t\n    -96t\n    -118t\n    -57t\n    23t\n    16t\n    27t\n    5t\n    -81t\n    -120t\n    80t\n    58t\n    -83t\n    86t\n    13t\n    127t\n    -28t\n    126t\n    -103t\n    86t\n    127t\n    94t\n    -75t\n    -11t\n    -102t\n    96t\n    -93t\n    4t\n    15t\n    -23t\n    109t\n    -52t\n    -3t\n    42t\n    65t\n    -73t\n    73t\n    -67t\n    15t\n    -12t\n    -90t\n    105t\n    117t\n    51t\n    -34t\n    102t\n    17t\n    -34t\n    92t\n    34t\n    34t\n    -4t\n    -2t\n    78t\n    82t\n    -44t\n    78t\n    8t\n    -11t\n    89t\n    -20t\n    -125t\n    12t\n    -95t\n    70t\n    -98t\n    -108t\n    -33t\n    64t\n    57t\n    44t\n    122t\n    -95t\n    56t\n    112t\n    127t\n    -108t\n    28t\n    108t\n    117t\n    77t\n    90t\n    -12t\n    -43t\n    60t\n    -92t\n    58t\n    -72t\n    -26t\n    -49t\n    -118t\n    -31t\n    71t\n    28t\n    -128t\n    120t\n    -40t\n    -101t\n    123t\n    -42t\n    -35t\n    127t\n    -49t\n    -46t\n    -110t\n    -120t\n    -44t\n    -21t\n    113t\n    -12t\n    -74t\n    -91t\n    107t\n    -17t\n    -90t\n    -95t\n    -115t\n    -37t\n    -38t\n    -41t\n    123t\n    -125t\n    -11t\n    123t\n    -81t\n    3t\n    -118t\n    -88t\n    -20t\n    -47t\n    -103t\n    105t\n    21t\n    -101t\n    -41t\n    -64t\n    96t\n    -115t\n    88t\n    9t\n    -110t\n    -11t\n    66t\n    -63t\n    -55t\n    -82t\n    16t\n    -56t\n    -86t\n    75t\n    -38t\n    -54t\n    103t\n    -100t\n    40t\n    110t\n    8t\n    -11t\n    13t\n    10t\n    -15t\n    113t\n    -69t\n    104t\n    64t\n    85t\n    53t\n    65t\n    16t\n    95t\n    125t\n    127t\n    -18t\n    81t\n    37t\n    -117t\n    77t\n    41t\n    -97t\n    112t\n    67t\n    62t\n    -13t\n    119t\n    85t\n    64t\n    51t\n    -66t\n    -40t\n    77t\n    -101t\n    -107t\n    -69t\n    -122t\n    -10t\n    106t\n    -125t\n    29t\n    -28t\n    -5t\n    58t\n    54t\n    -51t\n    94t\n    70t\n    71t\n    -117t\n    -4t\n    -8t\n    -7t\n    -67t\n    28t\n    124t\n    -102t\n    -80t\n    -26t\n    -71t\n    78t\n    51t\n    -60t\n    -53t\n    120t\n    -31t\n    -22t\n    -40t\n    -30t\n    -38t\n    -45t\n    5t\n    -2t\n    37t\n    -21t\n    -46t\n    42t\n    -42t\n    -27t\n    -21t\n    55t\n    -24t\n    109t\n    105t\n    80t\n    -100t\n    -117t\n    -37t\n    46t\n    -113t\n    -11t\n    51t\n    -3t\n    -127t\n    -27t\n    -45t\n    18t\n    1t\n    -49t\n    -73t\n    4t\n    98t\n    23t\n    -50t\n    -22t\n    -119t\n    -40t\n    -127t\n    -85t\n    -36t\n    50t\n    46t\n    58t\n    49t\n    88t\n    -106t\n    93t\n    -74t\n    -14t\n    -71t\n    -64t\n    -100t\n    119t\n    18t\n    40t\n    -47t\n    11t\n    115t\n    89t\n    -120t\n    37t\n    -22t\n    10t\n    4t\n    69t\n    -66t\n    20t\n    -23t\n    30t\n    77t\n    -36t\n    -122t\n    3t\n    -39t\n    -106t\n    -120t\n    -3t\n    -125t\n    42t\n    25t\n    -34t\n    35t\n    -127t\n    37t\n    -24t\n    -64t\n    -98t\n    -121t\n    56t\n    74t\n    78t\n    124t\n    -118t\n    -71t\n    -38t\n    116t\n    -20t\n    69t\n    1t\n    -57t\n    -105t\n    -29t\n    -35t\n    2t\n    -48t\n    84t\n    -66t\n    -77t\n    69t\n    9t\n    85t\n    112t\n    111t\n    -39t\n    -68t\n    -39t\n    36t\n    76t\n    115t\n    10t\n    -59t\n    25t\n    -65t\n    72t\n    -107t\n    -16t\n    -58t\n    -77t\n    -5t\n    39t\n    -102t\n    38t\n    49t\n    -116t\n    -48t\n    -41t\n    -95t\n    35t\n    43t\n    -54t\n    -22t\n    -123t\n    40t\n    112t\n    10t\n    -17t\n    106t\n    100t\n    50t\n    -56t\n    71t\n    70t\n    98t\n    122t\n    -26t\n    -21t\n    -123t\n    -89t\n    -9t\n    -79t\n    14t\n    39t\n    67t\n    -81t\n    -89t\n    82t\n    93t\n    117t\n    98t\n    -80t\n    -64t\n    -97t\n    -65t\n    -2t\n    -95t\n    -109t\n    78t\n    -9t\n    102t\n    -109t\n    106t\n    -69t\n    -2t\n    90t\n    81t\n    -78t\n    -16t\n    -93t\n    -8t\n    0t\n    -115t\n    -81t\n    -33t\n    98t\n    92t\n    -6t\n    62t\n    -56t\n    -94t\n    21t\n    123t\n    -31t\n    -87t\n    -43t\n    -70t\n    -80t\n    82t\n    99t\n    14t\n    47t\n    13t\n    -18t\n    34t\n    -13t\n    -58t\n    -117t\n    82t\n    17t\n    -112t\n    -40t\n    -36t\n    -17t\n    -25t\n    -109t\n    -88t\n    -80t\n    71t\n    92t\n    59t\n    -18t\n    21t\n    -43t\n    -54t\n    69t\n    40t\n    104t\n    40t\n    79t\n    84t\n    12t\n    -9t\n    77t\n    13t\n    -124t\n    -20t\n    96t\n    -85t\n    -67t\n    80t\n    59t\n    -53t\n    79t\n    -123t\n    70t\n    49t\n    -64t\n    -125t\n    7t\n    109t\n    -42t\n    43t\n    42t\n    21t\n    -90t\n    -93t\n    72t\n    -4t\n    53t\n    31t\n    -4t\n    -18t\n    -18t\n    87t\n    -98t\n    81t\n    -69t\n    61t\n    -23t\n    107t\n    40t\n    81t\n    48t\n    16t\n    -78t\n    70t\n    123t\n    16t\n    6t\n    16t\n    -124t\n    -65t\n    95t\n    -114t\n    109t\n    -37t\n    -94t\n    -42t\n    -124t\n    113t\n    -115t\n    114t\n    125t\n    57t\n    98t\n    12t\n    -47t\n    -117t\n    -17t\n    127t\n    50t\n    -11t\n    -45t\n    -2t\n    -114t\n    127t\n    81t\n    -120t\n    -23t\n    -2t\n    -117t\n    12t\n    25t\n    52t\n    -3t\n    98t\n    55t\n    23t\n    4t\n    -55t\n    26t\n    -31t\n    19t\n    85t\n    126t\n    -3t\n    45t\n    -56t\n    73t\n    -16t\n    -27t\n    93t\n    -77t\n    83t\n    51t\n    116t\n    -124t\n    -112t\n    -39t\n    -45t\n    7t\n    -92t\n    -104t\n    33t\n    52t\n    3t\n    -109t\n    -15t\n    0t\n    -25t\n    -88t\n    -124t\n    -41t\n    -95t\n    -127t\n    88t\n    30t\n    10t\n    70t\n    -47t\n    105t\n    15t\n    -48t\n    -107t\n    58t\n    -19t\n    104t\n    -63t\n    19t\n    -110t\n    13t\n    -41t\n    120t\n    6t\n    122t\n    103t\n    4t\n    74t\n    -78t\n    102t\n    -31t\n    -23t\n    37t\n    -105t\n    -79t\n    -47t\n    -73t\n    -77t\n    -99t\n    -112t\n    3t\n    -121t\n    -119t\n    114t\n    -17t\n    -13t\n    -50t\n    -103t\n    -72t\n    -60t\n    -44t\n    38t\n    2t\n    53t\n    39t\n    127t\n    98t\n    -23t\n    -80t\n    -45t\n    71t\n    87t\n    47t\n    -43t\n    45t\n    84t\n    -125t\n    37t\n    -14t\n    61t\n    -6t\n    42t\n    101t\n    55t\n    -2t\n    -70t\n    -87t\n    -107t\n    -34t\n    -41t\n    87t\n    -101t\n    -91t\n    -28t\n    -113t\n    79t\n    29t\n    62t\n    109t\n    -80t\n    83t\n    0t\n    -20t\n    -14t\n    -14t\n    7t\n    -8t\n    -47t\n    -78t\n    -101t\n    -80t\n    12t\n    60t\n    91t\n    -25t\n    35t\n    -108t\n    29t\n    -65t\n    -74t\n    68t\n    -110t\n    42t\n    -91t\n    90t\n    -38t\n    96t\n    100t\n    -3t\n    -86t\n    95t\n    -128t\n    31t\n    105t\n    -38t\n    110t\n    25t\n    77t\n    -121t\n    80t\n    29t\n    65t\n    79t\n    -126t\n    35t\n    86t\n    119t\n    29t\n    -115t\n    -87t\n    -127t\n    -48t\n    54t\n    -5t\n    -29t\n    1t\n    13t\n    45t\n    -116t\n    -127t\n    78t\n    -49t\n    37t\n    -111t\n    -94t\n    -104t\n    -119t\n    -16t\n    -58t\n    118t\n    82t\n    -68t\n    -18t\n    -2t\n    -83t\n    36t\n    -103t\n    78t\n    127t\n    92t\n    11t\n    104t\n    -19t\n    -103t\n    -74t\n    51t\n    -80t\n    16t\n    59t\n    115t\n    79t\n    -14t\n    -85t\n    -61t\n    -85t\n    -99t\n    15t\n    -45t\n    -32t\n    -117t\n    -40t\n    -58t\n    74t\n    -122t\n    -61t\n    -63t\n    -23t\n    121t\n    -23t\n    110t\n    3t\n    126t\n    94t\n    77t\n    -84t\n    -67t\n    -119t\n    66t\n    58t\n    45t\n    31t\n    -60t\n    -63t\n    -42t\n    -38t\n    123t\n    1t\n    79t\n    -123t\n    -16t\n    -16t\n    26t\n    86t\n    14t\n    -109t\n    109t\n    76t\n    -15t\n    -122t\n    -109t\n    65t\n    -48t\n    17t\n    -118t\n    88t\n    15t\n    73t\n    -92t\n    -93t\n    67t\n    44t\n    61t\n    -67t\n    120t\n    -43t\n    50t\n    104t\n    33t\n    -102t\n    75t\n    87t\n    36t\n    35t\n    -83t\n    5t\n    95t\n    81t\n    -64t\n    111t\n    -35t\n    30t\n    126t\n    40t\n    -50t\n    7t\n    -18t\n    37t\n    24t\n    -110t\n    61t\n    -6t\n    -78t\n    81t\n    114t\n    31t\n    60t\n    -49t\n    -8t\n    -121t\n    125t\n    59t\n    -124t\n    -118t\n    123t\n    96t\n    6t\n    -107t\n    24t\n    4t\n    21t\n    110t\n    -107t\n    63t\n    124t\n    54t\n    121t\n    34t\n    97t\n    88t\n    -30t\n    34t\n    -39t\n    14t\n    84t\n    88t\n    -106t\n    106t\n    109t\n    -22t\n    124t\n    -126t\n    6t\n    21t\n    65t\n    -80t\n    -22t\n    73t\n    78t\n    -111t\n    105t\n    -14t\n    102t\n    22t\n    75t\n    79t\n    69t\n    94t\n    57t\n    -115t\n    70t\n    30t\n    13t\n    -115t\n    -94t\n    86t\n    -9t\n    -35t\n    80t\n    97t\n    -22t\n    -50t\n    -71t\n    -16t\n    -41t\n    -82t\n    2t\n    38t\n    34t\n    16t\n    -74t\n    -103t\n    -24t\n    41t\n    -49t\n    -126t\n    -58t\n    30t\n    -126t\n    -47t\n    -59t\n    -96t\n    98t\n    -57t\n    49t\n    -52t\n    -84t\n    17t\n    -105t\n    53t\n    36t\n    -89t\n    -84t\n    -43t\n    -78t\n    23t\n    11t\n    26t\n    -2t\n    -47t\n    94t\n    89t\n    89t\n    71t\n    -87t\n    -28t\n    -62t\n    67t\n    -54t\n    40t\n    14t\n    85t\n    71t\n    35t\n    22t\n    -32t\n    0t\n    -29t\n    -122t\n    -30t\n    126t\n    -81t\n    -87t\n    -78t\n    16t\n    -33t\n    -11t\n    84t\n    -124t\n    9t\n    107t\n    -103t\n    48t\n    -97t\n    -25t\n    6t\n    40t\n    -91t\n    61t\n    -22t\n    77t\n    -43t\n    -65t\n    -90t\n    -17t\n    -27t\n    -45t\n    14t\n    -38t\n    24t\n    101t\n    74t\n    123t\n    116t\n    101t\n    -47t\n    77t\n    -89t\n    107t\n    51t\n    85t\n    41t\n    38t\n    29t\n    11t\n    -118t\n    -123t\n    -67t\n    74t\n    -106t\n    -18t\n    -63t\n    114t\n    25t\n    -20t\n    -106t\n    -38t\n    49t\n    -84t\n    -92t\n    43t\n    6t\n    95t\n    120t\n    -54t\n    43t\n    124t\n    3t\n    52t\n    93t\n    50t\n    -25t\n    54t\n    -92t\n    31t\n    -117t\n    -109t\n    -107t\n    -81t\n    73t\n    -80t\n    11t\n    -48t\n    110t\n    100t\n    126t\n    55t\n    -2t\n    -63t\n    -61t\n    50t\n    -26t\n    54t\n    -24t\n    -26t\n    83t\n    5t\n    108t\n    45t\n    90t\n    -118t\n    -90t\n    -5t\n    37t\n    48t\n    -70t\n    86t\n    -95t\n    123t\n    38t\n    -9t\n    -65t\n    68t\n    -108t\n    -90t\n    -80t\n    98t\n    -58t\n    -89t\n    32t\n    2t\n    103t\n    21t\n    103t\n    30t\n    -120t\n    -122t\n    -26t\n    92t\n    46t\n    47t\n    -80t\n    -22t\n    -60t\n    -10t\n    8t\n    -94t\n    76t\n    -119t\n    -72t\n    116t\n    -75t\n    100t\n    83t\n    -61t\n    -49t\n    -58t\n    48t\n    -85t\n    55t\n    56t\n    -31t\n    -2t\n    115t\n    107t\n    -28t\n    37t\n    92t\n    25t\n    35t\n    -83t\n    -78t\n    37t\n    -66t\n    64t\n    -66t\n    -80t\n    1t\n    44t\n    56t\n    -5t\n    -12t\n    29t\n    -38t\n    24t\n    12t\n    91t\n    -12t\n    108t\n    -9t\n    104t\n    100t\n    23t\n    -7t\n    -82t\n    30t\n    17t\n    2t\n    44t\n    -40t\n    37t\n    -5t\n    -102t\n    36t\n    -123t\n    -102t\n    69t\n    53t\n    73t\n    -57t\n    112t\n    -96t\n    109t\n    -91t\n    -95t\n    -81t\n    110t\n    -116t\n    95t\n    -36t\n    -54t\n    100t\n    -64t\n    38t\n    -126t\n    88t\n    8t\n    16t\n    -59t\n    -62t\n    29t\n    -122t\n    -56t\n    100t\n    -42t\n    -39t\n    -8t\n    16t\n    117t\n    82t\n    18t\n    85t\n    -105t\n    59t\n    -23t\n    -52t\n    101t\n    -48t\n    -21t\n    -97t\n    78t\n    -68t\n    85t\n    -121t\n    -69t\n    43t\n    57t\n    -56t\n    67t\n    -24t\n    -39t\n    125t\n    -100t\n    -35t\n    74t\n    105t\n    10t\n    104t\n    -8t\n    34t\n    52t\n    -67t\n    64t\n    -67t\n    -28t\n    -59t\n    69t\n    -68t\n    24t\n    76t\n    115t\n    21t\n    12t\n    96t\n    -71t\n    69t\n    84t\n    84t\n    -115t\n    -75t\n    -111t\n    121t\n    -72t\n    68t\n    -94t\n    12t\n    -88t\n    -91t\n    -100t\n    1t\n    -6t\n    10t\n    90t\n    40t\n    -128t\n    13t\n    -91t\n    97t\n    -89t\n    33t\n    -44t\n    -82t\n    59t\n    39t\n    -94t\n    29t\n    69t\n    116t\n    -43t\n    -100t\n    91t\n    -20t\n    -127t\n    -114t\n    -122t\n    31t\n    85t\n    -10t\n    -91t\n    -117t\n    -87t\n    -120t\n    8t\n    -109t\n    28t\n    115t\n    -48t\n    104t\n    -22t\n    35t\n    72t\n    -14t\n    36t\n    51t\n    97t\n    104t\n    -109t\n    -122t\n    -127t\n    -64t\n    39t\n    -20t\n    -88t\n    -66t\n    -20t\n    -32t\n    -50t\n    87t\n    81t\n    99t\n    -81t\n    -20t\n    -39t\n    -79t\n    -90t\n    0t\n    54t\n    -109t\n    46t\n    124t\n    -64t\n    105t\n    -94t\n    13t\n    -10t\n    46t\n    -106t\n    -77t\n    -3t\n    -99t\n    58t\n    -13t\n    -99t\n    -98t\n    -10t\n    24t\n    113t\n    -43t\n    60t\n    62t\n    -23t\n    -20t\n    -114t\n    67t\n    110t\n    125t\n    101t\n    -110t\n    -53t\n    103t\n    -119t\n    -12t\n    -55t\n    -63t\n    78t\n    69t\n    120t\n    -80t\n    62t\n    4t\n    -75t\n    -27t\n    -78t\n    13t\n    21t\n    -36t\n    -24t\n    -97t\n    111t\n    -80t\n    67t\n    -79t\n    32t\n    -52t\n    -71t\n    -60t\n    78t\n    62t\n    -117t\n    -29t\n    -107t\n    70t\n    48t\n    -62t\n    112t\n    6t\n    59t\n    90t\n    115t\n    50t\n    -38t\n    -46t\n    -125t\n    95t\n    -94t\n    -125t\n    -34t\n    76t\n    60t\n    123t\n    -60t\n    -42t\n    96t\n    54t\n    102t\n    65t\n    -51t\n    100t\n    -42t\n    -111t\n    -119t\n    62t\n    40t\n    -12t\n    49t\n    -69t\n    -97t\n    81t\n    -110t\n    32t\n    -54t\n    125t\n    115t\n    -93t\n    111t\n    98t\n    -92t\n    63t\n    -98t\n    85t\n    39t\n    -2t\n    -127t\n    31t\n    90t\n    -30t\n    98t\n    56t\n    -122t\n    -10t\n    6t\n    -116t\n    2t\n    104t\n    41t\n    16t\n    -82t\n    -70t\n    22t\n    -72t\n    68t\n    114t\n    -58t\n    -75t\n    43t\n    -70t\n    -23t\n    -29t\n    -41t\n    -38t\n    79t\n    2t\n    42t\n    85t\n    96t\n    -60t\n    -74t\n    -87t\n    3t\n    -77t\n    47t\n    4t\n    -34t\n    -11t\n    38t\n    -70t\n    -39t\n    -59t\n    -64t\n    -64t\n    28t\n    -60t\n    48t\n    -77t\n    57t\n    -99t\n    87t\n    55t\n    47t\n    104t\n    55t\n    -110t\n    -85t\n    122t\n    -57t\n    17t\n    -121t\n    -76t\n    57t\n    104t\n    -23t\n    88t\n    19t\n    -31t\n    -36t\n    71t\n    49t\n    105t\n    -31t\n    65t\n    -62t\n    44t\n    -45t\n    -19t\n    72t\n    -26t\n    -23t\n    26t\n    61t\n    -51t\n    102t\n    61t\n    -4t\n    -41t\n    -20t\n    40t\n    19t\n    66t\n    -58t\n    -50t\n    7t\n    -89t\n    105t\n    -114t\n    -23t\n    -70t\n    45t\n    126t\n    93t\n    -117t\n    76t\n    -126t\n    -81t\n    16t\n    31t\n    43t\n    93t\n    -71t\n    -62t\n    -91t\n    -117t\n    -27t\n    -8t\n    111t\n    29t\n    65t\n    -55t\n    45t\n    54t\n    55t\n    -16t\n    -124t\n    10t\n    46t\n    27t\n    -55t\n    -29t\n    -38t\n    106t\n    111t\n    -48t\n    -104t\n    40t\n    124t\n    4t\n    2t\n    8t\n    72t\n    108t\n    1t\n    -104t\n    18t\n    -57t\n    54t\n    44t\n    15t\n    -47t\n    110t\n    -77t\n    80t\n    18t\n    -89t\n    38t\n    25t\n    -5t\n    5t\n    -125t\n    -66t\n    91t\n    -59t\n    -2t\n    42t\n    45t\n    -32t\n    16t\n    -69t\n    100t\n    -69t\n    -56t\n    -5t\n    -32t\n    44t\n    -56t\n    -36t\n    -94t\n    -74t\n    -97t\n    62t\n    111t\n    19t\n    -126t\n    -32t\n    -126t\n    102t\n    -128t\n    16t\n    99t\n    -93t\n    34t\n    -85t\n    -42t\n    -29t\n    30t\n    -7t\n    -27t\n    122t\n    35t\n    -31t\n    -53t\n    -53t\n    -21t\n    -12t\n    90t\n    -97t\n    46t\n    -65t\n    -79t\n    -109t\n    44t\n    110t\n    99t\n    -83t\n    -30t\n    88t\n    77t\n    -86t\n    -13t\n    -68t\n    12t\n    -51t\n    -76t\n    76t\n    -85t\n    124t\n    -54t\n    -7t\n    39t\n    -4t\n    114t\n    125t\n    49t\n    -66t\n    -10t\n    -114t\n    -68t\n    -52t\n    -121t\n    -34t\n    -107t\n    78t\n    -35t\n    40t\n    -124t\n    28t\n    -121t\n    81t\n    -57t\n    72t\n    97t\n    -88t\n    8t\n    50t\n    -86t\n    95t\n    -110t\n    -93t\n    -39t\n    -121t\n    111t\n    -47t\n    -72t\n    -10t\n    72t\n    -19t\n    91t\n    -74t\n    79t\n    -95t\n    -51t\n    -62t\n    -55t\n    62t\n    -48t\n    -51t\n    -36t\n    -112t\n    -110t\n    127t\n    82t\n    60t\n    53t\n    125t\n    -111t\n    -76t\n    -90t\n    -55t\n    -113t\n    -36t\n    113t\n    28t\n    -74t\n    56t\n    69t\n    40t\n    69t\n    -37t\n    -106t\n    -43t\n    16t\n    2t\n    -96t\n    -88t\n    -88t\n    -98t\n    -106t\n    -38t\n    -118t\n    -127t\n    -102t\n    -102t\n    -38t\n    88t\n    96t\n    -44t\n    -122t\n    -44t\n    38t\n    -34t\n    -103t\n    19t\n    -24t\n    102t\n    5t\n    -37t\n    -52t\n    -28t\n    -31t\n    -7t\n    85t\n    1t\n    87t\n    -110t\n    65t\n    -3t\n    63t\n    26t\n    24t\n    -20t\n    54t\n    -65t\n    -49t\n    -123t\n    -121t\n    -26t\n    106t\n    -51t\n    -111t\n    -100t\n    11t\n    -37t\n    58t\n    38t\n    -73t\n    124t\n    17t\n    -44t\n    111t\n    122t\n    -12t\n    73t\n    87t\n    -109t\n    0t\n    119t\n    58t\n    69t\n    118t\n    5t\n    57t\n    -73t\n    -14t\n    -24t\n    -13t\n    -83t\n    51t\n    69t\n    127t\n    -94t\n    -96t\n    -97t\n    55t\n    -16t\n    104t\n    122t\n    -18t\n    48t\n    1t\n    -97t\n    96t\n    50t\n    55t\n    86t\n    60t\n    -79t\n    126t\n    117t\n    100t\n    -38t\n    -19t\n    103t\n    -109t\n    -25t\n    -33t\n    -36t\n    -28t\n    58t\n    -43t\n    -59t\n    41t\n    -107t\n    -68t\n    92t\n    68t\n    120t\n    -107t\n    -63t\n    -5t\n    -36t\n    -27t\n    -123t\n    53t\n    -104t\n    -1t\n    -23t\n    -66t\n    116t\n    -53t\n    -74t\n    -100t\n    -54t\n    31t\n    -119t\n    -68t\n    -68t\n    -101t\n    -6t\n    54t\n    -34t\n    -15t\n    -53t\n    -23t\n    -28t\n    -105t\n    49t\n    34t\n    31t\n    26t\n    -52t\n    -78t\n    -69t\n    48t\n    37t\n    99t\n    -14t\n    -122t\n    104t\n    9t\n    40t\n    -23t\n    -124t\n    -98t\n    -33t\n    34t\n    4t\n    59t\n    112t\n    79t\n    -43t\n    -24t\n    33t\n    -115t\n    -68t\n    79t\n    -102t\n    -105t\n    85t\n    -18t\n    96t\n    19t\n    81t\n    44t\n    -55t\n    112t\n    124t\n    80t\n    -36t\n    48t\n    -103t\n    4t\n    -36t\n    -60t\n    83t\n    126t\n    0t\n    120t\n    121t\n    26t\n    2t\n    -12t\n    103t\n    -119t\n    -51t\n    -110t\n    28t\n    -110t\n    -26t\n    53t\n    46t\n    13t\n    -26t\n    38t\n    -87t\n    -59t\n    -23t\n    -28t\n    -84t\n    101t\n    17t\n    60t\n    -74t\n    -104t\n    -24t\n    33t\n    96t\n    65t\n    -123t\n    35t\n    45t\n    -80t\n    118t\n    76t\n    -80t\n    59t\n    -87t\n    -74t\n    27t\n    -103t\n    -62t\n    121t\n    -35t\n    6t\n    64t\n    -107t\n    17t\n    29t\n    -107t\n    97t\n    44t\n    -35t\n    -112t\n    39t\n    61t\n    -42t\n    41t\n    69t\n    98t\n    98t\n    44t\n    39t\n    62t\n    88t\n    -26t\n    -92t\n    -87t\n    -78t\n    -109t\n    10t\n    -106t\n    -26t\n    -118t\n    -38t\n    -71t\n    91t\n    58t\n    27t\n    -39t\n    109t\n    85t\n    47t\n    122t\n    -74t\n    -35t\n    -5t\n    -121t\n    -43t\n    -20t\n    -40t\n    -83t\n    -53t\n    19t\n    -109t\n    121t\n    -81t\n    -124t\n    8t\n    84t\n    45t\n    60t\n    -5t\n    -85t\n    -23t\n    -9t\n    15t\n    -25t\n    73t\n    39t\n    44t\n    127t\n    7t\n    71t\n    92t\n    116t\n    10t\n    4t\n    -40t\n    -112t\n    52t\n    97t\n    28t\n    -92t\n    72t\n    113t\n    58t\n    -5t\n    40t\n    110t\n    -50t\n    15t\n    -27t\n    -110t\n    -104t\n    -30t\n    -90t\n    61t\n    -1t\n    -70t\n    -88t\n    -22t\n    -41t\n    23t\n    86t\n    93t\n    32t\n    96t\n    30t\n    -14t\n    75t\n    -10t\n    -2t\n    54t\n    90t\n    104t\n    90t\n    77t\n    -122t\n    -35t\n    -6t\n    -119t\n    59t\n    -46t\n    39t\n    65t\n    -21t\n    -27t\n    -121t\n    3t\n    60t\n    102t\n    -2t\n    -40t\n    99t\n    7t\n    -24t\n    -102t\n    101t\n    17t\n    -92t\n    -121t\n    18t\n    84t\n    -111t\n    113t\n    49t\n    -62t\n    -121t\n    7t\n    -18t\n    -117t\n    36t\n    -121t\n    42t\n    43t\n    -72t\n    -55t\n    -12t\n    99t\n    -63t\n    88t\n    69t\n    -41t\n    -39t\n    -9t\n    -4t\n    46t\n    -26t\n    58t\n    -106t\n    -2t\n    -17t\n    -70t\n    -114t\n    -70t\n    40t\n    -86t\n    -108t\n    65t\n    80t\n    -57t\n    -104t\n    -83t\n    38t\n    46t\n    -78t\n    -100t\n    37t\n    116t\n    52t\n    50t\n    4t\n    19t\n    15t\n    61t\n    -111t\n    76t\n    -78t\n    -64t\n    -120t\n    -119t\n    -71t\n    -3t\n    84t\n    32t\n    102t\n    -17t\n    -94t\n    38t\n    -126t\n    96t\n    63t\n    94t\n    -110t\n    98t\n    -100t\n    -63t\n    26t\n    -99t\n    122t\n    -50t\n    13t\n    -23t\n    17t\n    -52t\n    -10t\n    45t\n    39t\n    94t\n    113t\n    122t\n    121t\n    23t\n    62t\n    -39t\n    100t\n    -95t\n    76t\n    123t\n    35t\n    75t\n    111t\n    50t\n    -91t\n    -50t\n    23t\n    101t\n    -120t\n    52t\n    -79t\n    82t\n    3t\n    11t\n    -119t\n    -126t\n    -126t\n    -106t\n    -67t\n    -111t\n    117t\n    -30t\n    6t\n    -16t\n    -9t\n    -74t\n    125t\n    -42t\n    77t\n    -32t\n    7t\n    0t\n    81t\n    88t\n    117t\n    -93t\n    38t\n    43t\n    111t\n    21t\n    3t\n    78t\n    23t\n    -76t\n    -109t\n    48t\n    11t\n    14t\n    -104t\n    20t\n    29t\n    14t\n    82t\n    -35t\n    -113t\n    -83t\n    -115t\n    -39t\n    -91t\n    -118t\n    -95t\n    -25t\n    14t\n    24t\n    51t\n    -89t\n    60t\n    -102t\n    -85t\n    64t\n    -88t\n    9t\n    30t\n    85t\n    21t\n    -30t\n    83t\n    65t\n    40t\n    -54t\n    -33t\n    20t\n    -113t\n    68t\n    -126t\n    -16t\n    110t\n    38t\n    41t\n    8t\n    -45t\n    -11t\n    31t\n    71t\n    -99t\n    16t\n    110t\n    -118t\n    -95t\n    -96t\n    -20t\n    91t\n    65t\n    -37t\n    96t\n    11t\n    -38t\n    86t\n    38t\n    122t\n    85t\n    41t\n    -8t\n    -89t\n    121t\n    93t\n    -86t\n    79t\n    -61t\n    -73t\n    -70t\n    -31t\n    73t\n    127t\n    -67t\n    -47t\n    40t\n    122t\n    83t\n    68t\n    39t\n    74t\n    -44t\n    81t\n    -75t\n    -89t\n    -22t\n    -23t\n    10t\n    60t\n    1t\n    -25t\n    80t\n    51t\n    72t\n    9t\n    2t\n    -22t\n    28t\n    6t\n    106t\n    -101t\n    12t\n    -108t\n    71t\n    -52t\n    -35t\n    98t\n    97t\n    73t\n    -108t\n    -49t\n    122t\n    -116t\n    -98t\n    -41t\n    96t\n    22t\n    -57t\n    120t\n    49t\n    76t\n    75t\n    -41t\n    -64t\n    -112t\n    -102t\n    63t\n    38t\n    49t\n    15t\n    29t\n    -39t\n    54t\n    42t\n    27t\n    -36t\n    85t\n    96t\n    88t\n    -53t\n    11t\n    -71t\n    65t\n    120t\n    -58t\n    54t\n    91t\n    -115t\n    -70t\n    -52t\n    -70t\n    61t\n    -24t\n    78t\n    51t\n    122t\n    69t\n    -102t\n    -18t\n    13t\n    -126t\n    -22t\n    60t\n    -41t\n    32t\n    86t\n    -53t\n    87t\n    35t\n    44t\n    -38t\n    -42t\n    -43t\n    -83t\n    107t\n    -64t\n    -98t\n    -49t\n    -63t\n    3t\n    10t\n    45t\n    -53t\n    -87t\n    -55t\n    -121t\n    -118t\n    -12t\n    -53t\n    -55t\n    0t\n    80t\n    2t\n    -109t\n    -23t\n    -17t\n    -40t\n    69t\n    -33t\n    4t\n    -78t\n    114t\n    100t\n    -125t\n    1t\n    109t\n    -28t\n    -117t\n    -34t\n    -72t\n    49t\n    -73t\n    13t\n    -3t\n    63t\n    -43t\n    111t\n    41t\n    123t\n    -70t\n    -28t\n    91t\n    112t\n    116t\n    51t\n    -73t\n    -58t\n    -24t\n    -47t\n    11t\n    -50t\n    62t\n    -85t\n    33t\n    11t\n    122t\n    1t\n    111t\n    -98t\n    -21t\n    59t\n    52t\n    -44t\n    -85t\n    115t\n    -93t\n    -80t\n    125t\n    -96t\n    91t\n    45t\n    -80t\n    -29t\n    79t\n    127t\n    121t\n    93t\n    56t\n    -94t\n    -28t\n    24t\n    -93t\n    -95t\n    -31t\n    -15t\n    -86t\n    -49t\n    -83t\n    -104t\n    100t\n    106t\n    -114t\n    17t\n    -18t\n    12t\n    65t\n    -121t\n    -13t\n    22t\n    -43t\n    -121t\n    -83t\n    57t\n    118t\n    20t\n    -69t\n    67t\n    41t\n    -21t\n    17t\n    -104t\n    -50t\n    -37t\n    -108t\n    3t\n    -3t\n    -82t\n    -106t\n    -18t\n    88t\n    87t\n    36t\n    -56t\n    -6t\n    27t\n    -62t\n    51t\n    22t\n    -105t\n    -41t\n    113t\n    85t\n    -84t\n    -49t\n    39t\n    -68t\n    107t\n    62t\n    49t\n    124t\n    -88t\n    -24t\n    -89t\n    122t\n    67t\n    -31t\n    -8t\n    -41t\n    74t\n    -26t\n    -102t\n    -68t\n    55t\n    35t\n    -90t\n    -51t\n    30t\n    -69t\n    78t\n    -112t\n    -68t\n    -108t\n    -22t\n    71t\n    -19t\n    51t\n    44t\n    -96t\n    -32t\n    -117t\n    33t\n    -45t\n    -66t\n    1t\n    -18t\n    77t\n    50t\n    9t\n    -61t\n    124t\n    118t\n    105t\n    33t\n    8t\n    66t\n    -54t\n    -127t\n    97t\n    115t\n    38t\n    -95t\n    48t\n    100t\n    53t\n    63t\n    -15t\n    -108t\n    20t\n    102t\n    60t\n    -6t\n    114t\n    33t\n    65t\n    -109t\n    -39t\n    -7t\n    -34t\n    87t\n    -62t\n    -127t\n    -12t\n    -37t\n    -115t\n    60t\n    52t\n    97t\n    -46t\n    2t\n    9t\n    -112t\n    -101t\n    125t\n    21t\n    -44t\n    6t\n    87t\n    109t\n    107t\n    -70t\n    -102t\n    -126t\n    -36t\n    53t\n    68t\n    103t\n    -128t\n    14t\n    -70t\n    -43t\n    -80t\n    43t\n    -85t\n    -11t\n    -44t\n    34t\n    30t\n    -51t\n    16t\n    35t\n    96t\n    107t\n    71t\n    -63t\n    -57t\n    -36t\n    92t\n    -92t\n    -110t\n    -47t\n    89t\n    57t\n    -30t\n    115t\n    82t\n    74t\n    42t\n    -50t\n    70t\n    37t\n    -46t\n    -62t\n    125t\n    86t\n    59t\n    69t\n    -123t\n    -48t\n    -55t\n    104t\n    -85t\n    38t\n    -42t\n    103t\n    127t\n    -86t\n    109t\n    -61t\n    121t\n    -103t\n    34t\n    -67t\n    17t\n    -35t\n    114t\n    109t\n    38t\n    -68t\n    -37t\n    83t\n    29t\n    110t\n    126t\n    -46t\n    110t\n    -14t\n    -61t\n    -66t\n    79t\n    -24t\n    -102t\n    124t\n    -64t\n    99t\n    -116t\n    -100t\n    113t\n    77t\n    -21t\n    22t\n    87t\n    24t\n    -8t\n    -50t\n    -16t\n    31t\n    100t\n    -99t\n    -13t\n    -4t\n    -69t\n    77t\n    102t\n    -15t\n    -25t\n    -35t\n    -22t\n    -34t\n    25t\n    59t\n    85t\n    -123t\n    -44t\n    -115t\n    -119t\n    106t\n    39t\n    51t\n    -25t\n    -107t\n    -25t\n    126t\n    5t\n    104t\n    -92t\n    41t\n    -25t\n    -122t\n    -91t\n    19t\n    -7t\n    -16t\n    -56t\n    -119t\n    120t\n    74t\n    -21t\n    59t\n    -112t\n    75t\n    -126t\n    -126t\n    -102t\n    6t\n    -9t\n    113t\n    -35t\n    -48t\n    -79t\n    0t\n    114t\n    126t\n    -82t\n    17t\n    -41t\n    -53t\n    114t\n    84t\n    -124t\n    -10t\n    96t\n    35t\n    -91t\n    -88t\n    -77t\n    99t\n    -123t\n    80t\n    -73t\n    -88t\n    -25t\n    47t\n    11t\n    -1t\n    -20t\n    65t\n    -42t\n    -8t\n    123t\n    -54t\n    -127t\n    -82t\n    -5t\n    1t\n    -35t\n    -8t\n    52t\n    -92t\n    51t\n    -26t\n    121t\n    4t\n    -94t\n    -1t\n    29t\n    60t\n    0t\n    -14t\n    67t\n    25t\n    82t\n    -83t\n    51t\n    65t\n    -59t\n    34t\n    115t\n    -100t\n    102t\n    3t\n    41t\n    23t\n    85t\n    -28t\n    -107t\n    -31t\n    14t\n    -75t\n    99t\n    123t\n    123t\n    113t\n    -23t\n    -125t\n    6t\n    124t\n    -82t\n    83t\n    74t\n    -26t\n    -79t\n    -6t\n    -91t\n    -62t\n    -82t\n    10t\n    82t\n    11t\n    -33t\n    110t\n    125t\n    123t\n    -6t\n    98t\n    50t\n    82t\n    41t\n    -55t\n    -82t\n    -115t\n    93t\n    111t\n    -76t\n    -32t\n    -40t\n    125t\n    -87t\n    -10t\n    94t\n    18t\n    82t\n    -54t\n    50t\n    -35t\n    99t\n    -1t\n    92t\n    -2t\n    118t\n    -101t\n    13t\n    -63t\n    -115t\n    -81t\n    -78t\n    41t\n    -111t\n    -2t\n    48t\n    55t\n    -4t\n    94t\n    56t\n    67t\n    31t\n    -94t\n    46t\n    -2t\n    117t\n    -21t\n    112t\n    -109t\n    -94t\n    -82t\n    -65t\n    41t\n    -95t\n    107t\n    -20t\n    -15t\n    93t\n    -43t\n    127t\n    -24t\n    19t\n    -22t\n    43t\n    -4t\n    64t\n    108t\n    88t\n    103t\n    79t\n    -52t\n    -52t\n    -80t\n    -63t\n    -70t\n    2t\n    -22t\n    -92t\n    -21t\n    30t\n    -105t\n    -22t\n    -13t\n    -18t\n    107t\n    36t\n    -63t\n    3t\n    115t\n    45t\n    -107t\n    -95t\n    -24t\n    112t\n    15t\n    -70t\n    29t\n    68t\n    47t\n    -79t\n    -96t\n    105t\n    -60t\n    101t\n    91t\n    -110t\n    -104t\n    -121t\n    37t\n    103t\n    58t\n    82t\n    -88t\n    73t\n    -13t\n    -112t\n    -101t\n    -108t\n    -69t\n    38t\n    -113t\n    18t\n    -85t\n    -72t\n    44t\n    99t\n    118t\n    -58t\n    -101t\n    55t\n    121t\n    0t\n    -73t\n    -58t\n    112t\n    19t\n    47t\n    66t\n    -58t\n    -101t\n    -105t\n    -3t\n    58t\n    35t\n    -92t\n    -33t\n    -25t\n    -45t\n    52t\n    -44t\n    98t\n    -86t\n    -100t\n    92t\n    -90t\n    31t\n    125t\n    42t\n    -58t\n    -39t\n    70t\n    -113t\n    121t\n    -99t\n    -60t\n    40t\n    -53t\n    -83t\n    44t\n    17t\n    -8t\n    -66t\n    -101t\n    -77t\n    22t\n    -21t\n    23t\n    117t\n    83t\n    105t\n    -81t\n    4t\n    6t\n    31t\n    -97t\n    61t\n    -82t\n    29t\n    60t\n    -64t\n    21t\n    -5t\n    47t\n    -82t\n    68t\n    64t\n    -16t\n    -120t\n    -69t\n    -121t\n    -9t\n    -11t\n    -14t\n    -65t\n    -64t\n    18t\n    -112t\n    -51t\n    -32t\n    120t\n    -82t\n    41t\n    51t\n    69t\n    3t\n    -73t\n    9t\n    -71t\n    103t\n    -84t\n    46t\n    -121t\n    -97t\n    -16t\n    33t\n    -85t\n    -3t\n    -79t\n    -106t\n    -116t\n    5t\n    97t\n    -62t\n    85t\n    49t\n    18t\n    -22t\n    -22t\n    -82t\n    76t\n    104t\n    83t\n    6t\n    118t\n    117t\n    -3t\n    -111t\n    -54t\n    -47t\n    -24t\n    -28t\n    105t\n    118t\n    -127t\n    -48t\n    11t\n    39t\n    44t\n    -122t\n    -26t\n    39t\n    28t\n    23t\n    -54t\n    -62t\n    16t\n    -85t\n    -109t\n    48t\n    38t\n    -42t\n    100t\n    -64t\n    -66t\n    -84t\n    -102t\n    -104t\n    -36t\n    -46t\n    29t\n    -38t\n    -37t\n    27t\n    84t\n    74t\n    77t\n    -1t\n    -74t\n    -116t\n    48t\n    -6t\n    -58t\n    80t\n    -107t\n    -22t\n    84t\n    112t\n    104t\n    -43t\n    54t\n    -2t\n    32t\n    -117t\n    -77t\n    -98t\n    63t\n    74t\n    -10t\n    116t\n    64t\n    103t\n    40t\n    -69t\n    3t\n    34t\n    80t\n    93t\n    -86t\n    28t\n    98t\n    86t\n    -38t\n    86t\n    40t\n    41t\n    -126t\n    75t\n    -14t\n    -89t\n    83t\n    -102t\n    29t\n    23t\n    107t\n    25t\n    -49t\n    -76t\n    6t\n    -94t\n    42t\n    -82t\n    92t\n    49t\n    19t\n    -62t\n    18t\n    -106t\n    80t\n    -68t\n    70t\n    -92t\n    -13t\n    8t\n    125t\n    115t\n    62t\n    -63t\n    -16t\n    -17t\n    1t\n    -49t\n    -69t\n    119t\n    104t\n    -113t\n    -35t\n    -57t\n    17t\n    3t\n    -94t\n    -118t\n    20t\n    -7t\n    36t\n    -6t\n    -55t\n    76t\n    38t\n    85t\n    89t\n    66t\n    -59t\n    -38t\n    70t\n    -82t\n    -10t\n    -4t\n    -12t\n    20t\n    -24t\n    -57t\n    -86t\n    119t\n    -87t\n    -3t\n    31t\n    94t\n    49t\n    39t\n    -104t\n    -70t\n    62t\n    -63t\n    127t\n    111t\n    97t\n    -15t\n    105t\n    -38t\n    120t\n    -102t\n    101t\n    -35t\n    -24t\n    -102t\n    46t\n    56t\n    96t\n    79t\n    -78t\n    -115t\n    -68t\n    -52t\n    84t\n    35t\n    107t\n    124t\n    8t\n    -114t\n    -14t\n    -33t\n    -102t\n    -91t\n    63t\n    117t\n    56t\n    80t\n    -110t\n    -115t\n    25t\n    12t\n    91t\n    85t\n    -68t\n    -86t\n    -97t\n    1t\n    13t\n    -38t\n    44t\n    -12t\n    102t\n    109t\n    -24t\n    38t\n    74t\n    -102t\n    -127t\n    85t\n    26t\n    51t\n    17t\n    111t\n    109t\n    -46t\n    113t\n    -99t\n    106t\n    44t\n    39t\n    -1t\n    86t\n    -32t\n    96t\n    -37t\n    49t\n    -36t\n    -104t\n    -106t\n    95t\n    118t\n    23t\n    111t\n    -126t\n    91t\n    -62t\n    19t\n    -36t\n    66t\n    -22t\n    -36t\n    76t\n    79t\n    -34t\n    -101t\n    -38t\n    -59t\n    -107t\n    -87t\n    21t\n    -61t\n    27t\n    17t\n    -51t\n    101t\n    54t\n    0t\n    5t\n    -31t\n    -2t\n    43t\n    -83t\n    -4t\n    52t\n    34t\n    58t\n    19t\n    121t\n    31t\n    -42t\n    114t\n    19t\n    106t\n    89t\n    -106t\n    -9t\n    5t\n    -65t\n    93t\n    14t\n    -29t\n    -12t\n    119t\n    9t\n    -76t\n    126t\n    15t\n    15t\n    1t\n    70t\n    -113t\n    55t\n    -57t\n    66t\n    -43t\n    -34t\n    -80t\n    -4t\n    -87t\n    80t\n    6t\n    46t\n    -20t\n    33t\n    49t\n    -57t\n    21t\n    105t\n    -45t\n    71t\n    1t\n    57t\n    112t\n    107t\n    85t\n    121t\n    100t\n    44t\n    -99t\n    108t\n    123t\n    59t\n    -23t\n    -95t\n    -126t\n    -101t\n    -51t\n    -115t\n    115t\n    11t\n    -5t\n    24t\n    88t\n    -38t\n    -120t\n    -87t\n    24t\n    61t\n    46t\n    28t\n    -57t\n    42t\n    -15t\n    -11t\n    104t\n    -60t\n    -42t\n    85t\n    122t\n    0t\n    120t\n    26t\n    -74t\n    -105t\n    57t\n    28t\n    -55t\n    50t\n    -107t\n    54t\n    60t\n    -83t\n    -67t\n    30t\n    0t\n    -128t\n    52t\n    37t\n    65t\n    6t\n    15t\n    31t\n    -106t\n    106t\n    39t\n    -11t\n    69t\n    -30t\n    124t\n    -19t\n    56t\n    -29t\n    71t\n    -34t\n    83t\n    -76t\n    -23t\n    -71t\n    102t\n    -32t\n    -25t\n    64t\n    -122t\n    -47t\n    -112t\n    100t\n    102t\n    -126t\n    -82t\n    116t\n    96t\n    -25t\n    -55t\n    96t\n    -100t\n    -103t\n    -108t\n    -30t\n    -100t\n    -107t\n    -89t\n    -117t\n    -20t\n    -124t\n    -26t\n    -98t\n    127t\n    118t\n    -95t\n    48t\n    -26t\n    93t\n    72t\n    107t\n    10t\n    14t\n    8t\n    -34t\n    -124t\n    -52t\n    -9t\n    -109t\n    6t\n    23t\n    24t\n    -42t\n    73t\n    18t\n    -97t\n    -107t\n    70t\n    -50t\n    -113t\n    -52t\n    97t\n    9t\n    46t\n    -21t\n    89t\n    -119t\n    66t\n    -28t\n    1t\n    -58t\n    31t\n    -50t\n    97t\n    -49t\n    -5t\n    -108t\n    -62t\n    73t\n    23t\n    75t\n    28t\n    11t\n    -83t\n    29t\n    96t\n    -5t\n    121t\n    -125t\n    -34t\n    2t\n    -24t\n    -100t\n    -68t\n    -4t\n    117t\n    30t\n    126t\n    -54t\n    -121t\n    34t\n    19t\n    -107t\n    -81t\n    -66t\n    27t\n    27t\n    -103t\n    -109t\n    28t\n    -103t\n    70t\n    -60t\n    -87t\n    53t\n    -30t\n    121t\n    -96t\n    16t\n    29t\n    70t\n    1t\n    -122t\n    106t\n    -41t\n    -62t\n    62t\n    -86t\n    -38t\n    -111t\n    63t\n    -17t\n    103t\n    35t\n    39t\n    88t\n    122t\n    115t\n    -61t\n    -95t\n    61t\n    118t\n    -65t\n    86t\n    -116t\n    -122t\n    -17t\n    46t\n    121t\n    -5t\n    -39t\n    -100t\n    49t\n    -103t\n    10t\n    95t\n    28t\n    82t\n    -56t\n    37t\n    -8t\n    -102t\n    -97t\n    -41t\n    86t\n    65t\n    111t\n    63t\n    85t\n    47t\n    -118t\n    -64t\n    77t\n    44t\n    118t\n    -81t\n    -38t\n    110t\n    1t\n    11t\n    117t\n    106t\n    -72t\n    69t\n    51t\n    29t\n    117t\n    -69t\n    55t\n    -55t\n    -42t\n    38t\n    -1t\n    -33t\n    116t\n    111t\n    -67t\n    64t\n    -117t\n    -80t\n    -108t\n    3t\n    -119t\n    8t\n    -6t\n    123t\n    -60t\n    122t\n    -50t\n    95t\n    12t\n    -27t\n    58t\n    8t\n    70t\n    47t\n    52t\n    8t\n    -4t\n    45t\n    43t\n    -35t\n    -24t\n    -48t\n    -48t\n    -76t\n    -106t\n    -80t\n    44t\n    94t\n    105t\n    -75t\n    78t\n    76t\n    -101t\n    97t\n    36t\n    -93t\n    70t\n    -44t\n    41t\n    11t\n    3t\n    76t\n    90t\n    86t\n    -24t\n    -30t\n    112t\n    54t\n    -58t\n    55t\n    52t\n    74t\n    -33t\n    48t\n    -88t\n    61t\n    -22t\n    112t\n    -59t\n    25t\n    -36t\n    -43t\n    83t\n    68t\n    66t\n    90t\n    -128t\n    14t\n    21t\n    30t\n    -57t\n    -81t\n    -126t\n    -97t\n    -70t\n    -57t\n    27t\n    -108t\n    -77t\n    -14t\n    121t\n    37t\n    -17t\n    -89t\n    -91t\n    5t\n    -87t\n    -8t\n    -104t\n    41t\n    55t\n    -29t\n    -87t\n    -105t\n    52t\n    -90t\n    92t\n    8t\n    -61t\n    86t\n    22t\n    -115t\n    19t\n    87t\n    -53t\n    106t\n    -37t\n    -12t\n    -78t\n    -24t\n    -66t\n    -95t\n    -58t\n    108t\n    8t\n    37t\n    -73t\n    83t\n    11t\n    -82t\n    9t\n    -61t\n    -53t\n    -3t\n    101t\n    -80t\n    125t\n    -103t\n    27t\n    -99t\n    88t\n    65t\n    -125t\n    -40t\n    83t\n    108t\n    115t\n    100t\n    23t\n    -98t\n    -125t\n    -18t\n    -8t\n    -119t\n    -92t\n    -127t\n    103t\n    33t\n    -75t\n    90t\n    21t\n    66t\n    -37t\n    -80t\n    60t\n    -59t\n    -63t\n    -15t\n    -29t\n    -6t\n    104t\n    -30t\n    -57t\n    -13t\n    -126t\n    -13t\n    -80t\n    95t\n    73t\n    -57t\n    49t\n    -84t\n    8t\n    74t\n    -9t\n    -76t\n    -7t\n    -35t\n    39t\n    57t\n    97t\n    -32t\n    100t\n    87t\n    125t\n    -110t\n    66t\n    -97t\n    88t\n    16t\n    104t\n    81t\n    6t\n    -82t\n    -111t\n    82t\n    -16t\n    91t\n    -60t\n    29t\n    -57t\n    25t\n    -11t\n    77t\n    58t\n    -78t\n    122t\n    -15t\n    106t\n    84t\n    86t\n    -17t\n    -93t\n    -60t\n    -36t\n    -66t\n    -33t\n    -107t\n    38t\n    72t\n    24t\n    1t\n    3t\n    -44t\n    -75t\n    38t\n    -44t\n    75t\n    10t\n    -58t\n    -46t\n    94t\n    123t\n    61t\n    -17t\n    10t\n    118t\n    -15t\n    125t\n    97t\n    -83t\n    38t\n    107t\n    66t\n    6t\n    111t\n    -17t\n    79t\n    -63t\n    28t\n    28t\n    -120t\n    -109t\n    20t\n    32t\n    -18t\n    15t\n    16t\n    -94t\n    16t\n    51t\n    82t\n    -54t\n    -86t\n    12t\n    104t\n    -59t\n    -96t\n    -25t\n    -35t\n    -69t\n    78t\n    114t\n    79t\n    -92t\n    -58t\n    -5t\n    92t\n    -79t\n    43t\n    -115t\n    25t\n    -66t\n    65t\n    -93t\n    -113t\n    -27t\n    67t\n    99t\n    -43t\n    -66t\n    35t\n    88t\n    11t\n    -5t\n    126t\n    -61t\n    -105t\n    11t\n    30t\n    -73t\n    78t\n    126t\n    77t\n    -29t\n    60t\n    12t\n    65t\n    -84t\n    105t\n    -46t\n    -64t\n    -124t\n    51t\n    5t\n    65t\n    -84t\n    -89t\n    -93t\n    86t\n    72t\n    3t\n    -15t\n    -36t\n    93t\n    -3t\n    32t\n    -57t\n    81t\n    -3t\n    101t\n    -91t\n    -110t\n    -65t\n    -39t\n    -92t\n    90t\n    -31t\n    76t\n    -101t\n    -119t\n    65t\n    102t\n    -122t\n    -62t\n    89t\n    18t\n    -36t\n    -68t\n    78t\n    41t\n    123t\n    -93t\n    119t\n    -75t\n    94t\n    -72t\n    -105t\n    -79t\n    -33t\n    120t\n    -71t\n    -45t\n    -126t\n    -118t\n    -16t\n    62t\n    -119t\n    36t\n    -80t\n    123t\n    37t\n    91t\n    -68t\n    -14t\n    43t\n    99t\n    -66t\n    89t\n    -16t\n    -56t\n    -31t\n    21t\n    -1t\n    -77t\n    -80t\n    -77t\n    -40t\n    74t\n    117t\n    111t\n    -65t\n    -32t\n    -14t\n    -71t\n    -67t\n    -32t\n    117t\n    27t\n    51t\n    -40t\n    -110t\n    -116t\n    -3t\n    -61t\n    -104t\n    63t\n    -43t\n    -103t\n    -58t\n    -80t\n    2t\n    39t\n    35t\n    94t\n    12t\n    -17t\n    103t\n    108t\n    31t\n    114t\n    81t\n    1t\n    -94t\n    120t\n    112t\n    110t\n    -6t\n    -76t\n    -117t\n    84t\n    5t\n    -7t\n    63t\n    -72t\n    2t\n    -79t\n    44t\n    110t\n    -44t\n    93t\n    23t\n    92t\n    -124t\n    -11t\n    -63t\n    -70t\n    -29t\n    74t\n    -34t\n    23t\n    -14t\n    112t\n    79t\n    -123t\n    -66t\n    39t\n    40t\n    38t\n    112t\n    -70t\n    85t\n    -3t\n    -45t\n    -78t\n    84t\n    -115t\n    -107t\n    47t\n    -97t\n    -122t\n    -112t\n    105t\n    -13t\n    38t\n    70t\n    -3t\n    83t\n    -117t\n    6t\n    51t\n    53t\n    26t\n    -113t\n    5t\n    -79t\n    -30t\n    -81t\n    96t\n    -34t\n    106t\n    -110t\n    12t\n    66t\n    -94t\n    41t\n    -101t\n    -43t\n    35t\n    -65t\n    98t\n    32t\n    -12t\n    127t\n    4t\n    -81t\n    -37t\n    -26t\n    -92t\n    -93t\n    123t\n    81t\n    -17t\n    -52t\n    -116t\n    -73t\n    38t\n    115t\n    40t\n    126t\n    -61t\n    33t\n    -29t\n    116t\n    -112t\n    -106t\n    88t\n    -15t\n    -68t\n    -71t\n    -32t\n    -103t\n    -37t\n    38t\n    74t\n    -114t\n    21t\n    3t\n    -48t\n    16t\n    -1t\n    -115t\n    -24t\n    -84t\n    -121t\n    -45t\n    25t\n    11t\n    64t\n    74t\n    101t\n    13t\n    22t\n    36t\n    45t\n    -47t\n    88t\n    -28t\n    105t\n    -32t\n    110t\n    20t\n    -112t\n    35t\n    -93t\n    -26t\n    -67t\n    -121t\n    -71t\n    49t\n    57t\n    -119t\n    -69t\n    -84t\n    19t\n    27t\n    96t\n    122t\n    -48t\n    -40t\n    -34t\n    -122t\n    52t\n    15t\n    32t\n    7t\n    44t\n    66t\n    21t\n    118t\n    -112t\n    -28t\n    89t\n    -73t\n    -88t\n    83t\n    -1t\n    -13t\n    -48t\n    -62t\n    30t\n    -69t\n    -113t\n    -26t\n    -61t\n    -94t\n    48t\n    -70t\n    93t\n    -31t\n    18t\n    -75t\n    114t\n    -128t\n    -9t\n    -112t\n    -70t\n    -57t\n    -2t\n    7t\n    55t\n    97t\n    -40t\n    96t\n    46t\n    -124t\n    -66t\n    95t\n    21t\n    105t\n    115t\n    -25t\n    18t\n    51t\n    37t\n    -54t\n    82t\n    46t\n    63t\n    -125t\n    -64t\n    100t\n    -119t\n    34t\n    57t\n    -14t\n    -113t\n    49t\n    23t\n    59t\n    -67t\n    -81t\n    105t\n    109t\n    125t\n    -77t\n    97t\n    30t\n    -60t\n    68t\n    96t\n    101t\n    -106t\n    13t\n    -122t\n    28t\n    87t\n    -50t\n    123t\n    35t\n    -81t\n    90t\n    49t\n    -38t\n    118t\n    10t\n    126t\n    -2t\n    -94t\n    -114t\n    24t\n    120t\n    -53t\n    83t\n    71t\n    -91t\n    26t\n    -44t\n    -33t\n    125t\n    8t\n    25t\n    -70t\n    -21t\n    -67t\n    -110t\n    -20t\n    21t\n    -102t\n    118t\n    40t\n    9t\n    -67t\n    92t\n    -41t\n    -73t\n    -126t\n    -80t\n    81t\n    20t\n    29t\n    94t\n    76t\n    -79t\n    -75t\n    102t\n    -42t\n    -5t\n    83t\n    59t\n    -56t\n    -104t\n    68t\n    -44t\n    57t\n    27t\n    -115t\n    29t\n    -93t\n    125t\n    111t\n    -77t\n    47t\n    -39t\n    127t\n    -33t\n    -77t\n    40t\n    122t\n    -10t\n    -32t\n    70t\n    -117t\n    -115t\n    -96t\n    121t\n    -64t\n    -32t\n    -13t\n    121t\n    41t\n    37t\n    86t\n    -66t\n    7t\n    92t\n    -124t\n    110t\n    -90t\n    125t\n    -98t\n    -90t\n    115t\n    40t\n    -113t\n    -101t\n    13t\n    -104t\n    -31t\n    -53t\n    -29t\n    -121t\n    118t\n    70t\n    -52t\n    42t\n    -42t\n    126t\n    29t\n    71t\n    -17t\n    -106t\n    82t\n    67t\n    111t\n    -49t\n    -123t\n    -43t\n    -74t\n    89t\n    -97t\n    -92t\n    -47t\n    -62t\n    6t\n    -117t\n    4t\n    63t\n    -7t\n    -73t\n    -66t\n    52t\n    -46t\n    -8t\n    -107t\n    -60t\n    57t\n    -87t\n    92t\n    -92t\n    -53t\n    -94t\n    39t\n    47t\n    8t\n    -48t\n    29t\n    10t\n    -2t\n    126t\n    43t\n    20t\n    -103t\n    14t\n    -42t\n    -40t\n    67t\n    77t\n    6t\n    89t\n    33t\n    58t\n    -126t\n    17t\n    -84t\n    -103t\n    -76t\n    49t\n    80t\n    91t\n    43t\n    -66t\n    -37t\n    -67t\n    85t\n    43t\n    -62t\n    3t\n    -9t\n    115t\n    -53t\n    60t\n    -39t\n    117t\n    -101t\n    -65t\n    -61t\n    111t\n    -7t\n    -78t\n    -120t\n    -21t\n    111t\n    71t\n    7t\n    72t\n    94t\n    116t\n    -70t\n    -77t\n    -78t\n    62t\n    -116t\n    119t\n    63t\n    100t\n    74t\n    56t\n    127t\n    6t\n    73t\n    -57t\n    32t\n    -20t\n    -83t\n    -71t\n    -90t\n    -92t\n    -24t\n    -98t\n    118t\n    -13t\n    45t\n    112t\n    97t\n    -103t\n    -102t\n    1t\n    -69t\n    -74t\n    80t\n    87t\n    120t\n    -87t\n    66t\n    104t\n    43t\n    -65t\n    123t\n    -24t\n    -31t\n    19t\n    92t\n    69t\n    -79t\n    101t\n    32t\n    -32t\n    41t\n    120t\n    77t\n    -36t\n    18t\n    -115t\n    -75t\n    -116t\n    -52t\n    -24t\n    9t\n    -55t\n    -40t\n    67t\n    81t\n    -108t\n    9t\n    38t\n    71t\n    123t\n    1t\n    76t\n    -126t\n    84t\n    14t\n    -17t\n    -53t\n    100t\n    -94t\n    22t\n    -124t\n    -2t\n    -75t\n    51t\n    50t\n    51t\n    125t\n    -54t\n    -22t\n    -26t\n    22t\n    125t\n    74t\n    56t\n    -13t\n    115t\n    -124t\n    -32t\n    14t\n    -46t\n    -116t\n    -76t\n    -109t\n    74t\n    50t\n    -38t\n    -6t\n    -116t\n    21t\n    -4t\n    -95t\n    70t\n    -113t\n    -100t\n    -127t\n    -72t\n    -115t\n    62t\n    26t\n    -89t\n    126t\n    -42t\n    86t\n    -41t\n    3t\n    -108t\n    -75t\n    32t\n    -32t\n    -42t\n    -72t\n    -102t\n    81t\n    -12t\n    92t\n    21t\n    76t\n    -69t\n    48t\n    113t\n    -113t\n    -60t\n    99t\n    -30t\n    25t\n    -77t\n    -117t\n    -49t\n    -12t\n    104t\n    47t\n    3t\n    9t\n    -111t\n    -103t\n    -36t\n    103t\n    10t\n    -19t\n    8t\n    -46t\n    57t\n    -113t\n    117t\n    125t\n    -124t\n    -126t\n    -71t\n    -29t\n    120t\n    -99t\n    -58t\n    -78t\n    123t\n    26t\n    -49t\n    30t\n    -25t\n    -105t\n    5t\n    -115t\n    118t\n    44t\n    -27t\n    47t\n    -37t\n    67t\n    11t\n    -52t\n    -114t\n    -41t\n    94t\n    14t\n    54t\n    -112t\n    49t\n    -30t\n    98t\n    -111t\n    -61t\n    89t\n    106t\n    -61t\n    121t\n    46t\n    71t\n    -52t\n    119t\n    -53t\n    101t\n    -100t\n    72t\n    -35t\n    109t\n    50t\n    68t\n    -39t\n    9t\n    70t\n    -77t\n    -56t\n    -48t\n    -49t\n    -58t\n    74t\n    -127t\n    -94t\n    47t\n    -6t\n    -127t\n    70t\n    117t\n    -41t\n    123t\n    111t\n    18t\n    120t\n    -13t\n    14t\n    80t\n    91t\n    -45t\n    115t\n    -51t\n    7t\n    120t\n    -6t\n    111t\n    38t\n    -42t\n    12t\n    123t\n    -28t\n    99t\n    1t\n    115t\n    -11t\n    5t\n    126t\n    61t\n    105t\n    -22t\n    -117t\n    -1t\n    87t\n    -42t\n    -20t\n    -5t\n    -87t\n    -16t\n    48t\n    -15t\n    18t\n    2t\n    -116t\n    101t\n    120t\n    -64t\n    81t\n    66t\n    94t\n    -18t\n    115t\n    89t\n    -76t\n    116t\n    54t\n    -50t\n    -67t\n    55t\n    9t\n    108t\n    105t\n    24t\n    24t\n    -21t\n    72t\n    86t\n    -11t\n    21t\n    -45t\n    -121t\n    -39t\n    33t\n    29t\n    26t\n    114t\n    123t\n    -107t\n    -87t\n    49t\n    -125t\n    -103t\n    83t\n    -51t\n    -39t\n    -78t\n    67t\n    99t\n    -55t\n    -127t\n    20t\n    53t\n    -76t\n    113t\n    -97t\n    61t\n    -124t\n    91t\n    4t\n    71t\n    -121t\n    -125t\n    66t\n    -97t\n    109t\n    77t\n    20t\n    75t\n    113t\n    -55t\n    -46t\n    100t\n    19t\n    42t\n    -103t\n    -98t\n    121t\n    -87t\n    117t\n    -4t\n    -119t\n    -44t\n    25t\n    -42t\n    15t\n    -113t\n    26t\n    -59t\n    88t\n    -64t\n    -101t\n    -6t\n    11t\n    -75t\n    -59t\n    39t\n    76t\n    -128t\n    -118t\n    -4t\n    123t\n    -118t\n    92t\n    103t\n    30t\n    36t\n    -106t\n    -50t\n    -98t\n    54t\n    37t\n    43t\n    78t\n    -70t\n    12t\n    -122t\n    -101t\n    -46t\n    -82t\n    123t\n    79t\n    -113t\n    19t\n    -81t\n    35t\n    56t\n    -18t\n    0t\n    -118t\n    106t\n    90t\n    126t\n    76t\n    -32t\n    -20t\n    -128t\n    -38t\n    -118t\n    110t\n    -106t\n    18t\n    74t\n    126t\n    -90t\n    -125t\n    87t\n    25t\n    48t\n    -62t\n    -109t\n    -80t\n    31t\n    47t\n    81t\n    73t\n    -71t\n    -36t\n    -85t\n    -86t\n    -44t\n    -83t\n    -80t\n    -7t\n    -73t\n    86t\n    71t\n    -45t\n    -82t\n    -70t\n    87t\n    -7t\n    90t\n    -89t\n    -86t\n    74t\n    51t\n    -41t\n    115t\n    -6t\n    -4t\n    -60t\n    84t\n    -81t\n    79t\n    124t\n    -111t\n    15t\n    -40t\n    -116t\n    -29t\n    47t\n    60t\n    38t\n    16t\n    -83t\n    19t\n    -92t\n    41t\n    114t\n    -62t\n    -104t\n    -108t\n    20t\n    100t\n    -51t\n    23t\n    72t\n    108t\n    -62t\n    62t\n    13t\n    -47t\n    -78t\n    -34t\n    -91t\n    -92t\n    20t\n    -71t\n    -18t\n    37t\n    55t\n    49t\n    15t\n    77t\n    -20t\n    0t\n    14t\n    17t\n    -63t\n    -52t\n    120t\n    124t\n    65t\n    -127t\n    -58t\n    -3t\n    72t\n    -82t\n    -95t\n    24t\n    109t\n    -84t\n    92t\n    -19t\n    101t\n    21t\n    4t\n    -55t\n    14t\n    -46t\n    -58t\n    115t\n    56t\n    -116t\n    68t\n    24t\n    48t\n    -5t\n    55t\n    23t\n    62t\n    -49t\n    -72t\n    20t\n    -86t\n    33t\n    -72t\n    6t\n    89t\n    7t\n    -6t\n    -119t\n    -72t\n    -84t\n    -15t\n    -24t\n    88t\n    -78t\n    -16t\n    112t\n    -38t\n    -84t\n    64t\n    -15t\n    115t\n    -23t\n    31t\n    13t\n    -101t\n    23t\n    -104t\n    -84t\n    126t\n    15t\n    -69t\n    82t\n    -110t\n    -97t\n    -13t\n    -63t\n    67t\n    -52t\n    -99t\n    -126t\n    86t\n    -87t\n    42t\n    -42t\n    -51t\n    20t\n    2t\n    -27t\n    -34t\n    -81t\n    87t\n    -5t\n    71t\n    -66t\n    -9t\n    -41t\n    86t\n    82t\n    -44t\n    106t\n    -1t\n    73t\n    101t\n    -105t\n    -97t\n    -31t\n    72t\n    -84t\n    -103t\n    19t\n    10t\n    -56t\n    6t\n    95t\n    -53t\n    -66t\n    -121t\n    49t\n    1t\n    -41t\n    40t\n    24t\n    101t\n    -83t\n    64t\n    105t\n    63t\n    -51t\n    -39t\n    71t\n    35t\n    -13t\n    -61t\n    43t\n    -51t\n    -94t\n    81t\n    60t\n    34t\n    87t\n    82t\n    -87t\n    123t\n    87t\n    -82t\n    -33t\n    47t\n    -30t\n    -53t\n    -13t\n    -5t\n    22t\n    -36t\n    71t\n    45t\n    7t\n    109t\n    66t\n    74t\n    -125t\n    44t\n    -63t\n    13t\n    -127t\n    85t\n    7t\n    -127t\n    23t\n    -10t\n    18t\n    53t\n    18t\n    102t\n    -8t\n    -39t\n    83t\n    58t\n    79t\n    -33t\n    -47t\n    -95t\n    -78t\n    60t\n    -72t\n    -11t\n    -1t\n    105t\n    -128t\n    -49t\n    86t\n    -58t\n    -110t\n    102t\n    -19t\n    13t\n    -67t\n    95t\n    51t\n    -63t\n    11t\n    -84t\n    83t\n    -24t\n    -10t\n    -17t\n    114t\n    -55t\n    -39t\n    51t\n    -67t\n    58t\n    -39t\n    84t\n    -5t\n    -114t\n    -9t\n    35t\n    -82t\n    -42t\n    74t\n    100t\n    -70t\n    125t\n    -49t\n    24t\n    -82t\n    -114t\n    104t\n    52t\n    -126t\n    25t\n    -58t\n    85t\n    -55t\n    30t\n    107t\n    -52t\n    -126t\n    58t\n    68t\n    124t\n    -102t\n    -14t\n    13t\n    101t\n    27t\n    102t\n    -64t\n    114t\n    -68t\n    -117t\n    124t\n    117t\n    -91t\n    18t\n    110t\n    -90t\n    -103t\n    -112t\n    34t\n    -72t\n    9t\n    86t\n    -101t\n    -61t\n    50t\n    -74t\n    61t\n    36t\n    -79t\n    126t\n    -15t\n    -6t\n    102t\n    -23t\n    -54t\n    -30t\n    67t\n    5t\n    -104t\n    64t\n    49t\n    61t\n    -38t\n    31t\n    -2t\n    -24t\n    14t\n    5t\n    90t\n    51t\n    -69t\n    -107t\n    43t\n    -4t\n    -68t\n    103t\n    59t\n    -103t\n    126t\n    -6t\n    71t\n    -105t\n    49t\n    47t\n    24t\n    75t\n    95t\n    -29t\n    -93t\n    -3t\n    -28t\n    14t\n    87t\n    -71t\n    81t\n    93t\n    -109t\n    78t\n    -20t\n    59t\n    -114t\n    24t\n    -99t\n    -7t\n    115t\n    13t\n    124t\n    30t\n    -34t\n    52t\n    -33t\n    -31t\n    -11t\n    25t\n    -80t\n    -20t\n    -105t\n    -90t\n    13t\n    -54t\n    84t\n    118t\n    -15t\n    -72t\n    -36t\n    -109t\n    -93t\n    -62t\n    -100t\n    66t\n    -112t\n    -6t\n    -62t\n    -77t\n    82t\n    51t\n    23t\n    -59t\n    110t\n    126t\n    -89t\n    -97t\n    6t\n    -66t\n    -61t\n    -92t\n    -58t\n    37t\n    -80t\n    -91t\n    -68t\n    -61t\n    90t\n    -108t\n    20t\n    75t\n    -82t\n    -40t\n    -11t\n    -2t\n    88t\n    27t\n    -2t\n    -118t\n    -116t\n    -112t\n    18t\n    -64t\n    -15t\n    79t\n    89t\n    46t\n    -124t\n    63t\n    97t\n    -116t\n    -114t\n    -103t\n    4t\n    -114t\n    16t\n    -115t\n    -65t\n    96t\n    51t\n    -30t\n    -75t\n    -64t\n    56t\n    -43t\n    48t\n    -63t\n    70t\n    -4t\n    33t\n    114t\n    114t\n    40t\n    -112t\n    -17t\n    -41t\n    11t\n    120t\n    -108t\n    94t\n    -96t\n    -115t\n    67t\n    3t\n    -118t\n    -111t\n    101t\n    81t\n    -36t\n    -6t\n    87t\n    54t\n    26t\n    47t\n    37t\n    116t\n    49t\n    15t\n    96t\n    26t\n    -87t\n    103t\n    -49t\n    -80t\n    -58t\n    65t\n    9t\n    37t\n    86t\n    -118t\n    -54t\n    121t\n    32t\n    7t\n    -103t\n    4t\n    -60t\n    96t\n    -84t\n    71t\n    -35t\n    -18t\n    79t\n    -89t\n    7t\n    -8t\n    -99t\n    -67t\n    94t\n    54t\n    -56t\n    96t\n    -3t\n    103t\n    -24t\n    9t\n    -10t\n    -82t\n    86t\n    86t\n    -6t\n    -23t\n    109t\n    -15t\n    111t\n    105t\n    63t\n    43t\n    -10t\n    -50t\n    112t\n    71t\n    -93t\n    21t\n    30t\n    20t\n    20t\n    72t\n    92t\n    -83t\n    100t\n    -119t\n    45t\n    126t\n    -119t\n    -93t\n    96t\n    -13t\n    -103t\n    -25t\n    -10t\n    -59t\n    -47t\n    8t\n    -13t\n    65t\n    62t\n    -98t\n    -85t\n    109t\n    -123t\n    71t\n    -25t\n    -106t\n    -94t\n    92t\n    -53t\n    -30t\n    -85t\n    -120t\n    68t\n    -1t\n    90t\n    -9t\n    33t\n    85t\n    -112t\n    -55t\n    -68t\n    113t\n    19t\n    119t\n    -12t\n    -107t\n    -52t\n    31t\n    79t\n    -69t\n    -118t\n    -54t\n    125t\n    -62t\n    -52t\n    95t\n    3t\n    120t\n    70t\n    -54t\n    -30t\n    -13t\n    16t\n    -109t\n    -117t\n    44t\n    -54t\n    91t\n    42t\n    -120t\n    56t\n    53t\n    -124t\n    4t\n    43t\n    67t\n    -17t\n    -67t\n    -65t\n    8t\n    16t\n    19t\n    39t\n    15t\n    56t\n    -53t\n    102t\n    34t\n    -42t\n    42t\n    45t\n    123t\n    96t\n    64t\n    -10t\n    -78t\n    -116t\n    -9t\n    -96t\n    110t\n    -63t\n    34t\n    -119t\n    -8t\n    -50t\n    53t\n    54t\n    -26t\n    -63t\n    -105t\n    -11t\n    102t\n    26t\n    118t\n    -90t\n    122t\n    -50t\n    -72t\n    -44t\n    -109t\n    -11t\n    126t\n    -59t\n    -67t\n    105t\n    92t\n    53t\n    118t\n    48t\n    -23t\n    -124t\n    73t\n    -123t\n    33t\n    -116t\n    -53t\n    4t\n    106t\n    -87t\n    -122t\n    78t\n    48t\n    -15t\n    -94t\n    -77t\n    69t\n    -73t\n    -104t\n    -8t\n    -66t\n    75t\n    -117t\n    108t\n    99t\n    51t\n    -68t\n    89t\n    46t\n    -94t\n    -78t\n    -90t\n    40t\n    -58t\n    -95t\n    38t\n    -10t\n    -111t\n    4t\n    -19t\n    -5t\n    79t\n    -24t\n    -3t\n    -119t\n    127t\n    74t\n    -32t\n    103t\n    16t\n    44t\n    87t\n    -83t\n    85t\n    64t\n    -89t\n    16t\n    -113t\n    103t\n    -80t\n    -19t\n    -108t\n    115t\n    -80t\n    84t\n    -128t\n    67t\n    62t\n    -88t\n    -120t\n    -99t\n    11t\n    -113t\n    126t\n    -69t\n    -73t\n    -54t\n    -57t\n    -68t\n    37t\n    -103t\n    58t\n    -38t\n    16t\n    -71t\n    -68t\n    107t\n    -102t\n    63t\n    82t\n    -5t\n    52t\n    109t\n    91t\n    117t\n    105t\n    -41t\n    34t\n    35t\n    86t\n    -93t\n    64t\n    -28t\n    -42t\n    -76t\n    -69t\n    -4t\n    50t\n    10t\n    -60t\n    -14t\n    12t\n    -2t\n    -96t\n    -78t\n    -99t\n    67t\n    -23t\n    -74t\n    -88t\n    -6t\n    84t\n    -41t\n    56t\n    -34t\n    -112t\n    26t\n    127t\n    78t\n    -26t\n    -25t\n    -115t\n    -114t\n    19t\n    -21t\n    44t\n    47t\n    109t\n    -107t\n    39t\n    76t\n    -94t\n    -106t\n    -90t\n    -80t\n    40t\n    109t\n    24t\n    66t\n    103t\n    -36t\n    19t\n    9t\n    7t\n    -86t\n    -63t\n    108t\n    89t\n    -125t\n    93t\n    38t\n    121t\n    -82t\n    58t\n    43t\n    -105t\n    0t\n    11t\n    118t\n    123t\n    -83t\n    38t\n    -62t\n    42t\n    106t\n    -113t\n    -53t\n    -43t\n    93t\n    -70t\n    57t\n    63t\n    -1t\n    -28t\n    2t\n    50t\n    -98t\n    58t\n    -49t\n    55t\n    -29t\n    48t\n    -84t\n    72t\n    -75t\n    38t\n    -91t\n    -90t\n    126t\n    -7t\n    36t\n    -96t\n    40t\n    27t\n    27t\n    16t\n    -115t\n    71t\n    -78t\n    124t\n    -52t\n    106t\n    20t\n    -39t\n    125t\n    116t\n    -88t\n    -65t\n    114t\n    88t\n    -43t\n    5t\n    -3t\n    -96t\n    113t\n    -72t\n    110t\n    59t\n    62t\n    80t\n    26t\n    79t\n    -13t\n    109t\n    -111t\n    52t\n    117t\n    -16t\n    -103t\n    -81t\n    -112t\n    65t\n    33t\n    101t\n    70t\n    -13t\n    90t\n    101t\n    39t\n    29t\n    -8t\n    -111t\n    39t\n    25t\n    96t\n    -84t\n    84t\n    -117t\n    52t\n    -96t\n    10t\n    95t\n    -66t\n    70t\n    65t\n    4t\n    -77t\n    100t\n    109t\n    -120t\n    -17t\n    21t\n    -87t\n    -72t\n    69t\n    -117t\n    51t\n    14t\n    -102t\n    118t\n    -42t\n    -109t\n    -4t\n    -26t\n    11t\n    -68t\n    -88t\n    8t\n    -86t\n    89t\n    44t\n    5t\n    119t\n    -106t\n    46t\n    95t\n    -50t\n    55t\n    94t\n    33t\n    92t\n    121t\n    86t\n    -80t\n    82t\n    85t\n    -30t\n    -33t\n    74t\n    101t\n    4t\n    -31t\n    -116t\n    80t\n    -37t\n    50t\n    -79t\n    -15t\n    -91t\n    -29t\n    -63t\n    112t\n    -1t\n    -54t\n    127t\n    -98t\n    -109t\n    -47t\n    -119t\n    -39t\n    94t\n    -52t\n    29t\n    -61t\n    -49t\n    84t\n    -16t\n    22t\n    -119t\n    -10t\n    80t\n    31t\n    -7t\n    -115t\n    51t\n    -23t\n    93t\n    -105t\n    119t\n    43t\n    -47t\n    92t\n    58t\n    -94t\n    83t\n    -53t\n    -81t\n    -26t\n    94t\n    30t\n    89t\n    -106t\n    -116t\n    82t\n    5t\n    -22t\n    2t\n    -51t\n    84t\n    -81t\n    -118t\n    -81t\n    -51t\n    -10t\n    -115t\n    90t\n    -88t\n    -14t\n    -117t\n    -28t\n    -39t\n    -126t\n    30t\n    47t\n    51t\n    76t\n    -17t\n    -110t\n    -4t\n    -83t\n    77t\n    -31t\n    -12t\n    -62t\n    -27t\n    117t\n    7t\n    13t\n    28t\n    -35t\n    8t\n    30t\n    -101t\n    98t\n    -70t\n    91t\n    -35t\n    40t\n    -28t\n    -128t\n    -104t\n    87t\n    77t\n    62t\n    69t\n    89t\n    -66t\n    -15t\n    -111t\n    -81t\n    -41t\n    79t\n    11t\n    -93t\n    69t\n    125t\n    113t\n    -33t\n    -114t\n    -124t\n    -41t\n    73t\n    38t\n    105t\n    120t\n    -75t\n    -61t\n    -110t\n    -3t\n    77t\n    -51t\n    -28t\n    89t\n    -37t\n    -78t\n    25t\n    -37t\n    26t\n    -49t\n    13t\n    74t\n    -15t\n    -6t\n    -83t\n    -18t\n    82t\n    6t\n    -104t\n    118t\n    -73t\n    -18t\n    -55t\n    17t\n    -75t\n    -74t\n    -39t\n    -49t\n    17t\n    55t\n    8t\n    31t\n    -71t\n    105t\n    111t\n    -98t\n    -109t\n    -24t\n    -12t\n    21t\n    -13t\n    -121t\n    -124t\n    124t\n    -31t\n    -13t\n    49t\n    123t\n    -55t\n    -116t\n    -23t\n    96t\n    13t\n    107t\n    100t\n    -116t\n    72t\n    3t\n    24t\n    23t\n    94t\n    25t\n    -47t\n    -101t\n    -53t\n    -59t\n    25t\n    121t\n    27t\n    -75t\n    79t\n    126t\n    -37t\n    -8t\n    -127t\n    63t\n    20t\n    10t\n    -125t\n    -31t\n    -75t\n    -9t\n    -97t\n    62t\n    97t\n    -97t\n    -58t\n    -67t\n    95t\n    -79t\n    109t\n    16t\n    -24t\n    -6t\n    91t\n    -126t\n    -101t\n    121t\n    -21t\n    22t\n    -2t\n    -51t\n    91t\n    69t\n    61t\n    57t\n    100t\n    16t\n    58t\n    -56t\n    111t\n    70t\n    12t\n    48t\n    49t\n    -105t\n    -26t\n    -82t\n    -79t\n    -96t\n    31t\n    44t\n    74t\n    58t\n    34t\n    -15t\n    16t\n    -93t\n    -81t\n    -126t\n    84t\n    -50t\n    80t\n    -33t\n    -71t\n    -51t\n    27t\n    75t\n    -127t\n    9t\n    62t\n    89t\n    49t\n    121t\n    124t\n    -121t\n    20t\n    -32t\n    73t\n    -92t\n    52t\n    -92t\n    -128t\n    -55t\n    59t\n    8t\n    125t\n    84t\n    -71t\n    28t\n    57t\n    -90t\n    -47t\n    -120t\n    93t\n    20t\n    100t\n    -22t\n    16t\n    78t\n    124t\n    -45t\n    28t\n    5t\n    -44t\n    -5t\n    -25t\n    -42t\n    -65t\n    61t\n    -128t\n    -117t\n    -7t\n    86t\n    77t\n    123t\n    14t\n    -32t\n    89t\n    -101t\n    -85t\n    121t\n    1t\n    56t\n    -49t\n    -35t\n    -94t\n    90t\n    -113t\n    91t\n    116t\n    -105t\n    -95t\n    11t\n    31t\n    -76t\n    -72t\n    78t\n    -1t\n    -49t\n    -48t\n    -124t\n    -53t\n    125t\n    -119t\n    123t\n    -54t\n    92t\n    -13t\n    -75t\n    108t\n    82t\n    -102t\n    115t\n    -46t\n    -7t\n    45t\n    -121t\n    -85t\n    -3t\n    -124t\n    -115t\n    44t\n    46t\n    -94t\n    -113t\n    56t\n    -70t\n    116t\n    77t\n    -67t\n    14t\n    69t\n    -90t\n    25t\n    108t\n    -76t\n    -124t\n    -113t\n    17t\n    62t\n    92t\n    2t\n    -48t\n    -32t\n    -100t\n    -98t\n    -15t\n    -97t\n    63t\n    20t\n    110t\n    100t\n    -1t\n    56t\n    -42t\n    -93t\n    12t\n    15t\n    31t\n    -113t\n    87t\n    112t\n    109t\n    -10t\n    24t\n    126t\n    -54t\n    -29t\n    -35t\n    -101t\n    -19t\n    0t\n    32t\n    -1t\n    10t\n    -105t\n    115t\n    41t\n    20t\n    4t\n    -95t\n    84t\n    90t\n    -13t\n    -70t\n    -75t\n    -115t\n    43t\n    -111t\n    79t\n    -114t\n    80t\n    -65t\n    19t\n    73t\n    -110t\n    -67t\n    7t\n    31t\n    59t\n    43t\n    -22t\n    -37t\n    33t\n    61t\n    28t\n    -2t\n    54t\n    -65t\n    15t\n    -95t\n    -32t\n    125t\n    -26t\n    117t\n    33t\n    9t\n    13t\n    83t\n    -14t\n    -17t\n    -68t\n    30t\n    -82t\n    76t\n    -35t\n    54t\n    -89t\n    -85t\n    -50t\n    24t\n    2t\n    22t\n    -86t\n    24t\n    78t\n    70t\n    42t\n    50t\n    -107t\n    19t\n    98t\n    58t\n    120t\n    51t\n    -49t\n    45t\n    -54t\n    98t\n    17t\n    -86t\n    104t\n    61t\n    82t\n    -77t\n    -40t\n    64t\n    96t\n    -107t\n    -102t\n    105t\n    -31t\n    -13t\n    56t\n    58t\n    24t\n    -5t\n    -125t\n    -124t\n    50t\n    -82t\n    -83t\n    -61t\n    61t\n    101t\n    36t\n    119t\n    -10t\n    94t\n    106t\n    -115t\n    102t\n    -57t\n    44t\n    -59t\n    -80t\n    -107t\n    105t\n    0t\n    109t\n    -91t\n    44t\n    61t\n    67t\n    -30t\n    29t\n    -122t\n    -110t\n    107t\n    -114t\n    -66t\n    112t\n    -34t\n    -128t\n    -11t\n    -52t\n    -62t\n    -93t\n    -127t\n    -117t\n    -1t\n    8t\n    -111t\n    -106t\n    -2t\n    -112t\n    -67t\n    -74t\n    79t\n    120t\n    -126t\n    -17t\n    71t\n    46t\n    -47t\n    -72t\n    -28t\n    116t\n    -75t\n    64t\n    -10t\n    70t\n    -85t\n    81t\n    46t\n    78t\n    116t\n    -102t\n    -76t\n    -82t\n    -11t\n    41t\n    33t\n    -127t\n    127t\n    68t\n    1t\n    -86t\n    50t\n    93t\n    -66t\n    38t\n    39t\n    118t\n    12t\n    -85t\n    -10t\n    43t\n    28t\n    76t\n    -53t\n    -100t\n    103t\n    124t\n    -116t\n    -21t\n    -71t\n    114t\n    24t\n    -92t\n    -55t\n    111t\n    54t\n    113t\n    123t\n    -104t\n    -28t\n    120t\n    68t\n    104t\n    -82t\n    -103t\n    99t\n    -120t\n    -89t\n    50t\n    -82t\n    96t\n    -77t\n    62t\n    41t\n    122t\n    -14t\n    4t\n    -3t\n    -112t\n    56t\n    -46t\n    83t\n    93t\n    16t\n    33t\n    32t\n    -99t\n    -50t\n    59t\n    57t\n    -90t\n    -101t\n    17t\n    24t\n    -57t\n    49t\n    -30t\n    47t\n    39t\n    72t\n    98t\n    -124t\n    95t\n    108t\n    75t\n    52t\n    73t\n    82t\n    95t\n    -72t\n    6t\n    40t\n    -99t\n    33t\n    -81t\n    9t\n    -11t\n    52t\n    -44t\n    -25t\n    107t\n    -31t\n    -75t\n    94t\n    -18t\n    44t\n    -101t\n    0t\n    -25t\n    55t\n    9t\n    -107t\n    -69t\n    -103t\n    29t\n    -4t\n    -124t\n    -43t\n    52t\n    21t\n    -86t\n    -48t\n    39t\n    -109t\n    -117t\n    -66t\n    -51t\n    4t\n    -62t\n    45t\n    -93t\n    20t\n    -126t\n    -17t\n    44t\n    -89t\n    -97t\n    -77t\n    16t\n    -119t\n    127t\n    -59t\n    9t\n    -71t\n    97t\n    -68t\n    33t\n    24t\n    -21t\n    119t\n    16t\n    46t\n    -72t\n    48t\n    -66t\n    -67t\n    116t\n    73t\n    -42t\n    42t\n    -17t\n    -72t\n    -69t\n    49t\n    44t\n    67t\n    114t\n    -100t\n    87t\n    36t\n    66t\n    -103t\n    -32t\n    -62t\n    -34t\n    -99t\n    40t\n    6t\n    51t\n    4t\n    9t\n    -49t\n    -56t\n    -96t\n    -120t\n    -108t\n    -81t\n    -122t\n    104t\n    -104t\n    -26t\n    -119t\n    -35t\n    -88t\n    117t\n    73t\n    -91t\n    37t\n    74t\n    -13t\n    -81t\n    -11t\n    123t\n    29t\n    15t\n    -20t\n    -49t\n    -79t\n    51t\n    -76t\n    -64t\n    -127t\n    -74t\n    -107t\n    56t\n    -119t\n    0t\n    -9t\n    -92t\n    -27t\n    -127t\n    14t\n    -64t\n    -88t\n    -33t\n    35t\n    -63t\n    71t\n    83t\n    83t\n    28t\n    -66t\n    -18t\n    -117t\n    5t\n    -22t\n    93t\n    -122t\n    -59t\n    -49t\n    -42t\n    -54t\n    -48t\n    41t\n    108t\n    92t\n    -43t\n    107t\n    112t\n    -111t\n    34t\n    -39t\n    110t\n    -120t\n    -36t\n    31t\n    -46t\n    69t\n    72t\n    -6t\n    -40t\n    54t\n    -99t\n    59t\n    -25t\n    -54t\n    123t\n    77t\n    44t\n    84t\n    53t\n    4t\n    37t\n    -8t\n    73t\n    45t\n    96t\n    123t\n    94t\n    90t\n    11t\n    85t\n    -89t\n    -94t\n    127t\n    54t\n    96t\n    120t\n    78t\n    -25t\n    -100t\n    -119t\n    48t\n    44t\n    -31t\n    51t\n    -128t\n    78t\n    -82t\n    58t\n    110t\n    -122t\n    87t\n    0t\n    -68t\n    39t\n    -95t\n    76t\n    63t\n    -111t\n    -49t\n    -116t\n    85t\n    -95t\n    121t\n    69t\n    103t\n    -123t\n    56t\n    57t\n    -69t\n    76t\n    -32t\n    -22t\n    -34t\n    -115t\n    -8t\n    -44t\n    -13t\n    8t\n    64t\n    18t\n    -43t\n    66t\n    -7t\n    -75t\n    93t\n    65t\n    10t\n    -78t\n    123t\n    85t\n    32t\n    81t\n    -5t\n    -22t\n    -17t\n    89t\n    -30t\n    85t\n    47t\n    71t\n    69t\n    77t\n    50t\n    -26t\n    34t\n    -28t\n    -47t\n    0t\n    -111t\n    -8t\n    25t\n    99t\n    -94t\n    -55t\n    40t\n    -24t\n    -2t\n    87t\n    -29t\n    -127t\n    67t\n    91t\n    -7t\n    122t\n    68t\n    -70t\n    122t\n    61t\n    40t\n    48t\n    -30t\n    106t\n    84t\n    -90t\n    60t\n    -89t\n    34t\n    -123t\n    49t\n    109t\n    -22t\n    -94t\n    76t\n    73t\n    -49t\n    -117t\n    -58t\n    -56t\n    123t\n    45t\n    36t\n    -85t\n    127t\n    -100t\n    -34t\n    40t\n    45t\n    -21t\n    -10t\n    -80t\n    -121t\n    -63t\n    0t\n    80t\n    28t\n    -106t\n    102t\n    -111t\n    30t\n    75t\n    -119t\n    14t\n    -38t\n    -3t\n    -96t\n    118t\n    68t\n    -83t\n    5t\n    -22t\n    37t\n    -86t\n    -29t\n    1t\n    -91t\n    -24t\n    64t\n    75t\n    -116t\n    -120t\n    -62t\n    23t\n    -34t\n    92t\n    -120t\n    -78t\n    -25t\n    17t\n    98t\n    -97t\n    -48t\n    42t\n    -113t\n    -36t\n    -38t\n    -78t\n    13t\n    56t\n    -50t\n    -2t\n    -81t\n    71t\n    -68t\n    127t\n    -125t\n    43t\n    36t\n    -88t\n    -28t\n    -127t\n    -1t\n    -72t\n    -109t\n    104t\n    55t\n    -97t\n    -92t\n    -79t\n    -41t\n    -56t\n    96t\n    87t\n    -87t\n    110t\n    74t\n    -36t\n    -37t\n    125t\n    28t\n    56t\n    -113t\n    -105t\n    18t\n    -3t\n    -57t\n    84t\n    87t\n    -4t\n    -57t\n    -89t\n    117t\n    6t\n    -119t\n    108t\n    80t\n    12t\n    -122t\n    122t\n    -26t\n    14t\n    -38t\n    71t\n    -30t\n    -52t\n    -11t\n    0t\n    -85t\n    0t\n    -89t\n    124t\n    -50t\n    46t\n    -22t\n    28t\n    114t\n    -109t\n    -57t\n    -117t\n    -5t\n    -32t\n    -27t\n    122t\n    0t\n    -79t\n    38t\n    -58t\n    -6t\n    116t\n    -55t\n    -46t\n    -44t\n    -66t\n    42t\n    -69t\n    -108t\n    -13t\n    -74t\n    121t\n    -44t\n    22t\n    66t\n    29t\n    -55t\n    98t\n    -92t\n    59t\n    -116t\n    -39t\n    -115t\n    -58t\n    89t\n    -78t\n    -102t\n    34t\n    -85t\n    -87t\n    -116t\n    -85t\n    -56t\n    89t\n    51t\n    -84t\n    91t\n    -122t\n    -13t\n    -58t\n    -95t\n    83t\n    75t\n    -125t\n    -106t\n    48t\n    -39t\n    -6t\n    4t\n    4t\n    -103t\n    -32t\n    -33t\n    -51t\n    -48t\n    -76t\n    121t\n    -41t\n    100t\n    -26t\n    97t\n    -125t\n    28t\n    68t\n    92t\n    116t\n    -34t\n    4t\n    75t\n    91t\n    -85t\n    -76t\n    -118t\n    88t\n    -14t\n    -54t\n    -12t\n    77t\n    -10t\n    92t\n    122t\n    -100t\n    89t\n    70t\n    102t\n    -46t\n    -62t\n    -25t\n    118t\n    45t\n    32t\n    -11t\n    78t\n    16t\n    -28t\n    66t\n    -64t\n    44t\n    -52t\n    15t\n    -4t\n    -47t\n    33t\n    -91t\n    114t\n    114t\n    -120t\n    -66t\n    -1t\n    -88t\n    -28t\n    -15t\n    96t\n    -118t\n    45t\n    -86t\n    -98t\n    -107t\n    8t\n    -56t\n    -88t\n    -67t\n    38t\n    -115t\n    -101t\n    -109t\n    -45t\n    -120t\n    -113t\n    110t\n    -109t\n    1t\n    -51t\n    49t\n    80t\n    90t\n    69t\n    -118t\n    113t\n    -101t\n    -30t\n    -89t\n    14t\n    -87t\n    -30t\n    18t\n    14t\n    -37t\n    -109t\n    -121t\n    35t\n    -81t\n    25t\n    -113t\n    -52t\n    -95t\n    -38t\n    -106t\n    -110t\n    -14t\n    -58t\n    -38t\n    -117t\n    72t\n    81t\n    5t\n    74t\n    -81t\n    -57t\n    43t\n    24t\n    -121t\n    112t\n    -55t\n    119t\n    38t\n    -26t\n    92t\n    5t\n    -116t\n    43t\n    59t\n    76t\n    66t\n    -92t\n    19t\n    87t\n    -16t\n    -116t\n    -113t\n    114t\n    79t\n    -56t\n    -2t\n    -86t\n    -121t\n    -77t\n    -57t\n    -12t\n    36t\n    -63t\n    113t\n    -78t\n    -126t\n    4t\n    38t\n    109t\n    -89t\n    99t\n    -25t\n    65t\n    91t\n    -21t\n    25t\n    24t\n    -11t\n    44t\n    44t\n    67t\n    -109t\n    -51t\n    121t\n    -27t\n    100t\n    -74t\n    108t\n    -120t\n    -32t\n    -20t\n    -39t\n    83t\n    -106t\n    96t\n    100t\n    91t\n    -100t\n    0t\n    -85t\n    -7t\n    -64t\n    -110t\n    -16t\n    -50t\n    -43t\n    61t\n    84t\n    16t\n    26t\n    64t\n    -94t\n    110t\n    86t\n    -119t\n    78t\n    98t\n    -108t\n    73t\n    125t\n    -88t\n    -103t\n    48t\n    -42t\n    89t\n    53t\n    -47t\n    -32t\n    70t\n    -93t\n    26t\n    -53t\n    -48t\n    44t\n    -99t\n    -10t\n    96t\n    15t\n    -23t\n    64t\n    -105t\n    -108t\n    76t\n    -71t\n    -27t\n    68t\n    32t\n    2t\n    9t\n    115t\n    98t\n    -60t\n    -102t\n    122t\n    -97t\n    115t\n    90t\n    52t\n    -37t\n    -73t\n    -4t\n    71t\n    113t\n    2t\n    64t\n    -66t\n    101t\n    22t\n    -41t\n    108t\n    20t\n    98t\n    89t\n    -63t\n    106t\n    -69t\n    -116t\n    -44t\n    -118t\n    10t\n    -52t\n    -59t\n    94t\n    -13t\n    13t\n    -100t\n    101t\n    90t\n    53t\n    -80t\n    -68t\n    -94t\n    -107t\n    -67t\n    -8t\n    92t\n    -51t\n    32t\n    68t\n    118t\n    -100t\n    124t\n    -43t\n    -40t\n    87t\n    119t\n    -65t\n    25t\n    -72t\n    -97t\n    -18t\n    -53t\n    12t\n    -41t\n    60t\n    36t\n    -68t\n    -94t\n    44t\n    16t\n    122t\n    58t\n    -114t\n    70t\n    97t\n    -109t\n    -79t\n    -109t\n    -8t\n    2t\n    80t\n    -17t\n    -16t\n    -114t\n    -84t\n    94t\n    34t\n    21t\n    106t\n    -18t\n    110t\n    -78t\n    -70t\n    -123t\n    -64t\n    -51t\n    -44t\n    56t\n    -2t\n    113t\n    9t\n    -16t\n    15t\n    76t\n    -66t\n    43t\n    117t\n    47t\n    -38t\n    33t\n    -84t\n    -4t\n    6t\n    -30t\n    -78t\n    -89t\n    -30t\n    33t\n    -36t\n    25t\n    112t\n    -52t\n    106t\n    -51t\n    54t\n    -58t\n    -126t\n    -75t\n    1t\n    -5t\n    -23t\n    -29t\n    98t\n    -121t\n    -111t\n    113t\n    -106t\n    -105t\n    9t\n    70t\n    34t\n    -115t\n    31t\n    105t\n    -106t\n    -109t\n    70t\n    -25t\n    20t\n    118t\n    -125t\n    112t\n    23t\n    124t\n    27t\n    -83t\n    44t\n    121t\n    42t\n    32t\n    -45t\n    12t\n    -3t\n    1t\n    -19t\n    53t\n    5t\n    -84t\n    31t\n    89t\n    -58t\n    33t\n    56t\n    31t\n    20t\n    35t\n    85t\n    -46t\n    -91t\n    12t\n    64t\n    124t\n    88t\n    -71t\n    -98t\n    96t\n    -82t\n    54t\n    -123t\n    -24t\n    -107t\n    66t\n    29t\n    -77t\n    -111t\n    42t\n    65t\n    -67t\n    22t\n    110t\n    -41t\n    3t\n    -70t\n    -101t\n    99t\n    24t\n    -126t\n    -26t\n    46t\n    31t\n    70t\n    -86t\n    76t\n    -60t\n    -96t\n    37t\n    -44t\n    68t\n    27t\n    -1t\n    30t\n    100t\n    30t\n    -30t\n    -62t\n    -127t\n    12t\n    58t\n    -112t\n    39t\n    -50t\n    42t\n    115t\n    -28t\n    13t\n    -47t\n    -56t\n    87t\n    -112t\n    -69t\n    -122t\n    -100t\n    -88t\n    86t\n    55t\n    30t\n    -22t\n    44t\n    37t\n    87t\n    -38t\n    -99t\n    118t\n    -55t\n    97t\n    118t\n    116t\n    -51t\n    -11t\n    -15t\n    -108t\n    -30t\n    43t\n    39t\n    68t\n    -99t\n    87t\n    -103t\n    22t\n    37t\n    25t\n    -70t\n    91t\n    -100t\n    -18t\n    -93t\n    -25t\n    103t\n    -123t\n    91t\n    -67t\n    102t\n    -86t\n    -3t\n    110t\n    32t\n    -55t\n    -40t\n    61t\n    3t\n    -79t\n    113t\n    69t\n    -63t\n    -92t\n    125t\n    -56t\n    -128t\n    74t\n    95t\n    -22t\n    -108t\n    124t\n    -49t\n    -49t\n    -92t\n    -33t\n    66t\n    -7t\n    12t\n    -46t\n    87t\n    -62t\n    -83t\n    6t\n    51t\n    45t\n    -2t\n    -91t\n    -43t\n    -100t\n    -67t\n    0t\n    -14t\n    -74t\n    -98t\n    -118t\n    -60t\n    2t\n    71t\n    5t\n    -76t\n    -67t\n    -55t\n    114t\n    -40t\n    113t\n    -46t\n    -60t\n    69t\n    -46t\n    -120t\n    -9t\n    95t\n    82t\n    -99t\n    106t\n    44t\n    30t\n    101t\n    115t\n    90t\n    -15t\n    22t\n    -53t\n    -81t\n    -126t\n    -127t\n    112t\n    114t\n    43t\n    110t\n    53t\n    78t\n    -54t\n    -39t\n    -1t\n    68t\n    -83t\n    76t\n    -30t\n    11t\n    24t\n    -35t\n    10t\n    105t\n    -1t\n    -111t\n    101t\n    41t\n    -1t\n    -87t\n    -4t\n    -33t\n    25t\n    -12t\n    -52t\n    100t\n    21t\n    -17t\n    -53t\n    -57t\n    41t\n    93t\n    -64t\n    1t\n    110t\n    8t\n    118t\n    48t\n    -125t\n    -20t\n    112t\n    44t\n    105t\n    -23t\n    -30t\n    97t\n    -103t\n    -105t\n    110t\n    12t\n    -86t\n    -61t\n    -23t\n    -115t\n    50t\n    -126t\n    -42t\n    -18t\n    -21t\n    127t\n    91t\n    -46t\n    50t\n    48t\n    45t\n    -66t\n    105t\n    37t\n    26t\n    82t\n    -26t\n    27t\n    -87t\n    -120t\n    -69t\n    -28t\n    -63t\n    -85t\n    -107t\n    -53t\n    120t\n    -39t\n    -6t\n    95t\n    24t\n    -42t\n    -17t\n    -1t\n    48t\n    -100t\n    6t\n    77t\n    121t\n    -121t\n    -117t\n    71t\n    -34t\n    -11t\n    -95t\n    -128t\n    -48t\n    30t\n    13t\n    -15t\n    -100t\n    68t\n    13t\n    -53t\n    -15t\n    97t\n    -21t\n    -83t\n    72t\n    6t\n    -10t\n    -39t\n    120t\n    26t\n    -121t\n    62t\n    6t\n    95t\n    -117t\n    120t\n    -101t\n    -4t\n    -59t\n    74t\n    -111t\n    127t\n    -71t\n    -44t\n    4t\n    118t\n    -86t\n    -82t\n    17t\n    64t\n    13t\n    60t\n    -73t\n    111t\n    45t\n    61t\n    21t\n    -117t\n    -102t\n    -88t\n    101t\n    -52t\n    116t\n    23t\n    -39t\n    39t\n    33t\n    70t\n    46t\n    101t\n    34t\n    -12t\n    33t\n    -51t\n    93t\n    119t\n    94t\n    85t\n    -38t\n    71t\n    -54t\n    25t\n    -111t\n    117t\n    -56t\n    -9t\n    -15t\n    77t\n    108t\n    77t\n    39t\n    -102t\n    113t\n    43t\n    71t\n    -75t\n    -34t\n    61t\n    -109t\n    -20t\n    -90t\n    -122t\n    76t\n    6t\n    5t\n    98t\n    36t\n    25t\n    -113t\n    117t\n    115t\n    -62t\n    -68t\n    30t\n    27t\n    -79t\n    -88t\n    100t\n    94t\n    66t\n    -54t\n    -22t\n    -105t\n    -121t\n    -27t\n    -62t\n    -67t\n    -19t\n    -63t\n    28t\n    -47t\n    75t\n    -56t\n    34t\n    -101t\n    -63t\n    61t\n    -76t\n    -100t\n    -117t\n    46t\n    -119t\n    -16t\n    -35t\n    67t\n    -104t\n    -91t\n    32t\n    -45t\n    117t\n    39t\n    -46t\n    -81t\n    8t\n    -121t\n    114t\n    4t\n    -4t\n    60t\n    -84t\n    -100t\n    -89t\n    97t\n    89t\n    -31t\n    53t\n    48t\n    38t\n    -7t\n    111t\n    -110t\n    28t\n    -13t\n    -104t\n    -124t\n    2t\n    9t\n    122t\n    6t\n    -49t\n    13t\n    19t\n    -72t\n    16t\n    -30t\n    -115t\n    -31t\n    -111t\n    -127t\n    6t\n    55t\n    -87t\n    -98t\n    84t\n    26t\n    6t\n    -96t\n    -91t\n    -128t\n    -72t\n    35t\n    10t\n    12t\n    -16t\n    -91t\n    47t\n    -8t\n    -70t\n    123t\n    6t\n    -62t\n    96t\n    -84t\n    -80t\n    45t\n    13t\n    9t\n    -95t\n    -40t\n    46t\n    62t\n    -7t\n    -65t\n    99t\n    -89t\n    -78t\n    45t\n    -109t\n    101t\n    57t\n    -80t\n    80t\n    67t\n    -75t\n    11t\n    -69t\n    72t\n    -72t\n    -14t\n    111t\n    -55t\n    -22t\n    -117t\n    -82t\n    63t\n    -124t\n    -14t\n    116t\n    53t\n    92t\n    -74t\n    41t\n    35t\n    -4t\n    79t\n    120t\n    -43t\n    -81t\n    -64t\n    76t\n    23t\n    92t\n    62t\n    -28t\n    -47t\n    49t\n    63t\n    -78t\n    106t\n    26t\n    -49t\n    127t\n    -83t\n    69t\n    -105t\n    -112t\n    40t\n    -75t\n    71t\n    -100t\n    -119t\n    6t\n    -70t\n    -61t\n    -115t\n    -35t\n    19t\n    -75t\n    33t\n    71t\n    -19t\n    75t\n    -20t\n    100t\n    57t\n    -11t\n    87t\n    -127t\n    -8t\n    -117t\n    97t\n    12t\n    27t\n    79t\n    -104t\n    -107t\n    -118t\n    -106t\n    -92t\n    22t\n    85t\n    105t\n    -86t\n    -48t\n    103t\n    -23t\n    -120t\n    108t\n    -74t\n    -83t\n    47t\n    -75t\n    100t\n    -117t\n    72t\n    -68t\n    20t\n    93t\n    -28t\n    96t\n    18t\n    -37t\n    60t\n    -95t\n    9t\n    93t\n    102t\n    -103t\n    26t\n    -51t\n    -43t\n    -91t\n    120t\n    107t\n    -113t\n    -126t\n    -52t\n    79t\n    -117t\n    28t\n    -81t\n    96t\n    -52t\n    42t\n    -39t\n    42t\n    68t\n    -47t\n    101t\n    77t\n    33t\n    30t\n    66t\n    53t\n    115t\n    14t\n    13t\n    -98t\n    9t\n    -80t\n    -70t\n    -26t\n    69t\n    -12t\n    72t\n    87t\n    58t\n    43t\n    33t\n    -32t\n    23t\n    -107t\n    -75t\n    -115t\n    114t\n    -102t\n    -120t\n    20t\n    -16t\n    -77t\n    -122t\n    51t\n    83t\n    -43t\n    -33t\n    -17t\n    91t\n    30t\n    -95t\n    -57t\n    -50t\n    -114t\n    94t\n    101t\n    -81t\n    36t\n    80t\n    -76t\n    -7t\n    -116t\n    106t\n    12t\n    15t\n    97t\n    -109t\n    -56t\n    -59t\n    59t\n    -23t\n    40t\n    31t\n    31t\n    -78t\n    -45t\n    38t\n    -125t\n    -116t\n    58t\n    118t\n    -58t\n    3t\n    90t\n    28t\n    -43t\n    35t\n    -104t\n    122t\n    54t\n    47t\n    -74t\n    -41t\n    -11t\n    -40t\n    116t\n    -113t\n    100t\n    63t\n    41t\n    -1t\n    -113t\n    57t\n    -5t\n    -69t\n    60t\n    -59t\n    -125t\n    26t\n    29t\n    -2t\n    40t\n    30t\n    53t\n    -10t\n    37t\n    82t\n    -124t\n    76t\n    -71t\n    -54t\n    20t\n    70t\n    97t\n    -119t\n    96t\n    -70t\n    87t\n    35t\n    -25t\n    23t\n    45t\n    22t\n    -66t\n    -119t\n    80t\n    104t\n    110t\n    -74t\n    -103t\n    -101t\n    6t\n    91t\n    101t\n    -57t\n    -5t\n    51t\n    -107t\n    7t\n    -43t\n    69t\n    -56t\n    -70t\n    103t\n    114t\n    81t\n    8t\n    78t\n    56t\n    -123t\n    -106t\n    -76t\n    -47t\n    119t\n    119t\n    76t\n    32t\n    17t\n    26t\n    126t\n    121t\n    88t\n    -3t\n    111t\n    87t\n    -2t\n    79t\n    18t\n    -80t\n    94t\n    36t\n    68t\n    92t\n    -90t\n    6t\n    -15t\n    4t\n    121t\n    -56t\n    -128t\n    -120t\n    1t\n    -92t\n    -55t\n    -57t\n    -68t\n    88t\n    123t\n    6t\n    123t\n    63t\n    50t\n    115t\n    72t\n    -33t\n    106t\n    -75t\n    -119t\n    76t\n    -111t\n    114t\n    68t\n    27t\n    17t\n    -87t\n    -80t\n    115t\n    -36t\n    115t\n    -4t\n    9t\n    105t\n    28t\n    -119t\n    -45t\n    -66t\n    36t\n    1t\n    -78t\n    -83t\n    -108t\n    -11t\n    -99t\n    -32t\n    -41t\n    12t\n    -89t\n    -89t\n    -128t\n    -104t\n    47t\n    19t\n    -111t\n    -98t\n    -39t\n    -114t\n    -55t\n    58t\n    106t\n    -58t\n    43t\n    48t\n    -34t\n    34t\n    -34t\n    48t\n    -83t\n    -125t\n    77t\n    5t\n    -1t\n    -93t\n    50t\n    47t\n    22t\n    14t\n    -41t\n    -66t\n    27t\n    -107t\n    -65t\n    -43t\n    -100t\n    127t\n    -99t\n    43t\n    -124t\n    15t\n    -25t\n    -104t\n    101t\n    85t\n    -44t\n    117t\n    -37t\n    -117t\n    -32t\n    118t\n    54t\n    96t\n    30t\n    -84t\n    -12t\n    -84t\n    -26t\n    121t\n    67t\n    -27t\n    110t\n    -125t\n    -83t\n    -70t\n    -83t\n    3t\n    -110t\n    -104t\n    -115t\n    110t\n    -16t\n    -10t\n    -18t\n    -126t\n    -124t\n    104t\n    -102t\n    18t\n    -13t\n    32t\n    78t\n    91t\n    -109t\n    -12t\n    9t\n    -116t\n    123t\n    -60t\n    104t\n    -51t\n    -13t\n    -113t\n    -1t\n    26t\n    -20t\n    -11t\n    -69t\n    88t\n    20t\n    42t\n    63t\n    12t\n    -23t\n    -102t\n    110t\n    54t\n    99t\n    -60t\n    -107t\n    -92t\n    59t\n    77t\n    3t\n    -83t\n    110t\n    -46t\n    53t\n    56t\n    -73t\n    83t\n    -6t\n    -66t\n    -2t\n    80t\n    -72t\n    77t\n    -38t\n    -85t\n    -109t\n    -87t\n    81t\n    -42t\n    -88t\n    39t\n    -58t\n    124t\n    -14t\n    -63t\n    30t\n    44t\n    68t\n    32t\n    -114t\n    -25t\n    -110t\n    30t\n    -28t\n    121t\n    43t\n    33t\n    68t\n    80t\n    -35t\n    -35t\n    -112t\n    -115t\n    -123t\n    121t\n    53t\n    2t\n    -52t\n    62t\n    111t\n    -106t\n    25t\n    -93t\n    1t\n    -72t\n    92t\n    -103t\n    -7t\n    53t\n    10t\n    -62t\n    50t\n    119t\n    -100t\n    -94t\n    -41t\n    -46t\n    79t\n    -21t\n    -53t\n    39t\n    67t\n    -61t\n    98t\n    -19t\n    -23t\n    98t\n    45t\n    -4t\n    5t\n    -54t\n    -62t\n    -124t\n    -34t\n    -95t\n    116t\n    -65t\n    51t\n    4t\n    20t\n    100t\n    -73t\n    2t\n    -49t\n    127t\n    -62t\n    106t\n    -26t\n    -108t\n    97t\n    54t\n    -4t\n    122t\n    -12t\n    -59t\n    -89t\n    93t\n    61t\n    -46t\n    -127t\n    18t\n    32t\n    -79t\n    27t\n    -57t\n    -34t\n    -57t\n    43t\n    0t\n    61t\n    -77t\n    1t\n    3t\n    -93t\n    -54t\n    -104t\n    29t\n    -113t\n    104t\n    -17t\n    49t\n    22t\n    22t\n    -7t\n    -127t\n    64t\n    63t\n    36t\n    34t\n    -71t\n    -117t\n    118t\n    97t\n    -77t\n    -23t\n    -66t\n    -13t\n    -82t\n    101t\n    18t\n    25t\n    -76t\n    -122t\n    -74t\n    -52t\n    -17t\n    52t\n    81t\n    -69t\n    -3t\n    125t\n    15t\n    24t\n    -99t\n    -65t\n    91t\n    69t\n    84t\n    94t\n    -64t\n    -31t\n    -31t\n    -57t\n    59t\n    -9t\n    66t\n    106t\n    117t\n    64t\n    -54t\n    -90t\n    -5t\n    64t\n    46t\n    -50t\n    -109t\n    111t\n    -97t\n    14t\n    -52t\n    47t\n    -1t\n    -7t\n    88t\n    -25t\n    21t\n    -54t\n    22t\n    75t\n    -107t\n    64t\n    -6t\n    -76t\n    -45t\n    50t\n    47t\n    77t\n    12t\n    100t\n    31t\n    110t\n    -121t\n    -24t\n    -79t\n    29t\n    87t\n    -77t\n    98t\n    -3t\n    55t\n    -99t\n    -108t\n    118t\n    -27t\n    -1t\n    125t\n    112t\n    -22t\n    -36t\n    72t\n    91t\n    100t\n    57t\n    97t\n    -68t\n    112t\n    62t\n    -86t\n    -8t\n    -26t\n    33t\n    40t\n    -107t\n    22t\n    22t\n    118t\n    1t\n    -6t\n    -58t\n    54t\n    -3t\n    -14t\n    -83t\n    112t\n    85t\n    46t\n    69t\n    67t\n    -65t\n    65t\n    -119t\n    111t\n    -34t\n    -16t\n    -128t\n    59t\n    -44t\n    -28t\n    -99t\n    126t\n    -17t\n    -88t\n    67t\n    -103t\n    -109t\n    -114t\n    17t\n    -62t\n    36t\n    -34t\n    41t\n    49t\n    103t\n    82t\n    73t\n    -76t\n    -47t\n    61t\n    0t\n    78t\n    -45t\n    -110t\n    27t\n    -120t\n    88t\n    -119t\n    9t\n    -44t\n    68t\n    110t\n    1t\n    -88t\n    95t\n    56t\n    86t\n    -19t\n    114t\n    -112t\n    -44t\n    -65t\n    -2t\n    42t\n    -3t\n    -41t\n    -72t\n    -57t\n    80t\n    -9t\n    -19t\n    11t\n    -67t\n    23t\n    -10t\n    20t\n    72t\n    -56t\n    -57t\n    -72t\n    -114t\n    57t\n    88t\n    98t\n    -52t\n    43t\n    -59t\n    5t\n    -75t\n    -101t\n    -116t\n    1t\n    -45t\n    -1t\n    -56t\n    11t\n    -67t\n    1t\n    24t\n    93t\n    -98t\n    -3t\n    55t\n    119t\n    105t\n    82t\n    99t\n    45t\n    23t\n    43t\n    1t\n    24t\n    -50t\n    103t\n    -22t\n    33t\n    76t\n    44t\n    98t\n    62t\n    71t\n    66t\n    -72t\n    -80t\n    -7t\n    53t\n    51t\n    -1t\n    -39t\n    -123t\n    -23t\n    -100t\n    -29t\n    -30t\n    -88t\n    86t\n    96t\n    -17t\n    -9t\n    -126t\n    64t\n    -44t\n    79t\n    63t\n    -89t\n    115t\n    81t\n    120t\n    109t\n    71t\n    -43t\n    16t\n    8t\n    10t\n    -87t\n    61t\n    -124t\n    -102t\n    114t\n    -59t\n    49t\n    -25t\n    11t\n    -112t\n    -106t\n    -11t\n    107t\n    26t\n    111t\n    77t\n    -72t\n    -47t\n    127t\n    -98t\n    -49t\n    -123t\n    76t\n    120t\n    -17t\n    118t\n    -124t\n    -98t\n    -117t\n    -32t\n    45t\n    35t\n    78t\n    46t\n    27t\n    -50t\n    -42t\n    -68t\n    -43t\n    8t\n    -66t\n    56t\n    42t\n    -20t\n    60t\n    52t\n    76t\n    35t\n    85t\n    75t\n    -96t\n    47t\n    18t\n    55t\n    101t\n    9t\n    89t\n    -126t\n    66t\n    11t\n    98t\n    28t\n    -61t\n    -107t\n    120t\n    -74t\n    80t\n    126t\n    87t\n    -4t\n    -60t\n    -97t\n    -84t\n    -13t\n    -119t\n    -52t\n    119t\n    85t\n    96t\n    47t\n    -50t\n    51t\n    86t\n    -35t\n    96t\n    8t\n    6t\n    91t\n    1t\n    -13t\n    45t\n    -94t\n    -59t\n    -98t\n    69t\n    -123t\n    52t\n    47t\n    70t\n    100t\n    -87t\n    -46t\n    114t\n    -107t\n    42t\n    118t\n    22t\n    65t\n    102t\n    28t\n    0t\n    99t\n    -1t\n    36t\n    -95t\n    -28t\n    -76t\n    127t\n    -123t\n    -67t\n    69t\n    -92t\n    4t\n    10t\n    63t\n    84t\n    116t\n    101t\n    61t\n    86t\n    -37t\n    106t\n    45t\n    110t\n    63t\n    -32t\n    -12t\n    -41t\n    14t\n    111t\n    57t\n    -116t\n    -64t\n    91t\n    104t\n    105t\n    -71t\n    -77t\n    -105t\n    85t\n    -65t\n    93t\n    -113t\n    80t\n    -78t\n    -113t\n    16t\n    109t\n    14t\n    44t\n    59t\n    -65t\n    -41t\n    125t\n    -82t\n    -51t\n    -47t\n    35t\n    81t\n    73t\n    120t\n    -44t\n    78t\n    -62t\n    88t\n    -93t\n    25t\n    -72t\n    79t\n    34t\n    -79t\n    -117t\n    96t\n    80t\n    -108t\n    1t\n    8t\n    77t\n    -115t\n    -61t\n    -26t\n    3t\n    64t\n    -30t\n    93t\n    -5t\n    94t\n    -88t\n    124t\n    47t\n    25t\n    -55t\n    112t\n    -112t\n    -8t\n    28t\n    -83t\n    -50t\n    -109t\n    27t\n    -44t\n    -128t\n    -28t\n    -120t\n    78t\n    -6t\n    -111t\n    9t\n    29t\n    -8t\n    74t\n    65t\n    -78t\n    32t\n    58t\n    -108t\n    43t\n    90t\n    -107t\n    -72t\n    124t\n    -117t\n    -55t\n    121t\n    81t\n    115t\n    -95t\n    -121t\n    2t\n    50t\n    -11t\n    -68t\n    -17t\n    79t\n    -53t\n    66t\n    104t\n    16t\n    127t\n    -90t\n    77t\n    69t\n    -52t\n    55t\n    36t\n    40t\n    -25t\n    85t\n    32t\n    86t\n    -39t\n    101t\n    84t\n    -72t\n    92t\n    24t\n    -71t\n    -59t\n    11t\n    103t\n    -72t\n    -123t\n    100t\n    33t\n    -123t\n    -20t\n    48t\n    -44t\n    -113t\n    -77t\n    -104t\n    -18t\n    101t\n    -93t\n    -45t\n    15t\n    58t\n    -19t\n    -91t\n    47t\n    27t\n    43t\n    -4t\n    27t\n    -31t\n    85t\n    -65t\n    -85t\n    50t\n    37t\n    -24t\n    -100t\n    74t\n    23t\n    1t\n    -28t\n    9t\n    -61t\n    -20t\n    22t\n    99t\n    34t\n    93t\n    124t\n    -124t\n    93t\n    60t\n    35t\n    -95t\n    -94t\n    2t\n    -56t\n    -22t\n    -71t\n    14t\n    -94t\n    63t\n    -42t\n    66t\n    30t\n    -16t\n    -32t\n    -125t\n    -73t\n    79t\n    39t\n    68t\n    55t\n    16t\n    4t\n    110t\n    -5t\n    124t\n    -1t\n    20t\n    -107t\n    -98t\n    -28t\n    97t\n    -127t\n    -96t\n    85t\n    -106t\n    -96t\n    -108t\n    -45t\n    110t\n    113t\n    28t\n    67t\n    -26t\n    -117t\n    49t\n    -38t\n    1t\n    2t\n    -102t\n    -95t\n    108t\n    28t\n    -21t\n    115t\n    -37t\n    -49t\n    -36t\n    -93t\n    102t\n    -68t\n    58t\n    -74t\n    115t\n    -46t\n    -117t\n    0t\n    9t\n    -46t\n    33t\n    -28t\n    -103t\n    -25t\n    115t\n    -80t\n    93t\n    -37t\n    -6t\n    57t\n    63t\n    82t\n    85t\n    2t\n    16t\n    85t\n    -26t\n    -30t\n    -67t\n    -28t\n    15t\n    -49t\n    -111t\n    57t\n    122t\n    -63t\n    55t\n    84t\n    -68t\n    43t\n    -14t\n    -29t\n    -44t\n    59t\n    -80t\n    100t\n    -15t\n    -114t\n    29t\n    -100t\n    -62t\n    104t\n    -97t\n    81t\n    119t\n    -49t\n    56t\n    -31t\n    -121t\n    90t\n    3t\n    -128t\n    -27t\n    70t\n    -102t\n    -21t\n    -102t\n    78t\n    -53t\n    14t\n    -117t\n    -7t\n    65t\n    74t\n    -66t\n    21t\n    -91t\n    71t\n    60t\n    13t\n    -66t\n    -74t\n    73t\n    -64t\n    18t\n    -8t\n    -124t\n    -69t\n    109t\n    -118t\n    -49t\n    32t\n    70t\n    -11t\n    -75t\n    84t\n    -10t\n    -119t\n    -97t\n    114t\n    28t\n    45t\n    -14t\n    61t\n    2t\n    -127t\n    -32t\n    39t\n    27t\n    110t\n    72t\n    49t\n    -65t\n    81t\n    -46t\n    -107t\n    55t\n    -119t\n    43t\n    124t\n    2t\n    8t\n    56t\n    121t\n    47t\n    103t\n    -10t\n    90t\n    -109t\n    -55t\n    113t\n    12t\n    3t\n    56t\n    36t\n    112t\n    -93t\n    83t\n    79t\n    -16t\n    -112t\n    -46t\n    83t\n    52t\n    126t\n    106t\n    109t\n    -45t\n    103t\n    -95t\n    21t\n    -13t\n    -125t\n    52t\n    -44t\n    -100t\n    -97t\n    82t\n    26t\n    79t\n    45t\n    124t\n    84t\n    -78t\n    -104t\n    43t\n    61t\n    77t\n    47t\n    57t\n    -53t\n    -99t\n    -70t\n    67t\n    51t\n    34t\n    96t\n    89t\n    -74t\n    8t\n    27t\n    -124t\n    3t\n    98t\n    86t\n    -56t\n    -83t\n    24t\n    -18t\n    -68t\n    14t\n    14t\n    -79t\n    -74t\n    -114t\n    72t\n    109t\n    83t\n    -128t\n    44t\n    -91t\n    31t\n    -113t\n    -3t\n    113t\n    -10t\n    91t\n    -127t\n    74t\n    98t\n    125t\n    96t\n    10t\n    -58t\n    -7t\n    -25t\n    -92t\n    -58t\n    88t\n    70t\n    96t\n    44t\n    87t\n    63t\n    67t\n    -26t\n    117t\n    -57t\n    125t\n    110t\n    15t\n    -121t\n    -64t\n    25t\n    -49t\n    85t\n    -59t\n    53t\n    -84t\n    116t\n    17t\n    83t\n    -88t\n    -41t\n    21t\n    -22t\n    97t\n    8t\n    -7t\n    82t\n    -45t\n    -112t\n    -104t\n    5t\n    -41t\n    39t\n    -53t\n    -54t\n    29t\n    -51t\n    -79t\n    -78t\n    1t\n    61t\n    -18t\n    39t\n    92t\n    116t\n    30t\n    -116t\n    -103t\n    -19t\n    108t\n    1t\n    -59t\n    101t\n    48t\n    65t\n    -37t\n    31t\n    47t\n    115t\n    -17t\n    89t\n    -48t\n    117t\n    -18t\n    -4t\n    86t\n    -7t\n    -111t\n    117t\n    79t\n    -44t\n    -128t\n    42t\n    -27t\n    -40t\n    100t\n    10t\n    14t\n    -92t\n    66t\n    -67t\n    51t\n    -88t\n    -43t\n    -80t\n    64t\n    -19t\n    -81t\n    -78t\n    -46t\n    67t\n    -64t\n    -82t\n    90t\n    -3t\n    74t\n    -15t\n    -5t\n    -54t\n    -128t\n    -95t\n    -8t\n    127t\n    58t\n    -6t\n    -128t\n    7t\n    -102t\n    10t\n    -124t\n    57t\n    -81t\n    -116t\n    50t\n    -116t\n    -52t\n    -7t\n    -106t\n    72t\n    106t\n    -97t\n    -23t\n    -54t\n    -88t\n    0t\n    -104t\n    -60t\n    -43t\n    82t\n    -21t\n    -10t\n    -74t\n    -76t\n    -52t\n    74t\n    95t\n    52t\n    46t\n    4t\n    -108t\n    -73t\n    -127t\n    -127t\n    -57t\n    -52t\n    -90t\n    63t\n    115t\n    59t\n    86t\n    30t\n    -120t\n    -101t\n    -124t\n    71t\n    -44t\n    -118t\n    -69t\n    -4t\n    59t\n    5t\n    73t\n    -109t\n    -90t\n    -127t\n    -45t\n    -88t\n    -47t\n    -75t\n    -41t\n    48t\n    -80t\n    35t\n    -88t\n    71t\n    74t\n    32t\n    81t\n    -30t\n    30t\n    -103t\n    -44t\n    50t\n    3t\n    -25t\n    90t\n    107t\n    68t\n    -111t\n    -98t\n    76t\n    45t\n    -40t\n    65t\n    81t\n    29t\n    -75t\n    -3t\n    18t\n    39t\n    86t\n    -88t\n    111t\n    42t\n    77t\n    4t\n    -30t\n    -117t\n    19t\n    -41t\n    -10t\n    -40t\n    -65t\n    -15t\n    -40t\n    -2t\n    -7t\n    -104t\n    -92t\n    -36t\n    -104t\n    114t\n    115t\n    14t\n    -116t\n    -49t\n    -44t\n    88t\n    20t\n    114t\n    17t\n    48t\n    72t\n    -74t\n    3t\n    -37t\n    101t\n    -49t\n    -108t\n    7t\n    90t\n    119t\n    72t\n    -68t\n    34t\n    31t\n    -55t\n    -14t\n    -9t\n    -21t\n    121t\n    -101t\n    117t\n    -50t\n    4t\n    106t\n    -117t\n    -112t\n    -93t\n    -41t\n    88t\n    30t\n    89t\n    9t\n    -77t\n    -36t\n    -36t\n    -92t\n    -40t\n    -58t\n    125t\n    66t\n    23t\n    -61t\n    -114t\n    -69t\n    -105t\n    17t\n    111t\n    -58t\n    111t\n    73t\n    -86t\n    -13t\n    107t\n    -58t\n    -79t\n    -91t\n    125t\n    -120t\n    -124t\n    -54t\n    112t\n    -99t\n    38t\n    -109t\n    30t\n    -34t\n    -126t\n    -121t\n    -85t\n    105t\n    -37t\n    -115t\n    17t\n    -99t\n    -58t\n    -47t\n    -49t\n    -48t\n    121t\n    56t\n    92t\n    -79t\n    90t\n    110t\n    -20t\n    74t\n    -119t\n    71t\n    -59t\n    -81t\n    103t\n    119t\n    -18t\n    66t\n    117t\n    90t\n    -92t\n    -5t\n    -4t\n    110t\n    -54t\n    -104t\n    -111t\n    -85t\n    -1t\n    54t\n    -102t\n    42t\n    -107t\n    61t\n    60t\n    48t\n    101t\n    -28t\n    39t\n    -76t\n    51t\n    53t\n    111t\n    112t\n    -7t\n    -89t\n    -81t\n    7t\n    -35t\n    122t\n    -24t\n    10t\n    -124t\n    66t\n    -38t\n    117t\n    76t\n    -45t\n    -126t\n    3t\n    -68t\n    121t\n    -70t\n    91t\n    41t\n    -25t\n    61t\n    -62t\n    -82t\n    -47t\n    -5t\n    -95t\n    47t\n    -52t\n    -80t\n    -15t\n    56t\n    -112t\n    -76t\n    -82t\n    72t\n    -13t\n    80t\n    -49t\n    -99t\n    -69t\n    -98t\n    -36t\n    -4t\n    94t\n    78t\n    -60t\n    74t\n    -58t\n    54t\n    -92t\n    -101t\n    34t\n    114t\n    -66t\n    77t\n    43t\n    62t\n    18t\n    28t\n    57t\n    -81t\n    -57t\n    59t\n    12t\n    -26t\n    -20t\n    -30t\n    5t\n    10t\n    122t\n    87t\n    107t\n    21t\n    -102t\n    92t\n    -105t\n    89t\n    12t\n    19t\n    -28t\n    -51t\n    -127t\n    -71t\n    37t\n    -110t\n    -18t\n    112t\n    -90t\n    50t\n    -32t\n    16t\n    103t\n    -3t\n    -19t\n    -46t\n    31t\n    2t\n    73t\n    -86t\n    0t\n    -32t\n    11t\n    -62t\n    116t\n    121t\n    -13t\n    -126t\n    54t\n    96t\n    -74t\n    57t\n    -36t\n    96t\n    50t\n    -103t\n    -33t\n    -23t\n    44t\n    115t\n    -71t\n    60t\n    -84t\n    5t\n    -28t\n    33t\n    -46t\n    4t\n    -70t\n    41t\n    102t\n    112t\n    -115t\n    -66t\n    107t\n    116t\n    76t\n    91t\n    -92t\n    92t\n    15t\n    -62t\n    -55t\n    -125t\n    -75t\n    -119t\n    63t\n    115t\n    -60t\n    -124t\n    8t\n    -6t\n    -100t\n    58t\n    17t\n    9t\n    -118t\n    -87t\n    -104t\n    102t\n    32t\n    91t\n    118t\n    117t\n    110t\n    98t\n    52t\n    44t\n    -44t\n    -111t\n    121t\n    -81t\n    56t\n    -57t\n    26t\n    53t\n    -20t\n    -10t\n    125t\n    -58t\n    -85t\n    -46t\n    -113t\n    73t\n    -108t\n    127t\n    17t\n    6t\n    -6t\n    -54t\n    28t\n    86t\n    90t\n    46t\n    -18t\n    6t\n    -123t\n    25t\n    -80t\n    -89t\n    18t\n    79t\n    -94t\n    55t\n    -20t\n    -98t\n    32t\n    -81t\n    -59t\n    -69t\n    117t\n    -54t\n    -124t\n    32t\n    -62t\n    -30t\n    24t\n    -68t\n    109t\n    -8t\n    -72t\n    65t\n    -103t\n    78t\n    -64t\n    127t\n    -2t\n    -91t\n    -118t\n    66t\n    7t\n    -83t\n    16t\n    66t\n    83t\n    -90t\n    22t\n    -44t\n    -15t\n    0t\n    11t\n    -25t\n    -58t\n    -106t\n    -50t\n    54t\n    -120t\n    40t\n    -85t\n    -76t\n    -51t\n    102t\n    -17t\n    -3t\n    10t\n    -34t\n    62t\n    -28t\n    4t\n    -46t\n    -79t\n    -36t\n    -88t\n    -63t\n    108t\n    -53t\n    102t\n    -63t\n    -46t\n    6t\n    -79t\n    8t\n    -121t\n    121t\n    -91t\n    77t\n    -87t\n    31t\n    -71t\n    55t\n    -106t\n    -125t\n    -103t\n    -61t\n    -116t\n    56t\n    -74t\n    51t\n    106t\n    52t\n    8t\n    82t\n    68t\n    67t\n    -100t\n    -106t\n    -97t\n    -76t\n    -63t\n    -43t\n    -121t\n    80t\n    3t\n    -119t\n    55t\n    -123t\n    -38t\n    76t\n    41t\n    -11t\n    -93t\n    -27t\n    -36t\n    -105t\n    -110t\n    51t\n    71t\n    -54t\n    -40t\n    -125t\n    -35t\n    117t\n    12t\n    -80t\n    -34t\n    -45t\n    51t\n    -31t\n    -103t\n    57t\n    -115t\n    5t\n    -90t\n    54t\n    12t\n    68t\n    22t\n    -45t\n    -25t\n    92t\n    77t\n    -101t\n    43t\n    -62t\n    28t\n    0t\n    5t\n    -111t\n    -123t\n    42t\n    -55t\n    91t\n    108t\n    -99t\n    8t\n    111t\n    110t\n    -89t\n    67t\n    60t\n    -51t\n    -3t\n    -90t\n    116t\n    28t\n    33t\n    71t\n    -82t\n    16t\n    -67t\n    -118t\n    -121t\n    124t\n    64t\n    103t\n    52t\n    -115t\n    57t\n    4t\n    14t\n    -51t\n    57t\n    -19t\n    -49t\n    -42t\n    68t\n    -95t\n    124t\n    79t\n    -15t\n    -87t\n    55t\n    97t\n    -122t\n    -49t\n    -31t\n    86t\n    94t\n    -55t\n    -27t\n    -90t\n    89t\n    -39t\n    15t\n    -73t\n    11t\n    -54t\n    -127t\n    42t\n    68t\n    57t\n    -74t\n    54t\n    71t\n    -53t\n    -89t\n    -107t\n    -2t\n    -126t\n    -65t\n    19t\n    122t\n    105t\n    109t\n    -84t\n    -107t\n    2t\n    123t\n    -39t\n    85t\n    34t\n    -12t\n    -8t\n    -19t\n    -42t\n    75t\n    55t\n    98t\n    -15t\n    46t\n    -31t\n    -87t\n    97t\n    82t\n    7t\n    -125t\n    69t\n    95t\n    31t\n    101t\n    17t\n    -14t\n    114t\n    94t\n    39t\n    7t\n    49t\n    -73t\n    -32t\n    71t\n    82t\n    -2t\n    -5t\n    55t\n    104t\n    -35t\n    12t\n    49t\n    2t\n    -88t\n    -96t\n    -55t\n    -80t\n    -78t\n    34t\n    90t\n    -62t\n    116t\n    70t\n    -71t\n    9t\n    37t\n    27t\n    50t\n    60t\n    17t\n    -73t\n    -10t\n    -111t\n    -20t\n    59t\n    -72t\n    111t\n    -15t\n    108t\n    -124t\n    -118t\n    9t\n    -17t\n    69t\n    -11t\n    -21t\n    49t\n    47t\n    -26t\n    6t\n    -75t\n    118t\n    10t\n    40t\n    23t\n    3t\n    -128t\n    -105t\n    97t\n    -17t\n    67t\n    -6t\n    -81t\n    22t\n    29t\n    -52t\n    -100t\n    -99t\n    -93t\n    48t\n    -66t\n    88t\n    -43t\n    -100t\n    79t\n    36t\n    -121t\n    -42t\n    4t\n    8t\n    44t\n    107t\n    82t\n    -20t\n    46t\n    -77t\n    -40t\n    19t\n    98t\n    -109t\n    55t\n    -13t\n    12t\n    117t\n    -27t\n    -75t\n    15t\n    -72t\n    -98t\n    -48t\n    -107t\n    -108t\n    -121t\n    20t\n    -96t\n    107t\n    -14t\n    -3t\n    -42t\n    -37t\n    -44t\n    -85t\n    126t\n    12t\n    -62t\n    117t\n    -100t\n    -19t\n    80t\n    0t\n    49t\n    -55t\n    -63t\n    -43t\n    -19t\n    39t\n    106t\n    -1t\n    112t\n    -111t\n    -37t\n    -37t\n    -83t\n    -22t\n    -99t\n    -104t\n    74t\n    119t\n    -94t\n    25t\n    117t\n    52t\n    -70t\n    4t\n    -106t\n    -68t\n    99t\n    96t\n    29t\n    -124t\n    119t\n    -13t\n    -117t\n    -113t\n    87t\n    -29t\n    -28t\n    -118t\n    98t\n    -31t\n    73t\n    -14t\n    -79t\n    48t\n    -115t\n    -51t\n    95t\n    -3t\n    53t\n    -25t\n    -54t\n    32t\n    -1t\n    63t\n    8t\n    -119t\n    17t\n    2t\n    -116t\n    -83t\n    -107t\n    -18t\n    75t\n    -54t\n    123t\n    6t\n    -123t\n    90t\n    -38t\n    -35t\n    -12t\n    -2t\n    -128t\n    8t\n    -91t\n    -128t\n    116t\n    55t\n    111t\n    -17t\n    37t\n    89t\n    4t\n    3t\n    -116t\n    -21t\n    -124t\n    -69t\n    -42t\n    120t\n    22t\n    122t\n    30t\n    -45t\n    17t\n    -107t\n    109t\n    20t\n    35t\n    -39t\n    17t\n    -67t\n    -59t\n    123t\n    -103t\n    -52t\n    -43t\n    -36t\n    -33t\n    68t\n    -126t\n    123t\n    -115t\n    -124t\n    39t\n    0t\n    13t\n    109t\n    -126t\n    -24t\n    110t\n    -39t\n    -41t\n    124t\n    124t\n    103t\n    -36t\n    83t\n    111t\n    -14t\n    -20t\n    6t\n    -120t\n    -22t\n    6t\n    90t\n    6t\n    114t\n    20t\n    33t\n    116t\n    -75t\n    19t\n    35t\n    63t\n    127t\n    61t\n    -104t\n    -49t\n    -128t\n    58t\n    9t\n    -28t\n    103t\n    87t\n    121t\n    105t\n    -33t\n    -3t\n    -103t\n    85t\n    50t\n    -90t\n    -120t\n    -16t\n    122t\n    -69t\n    2t\n    -114t\n    -32t\n    -47t\n    76t\n    14t\n    105t\n    75t\n    -43t\n    82t\n    97t\n    96t\n    113t\n    -86t\n    -1t\n    -121t\n    -81t\n    34t\n    24t\n    121t\n    -115t\n    31t\n    -12t\n    93t\n    111t\n    18t\n    77t\n    -29t\n    35t\n    35t\n    127t\n    41t\n    -8t\n    -93t\n    -50t\n    46t\n    -63t\n    28t\n    -119t\n    -124t\n    -24t\n    11t\n    -38t\n    5t\n    115t\n    -1t\n    38t\n    72t\n    -99t\n    30t\n    38t\n    -2t\n    -65t\n    29t\n    -68t\n    10t\n    -68t\n    67t\n    24t\n    -112t\n    124t\n    -102t\n    36t\n    18t\n    61t\n    89t\n    9t\n    115t\n    34t\n    -19t\n    30t\n    -69t\n    14t\n    103t\n    50t\n    -11t\n    37t\n    47t\n    -107t\n    75t\n    -29t\n    -54t\n    107t\n    -112t\n    10t\n    122t\n    105t\n    -118t\n    102t\n    86t\n    97t\n    101t\n    -52t\n    112t\n    115t\n    127t\n    -48t\n    62t\n    70t\n    -12t\n    -117t\n    10t\n    -91t\n    -109t\n    -124t\n    17t\n    -112t\n    32t\n    97t\n    -87t\n    61t\n    110t\n    31t\n    53t\n    -9t\n    45t\n    -48t\n    -72t\n    -26t\n    -86t\n    -120t\n    -10t\n    -124t\n    6t\n    -122t\n    -81t\n    -40t\n    41t\n    94t\n    71t\n    -42t\n    -124t\n    -58t\n    124t\n    115t\n    16t\n    70t\n    68t\n    60t\n    -39t\n    106t\n    -46t\n    -98t\n    43t\n    12t\n    80t\n    77t\n    61t\n    35t\n    -122t\n    52t\n    -48t\n    -32t\n    64t\n    -54t\n    54t\n    48t\n    -84t\n    -53t\n    50t\n    34t\n    -2t\n    -32t\n    107t\n    -112t\n    97t\n    95t\n    -34t\n    79t\n    20t\n    -61t\n    -120t\n    -117t\n    93t\n    -14t\n    109t\n    -90t\n    -71t\n    -66t\n    90t\n    -107t\n    55t\n    -76t\n    118t\n    -114t\n    -55t\n    39t\n    39t\n    -88t\n    37t\n    95t\n    29t\n    92t\n    -68t\n    -10t\n    -123t\n    -21t\n    49t\n    87t\n    -61t\n    -18t\n    23t\n    -66t\n    -34t\n    101t\n    -3t\n    -102t\n    35t\n    -34t\n    -8t\n    39t\n    -88t\n    69t\n    -121t\n    -118t\n    72t\n    -81t\n    -94t\n    111t\n    -120t\n    -47t\n    81t\n    -62t\n    55t\n    -19t\n    -9t\n    126t\n    -36t\n    -29t\n    -85t\n    74t\n    -35t\n    -98t\n    120t\n    -23t\n    26t\n    -35t\n    -95t\n    -9t\n    -74t\n    -116t\n    -45t\n    68t\n    -54t\n    111t\n    98t\n    -116t\n    -79t\n    8t\n    80t\n    -100t\n    -72t\n    -109t\n    80t\n    109t\n    50t\n    -71t\n    -96t\n    -68t\n    15t\n    114t\n    5t\n    124t\n    -77t\n    72t\n    -125t\n    -103t\n    118t\n    -91t\n    70t\n    -21t\n    7t\n    -44t\n    -74t\n    -67t\n    -8t\n    71t\n    63t\n    67t\n    113t\n    -72t\n    -2t\n    -78t\n    -93t\n    -15t\n    123t\n    -3t\n    68t\n    -27t\n    -41t\n    82t\n    -124t\n    98t\n    -22t\n    97t\n    20t\n    -27t\n    -22t\n    89t\n    59t\n    50t\n    -6t\n    -37t\n    9t\n    -2t\n    -1t\n    19t\n    -113t\n    -126t\n    -30t\n    -31t\n    -104t\n    -33t\n    20t\n    -85t\n    -32t\n    -20t\n    18t\n    3t\n    0t\n    -4t\n    50t\n    -52t\n    -95t\n    42t\n    -128t\n    13t\n    46t\n    -93t\n    113t\n    -118t\n    -27t\n    125t\n    -94t\n    -95t\n    106t\n    -37t\n    121t\n    19t\n    93t\n    116t\n    118t\n    -104t\n    109t\n    -92t\n    -93t\n    -102t\n    -113t\n    106t\n    15t\n    -102t\n    44t\n    -46t\n    -31t\n    123t\n    10t\n    23t\n    124t\n    67t\n    -80t\n    31t\n    60t\n    -35t\n    -29t\n    21t\n    -105t\n    28t\n    -62t\n    58t\n    72t\n    30t\n    -91t\n    58t\n    78t\n    78t\n    -22t\n    123t\n    -47t\n    94t\n    15t\n    -70t\n    -75t\n    92t\n    72t\n    -62t\n    -108t\n    -76t\n    0t\n    -93t\n    -15t\n    -103t\n    11t\n    -37t\n    32t\n    -76t\n    53t\n    -89t\n    3t\n    -6t\n    111t\n    1t\n    -62t\n    41t\n    88t\n    29t\n    1t\n    -66t\n    -28t\n    127t\n    -103t\n    91t\n    113t\n    -8t\n    -88t\n    56t\n    85t\n    -105t\n    -31t\n    -4t\n    -50t\n    43t\n    117t\n    86t\n    -96t\n    123t\n    -42t\n    115t\n    64t\n    -53t\n    -98t\n    -16t\n    -79t\n    126t\n    42t\n    114t\n    -98t\n    -104t\n    -124t\n    -20t\n    97t\n    8t\n    -56t\n    29t\n    97t\n    -78t\n    20t\n    -92t\n    73t\n    -100t\n    118t\n    -109t\n    -57t\n    60t\n    -54t\n    -84t\n    -68t\n    -10t\n    -69t\n    -128t\n    -6t\n    -10t\n    41t\n    -78t\n    -37t\n    60t\n    -107t\n    -101t\n    -36t\n    13t\n    82t\n    -97t\n    39t\n    -59t\n    125t\n    106t\n    59t\n    -50t\n    -80t\n    88t\n    -43t\n    29t\n    67t\n    34t\n    21t\n    64t\n    12t\n    41t\n    -105t\n    11t\n    116t\n    -23t\n    35t\n    0t\n    -40t\n    -74t\n    71t\n    15t\n    38t\n    72t\n    -10t\n    -14t\n    57t\n    49t\n    47t\n    119t\n    104t\n    -84t\n    -121t\n    -24t\n    77t\n    -6t\n    47t\n    101t\n    -125t\n    64t\n    46t\n    82t\n    84t\n    -37t\n    -85t\n    96t\n    -100t\n    -32t\n    90t\n    -73t\n    -33t\n    -10t\n    90t\n    -21t\n    -84t\n    98t\n    -82t\n    -24t\n    -102t\n    72t\n    92t\n    29t\n    58t\n    -89t\n    1t\n    -20t\n    -38t\n    122t\n    29t\n    95t\n    60t\n    -74t\n    37t\n    -126t\n    68t\n    89t\n    -58t\n    -110t\n    45t\n    -73t\n    74t\n    98t\n    110t\n    -99t\n    31t\n    -58t\n    49t\n    42t\n    -36t\n    44t\n    78t\n    -82t\n    -112t\n    20t\n    72t\n    -67t\n    -57t\n    -120t\n    41t\n    -38t\n    107t\n    62t\n    16t\n    -27t\n    -80t\n    -86t\n    -23t\n    -14t\n    -99t\n    20t\n    86t\n    -95t\n    68t\n    98t\n    111t\n    65t\n    -67t\n    -21t\n    -48t\n    -96t\n    -18t\n    -106t\n    127t\n    125t\n    -6t\n    -36t\n    -114t\n    -60t\n    97t\n    50t\n    -112t\n    88t\n    -73t\n    103t\n    -58t\n    -62t\n    -100t\n    86t\n    -67t\n    -87t\n    46t\n    -62t\n    101t\n    48t\n    -58t\n    -113t\n    54t\n    -92t\n    -122t\n    80t\n    115t\n    96t\n    111t\n    0t\n    -85t\n    -7t\n    12t\n    99t\n    -2t\n    61t\n    47t\n    -16t\n    49t\n    -63t\n    -35t\n    -68t\n    -11t\n    -55t\n    107t\n    -17t\n    -32t\n    0t\n    -20t\n    -117t\n    -73t\n    -103t\n    18t\n    -73t\n    40t\n    1t\n    111t\n    -117t\n    -77t\n    33t\n    84t\n    53t\n    62t\n    67t\n    80t\n    21t\n    96t\n    -125t\n    78t\n    -112t\n    -20t\n    101t\n    28t\n    6t\n    59t\n    121t\n    40t\n    -83t\n    95t\n    -80t\n    -77t\n    74t\n    9t\n    107t\n    56t\n    -103t\n    127t\n    104t\n    53t\n    104t\n    28t\n    17t\n    79t\n    -115t\n    92t\n    40t\n    -84t\n    -114t\n    -104t\n    -21t\n    -10t\n    -1t\n    -75t\n    80t\n    115t\n    65t\n    23t\n    100t\n    126t\n    79t\n    -38t\n    85t\n    -44t\n    81t\n    -88t\n    22t\n    -90t\n    36t\n    84t\n    8t\n    33t\n    48t\n    -25t\n    -16t\n    -28t\n    64t\n    80t\n    -94t\n    -47t\n    25t\n    113t\n    4t\n    -28t\n    72t\n    16t\n    -47t\n    -75t\n    -23t\n    -44t\n    0t\n    89t\n    -55t\n    -36t\n    37t\n    53t\n    -79t\n    -19t\n    53t\n    118t\n    -9t\n    111t\n    -68t\n    -53t\n    79t\n    -118t\n    14t\n    -47t\n    -9t\n    80t\n    -98t\n    115t\n    -107t\n    6t\n    105t\n    -93t\n    125t\n    15t\n    -74t\n    84t\n    74t\n    115t\n    -115t\n    102t\n    50t\n    -123t\n    9t\n    -24t\n    -17t\n    -2t\n    114t\n    64t\n    92t\n    -67t\n    -12t\n    -50t\n    -52t\n    101t\n    90t\n    82t\n    -98t\n    76t\n    38t\n    -59t\n    -115t\n    23t\n    51t\n    -82t\n    -53t\n    8t\n    -112t\n    -107t\n    -83t\n    -14t\n    -31t\n    25t\n    -65t\n    -29t\n    -78t\n    -110t\n    69t\n    -35t\n    -7t\n    4t\n    -92t\n    -64t\n    65t\n    -39t\n    -64t\n    -78t\n    75t\n    69t\n    -8t\n    -66t\n    -41t\n    -67t\n    -19t\n    86t\n    -91t\n    3t\n    -40t\n    -1t\n    -55t\n    -77t\n    49t\n    -112t\n    25t\n    -102t\n    93t\n    -110t\n    -62t\n    -88t\n    4t\n    27t\n    36t\n    -102t\n    -84t\n    36t\n    59t\n    58t\n    103t\n    76t\n    2t\n    122t\n    65t\n    78t\n    -86t\n    104t\n    -101t\n    58t\n    99t\n    88t\n    -79t\n    80t\n    -66t\n    -115t\n    -116t\n    -48t\n    51t\n    -126t\n    -35t\n    -67t\n    55t\n    -59t\n    114t\n    112t\n    -74t\n    -66t\n    -29t\n    -74t\n    38t\n    -99t\n    59t\n    35t\n    -61t\n    13t\n    40t\n    39t\n    -40t\n    -106t\n    -121t\n    -106t\n    28t\n    -25t\n    -28t\n    -72t\n    26t\n    -85t\n    23t\n    15t\n    102t\n    90t\n    -54t\n    87t\n    -75t\n    109t\n    -19t\n    75t\n    -127t\n    51t\n    126t\n    63t\n    -43t\n    -10t\n    48t\n    -18t\n    25t\n    -71t\n    -14t\n    -80t\n    21t\n    94t\n    -69t\n    -31t\n    116t\n    55t\n    -127t\n    -33t\n    -58t\n    94t\n    41t\n    -68t\n    -80t\n    125t\n    -125t\n    -48t\n    119t\n    44t\n    -100t\n    -122t\n    -105t\n    -70t\n    28t\n    -50t\n    -56t\n    28t\n    -119t\n    58t\n    -77t\n    -87t\n    -59t\n    96t\n    103t\n    -64t\n    96t\n    24t\n    0t\n    -58t\n    -12t\n    122t\n    108t\n    -127t\n    -6t\n    -17t\n    41t\n    -32t\n    -20t\n    67t\n    76t\n    -46t\n    -48t\n    125t\n    3t\n    93t\n    -76t\n    -39t\n    108t\n    88t\n    41t\n    -5t\n    34t\n    -86t\n    -39t\n    -16t\n    59t\n    -45t\n    27t\n    -14t\n    -91t\n    54t\n    -120t\n    -56t\n    72t\n    -86t\n    -76t\n    -90t\n    75t\n    36t\n    16t\n    -89t\n    36t\n    -65t\n    -44t\n    3t\n    67t\n    -10t\n    118t\n    -44t\n    17t\n    30t\n    -106t\n    50t\n    -35t\n    -80t\n    95t\n    2t\n    78t\n    8t\n    -44t\n    82t\n    -28t\n    -82t\n    46t\n    -88t\n    0t\n    -22t\n    -89t\n    -7t\n    73t\n    101t\n    98t\n    -52t\n    103t\n    75t\n    51t\n    -106t\n    126t\n    52t\n    104t\n    -118t\n    -56t\n    -95t\n    -24t\n    -123t\n    55t\n    -127t\n    -41t\n    -51t\n    -60t\n    1t\n    -10t\n    23t\n    -49t\n    -126t\n    -64t\n    45t\n    37t\n    79t\n    58t\n    10t\n    -39t\n    83t\n    -75t\n    -62t\n    -49t\n    101t\n    38t\n    102t\n    66t\n    -109t\n    100t\n    110t\n    49t\n    58t\n    -2t\n    -38t\n    106t\n    25t\n    -91t\n    37t\n    -56t\n    -84t\n    -104t\n    -103t\n    -37t\n    25t\n    46t\n    124t\n    6t\n    -78t\n    -55t\n    67t\n    -68t\n    -15t\n    -2t\n    -61t\n    20t\n    -98t\n    -102t\n    89t\n    -95t\n    67t\n    2t\n    51t\n    -90t\n    -3t\n    -11t\n    59t\n    81t\n    13t\n    -1t\n    -83t\n    -71t\n    -121t\n    -6t\n    89t\n    -82t\n    12t\n    -94t\n    -27t\n    -21t\n    16t\n    62t\n    -118t\n    -38t\n    -68t\n    -55t\n    97t\n    -37t\n    53t\n    -36t\n    60t\n    -104t\n    -49t\n    9t\n    54t\n    -49t\n    65t\n    -6t\n    -12t\n    -30t\n    -65t\n    -3t\n    -27t\n    16t\n    121t\n    -67t\n    4t\n    -122t\n    58t\n    76t\n    -32t\n    -68t\n    85t\n    65t\n    -23t\n    -73t\n    -122t\n    -19t\n    -44t\n    48t\n    124t\n    78t\n    43t\n    -43t\n    4t\n    20t\n    -26t\n    -118t\n    -52t\n    -25t\n    117t\n    24t\n    37t\n    99t\n    101t\n    49t\n    100t\n    -37t\n    -98t\n    58t\n    108t\n    -62t\n    109t\n    -111t\n    100t\n    12t\n    -125t\n    111t\n    -65t\n    -31t\n    94t\n    -19t\n    -7t\n    -102t\n    44t\n    119t\n    47t\n    33t\n    -60t\n    -6t\n    -9t\n    112t\n    -27t\n    -120t\n    46t\n    94t\n    46t\n    58t\n    -17t\n    -38t\n    -105t\n    -41t\n    -6t\n    24t\n    -110t\n    44t\n    29t\n    121t\n    -30t\n    37t\n    -56t\n    -107t\n    -67t\n    77t\n    -3t\n    75t\n    -54t\n    31t\n    -124t\n    -34t\n    81t\n    -60t\n    108t\n    56t\n    32t\n    17t\n    -127t\n    66t\n    -72t\n    -30t\n    -56t\n    -78t\n    54t\n    -13t\n    46t\n    -64t\n    126t\n    84t\n    12t\n    64t\n    -37t\n    28t\n    -57t\n    28t\n    39t\n    89t\n    -72t\n    -115t\n    80t\n    -4t\n    20t\n    -79t\n    67t\n    115t\n    7t\n    50t\n    58t\n    -113t\n    -124t\n    95t\n    60t\n    10t\n    -1t\n    -64t\n    116t\n    102t\n    -69t\n    -125t\n    48t\n    -25t\n    -60t\n    107t\n    -106t\n    -105t\n    -81t\n    -17t\n    -117t\n    114t\n    31t\n    47t\n    -42t\n    83t\n    -26t\n    90t\n    14t\n    64t\n    -53t\n    -115t\n    83t\n    -111t\n    -1t\n    84t\n    98t\n    -116t\n    110t\n    -85t\n    47t\n    -57t\n    85t\n    33t\n    -69t\n    -39t\n    26t\n    108t\n    -32t\n    -50t\n    -127t\n    67t\n    -74t\n    50t\n    -93t\n    -29t\n    75t\n    -108t\n    80t\n    -111t\n    -77t\n    -124t\n    -1t\n    30t\n    93t\n    -20t\n    -89t\n    31t\n    -122t\n    40t\n    -69t\n    -107t\n    23t\n    81t\n    -103t\n    35t\n    -13t\n    -26t\n    44t\n    12t\n    74t\n    52t\n    -68t\n    16t\n    -77t\n    4t\n    89t\n    -52t\n    -85t\n    40t\n    120t\n    69t\n    38t\n    -18t\n    -80t\n    -112t\n    -24t\n    -89t\n    60t\n    -14t\n    33t\n    118t\n    70t\n    -100t\n    123t\n    -116t\n    113t\n    -10t\n    67t\n    81t\n    27t\n    85t\n    80t\n    -124t\n    -27t\n    50t\n    113t\n    83t\n    -113t\n    -92t\n    104t\n    45t\n    70t\n    -4t\n    -85t\n    108t\n    42t\n    -46t\n    -68t\n    28t\n    27t\n    114t\n    77t\n    -18t\n    35t\n    -57t\n    10t\n    -111t\n    84t\n    97t\n    23t\n    67t\n    53t\n    -95t\n    106t\n    101t\n    -106t\n    65t\n    -51t\n    55t\n    -44t\n    101t\n    -100t\n    -62t\n    114t\n    121t\n    -23t\n    91t\n    38t\n    27t\n    -22t\n    118t\n    -4t\n    -12t\n    -109t\n    118t\n    125t\n    13t\n    6t\n    12t\n    65t\n    -43t\n    38t\n    -34t\n    17t\n    -23t\n    -27t\n    0t\n    14t\n    -43t\n    117t\n    76t\n    65t\n    78t\n    -126t\n    82t\n    38t\n    -119t\n    -59t\n    -35t\n    32t\n    86t\n    -48t\n    92t\n    35t\n    37t\n    -20t\n    -87t\n    25t\n    -42t\n    -47t\n    -15t\n    89t\n    19t\n    68t\n    69t\n    58t\n    8t\n    125t\n    -23t\n    -10t\n    -45t\n    -118t\n    -22t\n    -38t\n    85t\n    -12t\n    26t\n    34t\n    -42t\n    93t\n    97t\n    -55t\n    114t\n    -2t\n    -84t\n    -42t\n    -16t\n    115t\n    51t\n    -81t\n    -113t\n    25t\n    71t\n    127t\n    126t\n    -96t\n    -25t\n    -71t\n    -66t\n    37t\n    120t\n    -57t\n    33t\n    -99t\n    96t\n    -108t\n    -104t\n    -114t\n    30t\n    98t\n    -12t\n    91t\n    -89t\n    -39t\n    28t\n    -103t\n    89t\n    -102t\n    44t\n    4t\n    114t\n    -98t\n    57t\n    52t\n    110t\n    -111t\n    91t\n    96t\n    64t\n    99t\n    122t\n    -117t\n    -121t\n    116t\n    -80t\n    55t\n    103t\n    63t\n    85t\n    55t\n    -49t\n    4t\n    83t\n    -86t\n    35t\n    -128t\n    53t\n    -88t\n    6t\n    -87t\n    -22t\n    110t\n    -30t\n    -12t\n    -15t\n    -6t\n    109t\n    -6t\n    -79t\n    104t\n    -3t\n    115t\n    -107t\n    -23t\n    43t\n    -70t\n    89t\n    94t\n    8t\n    -64t\n    -59t\n    61t\n    58t\n    -44t\n    63t\n    71t\n    33t\n    12t\n    12t\n    67t\n    -2t\n    11t\n    -68t\n    87t\n    -68t\n    96t\n    -32t\n    -48t\n    -27t\n    95t\n    -34t\n    95t\n    -34t\n    -44t\n    -71t\n    -94t\n    -83t\n    119t\n    119t\n    92t\n    3t\n    -72t\n    -121t\n    36t\n    116t\n    18t\n    30t\n    104t\n    46t\n    -37t\n    14t\n    -110t\n    74t\n    10t\n    -29t\n    -76t\n    125t\n    -25t\n    -70t\n    -114t\n    31t\n    -76t\n    -121t\n    -52t\n    122t\n    4t\n    19t\n    57t\n    -120t\n    -96t\n    -99t\n    127t\n    -28t\n    -104t\n    13t\n    60t\n    -64t\n    -18t\n    101t\n    -87t\n    -48t\n    61t\n    29t\n    79t\n    56t\n    46t\n    53t\n    -45t\n    93t\n    49t\n    103t\n    -113t\n    16t\n    57t\n    113t\n    -16t\n    -125t\n    69t\n    -3t\n    44t\n    -110t\n    64t\n    -58t\n    79t\n    48t\n    -88t\n    -97t\n    113t\n    8t\n    45t\n    -37t\n    -50t\n    -70t\n    46t\n    -34t\n    93t\n    112t\n    81t\n    69t\n    -47t\n    -58t\n    -93t\n    -23t\n    -102t\n    86t\n    7t\n    9t\n    106t\n    -57t\n    -100t\n    -21t\n    106t\n    94t\n    -121t\n    94t\n    73t\n    109t\n    39t\n    -107t\n    -116t\n    69t\n    -31t\n    109t\n    84t\n    -86t\n    -1t\n    20t\n    -29t\n    19t\n    119t\n    -58t\n    63t\n    55t\n    95t\n    -121t\n    12t\n    103t\n    -76t\n    -106t\n    111t\n    94t\n    44t\n    100t\n    -1t\n    -69t\n    96t\n    -97t\n    -94t\n    11t\n    -37t\n    52t\n    -118t\n    -122t\n    33t\n    101t\n    82t\n    -33t\n    -49t\n    -99t\n    105t\n    -101t\n    92t\n    39t\n    -58t\n    94t\n    93t\n    -74t\n    -108t\n    -1t\n    -112t\n    -44t\n    -28t\n    -6t\n    -127t\n    65t\n    98t\n    -89t\n    90t\n    78t\n    -26t\n    119t\n    19t\n    -17t\n    63t\n    70t\n    -122t\n    -84t\n    49t\n    44t\n    -115t\n    -1t\n    111t\n    -8t\n    92t\n    -4t\n    0t\n    -61t\n    -57t\n    -66t\n    49t\n    94t\n    -23t\n    7t\n    -77t\n    -57t\n    0t\n    60t\n    -74t\n    95t\n    34t\n    4t\n    105t\n    -116t\n    -108t\n    -83t\n    25t\n    67t\n    89t\n    -102t\n    -61t\n    -56t\n    -17t\n    -23t\n    -40t\n    -11t\n    8t\n    14t\n    -51t\n    58t\n    -59t\n    79t\n    58t\n    118t\n    117t\n    -7t\n    -44t\n    103t\n    18t\n    40t\n    -4t\n    79t\n    51t\n    51t\n    -63t\n    110t\n    127t\n    -51t\n    2t\n    -76t\n    75t\n    88t\n    -30t\n    76t\n    -94t\n    53t\n    -43t\n    52t\n    -68t\n    -33t\n    127t\n    -48t\n    64t\n    -26t\n    -127t\n    -85t\n    31t\n    -115t\n    -58t\n    78t\n    94t\n    0t\n    87t\n    95t\n    -117t\n    99t\n    -58t\n    -32t\n    38t\n    -79t\n    39t\n    -14t\n    101t\n    88t\n    -11t\n    -43t\n    113t\n    -73t\n    -56t\n    -120t\n    -4t\n    -85t\n    109t\n    -3t\n    110t\n    8t\n    -5t\n    102t\n    -94t\n    -88t\n    119t\n    71t\n    116t\n    54t\n    73t\n    -11t\n    20t\n    -1t\n    34t\n    121t\n    103t\n    -68t\n    -101t\n    -109t\n    -93t\n    86t\n    43t\n    26t\n    120t\n    -22t\n    -38t\n    -8t\n    -6t\n    -94t\n    -3t\n    73t\n    -56t\n    -30t\n    33t\n    -45t\n    108t\n    39t\n    -61t\n    -72t\n    -91t\n    -117t\n    119t\n    119t\n    115t\n    46t\n    25t\n    86t\n    16t\n    91t\n    112t\n    38t\n    125t\n    60t\n    94t\n    -87t\n    16t\n    -25t\n    40t\n    87t\n    -69t\n    21t\n    -54t\n    103t\n    -2t\n    -92t\n    119t\n    -113t\n    125t\n    -108t\n    20t\n    123t\n    -74t\n    -75t\n    -35t\n    79t\n    -119t\n    89t\n    -1t\n    -61t\n    82t\n    -91t\n    72t\n    -116t\n    -38t\n    17t\n    -102t\n    69t\n    102t\n    -127t\n    -3t\n    -14t\n    -109t\n    82t\n    -106t\n    80t\n    -13t\n    -35t\n    -1t\n    41t\n    66t\n    18t\n    -112t\n    124t\n    66t\n    38t\n    -44t\n    -110t\n    -38t\n    -73t\n    -54t\n    -22t\n    73t\n    91t\n    -56t\n    -28t\n    77t\n    98t\n    -9t\n    -16t\n    -7t\n    -34t\n    -35t\n    83t\n    67t\n    54t\n    9t\n    90t\n    37t\n    -66t\n    93t\n    -112t\n    -93t\n    27t\n    -4t\n    -36t\n    -29t\n    80t\n    28t\n    10t\n    -59t\n    -61t\n    -46t\n    12t\n    0t\n    -70t\n    -62t\n    48t\n    102t\n    25t\n    85t\n    -28t\n    127t\n    14t\n    44t\n    93t\n    51t\n    -14t\n    -16t\n    55t\n    50t\n    -59t\n    -50t\n    -53t\n    -99t\n    -22t\n    -37t\n    124t\n    58t\n    2t\n    124t\n    -27t\n    -2t\n    23t\n    7t\n    98t\n    115t\n    -58t\n    -50t\n    -43t\n    -47t\n    -105t\n    112t\n    -15t\n    -42t\n    -10t\n    -6t\n    19t\n    46t\n    17t\n    22t\n    61t\n    -64t\n    17t\n    -31t\n    102t\n    95t\n    115t\n    113t\n    52t\n    66t\n    25t\n    -54t\n    26t\n    28t\n    111t\n    -48t\n    -85t\n    47t\n    -14t\n    6t\n    -117t\n    60t\n    115t\n    63t\n    -39t\n    -88t\n    -92t\n    8t\n    125t\n    -96t\n    93t\n    -77t\n    -69t\n    63t\n    13t\n    79t\n    71t\n    6t\n    -34t\n    84t\n    -74t\n    -72t\n    9t\n    -24t\n    101t\n    4t\n    -121t\n    -32t\n    47t\n    -62t\n    125t\n    -19t\n    59t\n    52t\n    -26t\n    120t\n    -8t\n    0t\n    96t\n    -49t\n    120t\n    -19t\n    -46t\n    -99t\n    -75t\n    75t\n    -96t\n    -104t\n    -60t\n    -43t\n    85t\n    58t\n    -3t\n    -107t\n    111t\n    -53t\n    17t\n    113t\n    26t\n    23t\n    -32t\n    -25t\n    6t\n    -59t\n    87t\n    -14t\n    -80t\n    93t\n    120t\n    -35t\n    -76t\n    -72t\n    16t\n    -33t\n    105t\n    57t\n    -11t\n    -109t\n    -82t\n    113t\n    -113t\n    36t\n    29t\n    -107t\n    -94t\n    -2t\n    88t\n    -104t\n    100t\n    -75t\n    28t\n    70t\n    -39t\n    -84t\n    -49t\n    68t\n    84t\n    -123t\n    -17t\n    -102t\n    -27t\n    -21t\n    -118t\n    91t\n    -9t\n    117t\n    54t\n    11t\n    29t\n    -99t\n    108t\n    81t\n    106t\n    76t\n    66t\n    -58t\n    -110t\n    -114t\n    44t\n    -88t\n    -21t\n    -121t\n    76t\n    100t\n    13t\n    16t\n    127t\n    -121t\n    -124t\n    92t\n    56t\n    78t\n    55t\n    43t\n    -81t\n    -47t\n    -29t\n    53t\n    -119t\n    -29t\n    94t\n    -13t\n    -94t\n    -9t\n    -82t\n    106t\n    -109t\n    -74t\n    -24t\n    102t\n    -4t\n    -6t\n    126t\n    -101t\n    -44t\n    37t\n    -4t\n    45t\n    -51t\n    -103t\n    3t\n    -86t\n    -125t\n    -104t\n    -29t\n    -87t\n    -95t\n    68t\n    51t\n    121t\n    17t\n    27t\n    -52t\n    24t\n    122t\n    127t\n    -39t\n    -106t\n    66t\n    91t\n    -55t\n    99t\n    34t\n    -113t\n    4t\n    -125t\n    59t\n    22t\n    59t\n    -105t\n    18t\n    13t\n    60t\n    33t\n    -72t\n    7t\n    -34t\n    -72t\n    -126t\n    -47t\n    40t\n    119t\n    93t\n    -27t\n    -74t\n    102t\n    59t\n    -124t\n    85t\n    62t\n    -66t\n    -93t\n    1t\n    -60t\n    39t\n    -45t\n    115t\n    127t\n    -121t\n    80t\n    108t\n    -61t\n    -90t\n    -55t\n    -41t\n    100t\n    -7t\n    106t\n    -3t\n    -45t\n    -96t\n    82t\n    -67t\n    -105t\n    -35t\n    62t\n    -91t\n    -96t\n    4t\n    -10t\n    -35t\n    9t\n    -124t\n    90t\n    -95t\n    85t\n    60t\n    87t\n    -76t\n    -88t\n    -117t\n    56t\n    -38t\n    -25t\n    -108t\n    106t\n    -94t\n    -10t\n    57t\n    -73t\n    -46t\n    -116t\n    -58t\n    -100t\n    -13t\n    45t\n    -32t\n    98t\n    79t\n    -26t\n    -70t\n    8t\n    -64t\n    -86t\n    -111t\n    -118t\n    -35t\n    101t\n    -88t\n    63t\n    -6t\n    83t\n    -88t\n    67t\n    127t\n    112t\n    -58t\n    72t\n    -18t\n    100t\n    40t\n    -31t\n    103t\n    -35t\n    -25t\n    -92t\n    -68t\n    70t\n    92t\n    127t\n    -92t\n    -64t\n    -83t\n    -54t\n    12t\n    61t\n    -17t\n    -115t\n    71t\n    -27t\n    -51t\n    10t\n    54t\n    54t\n    33t\n    55t\n    6t\n    -6t\n    -50t\n    59t\n    -22t\n    76t\n    -15t\n    89t\n    -1t\n    -110t\n    22t\n    -73t\n    -20t\n    -86t\n    -72t\n    78t\n    -99t\n    -90t\n    28t\n    58t\n    -96t\n    -34t\n    -16t\n    59t\n    -14t\n    31t\n    120t\n    111t\n    40t\n    -27t\n    20t\n    106t\n    -62t\n    83t\n    -75t\n    27t\n    23t\n    126t\n    -32t\n    -47t\n    -48t\n    -24t\n    -115t\n    -49t\n    -7t\n    44t\n    -20t\n    -68t\n    115t\n    -101t\n    -10t\n    -84t\n    -93t\n    -10t\n    -27t\n    117t\n    124t\n    -77t\n    -96t\n    -128t\n    77t\n    7t\n    53t\n    -38t\n    -117t\n    -28t\n    81t\n    -111t\n    22t\n    114t\n    71t\n    105t\n    -43t\n    57t\n    90t\n    -1t\n    -65t\n    28t\n    -51t\n    -91t\n    -116t\n    53t\n    -13t\n    28t\n    40t\n    43t\n    45t\n    -17t\n    45t\n    -82t\n    -128t\n    44t\n    89t\n    -8t\n    66t\n    14t\n    -2t\n    -92t\n    106t\n    56t\n    33t\n    -116t\n    81t\n    -89t\n    15t\n    95t\n    35t\n    -124t\n    40t\n    49t\n    56t\n    -44t\n    -94t\n    106t\n    -22t\n    24t\n    121t\n    -84t\n    12t\n    85t\n    4t\n    -67t\n    104t\n    57t\n    29t\n    -56t\n    59t\n    -68t\n    32t\n    52t\n    -107t\n    -44t\n    -15t\n    77t\n    -103t\n    24t\n    -50t\n    -72t\n    -71t\n    -42t\n    -4t\n    6t\n    81t\n    20t\n    -109t\n    91t\n    -48t\n    -74t\n    96t\n    -30t\n    104t\n    11t\n    60t\n    11t\n    95t\n    -123t\n    -60t\n    -48t\n    68t\n    78t\n    -20t\n    -20t\n    19t\n    63t\n    26t\n    101t\n    47t\n    3t\n    -81t\n    -54t\n    -90t\n    67t\n    59t\n    -15t\n    71t\n    -69t\n    76t\n    -8t\n    33t\n    -31t\n    28t\n    -86t\n    110t\n    -35t\n    -17t\n    57t\n    59t\n    -31t\n    79t\n    85t\n    -73t\n    40t\n    -16t\n    31t\n    -47t\n    -75t\n    60t\n    8t\n    -102t\n    -37t\n    -82t\n    -82t\n    -60t\n    1t\n    -111t\n    41t\n    92t\n    93t\n    -70t\n    95t\n    51t\n    -10t\n    -22t\n    -28t\n    -74t\n    -5t\n    -44t\n    -42t\n    89t\n    85t\n    -94t\n    95t\n    -25t\n    -113t\n    -12t\n    -51t\n    38t\n    -114t\n    -115t\n    -45t\n    -109t\n    23t\n    66t\n    -126t\n    -67t\n    -56t\n    -22t\n    -75t\n    -74t\n    -5t\n    77t\n    8t\n    56t\n    -10t\n    86t\n    -122t\n    -85t\n    38t\n    -15t\n    -69t\n    -18t\n    -69t\n    27t\n    109t\n    -43t\n    110t\n    101t\n    -117t\n    -67t\n    55t\n    -92t\n    75t\n    -61t\n    -50t\n    20t\n    -82t\n    -72t\n    92t\n    80t\n    93t\n    18t\n    -96t\n    33t\n    65t\n    120t\n    105t\n    -54t\n    -62t\n    126t\n    -121t\n    51t\n    127t\n    127t\n    -16t\n    79t\n    -29t\n    25t\n    -31t\n    -62t\n    16t\n    -113t\n    -105t\n    -84t\n    -43t\n    12t\n    71t\n    65t\n    -93t\n    -53t\n    -76t\n    27t\n    -93t\n    70t\n    -27t\n    40t\n    -61t\n    -95t\n    -7t\n    -68t\n    25t\n    -46t\n    -52t\n    -105t\n    -31t\n    -88t\n    -7t\n    114t\n    -48t\n    -60t\n    -116t\n    -19t\n    -37t\n    -92t\n    20t\n    19t\n    -71t\n    25t\n    108t\n    35t\n    -8t\n    -4t\n    101t\n    -47t\n    25t\n    -111t\n    72t\n    29t\n    -6t\n    -71t\n    9t\n    107t\n    -57t\n    103t\n    30t\n    -83t\n    40t\n    113t\n    -19t\n    -117t\n    55t\n    -15t\n    -48t\n    73t\n    59t\n    -48t\n    -104t\n    98t\n    77t\n    40t\n    -24t\n    -49t\n    124t\n    -50t\n    64t\n    -51t\n    -105t\n    58t\n    -71t\n    -3t\n    -40t\n    26t\n    -4t\n    74t\n    -63t\n    73t\n    82t\n    72t\n    9t\n    -78t\n    -95t\n    37t\n    -21t\n    94t\n    -62t\n    -40t\n    89t\n    -40t\n    -85t\n    44t\n    97t\n    -73t\n    112t\n    33t\n    1t\n    87t\n    -80t\n    -70t\n    13t\n    100t\n    86t\n    37t\n    92t\n    -127t\n    66t\n    -2t\n    -123t\n    -67t\n    -19t\n    58t\n    -6t\n    53t\n    22t\n    -121t\n    -94t\n    -41t\n    3t\n    102t\n    -93t\n    85t\n    39t\n    -120t\n    95t\n    -91t\n    -18t\n    96t\n    -41t\n    94t\n    -10t\n    18t\n    83t\n    73t\n    126t\n    72t\n    11t\n    119t\n    -55t\n    75t\n    -87t\n    -36t\n    -73t\n    121t\n    -53t\n    -118t\n    25t\n    14t\n    -67t\n    102t\n    113t\n    -20t\n    -69t\n    41t\n    -2t\n    -49t\n    -48t\n    88t\n    3t\n    116t\n    126t\n    -65t\n    -97t\n    47t\n    -15t\n    27t\n    109t\n    63t\n    87t\n    -37t\n    -54t\n    -58t\n    -16t\n    61t\n    4t\n    50t\n    -12t\n    95t\n    111t\n    -45t\n    27t\n    -41t\n    -22t\n    -40t\n    113t\n    120t\n    -37t\n    -112t\n    -103t\n    -35t\n    95t\n    30t\n    44t\n    -77t\n    28t\n    80t\n    82t\n    -93t\n    -90t\n    -4t\n    -119t\n    123t\n    -19t\n    -41t\n    -94t\n    -71t\n    -85t\n    125t\n    -92t\n    72t\n    -48t\n    51t\n    -69t\n    76t\n    -22t\n    -60t\n    83t\n    -9t\n    35t\n    12t\n    -2t\n    -28t\n    25t\n    111t\n    -126t\n    120t\n    107t\n    67t\n    -23t\n    64t\n    -79t\n    -68t\n    -116t\n    -106t\n    26t\n    -37t\n    -59t\n    -23t\n    63t\n    8t\n    2t\n    104t\n    6t\n    88t\n    42t\n    34t\n    -32t\n    96t\n    67t\n    -77t\n    49t\n    64t\n    54t\n    -117t\n    36t\n    -16t\n    126t\n    -119t\n    123t\n    58t\n    72t\n    99t\n    -75t\n    -83t\n    -25t\n    -60t\n    51t\n    -41t\n    -63t\n    -34t\n    -41t\n    66t\n    102t\n    -17t\n    84t\n    98t\n    101t\n    112t\n    -43t\n    -58t\n    -95t\n    -8t\n    -54t\n    87t\n    -38t\n    99t\n    126t\n    74t\n    -78t\n    21t\n    88t\n    -95t\n    -62t\n    125t\n    -47t\n    -99t\n    -43t\n    -81t\n    92t\n    48t\n    -16t\n    75t\n    -59t\n    29t\n    64t\n    -38t\n    -92t\n    98t\n    8t\n    66t\n    72t\n    65t\n    89t\n    103t\n    123t\n    -124t\n    48t\n    28t\n    64t\n    117t\n    -68t\n    77t\n    5t\n    -85t\n    41t\n    13t\n    86t\n    -77t\n    1t\n    -70t\n    6t\n    67t\n    -102t\n    -11t\n    -78t\n    -58t\n    -9t\n    108t\n    79t\n    -74t\n    -120t\n    84t\n    73t\n    91t\n    104t\n    48t\n    -4t\n    -6t\n    -15t\n    -99t\n    -19t\n    -95t\n    59t\n    0t\n    32t\n    -28t\n    81t\n    80t\n    94t\n    -52t\n    25t\n    34t\n    -89t\n    -78t\n    -115t\n    -106t\n    54t\n    -54t\n    102t\n    -6t\n    -121t\n    35t\n    13t\n    -99t\n    -32t\n    64t\n    -81t\n    99t\n    -105t\n    -95t\n    -116t\n    -85t\n    20t\n    -111t\n    122t\n    46t\n    59t\n    -55t\n    113t\n    -113t\n    77t\n    -52t\n    83t\n    -127t\n    -77t\n    14t\n    89t\n    58t\n    57t\n    -2t\n    125t\n    21t\n    -60t\n    -5t\n    105t\n    -100t\n    49t\n    -54t\n    81t\n    -5t\n    96t\n    -55t\n    8t\n    -116t\n    -26t\n    -29t\n    -108t\n    -40t\n    77t\n    -50t\n    -127t\n    -89t\n    -72t\n    65t\n    77t\n    -37t\n    -106t\n    122t\n    27t\n    -110t\n    -128t\n    120t\n    29t\n    50t\n    33t\n    -87t\n    73t\n    -5t\n    -42t\n    -115t\n    -44t\n    -126t\n    -87t\n    56t\n    29t\n    108t\n    13t\n    53t\n    83t\n    -42t\n    -100t\n    -72t\n    -84t\n    -50t\n    13t\n    -39t\n    -110t\n    98t\n    87t\n    115t\n    110t\n    -118t\n    22t\n    -69t\n    30t\n    -27t\n    -33t\n    -2t\n    86t\n    84t\n    -84t\n    79t\n    -55t\n    -80t\n    -41t\n    -27t\n    54t\n    -64t\n    -95t\n    -37t\n    -90t\n    61t\n    -46t\n    -52t\n    3t\n    -31t\n    -116t\n    37t\n    -29t\n    -58t\n    -38t\n    122t\n    59t\n    40t\n    -23t\n    83t\n    106t\n    -62t\n    -39t\n    -48t\n    -102t\n    46t\n    -65t\n    -127t\n    -55t\n    29t\n    -84t\n    -62t\n    90t\n    -103t\n    122t\n    -60t\n    13t\n    60t\n    108t\n    -87t\n    115t\n    -65t\n    -63t\n    -79t\n    85t\n    -36t\n    113t\n    92t\n    54t\n    -128t\n    -74t\n    -100t\n    29t\n    30t\n    5t\n    27t\n    115t\n    102t\n    123t\n    -100t\n    23t\n    0t\n    33t\n    -43t\n    -35t\n    18t\n    -5t\n    -52t\n    10t\n    -57t\n    117t\n    -18t\n    -9t\n    54t\n    116t\n    41t\n    -20t\n    -51t\n    121t\n    -101t\n    -60t\n    -26t\n    9t\n    10t\n    54t\n    -99t\n    -94t\n    -51t\n    122t\n    -110t\n    -1t\n    102t\n    89t\n    39t\n    -114t\n    -17t\n    83t\n    -57t\n    -110t\n    -68t\n    -103t\n    -57t\n    66t\n    -118t\n    34t\n    -30t\n    107t\n    -100t\n    -10t\n    -43t\n    -105t\n    -86t\n    60t\n    91t\n    -3t\n    -62t\n    -126t\n    -70t\n    -118t\n    77t\n    51t\n    -19t\n    117t\n    110t\n    -117t\n    89t\n    -85t\n    84t\n    106t\n    99t\n    45t\n    -78t\n    -35t\n    -115t\n    -128t\n    85t\n    1t\n    -43t\n    -60t\n    -97t\n    -97t\n    102t\n    52t\n    107t\n    -18t\n    34t\n    -83t\n    -86t\n    21t\n    39t\n    47t\n    54t\n    119t\n    105t\n    32t\n    52t\n    -99t\n    17t\n    -37t\n    10t\n    72t\n    -12t\n    -54t\n    12t\n    126t\n    -76t\n    -89t\n    16t\n    106t\n    -75t\n    44t\n    -9t\n    -78t\n    -88t\n    50t\n    19t\n    -40t\n    111t\n    -83t\n    -34t\n    -36t\n    -93t\n    -26t\n    -79t\n    0t\n    -23t\n    94t\n    79t\n    -53t\n    -47t\n    106t\n    -38t\n    -29t\n    93t\n    59t\n    -119t\n    -92t\n    -30t\n    -48t\n    -73t\n    86t\n    -20t\n    35t\n    20t\n    -92t\n    38t\n    2t\n    57t\n    61t\n    -42t\n    -110t\n    120t\n    -102t\n    -61t\n    -75t\n    -91t\n    -47t\n    -82t\n    74t\n    -102t\n    125t\n    14t\n    30t\n    40t\n    114t\n    69t\n    -57t\n    127t\n    -18t\n    75t\n    -110t\n    123t\n    99t\n    21t\n    -44t\n    -12t\n    -108t\n    127t\n    -123t\n    88t\n    113t\n    5t\n    119t\n    59t\n    -38t\n    50t\n    22t\n    115t\n    -95t\n    63t\n    121t\n    -74t\n    46t\n    -107t\n    -48t\n    126t\n    -82t\n    19t\n    -112t\n    -71t\n    -38t\n    -69t\n    7t\n    58t\n    -86t\n    -97t\n    100t\n    -120t\n    -59t\n    -14t\n    -60t\n    72t\n    -2t\n    -26t\n    -9t\n    -110t\n    -81t\n    4t\n    -78t\n    79t\n    11t\n    16t\n    10t\n    -18t\n    115t\n    29t\n    -43t\n    77t\n    -34t\n    2t\n    -10t\n    117t\n    4t\n    -24t\n    25t\n    13t\n    12t\n    120t\n    -28t\n    114t\n    62t\n    47t\n    -119t\n    73t\n    9t\n    95t\n    110t\n    78t\n    -86t\n    9t\n    75t\n    -81t\n    64t\n    24t\n    79t\n    -117t\n    111t\n    -9t\n    -81t\n    37t\n    -46t\n    -80t\n    101t\n    21t\n    36t\n    -124t\n    -112t\n    -104t\n    84t\n    53t\n    115t\n    -17t\n    122t\n    4t\n    -120t\n    42t\n    -83t\n    32t\n    -38t\n    75t\n    -125t\n    -10t\n    51t\n    50t\n    -95t\n    -103t\n    -33t\n    24t\n    -22t\n    56t\n    -107t\n    122t\n    -30t\n    -7t\n    30t\n    40t\n    84t\n    -5t\n    -47t\n    -88t\n    53t\n    69t\n    125t\n    88t\n    -16t\n    -17t\n    -12t\n    43t\n    28t\n    91t\n    0t\n    -104t\n    -87t\n    41t\n    51t\n    95t\n    33t\n    113t\n    -9t\n    34t\n    -10t\n    42t\n    -68t\n    -98t\n    -119t\n    49t\n    -15t\n    -12t\n    69t\n    -127t\n    -48t\n    108t\n    11t\n    -29t\n    -68t\n    -80t\n    -37t\n    67t\n    7t\n    -113t\n    -6t\n    -50t\n    -19t\n    112t\n    54t\n    96t\n    -50t\n    -7t\n    -78t\n    -98t\n    35t\n    -44t\n    -91t\n    -14t\n    -113t\n    84t\n    97t\n    -110t\n    112t\n    -94t\n    119t\n    37t\n    -82t\n    -32t\n    -51t\n    83t\n    -124t\n    -93t\n    72t\n    -54t\n    123t\n    -30t\n    95t\n    -13t\n    26t\n    -108t\n    -28t\n    43t\n    82t\n    116t\n    -78t\n    79t\n    -77t\n    87t\n    77t\n    -47t\n    -10t\n    -74t\n    -119t\n    94t\n    50t\n    -94t\n    12t\n    5t\n    -34t\n    -77t\n    71t\n    66t\n    -118t\n    -15t\n    -52t\n    39t\n    -94t\n    -106t\n    -89t\n    60t\n    48t\n    -87t\n    -75t\n    113t\n    40t\n    -23t\n    15t\n    -39t\n    -27t\n    107t\n    55t\n    68t\n    -86t\n    26t\n    119t\n    80t\n    48t\n    101t\n    1t\n    22t\n    24t\n    68t\n    11t\n    4t\n    81t\n    -25t\n    -15t\n    95t\n    11t\n    -121t\n    -71t\n    118t\n    -20t\n    85t\n    -80t\n    71t\n    122t\n    112t\n    77t\n    91t\n    -109t\n    52t\n    -28t\n    -21t\n    -29t\n    -29t\n    115t\n    118t\n    89t\n    68t\n    77t\n    95t\n    55t\n    45t\n    112t\n    40t\n    64t\n    -127t\n    -80t\n    118t\n    -101t\n    -77t\n    -126t\n    -19t\n    -118t\n    109t\n    -98t\n    98t\n    16t\n    -122t\n    83t\n    17t\n    -34t\n    -115t\n    40t\n    -6t\n    96t\n    114t\n    62t\n    8t\n    -67t\n    114t\n    114t\n    99t\n    99t\n    -87t\n    81t\n    -83t\n    91t\n    109t\n    63t\n    -58t\n    -10t\n    -34t\n    101t\n    -57t\n    -22t\n    -10t\n    -19t\n    -78t\n    -101t\n    55t\n    17t\n    -101t\n    -7t\n    25t\n    4t\n    -2t\n    -26t\n    74t\n    -51t\n    13t\n    38t\n    15t\n    18t\n    47t\n    0t\n    -89t\n    -49t\n    -113t\n    -107t\n    102t\n    -21t\n    -126t\n    -116t\n    -110t\n    5t\n    122t\n    44t\n    -44t\n    36t\n    -67t\n    75t\n    -88t\n    -26t\n    -104t\n    -82t\n    77t\n    17t\n    -81t\n    37t\n    13t\n    -79t\n    81t\n    -18t\n    52t\n    -12t\n    -32t\n    -24t\n    104t\n    111t\n    -50t\n    49t\n    58t\n    101t\n    -128t\n    -126t\n    -39t\n    -27t\n    3t\n    124t\n    -97t\n    7t\n    70t\n    18t\n    112t\n    36t\n    104t\n    -69t\n    -25t\n    -36t\n    -64t\n    4t\n    -24t\n    -64t\n    -1t\n    -8t\n    -102t\n    3t\n    -11t\n    -8t\n    1t\n    74t\n    -71t\n    -116t\n    93t\n    9t\n    113t\n    -64t\n    13t\n    -14t\n    15t\n    66t\n    113t\n    -119t\n    -88t\n    85t\n    26t\n    52t\n    58t\n    112t\n    94t\n    -85t\n    43t\n    116t\n    12t\n    37t\n    102t\n    -61t\n    -106t\n    21t\n    24t\n    105t\n    -29t\n    64t\n    -87t\n    71t\n    -121t\n    -1t\n    0t\n    109t\n    -57t\n    -117t\n    -54t\n    -73t\n    54t\n    -104t\n    -94t\n    115t\n    -55t\n    61t\n    -5t\n    -65t\n    -58t\n    13t\n    89t\n    -128t\n    96t\n    85t\n    -9t\n    -2t\n    -94t\n    66t\n    -66t\n    23t\n    -51t\n    -118t\n    -81t\n    -99t\n    81t\n    -27t\n    -90t\n    59t\n    -73t\n    82t\n    -120t\n    17t\n    -64t\n    -60t\n    -28t\n    109t\n    105t\n    50t\n    -54t\n    -6t\n    -79t\n    -36t\n    43t\n    113t\n    126t\n    -112t\n    20t\n    -33t\n    -77t\n    24t\n    105t\n    50t\n    17t\n    -118t\n    -67t\n    -59t\n    -30t\n    23t\n    41t\n    -20t\n    103t\n    -46t\n    -3t\n    -18t\n    -27t\n    -58t\n    127t\n    -65t\n    -10t\n    15t\n    18t\n    -58t\n    -93t\n    64t\n    75t\n    26t\n    90t\n    -111t\n    -19t\n    50t\n    -57t\n    98t\n    71t\n    109t\n    113t\n    -109t\n    -83t\n    -127t\n    127t\n    103t\n    97t\n    -46t\n    54t\n    -108t\n    103t\n    -60t\n    56t\n    -64t\n    -126t\n    37t\n    16t\n    -111t\n    31t\n    4t\n    -93t\n    80t\n    102t\n    10t\n    -70t\n    -36t\n    -24t\n    -44t\n    89t\n    107t\n    33t\n    -34t\n    -14t\n    -52t\n    -120t\n    19t\n    92t\n    -73t\n    73t\n    -116t\n    122t\n    -85t\n    127t\n    -64t\n    -34t\n    -47t\n    23t\n    114t\n    119t\n    30t\n    16t\n    -45t\n    -26t\n    69t\n    30t\n    11t\n    -28t\n    -109t\n    -33t\n    40t\n    111t\n    -29t\n    65t\n    -34t\n    96t\n    39t\n    -82t\n    -103t\n    -20t\n    -125t\n    31t\n    59t\n    123t\n    118t\n    -13t\n    -50t\n    -120t\n    118t\n    -69t\n    -6t\n    -68t\n    10t\n    -92t\n    -82t\n    -74t\n    -1t\n    16t\n    -74t\n    84t\n    -121t\n    126t\n    -35t\n    123t\n    37t\n    -6t\n    -57t\n    -112t\n    92t\n    -31t\n    -117t\n    111t\n    -28t\n    -7t\n    -69t\n    -59t\n    -124t\n    8t\n    -115t\n    -51t\n    120t\n    5t\n    -11t\n    -41t\n    36t\n    -110t\n    -13t\n    -94t\n    -53t\n    -38t\n    -106t\n    46t\n    67t\n    -102t\n    -45t\n    43t\n    112t\n    -62t\n    109t\n    96t\n    -39t\n    -20t\n    -110t\n    -55t\n    58t\n    -103t\n    100t\n    -74t\n    -125t\n    120t\n    50t\n    11t\n    -20t\n    -51t\n    100t\n    60t\n    22t\n    41t\n    53t\n    -46t\n    45t\n    20t\n    -27t\n    65t\n    -93t\n    -7t\n    -119t\n    82t\n    -122t\n    -75t\n    104t\n    61t\n    81t\n    -62t\n    92t\n    15t\n    54t\n    -52t\n    39t\n    5t\n    -22t\n    -116t\n    85t\n    -45t\n    12t\n    -59t\n    -19t\n    -55t\n    37t\n    -60t\n    -7t\n    33t\n    118t\n    56t\n    9t\n    39t\n    72t\n    47t\n    34t\n    -60t\n    -26t\n    60t\n    34t\n    39t\n    -23t\n    40t\n    116t\n    70t\n    101t\n    -13t\n    113t\n    68t\n    -74t\n    -17t\n    64t\n    54t\n    98t\n    112t\n    -51t\n    -5t\n    93t\n    32t\n    -7t\n    -72t\n    -43t\n    -38t\n    56t\n    -15t\n    91t\n    86t\n    39t\n    -115t\n    59t\n    107t\n    -74t\n    -121t\n    -4t\n    -50t\n    -40t\n    31t\n    106t\n    -1t\n    113t\n    -65t\n    47t\n    -78t\n    14t\n    -29t\n    -100t\n    -109t\n    100t\n    87t\n    -62t\n    -97t\n    92t\n    10t\n    98t\n    -20t\n    -40t\n    120t\n    -10t\n    88t\n    75t\n    -81t\n    -25t\n    53t\n    -122t\n    -101t\n    -4t\n    -90t\n    0t\n    -72t\n    99t\n    -2t\n    49t\n    4t\n    -55t\n    93t\n    59t\n    100t\n    24t\n    -63t\n    32t\n    35t\n    -18t\n    109t\n    -54t\n    -87t\n    87t\n    82t\n    37t\n    76t\n    -102t\n    65t\n    7t\n    -128t\n    92t\n    -93t\n    -7t\n    -38t\n    19t\n    122t\n    -97t\n    -76t\n    124t\n    -101t\n    -92t\n    -30t\n    67t\n    96t\n    -103t\n    -106t\n    -56t\n    -25t\n    -114t\n    -89t\n    -14t\n    -65t\n    113t\n    101t\n    -119t\n    79t\n    -91t\n    -72t\n    -15t\n    112t\n    -30t\n    -36t\n    -89t\n    62t\n    108t\n    -45t\n    56t\n    -122t\n    126t\n    24t\n    98t\n    -66t\n    -109t\n    -81t\n    -59t\n    -40t\n    4t\n    -12t\n    112t\n    14t\n    -119t\n    -86t\n    -69t\n    94t\n    110t\n    118t\n    77t\n    -87t\n    97t\n    15t\n    -10t\n    103t\n    14t\n    -98t\n    -69t\n    -62t\n    -33t\n    -98t\n    -56t\n    95t\n    -33t\n    -14t\n    70t\n    54t\n    -84t\n    81t\n    -116t\n    13t\n    36t\n    -12t\n    -29t\n    20t\n    82t\n    6t\n    117t\n    -36t\n    120t\n    -11t\n    -113t\n    -49t\n    -8t\n    24t\n    -23t\n    42t\n    120t\n    48t\n    17t\n    -66t\n    -24t\n    113t\n    -80t\n    -55t\n    -27t\n    -76t\n    121t\n    5t\n    64t\n    55t\n    -39t\n    23t\n    0t\n    -76t\n    29t\n    93t\n    85t\n    -98t\n    -114t\n    -14t\n    -24t\n    124t\n    56t\n    -7t\n    19t\n    72t\n    -74t\n    115t\n    -18t\n    83t\n    25t\n    -97t\n    19t\n    -47t\n    25t\n    41t\n    -3t\n    67t\n    62t\n    74t\n    -46t\n    -67t\n    -107t\n    65t\n    106t\n    -29t\n    115t\n    -98t\n    -6t\n    -95t\n    50t\n    126t\n    46t\n    43t\n    35t\n    -49t\n    46t\n    -74t\n    -87t\n    -83t\n    122t\n    81t\n    62t\n    -75t\n    120t\n    -44t\n    -20t\n    -28t\n    -54t\n    29t\n    52t\n    72t\n    101t\n    -112t\n    114t\n    23t\n    -85t\n    -55t\n    -33t\n    -45t\n    -75t\n    -49t\n    -51t\n    -115t\n    -103t\n    15t\n    104t\n    43t\n    52t\n    -112t\n    -25t\n    -67t\n    40t\n    119t\n    124t\n    -47t\n    -51t\n    -57t\n    -47t\n    110t\n    -124t\n    82t\n    -117t\n    -8t\n    -86t\n    -108t\n    121t\n    -124t\n    105t\n    92t\n    -122t\n    -52t\n    80t\n    -13t\n    -64t\n    -34t\n    45t\n    104t\n    11t\n    102t\n    -61t\n    3t\n    14t\n    -109t\n    118t\n    -58t\n    33t\n    -96t\n    -2t\n    24t\n    -84t\n    -125t\n    -36t\n    15t\n    5t\n    43t\n    -47t\n    94t\n    47t\n    97t\n    -29t\n    -28t\n    -30t\n    -110t\n    -62t\n    -53t\n    57t\n    104t\n    100t\n    -64t\n    -94t\n    -58t\n    65t\n    -113t\n    53t\n    78t\n    61t\n    -65t\n    -82t\n    50t\n    75t\n    74t\n    80t\n    -126t\n    -11t\n    -6t\n    -6t\n    52t\n    63t\n    -128t\n    -94t\n    -54t\n    113t\n    -82t\n    125t\n    -96t\n    -23t\n    115t\n    107t\n    -114t\n    2t\n    -12t\n    -124t\n    20t\n    -30t\n    -41t\n    10t\n    -8t\n    -2t\n    -97t\n    -7t\n    -62t\n    70t\n    50t\n    -15t\n    -61t\n    -32t\n    75t\n    113t\n    121t\n    -21t\n    -11t\n    17t\n    1t\n    72t\n    -91t\n    -124t\n    -110t\n    -24t\n    44t\n    -97t\n    -17t\n    38t\n    -29t\n    96t\n    -105t\n    25t\n    -70t\n    -38t\n    26t\n    43t\n    124t\n    -106t\n    126t\n    39t\n    42t\n    -89t\n    -113t\n    -1t\n    1t\n    -106t\n    -120t\n    107t\n    -71t\n    108t\n    114t\n    127t\n    -106t\n    -64t\n    46t\n    8t\n    12t\n    -82t\n    88t\n    46t\n    -116t\n    93t\n    -111t\n    36t\n    -53t\n    -3t\n    90t\n    -118t\n    115t\n    -8t\n    43t\n    -92t\n    50t\n    -79t\n    127t\n    -50t\n    -115t\n    -28t\n    125t\n    -44t\n    -56t\n    -9t\n    51t\n    73t\n    -50t\n    -79t\n    34t\n    -46t\n    85t\n    121t\n    -27t\n    94t\n    40t\n    72t\n    71t\n    -24t\n    74t\n    25t\n    19t\n    125t\n    -102t\n    -31t\n    107t\n    38t\n    32t\n    -3t\n    19t\n    -72t\n    -68t\n    119t\n    21t\n    -91t\n    -11t\n    21t\n    18t\n    104t\n    -88t\n    -93t\n    -78t\n    68t\n    29t\n    81t\n    -78t\n    -37t\n    -63t\n    50t\n    90t\n    -94t\n    23t\n    116t\n    30t\n    -76t\n    107t\n    -124t\n    -32t\n    -122t\n    -126t\n    102t\n    122t\n    -83t\n    -34t\n    17t\n    116t\n    6t\n    -38t\n    95t\n    -8t\n    -88t\n    -104t\n    -42t\n    -31t\n    2t\n    95t\n    82t\n    -31t\n    -121t\n    -96t\n    -69t\n    6t\n    14t\n    -56t\n    -81t\n    74t\n    -35t\n    2t\n    41t\n    -24t\n    24t\n    22t\n    20t\n    63t\n    67t\n    62t\n    -106t\n    -76t\n    -118t\n    35t\n    -91t\n    -104t\n    -94t\n    20t\n    45t\n    24t\n    0t\n    6t\n    -121t\n    98t\n    71t\n    -101t\n    -109t\n    -77t\n    113t\n    -97t\n    -67t\n    -94t\n    -32t\n    56t\n    9t\n    100t\n    44t\n    36t\n    124t\n    -31t\n    25t\n    103t\n    -87t\n    -17t\n    77t\n    -81t\n    -18t\n    -98t\n    81t\n    -108t\n    50t\n    -97t\n    -42t\n    95t\n    -60t\n    -36t\n    74t\n    -127t\n    -16t\n    -40t\n    0t\n    -29t\n    34t\n    57t\n    108t\n    92t\n    23t\n    -28t\n    -107t\n    -71t\n    95t\n    -66t\n    -25t\n    -32t\n    114t\n    12t\n    -46t\n    89t\n    -71t\n    6t\n    29t\n    -101t\n    99t\n    62t\n    101t\n    38t\n    6t\n    -68t\n    -14t\n    89t\n    -73t\n    -89t\n    -89t\n    -61t\n    -16t\n    5t\n    66t\n    -23t\n    63t\n    93t\n    64t\n    126t\n    45t\n    81t\n    91t\n    -81t\n    -51t\n    -9t\n    -9t\n    -79t\n    -24t\n    124t\n    127t\n    104t\n    101t\n    -65t\n    -85t\n    -116t\n    -119t\n    1t\n    -61t\n    -39t\n    12t\n    104t\n    17t\n    68t\n    -53t\n    123t\n    -34t\n    26t\n    -2t\n    -100t\n    69t\n    -78t\n    68t\n    -78t\n    -31t\n    -88t\n    113t\n    -90t\n    -31t\n    -14t\n    -64t\n    -127t\n    -25t\n    72t\n    -90t\n    -128t\n    -113t\n    14t\n    91t\n    18t\n    9t\n    -54t\n    -95t\n    -12t\n    54t\n    -85t\n    -67t\n    49t\n    -56t\n    -77t\n    51t\n    116t\n    -53t\n    -91t\n    79t\n    -38t\n    71t\n    -80t\n    -7t\n    -99t\n    7t\n    82t\n    99t\n    81t\n    33t\n    14t\n    -2t\n    -119t\n    -118t\n    -24t\n    -16t\n    70t\n    49t\n    19t\n    119t\n    -29t\n    5t\n    106t\n    -84t\n    74t\n    107t\n    -37t\n    43t\n    21t\n    53t\n    -99t\n    9t\n    103t\n    43t\n    40t\n    -84t\n    113t\n    -10t\n    -121t\n    28t\n    -117t\n    103t\n    41t\n    -110t\n    120t\n    39t\n    -50t\n    -59t\n    54t\n    -123t\n    114t\n    -77t\n    -98t\n    30t\n    -32t\n    19t\n    42t\n    -76t\n    7t\n    11t\n    -64t\n    -126t\n    -2t\n    90t\n    -58t\n    -85t\n    121t\n    -34t\n    76t\n    -82t\n    77t\n    -62t\n    -90t\n    -29t\n    79t\n    -120t\n    -76t\n    -101t\n    19t\n    74t\n    -100t\n    -25t\n    109t\n    -84t\n    2t\n    28t\n    122t\n    -115t\n    -20t\n    -4t\n    56t\n    32t\n    -31t\n    -89t\n    -32t\n    102t\n    100t\n    59t\n    -43t\n    8t\n    -99t\n    -90t\n    66t\n    -119t\n    -97t\n    62t\n    85t\n    65t\n    14t\n    29t\n    -13t\n    66t\n    -89t\n    31t\n    -116t\n    -27t\n    -68t\n    96t\n    22t\n    41t\n    -85t\n    0t\n    21t\n    -28t\n    54t\n    -128t\n    -65t\n    -32t\n    26t\n    91t\n    -84t\n    21t\n    -112t\n    -8t\n    -106t\n    98t\n    -25t\n    29t\n    87t\n    27t\n    -96t\n    25t\n    10t\n    -36t\n    -48t\n    -51t\n    89t\n    -49t\n    -16t\n    56t\n    80t\n    25t\n    33t\n    -109t\n    -110t\n    -90t\n    -37t\n    -80t\n    33t\n    25t\n    73t\n    123t\n    97t\n    14t\n    -56t\n    90t\n    -91t\n    9t\n    -93t\n    -32t\n    -70t\n    0t\n    20t\n    -40t\n    12t\n    -34t\n    -124t\n    74t\n    114t\n    -99t\n    -83t\n    -96t\n    -104t\n    -46t\n    26t\n    36t\n    -14t\n    -98t\n    -95t\n    80t\n    80t\n    -56t\n    109t\n    59t\n    66t\n    -7t\n    64t\n    -107t\n    -74t\n    15t\n    -87t\n    98t\n    -27t\n    -27t\n    -38t\n    7t\n    -7t\n    -2t\n    -128t\n    38t\n    -91t\n    -38t\n    96t\n    73t\n    -99t\n    -15t\n    103t\n    43t\n    13t\n    -96t\n    -36t\n    118t\n    -110t\n    101t\n    -34t\n    51t\n    -13t\n    -76t\n    -40t\n    109t\n    -102t\n    -35t\n    34t\n    3t\n    -79t\n    -118t\n    -79t\n    23t\n    -110t\n    92t\n    111t\n    94t\n    -60t\n    -30t\n    28t\n    -102t\n    78t\n    -45t\n    46t\n    18t\n    37t\n    -111t\n    -63t\n    30t\n    49t\n    -30t\n    -5t\n    -86t\n    -5t\n    3t\n    111t\n    -46t\n    -20t\n    -1t\n    97t\n    -58t\n    68t\n    -110t\n    78t\n    63t\n    -79t\n    75t\n    110t\n    -119t\n    81t\n    -87t\n    15t\n    -96t\n    60t\n    74t\n    6t\n    -14t\n    90t\n    -72t\n    -70t\n    -54t\n    48t\n    -56t\n    -126t\n    122t\n    -126t\n    -22t\n    -119t\n    56t\n    -81t\n    -89t\n    98t\n    -88t\n    17t\n    19t\n    -99t\n    26t\n    -51t\n    -120t\n    -59t\n    36t\n    -111t\n    -110t\n    55t\n    7t\n    -27t\n    96t\n    -59t\n    -55t\n    90t\n    -100t\n    68t\n    -59t\n    -120t\n    -70t\n    -119t\n    -3t\n    31t\n    -80t\n    -55t\n    5t\n    34t\n    -44t\n    89t\n    -14t\n    41t\n    93t\n    -83t\n    48t\n    105t\n    90t\n    107t\n    75t\n    -88t\n    123t\n    -39t\n    -23t\n    -45t\n    -23t\n    -35t\n    122t\n    -61t\n    -71t\n    -71t\n    -56t\n    -45t\n    -125t\n    -95t\n    65t\n    51t\n    79t\n    -58t\n    -114t\n    -73t\n    87t\n    44t\n    119t\n    104t\n    51t\n    -73t\n    103t\n    -114t\n    -74t\n    -25t\n    -126t\n    -26t\n    -53t\n    56t\n    0t\n    -114t\n    -47t\n    -112t\n    12t\n    44t\n    83t\n    75t\n    -96t\n    -62t\n    41t\n    54t\n    -112t\n    119t\n    -88t\n    -25t\n    122t\n    65t\n    -42t\n    -49t\n    16t\n    -12t\n    22t\n    -83t\n    -50t\n    -77t\n    -113t\n    -29t\n    -127t\n    -82t\n    -50t\n    -89t\n    -99t\n    -58t\n    -106t\n    81t\n    101t\n    -12t\n    -117t\n    -123t\n    45t\n    -64t\n    -46t\n    -122t\n    14t\n    -99t\n    -96t\n    -28t\n    -44t\n    -24t\n    -81t\n    -22t\n    -59t\n    -106t\n    120t\n    116t\n    24t\n    -123t\n    -72t\n    127t\n    -5t\n    32t\n    22t\n    60t\n    33t\n    -72t\n    119t\n    5t\n    -90t\n    25t\n    -91t\n    -91t\n    -10t\n    -12t\n    54t\n    71t\n    0t\n    71t\n    50t\n    -69t\n    92t\n    -87t\n    -23t\n    -62t\n    19t\n    -125t\n    2t\n    -73t\n    53t\n    -112t\n    27t\n    -102t\n    -83t\n    -96t\n    27t\n    37t\n    -2t\n    48t\n    -108t\n    -27t\n    61t\n    30t\n    27t\n    -126t\n    -118t\n    -104t\n    -6t\n    72t\n    100t\n    66t\n    15t\n    10t\n    -51t\n    101t\n    95t\n    -73t\n    -126t\n    27t\n    27t\n    35t\n    117t\n    -87t\n    -11t\n    -38t\n    -2t\n    -126t\n    -127t\n    66t\n    118t\n    -17t\n    -120t\n    116t\n    78t\n    61t\n    99t\n    -65t\n    13t\n    -51t\n    100t\n    -125t\n    103t\n    -96t\n    -83t\n    18t\n    -95t\n    60t\n    104t\n    -122t\n    -54t\n    -11t\n    105t\n    -16t\n    -119t\n    98t\n    -40t\n    -115t\n    113t\n    13t\n    118t\n    67t\n    3t\n    37t\n    46t\n    3t\n    123t\n    -126t\n    -6t\n    -34t\n    1t\n    40t\n    124t\n    52t\n    -68t\n    -122t\n    75t\n    -20t\n    -6t\n    -41t\n    -27t\n    -100t\n    -16t\n    -23t\n    -103t\n    -53t\n    -87t\n    23t\n    112t\n    -72t\n    -66t\n    31t\n    -108t\n    68t\n    25t\n    -12t\n    38t\n    54t\n    -51t\n    17t\n    53t\n    110t\n    39t\n    11t\n    44t\n    -48t\n    -84t\n    -63t\n    -91t\n    -18t\n    -23t\n    -42t\n    -94t\n    -88t\n    88t\n    -40t\n    -42t\n    30t\n    77t\n    88t\n    -34t\n    30t\n    83t\n    91t\n    -6t\n    -113t\n    -27t\n    16t\n    11t\n    -41t\n    72t\n    -86t\n    -90t\n    111t\n    48t\n    -63t\n    1t\n    -48t\n    -51t\n    97t\n    -80t\n    22t\n    -118t\n    -14t\n    115t\n    -6t\n    -110t\n    -112t\n    89t\n    82t\n    83t\n    -44t\n    83t\n    -62t\n    75t\n    67t\n    10t\n    27t\n    -102t\n    -46t\n    -23t\n    39t\n    46t\n    -101t\n    0t\n    48t\n    -119t\n    -69t\n    73t\n    9t\n    -17t\n    -27t\n    79t\n    -10t\n    31t\n    -99t\n    63t\n    -121t\n    -24t\n    115t\n    -117t\n    -83t\n    65t\n    88t\n    109t\n    -17t\n    -30t\n    29t\n    -104t\n    -36t\n    -95t\n    36t\n    -18t\n    101t\n    -74t\n    -8t\n    21t\n    90t\n    -67t\n  .end array-data\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/negative-array-size.smali",
    "content": ".class Li;\n.super Ljava/lang/Object;\n\n.method public getFileLength()I\n  .catch Ljava/lang/Exception; { :L0 .. :L1 } :L2\n  .catch Ljava/lang/Exception; { :L3 .. :L4 } :L5\n  .registers 3\n    const/4 v0, -1\n  :L0\n    new-array v1, v0, [I\n  :L1\n    goto :L0\n  :L2\n    move-exception v0\n    const/4 v0, 0\n    sput v0, Lz;->b:I\n  :L3\n    iget v0, p0, Lz;->b:I\n  :L4\n    return v0\n  :L5\n    move-exception v0\n    throw v0\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/npe-cause-trap-fail.smali",
    "content": ".class Lnpe/cause/trap/fail;\r\n.super Lb;\r\n\r\n.method public final run()V\r\n    .catch Ljava/lang/Exception; { :L0 .. :L1 } :L8\r\n    .catch Ljava/lang/Exception; { :L4 .. :L5 } :L8\r\n    .catch Ljava/lang/Exception; { :L5 .. :L6 } :L6\r\n    .catch Ljava/lang/Exception; { :L7 .. :L8 } :L8\r\n    .catch Ljava/lang/Exception; { :L9 .. :L10 } :L6\r\n    .catch Ljava/lang/Exception; { :L11 .. :L12 } :L22\r\n    .catch Ljava/lang/Exception; { :L13 .. :L14 } :L6\r\n    .catch Ljava/lang/Exception; { :L15 .. :L16 } :L22\r\n    .catch Ljava/lang/Exception; { :L18 .. :L21 } :L6\r\n    .registers 8\r\n    const/4 v6, 0\r\n    iput-object v7, v7, Lcom/jcraft/jsch/e;->a:Ljava/lang/Runnable;\r\n    :L0\r\n    iget-object v0, v7, Lcom/jcraft/jsch/e;->a:Ljava/lang/Runnable;\r\n    :L1\r\n    if-nez v0, :L3\r\n    :L2\r\n    iput-object v6, v7, Lcom/jcraft/jsch/e;->a:Ljava/lang/Runnable;\r\n    return-void\r\n    :L3\r\n    const/4 v0, 0\r\n    :L4\r\n    invoke-virtual { v0 }, Ljava/net/ServerSocket;->accept()Ljava/net/Socket;\r\n    move-result-object v0\r\n    const/4 v1, 1\r\n    invoke-virtual { v0, v1 }, Ljava/net/Socket;->setTcpNoDelay(Z)V\r\n    invoke-virtual { v0 }, Ljava/net/Socket;->getInputStream()Ljava/io/InputStream;\r\n    move-result-object v1\r\n    invoke-virtual { v0 }, Ljava/net/Socket;->getOutputStream()Ljava/io/OutputStream;\r\n    move-result-object v2\r\n    new-instance v3, Lcom/jcraft/jsch/v;\r\n    invoke-direct { v3 }, Lcom/jcraft/jsch/v;-><init>()V\r\n    invoke-virtual { v3 }, Lcom/jcraft/jsch/v;->a()V\r\n    iget-object v4, v3, Lcom/jcraft/jsch/v;->a:Lcom/jcraft/jsch/ad;\r\n    iput-object v1, v4, Lcom/jcraft/jsch/ad;->a:Ljava/io/InputStream;\r\n    iget-object v1, v3, Lcom/jcraft/jsch/v;->a:Lcom/jcraft/jsch/ad;\r\n    iput-object v2, v1, Lcom/jcraft/jsch/ad;->a:Ljava/io/OutputStream;\r\n    const/4 v1, 0\r\n    invoke-virtual { v1, v3 }, Lcom/jcraft/jsch/f;->a(Lcom/jcraft/jsch/ab;)V\r\n    const/4 v1, 0\r\n    iput-object v1, v3, Lcom/jcraft/jsch/v;->a:Ljava/lang/String;\r\n    const/4 v1, 0\r\n    iput v1, v3, Lcom/jcraft/jsch/v;->a:I\r\n    invoke-virtual { v0 }, Ljava/net/Socket;->getInetAddress()Ljava/net/InetAddress;\r\n    move-result-object v1\r\n    invoke-virtual { v1 }, Ljava/net/InetAddress;->getHostAddress()Ljava/lang/String;\r\n    move-result-object v1\r\n    iput-object v1, v3, Lcom/jcraft/jsch/v;->b:Ljava/lang/String;\r\n    invoke-virtual { v0 }, Ljava/net/Socket;->getPort()I\r\n    move-result v0\r\n    iput v0, v3, Lcom/jcraft/jsch/v;->b:I\r\n    :L5\r\n    invoke-virtual { v3 }, Lcom/jcraft/jsch/v;->a()Lcom/jcraft/jsch/f;\r\n    move-result-object v1\r\n    invoke-virtual { v1 }, Lcom/jcraft/jsch/f;->a()Z\r\n    move-result v0\r\n    if-nez v0, :L9\r\n    new-instance v0, Lcom/jcraft/jsch/JSchException;\r\n    const-string v1, \"session is down\"\r\n    invoke-direct { v0, v1 }, Lcom/jcraft/jsch/JSchException;-><init>(Ljava/lang/String;)V\r\n    throw v0\r\n    :L6\r\n    move-exception v0\r\n    :L7\r\n    iget-object v1, v3, Lcom/jcraft/jsch/v;->a:Lcom/jcraft/jsch/ad;\r\n    invoke-virtual { v1 }, Lcom/jcraft/jsch/ad;->b()V\r\n    const/4 v1, 0\r\n    iput-object v1, v3, Lcom/jcraft/jsch/v;->a:Lcom/jcraft/jsch/ad;\r\n    invoke-static { v3 }, Lcom/jcraft/jsch/ab;->a(Lcom/jcraft/jsch/ab;)V\r\n    instance-of v1, v0, Lcom/jcraft/jsch/JSchException;\r\n    if-eqz v1, :L0\r\n    check-cast v0, Lcom/jcraft/jsch/JSchException;\r\n    throw v0\r\n    :L8\r\n    move-exception v0\r\n    goto :L2\r\n    :L9\r\n    new-instance v0, Lcom/jcraft/jsch/k;\r\n    const/16 v2, 150\r\n    invoke-direct { v0, v2 }, Lcom/jcraft/jsch/k;-><init>(I)V\r\n    new-instance v2, Lcom/jcraft/jsch/i;\r\n    invoke-direct { v2, v0 }, Lcom/jcraft/jsch/i;-><init>(Lcom/jcraft/jsch/k;)V\r\n    invoke-virtual { v2 }, Lcom/jcraft/jsch/i;->a()V\r\n    const/16 v4, 90\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(B)V\r\n    const-string v4, \"direct-tcpip\"\r\n    invoke-static { v4 }, Lcom/jcraft/jsch/q;->a(Ljava/lang/String;)[B\r\n    move-result-object v4\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->b([B)V\r\n    iget v4, v3, Lcom/jcraft/jsch/v;->c:I\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(I)V\r\n    iget v4, v3, Lcom/jcraft/jsch/v;->f:I\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(I)V\r\n    iget v4, v3, Lcom/jcraft/jsch/v;->g:I\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(I)V\r\n    const/4 v4, 0\r\n    invoke-static { v4 }, Lcom/jcraft/jsch/q;->a(Ljava/lang/String;)[B\r\n    move-result-object v4\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->b([B)V\r\n    const/4 v4, 0\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(I)V\r\n    iget-object v4, v3, Lcom/jcraft/jsch/v;->b:Ljava/lang/String;\r\n    invoke-static { v4 }, Lcom/jcraft/jsch/q;->a(Ljava/lang/String;)[B\r\n    move-result-object v4\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->b([B)V\r\n    iget v4, v3, Lcom/jcraft/jsch/v;->b:I\r\n    invoke-virtual { v0, v4 }, Lcom/jcraft/jsch/k;->a(I)V\r\n    invoke-virtual { v1, v2 }, Lcom/jcraft/jsch/f;->a(Lcom/jcraft/jsch/i;)V\r\n    :L10\r\n    const/16 v0, 1000\r\n    :L11\r\n    invoke-virtual { v3 }, Lcom/jcraft/jsch/v;->a()I\r\n    move-result v2\r\n    const/4 v4, -1\r\n    if-ne v2, v4, :L13\r\n    invoke-virtual { v1 }, Lcom/jcraft/jsch/f;->a()Z\r\n    move-result v2\r\n    if-eqz v2, :L13\r\n    if-lez v0, :L13\r\n    iget-boolean v2, v3, Lcom/jcraft/jsch/v;->a:Z\r\n    :L12\r\n    if-eqz v2, :L14\r\n    :L13\r\n    invoke-virtual { v1 }, Lcom/jcraft/jsch/f;->a()Z\r\n    move-result v2\r\n    if-nez v2, :L17\r\n    new-instance v0, Lcom/jcraft/jsch/JSchException;\r\n    const-string v1, \"session is down\"\r\n    invoke-direct { v0, v1 }, Lcom/jcraft/jsch/JSchException;-><init>(Ljava/lang/String;)V\r\n    throw v0\r\n    :L14\r\n    const-wide/16 v4, 50\r\n    :L15\r\n    invoke-static { v4, v5 }, Ljava/lang/Thread;->sleep(J)V\r\n    :L16\r\n    add-int/lit8 v0, v0, -1\r\n    goto :L11\r\n    :L17\r\n    if-eqz v0, :L19\r\n    :L18\r\n    iget-boolean v0, v3, Lcom/jcraft/jsch/v;->a:Z\r\n    if-eqz v0, :L20\r\n    :L19\r\n    new-instance v0, Lcom/jcraft/jsch/JSchException;\r\n    const-string v1, \"channel is not opened.\"\r\n    invoke-direct { v0, v1 }, Lcom/jcraft/jsch/JSchException;-><init>(Ljava/lang/String;)V\r\n    throw v0\r\n    :L20\r\n    const/4 v0, 1\r\n    iput-boolean v0, v3, Lcom/jcraft/jsch/v;->c:Z\r\n    iget-object v0, v3, Lcom/jcraft/jsch/v;->a:Lcom/jcraft/jsch/ad;\r\n    iget-object v0, v0, Lcom/jcraft/jsch/ad;->a:Ljava/io/InputStream;\r\n    if-eqz v0, :L0\r\n    new-instance v0, Ljava/lang/Thread;\r\n    invoke-direct { v0, v3 }, Ljava/lang/Thread;-><init>(Ljava/lang/Runnable;)V\r\n    iput-object v0, v3, Lcom/jcraft/jsch/v;->a:Ljava/lang/Thread;\r\n    iget-object v0, v3, Lcom/jcraft/jsch/v;->a:Ljava/lang/Thread;\r\n    new-instance v2, Ljava/lang/StringBuilder;\r\n    const-string v4, \"DirectTCPIP thread \"\r\n    invoke-direct { v2, v4 }, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V\r\n    invoke-virtual { v1 }, Lcom/jcraft/jsch/f;->a()Ljava/lang/String;\r\n    move-result-object v1\r\n    invoke-virtual { v2, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;\r\n    move-result-object v1\r\n    invoke-virtual { v1 }, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;\r\n    move-result-object v1\r\n    invoke-virtual { v0, v1 }, Ljava/lang/Thread;->setName(Ljava/lang/String;)V\r\n    iget-object v0, v3, Lcom/jcraft/jsch/v;->a:Ljava/lang/Thread;\r\n    invoke-virtual { v0 }, Ljava/lang/Thread;->start()V\r\n    :L21\r\n    goto/16 :L0\r\n    :L22\r\n    move-exception v2\r\n    goto :L13\r\n.end method\r\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/opt-lock.smali",
    "content": ".class Lopt/lock;\n.super Ljava/lang/Object;\n.method public static a()V\n    .catchall { :L0 .. :L1 } :L2\n    .registers 2\n    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;\n    :L0\n    monitor-enter v0\n    const-string v1, \"haha\"\n    invoke-virtual { v0, v1 }, Ljava/io/PrintString;->println(Ljava/lang/String;)V\n    :L1\n    monitor-exit v0\n    return-void\n    :L2\n    move-exception v1\n    monitor-exit v0\n    throw v1\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/useless-new.smali",
    "content": ".class Luseless/new;\n.super Ljava/lang/Object;\n.method public onCreate1(Landroid/os/Bundle;)V\n    .registers 7\n    const/4 v4, -2\n    const/4 v3, 1\n    const/4 v2, 0\n    invoke-super { v5, v6 }, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V\n    const v0, 2130903050\n    invoke-virtual { v5, v0 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->setContentView(I)V\n    new-instance v0, Landroid/widget/LinearLayout;\n    invoke-direct { v0, v5 }, Landroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->container:Landroid/widget/LinearLayout;\n    move-result-object v0\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->PREFS_NAME:Ljava/lang/String;\n    invoke-virtual { v5, v0, v2 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;\n    move-result-object v0\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->settings:Landroid/content/SharedPreferences;\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->settings:Landroid/content/SharedPreferences;\n    const-string v1, \"times\"\n    invoke-interface { v0, v1, v2 }, Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z\n    move-result v0\n    iput-boolean v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->times:Z\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->settings:Landroid/content/SharedPreferences;\n    const-string v1, \"jump\"\n    invoke-interface { v0, v1, v2 }, Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z\n    move-result v0\n    iput-boolean v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->removeadv:Z\n    invoke-static { v5 }, Lcom/mobclick/android/MobclickAgent;->updateOnlineConfig(Landroid/content/Context;)V\n    invoke-static { v2 }, Lcom/mobclick/android/MobclickAgent;->setUpdateOnlyWifi(Z)V\n    invoke-direct { v5 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->se()V\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->a:Ljava/lang/String;\n    const-string v1, \"f90c2179e4ea7fb0531a1182b2ab90aa\"\n    invoke-virtual { v0, v1 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z\n    move-result v0\n    if-nez v0, :L0\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->pointsTextView:Landroid/widget/TextView;\n    const/16 v1, 111\n    invoke-virtual { v0, v1 }, Landroid/widget/TextView;->setText(I)V\n    :L0\n    iget-boolean v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->removeadv:Z\n    if-nez v0, :L2\n    invoke-virtual { v5 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->getApplicationContext()Landroid/content/Context;\n    move-result-object v0\n    const-string v1, \"window\"\n    invoke-virtual { v0, v1 }, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;\n    move-result-object v0\n    check-cast v0, Landroid/view/WindowManager;\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wm:Landroid/view/WindowManager;\n    new-instance v0, Landroid/view/WindowManager$LayoutParams;\n    invoke-direct { v0 }, Landroid/view/WindowManager$LayoutParams;-><init>()V\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    const/16 v1, 2003\n    iput v1, v0, Landroid/view/WindowManager$LayoutParams;->type:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iput v3, v0, Landroid/view/WindowManager$LayoutParams;->format:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    const/16 v1, 40\n    iput v1, v0, Landroid/view/WindowManager$LayoutParams;->flags:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iput v4, v0, Landroid/view/WindowManager$LayoutParams;->width:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iput v2, v0, Landroid/view/WindowManager$LayoutParams;->x:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iput v2, v0, Landroid/view/WindowManager$LayoutParams;->y:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    iput v4, v0, Landroid/view/WindowManager$LayoutParams;->height:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    const/16 v1, 49\n    iput v1, v0, Landroid/view/WindowManager$LayoutParams;->gravity:I\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wm:Landroid/view/WindowManager;\n    iget-object v1, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->container:Landroid/widget/LinearLayout;\n    iget-object v2, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->wmParams:Landroid/view/WindowManager$LayoutParams;\n    invoke-interface { v0, v1, v2 }, Landroid/view/WindowManager;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V\n    new-instance v0, Ljava/lang/Object;\n    iget-object v1, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->container:Landroid/widget/LinearLayout;\n    const/16 v1, 30\n    iput-boolean v3, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->Badview:Z\n    :L1\n    new-instance v0, Lcom/adroidbscpc/a15mSurvival3rh/MainA$ContThread;\n    invoke-direct { v0, v5 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA$ContThread;-><init>(Lcom/adroidbscpc/a15mSurvival3rh/MainA;)V\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->conthred:Ljava/lang/Thread;\n    iget-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->conthred:Ljava/lang/Thread;\n    invoke-virtual { v0 }, Ljava/lang/Thread;->start()V\n    new-instance v0, Lcom/adroidbscpc/a15mSurvival3rh/MainA$1;\n    invoke-direct { v0, v5 }, Lcom/adroidbscpc/a15mSurvival3rh/MainA$1;-><init>(Lcom/adroidbscpc/a15mSurvival3rh/MainA;)V\n    iput-object v0, v5, Lcom/adroidbscpc/a15mSurvival3rh/MainA;->mainHandler:Landroid/os/Handler;\n    return-void\n    :L2\n    invoke-static { v5 }, Lcom/cooguo/advideo/VideoAdsManager;->getInstance(Landroid/content/Context;)Lcom/cooguo/advideo/VideoAdsManager;\n    move-result-object v0\n    invoke-virtual { v0, v3 }, Lcom/cooguo/advideo/VideoAdsManager;->receiveVideoAd(I)V\n    move-result-object v0\n    invoke-static { }, Lcom/kuguo/ad/KuguoAdsManager;->getInstance()Lcom/kuguo/ad/KuguoAdsManager;\n    move-result-object v0\n    invoke-virtual { v0, v5, v3 }, Lcom/kuguo/ad/KuguoAdsManager;->receivePushMessage(Landroid/content/Context;Z)V\n    goto :L1\n.end method\n\n.method private static setAdmobAdView(Landroid/content/Context;Landroid/view/ViewGroup;Landroid/view/ViewGroup$LayoutParams;)V\n    .registers 5\n    new-instance v0, Ljava/lang/Object;\n    const/4 v1, 0\n    const v1, 16777215\n    const/4 v1, -1\n    const v1, -3355444\n    const-string v1, \"android game arcade action casual application\"\n    const/16 v1, 15\n    new-instance v1, Lorg/collcode/xrlophone/AdManager$1;\n    invoke-virtual { v3, v0, v4 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V\n    return-void\n.end method\n"
  },
  {
    "path": "dex-translator/src/test/resources/smalis/writeString.smali",
    "content": ".class LDD;\n.super Lee;\n.method writeString(Ljava/lang/String;[BIZ)I\n    .catch Ljava/io/UnsupportedEncodingException; { :L0 .. :L1 } :L14\n    .catch Ljava/io/UnsupportedEncodingException; { :L2 .. :L3 } :L16\n    .catch Ljava/io/UnsupportedEncodingException; { :L4 .. :L5 } :L14\n    .catch Ljava/io/UnsupportedEncodingException; { :L6 .. :L7 } :L16\n    .catch Ljava/io/UnsupportedEncodingException; { :L8 .. :L11 } :L14\n    .catch Ljava/io/UnsupportedEncodingException; { :L12 .. :L13 } :L16\n    .registers 12\n    move v2, v10\n    if-eqz v11, :L10\n    :L0\n    iget v4, v7, Ljcifs/smb/ServerMessageBlock;->headerStart:I\n    sub-int v4, v10, v4\n    rem-int/lit8 v4, v4, 2\n    :L1\n    if-eqz v4, :L4\n    add-int/lit8 v1, v10, 1\n    const/4 v4, 0\n    :L2\n    aput-byte v4, v9, v10\n    :L3\n    move v10, v1\n    :L4\n    const-string v4, \"UTF-16LE\"\n    invoke-virtual { v8, v4 }, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B\n    move-result-object v4\n    const/4 v5, 0\n    invoke-virtual { v8 }, Ljava/lang/String;->length()I\n    move-result v6\n    mul-int/lit8 v6, v6, 2\n    invoke-static { v4, v5, v9, v10, v6 }, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V\n    invoke-virtual { v8 }, Ljava/lang/String;->length()I\n    :L5\n    move-result v4\n    mul-int/lit8 v4, v4, 2\n    add-int/2addr v10, v4\n    add-int/lit8 v1, v10, 1\n    const/4 v4, 0\n    :L6\n    aput-byte v4, v9, v10\n    :L7\n    add-int/lit8 v10, v1, 1\n    const/4 v4, 0\n    :L8\n    aput-byte v4, v9, v1\n    :L9\n    sub-int v4, v10, v2\n    return v4\n    :L10\n    sget-object v4, Ljcifs/smb/SmbConstants;->OEM_ENCODING:Ljava/lang/String;\n    invoke-virtual { v8, v4 }, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B\n    move-result-object v0\n    const/4 v4, 0\n    array-length v5, v0\n    invoke-static { v0, v4, v9, v10, v5 }, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V\n    array-length v4, v0\n    :L11\n    add-int/2addr v10, v4\n    add-int/lit8 v1, v10, 1\n    const/4 v4, 0\n    :L12\n    aput-byte v4, v9, v10\n    :L13\n    move v10, v1\n    goto :L9\n    :L14\n    move-exception v4\n    move-object v3, v4\n    :L15\n    sget-object v4, Ljcifs/smb/ServerMessageBlock;->log:Ljcifs/util/LogStream;\n    sget v4, Ljcifs/util/LogStream;->level:I\n    const/4 v5, 1\n    if-le v4, v5, :L9\n    sget-object v4, Ljcifs/smb/ServerMessageBlock;->log:Ljcifs/util/LogStream;\n    invoke-virtual { v3, v4 }, Ljava/io/UnsupportedEncodingException;->printStackTrace(Ljava/io/PrintStream;)V\n    goto :L9\n    :L16\n    move-exception v4\n    move-object v3, v4\n    move v10, v1\n    goto :L15\n.end method\n"
  },
  {
    "path": "dex-writer/build.gradle",
    "content": "description = 'Dex Writer'\n\ndependencies {\n    compile project(':dex-reader-api')\n    testCompile group: 'junit', name: 'junit', version:'4.10'\n    testCompile project(':dex-reader')\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/AnnotationWriter.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.d2j.dex.writer.ev.EncodedAnnotation;\nimport com.googlecode.d2j.dex.writer.ev.EncodedAnnotation.AnnotationElement;\nimport com.googlecode.d2j.dex.writer.ev.EncodedArray;\nimport com.googlecode.d2j.dex.writer.ev.EncodedValue;\nimport com.googlecode.d2j.dex.writer.item.ConstPool;\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\n\nimport java.util.List;\n\n/*package*/class AnnotationWriter extends DexAnnotationVisitor {\n    ConstPool cp;\n    List<AnnotationElement> elements;\n\n    public AnnotationWriter(List<AnnotationElement> elements, ConstPool cp) {\n        this.elements = elements;\n        this.cp = cp;\n    }\n\n    AnnotationElement newAnnotationElement(String name) {\n        AnnotationElement ae = new AnnotationElement();\n        ae.name = cp.uniqString(name);\n        elements.add(ae);\n        return ae;\n    }\n\n    // int,int long\n    public void visit(String name, Object value) {\n        if (value instanceof Object[]) {\n            DexAnnotationVisitor s = visitArray(name);\n            if (s != null) {\n                for (Object v : (Object[]) value) {\n                    s.visit(null, v);\n                }\n                s.visitEnd();\n            }\n        } else {\n            AnnotationElement ae = newAnnotationElement(name);\n            ae.value = EncodedValue.wrap(cp.wrapEncodedItem(value));\n        }\n    }\n\n    @Override\n    public DexAnnotationVisitor visitAnnotation(String name, String desc) {\n        EncodedValue encodedValue;\n        EncodedAnnotation encodedAnnotation = new EncodedAnnotation();\n        encodedAnnotation.type = cp.uniqType(desc);\n        encodedValue = new EncodedValue(EncodedValue.VALUE_ANNOTATION,\n                encodedAnnotation);\n        AnnotationElement ae = newAnnotationElement(name);\n        ae.value = encodedValue;\n        return new AnnotationWriter(encodedAnnotation.elements, cp);\n    }\n\n    @Override\n    public DexAnnotationVisitor visitArray(String name) {\n        AnnotationElement ae = newAnnotationElement(name);\n        final EncodedArray encodedArray = new EncodedArray();\n        ae.value = new EncodedValue(EncodedValue.VALUE_ARRAY, encodedArray);\n        return new EncodedArrayAnnWriter(encodedArray);\n    }\n\n    @Override\n    public void visitEnum(String name, String fower, String fname) {\n        AnnotationElement ae = newAnnotationElement(name);\n        ae.value = new EncodedValue(EncodedValue.VALUE_ENUM, cp.uniqField(\n                fower, fname, fower));\n    }\n\n    class EncodedArrayAnnWriter extends DexAnnotationVisitor {\n        final EncodedArray encodedArray;\n\n        public EncodedArrayAnnWriter(EncodedArray encodedArray) {\n            super();\n            this.encodedArray = encodedArray;\n        }\n\n        @Override\n        public void visit(String name, Object value) {\n            EncodedValue encodedValue;\n            if (value instanceof String) {\n                encodedValue = new EncodedValue(EncodedValue.VALUE_STRING,\n                        cp.uniqString((String) value));\n            } else if (value instanceof DexType) {\n                encodedValue = new EncodedValue(EncodedValue.VALUE_TYPE,\n                        cp.uniqType(((DexType) value).desc));\n            } else {\n                encodedValue = EncodedValue.wrap(value);\n            }\n            encodedArray.values.add(encodedValue);\n        }\n\n        @Override\n        public DexAnnotationVisitor visitAnnotation(String name, String desc) {\n            EncodedValue encodedValue;\n            EncodedAnnotation encodedAnnotation = new EncodedAnnotation();\n            encodedAnnotation.type = cp.uniqType(desc);\n            encodedValue = new EncodedValue(EncodedValue.VALUE_ANNOTATION,\n                    encodedAnnotation);\n            encodedArray.values.add(encodedValue);\n            return new AnnotationWriter(encodedAnnotation.elements, cp);\n        }\n\n        @Override\n        public DexAnnotationVisitor visitArray(String name) {\n            EncodedValue encodedValue;\n            encodedValue = new EncodedValue(EncodedValue.VALUE_ARRAY,\n                    encodedArray);\n            encodedArray.values.add(encodedValue);\n            return new EncodedArrayAnnWriter(encodedArray);\n        }\n\n        @Override\n        public void visitEnum(String name, String fower, String fname) {\n            EncodedValue encodedValue;\n            encodedValue = new EncodedValue(EncodedValue.VALUE_ENUM,\n                    cp.uniqField(fower, fname, fower));\n            encodedArray.values.add(encodedValue);\n        }\n\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/CantNotFixContentException.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\nimport com.googlecode.d2j.reader.Op;\n\npublic class CantNotFixContentException extends RuntimeException {\n    private static final long serialVersionUID = 1L;\n\n    public CantNotFixContentException(Op op, String contentName, int v) {\n        super(String.format(\"content is not fit for op: %s, %s, value:0x%x\",\n                op.displayName, contentName, v));\n    }\n\n    public CantNotFixContentException(Op op, String contentName, long v) {\n        super(String.format(\"content is not fit for op: %s, %s, value:0x%x\",\n                op.displayName, contentName, v));\n    }\n}"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ClassWriter.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.dex.writer.ev.EncodedValue;\nimport com.googlecode.d2j.dex.writer.item.*;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\n\n/*package*/class ClassWriter extends DexClassVisitor implements DexConstants {\n\n    final public ConstPool cp;\n    public ClassDefItem defItem;\n    ClassDataItem dataItem = new ClassDataItem();\n\n    public ClassWriter(ClassDefItem defItem, ConstPool cp) {\n        super();\n        this.defItem = defItem;\n        this.cp = cp;\n    }\n\n    @Override\n    public AnnotationWriter visitAnnotation(String type, Visibility visibility) {\n        final AnnotationItem annItem = new AnnotationItem(cp.uniqType(type),\n                visibility);\n        AnnotationSetItem asi = defItem.classAnnotations;\n        if (asi == null) {\n            asi = new AnnotationSetItem();\n            defItem.classAnnotations = asi;\n        }\n        asi.annotations.add(annItem);\n        return new AnnotationWriter(annItem.annotation.elements, cp);\n    }\n\n    public void visitEnd() {\n        if (dataItem != null && dataItem.getMemberSize() > 0) {\n            cp.addClassDataItem(dataItem);\n            defItem.classData = dataItem;\n        }\n        defItem.prepare(cp);\n\n    }\n\n    @Override\n    public DexFieldVisitor visitField(int accessFlags, Field field, Object value) {\n        final ClassDataItem.EncodedField encodedField = new ClassDataItem.EncodedField();\n        encodedField.accessFlags = accessFlags;\n        encodedField.field = cp.uniqField(field);\n        if (value != null) {\n            encodedField.staticValue = EncodedValue.wrap(cp.wrapEncodedItem(value));\n        }\n        if (0 != (ACC_STATIC & accessFlags)) { // is static\n            dataItem.staticFields.add(encodedField);\n        } else {\n            dataItem.instanceFields.add(encodedField);\n        }\n\n        return new FieldWriter(encodedField, cp);\n    }\n\n    @Override\n    public DexMethodVisitor visitMethod(int accessFlags, Method method) {\n        final ClassDataItem.EncodedMethod encodedMethod = new ClassDataItem.EncodedMethod();\n        encodedMethod.accessFlags = accessFlags;\n        encodedMethod.method = cp.uniqMethod(method);\n        if (0 != (accessFlags & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR))) {\n            dataItem.directMethods.add(encodedMethod);\n        } else {\n            dataItem.virtualMethods.add(encodedMethod);\n        }\n\n        return new MethodWriter(encodedMethod, method,\n                0 != (accessFlags & ACC_STATIC), cp);\n    }\n\n    @Override\n    public void visitSource(String file) {\n        defItem.sourceFile = cp.uniqString(file);\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/CodeWriter.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\nimport com.googlecode.d2j.DexLabel;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.dex.writer.insn.*;\nimport com.googlecode.d2j.dex.writer.item.*;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\nimport com.googlecode.d2j.visitors.DexDebugVisitor;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.*;\n\nimport static com.googlecode.d2j.reader.InstructionFormat.*;\nimport static com.googlecode.d2j.reader.Op.*;\n\n@SuppressWarnings(\"incomplete-switch\")\npublic class CodeWriter extends DexCodeVisitor {\n    final CodeItem codeItem;\n    final ConstPool cp;\n    ByteBuffer b = ByteBuffer.allocate(10).order(ByteOrder.LITTLE_ENDIAN);\n    int in_reg_size = 0;\n    int max_out_reg_size = 0;\n    List<Insn> ops = new ArrayList<>();\n    List<Insn> tailOps = new ArrayList<>();\n    int total_reg;\n    List<CodeItem.TryItem> tryItems = new ArrayList<>();\n    Method owner;\n    Map<DexLabel, Label> labelMap = new HashMap<>();\n    ClassDataItem.EncodedMethod encodedMethod;\n\n    public CodeWriter(ClassDataItem.EncodedMethod encodedMethod, CodeItem codeItem, Method owner, boolean isStatic, ConstPool cp) {\n        this.encodedMethod = encodedMethod;\n        this.codeItem = codeItem;\n        this.owner = owner;\n        int in_reg_size = 0;\n        if (!isStatic) {\n            in_reg_size++;\n        }\n        for (String s : owner.getParameterTypes()) {\n            switch (s.charAt(0)) {\n            case 'J':\n            case 'D':\n                in_reg_size += 2;\n                break;\n            default:\n                in_reg_size++;\n                break;\n            }\n        }\n        this.in_reg_size = in_reg_size;\n        this.cp = cp;\n    }\n\n    public static void checkContentByte(Op op, String cc, int v) {\n        if (v > Byte.MAX_VALUE || v < Byte.MIN_VALUE) {\n            throw new CantNotFixContentException(op, cc, v);\n        }\n    }\n\n    public static void checkContentS4bit(Op op, String name, int v) {\n        if (v > 7 || v < -8) { // TODO check\n            throw new CantNotFixContentException(op, name, v);\n        }\n    }\n\n    public static void checkContentShort(Op op, String cccc, int v) {\n        if (v > Short.MAX_VALUE || v < Short.MIN_VALUE) {\n            throw new CantNotFixContentException(op, cccc, v);\n        }\n    }\n\n    public static void checkContentU4bit(Op op, String name, int v) {\n        if (v > 15 || v < 0) {\n            throw new CantNotFixContentException(op, name, v);\n        }\n    }\n\n    public static void checkContentUByte(Op op, String cc, int v) {\n        if (v > 0xFF || v < 0) {\n            throw new CantNotFixContentException(op, cc, v);\n        }\n    }\n\n    public static void checkContentUShort(Op op, String cccc, int v) {\n        if (v > 0xFFFF || v < 0) {\n            throw new CantNotFixContentException(op, cccc, v);\n        }\n    }\n\n    public static void checkRegA(Op op, String s, int reg) {\n        if (reg > 0xF || reg < 0) {\n            throw new CantNotFixContentException(op, s, reg);\n        }\n    }\n\n    public static void checkRegAA(Op op, String s, int reg) {\n        if (reg > 0xFF || reg < 0) {\n            throw new CantNotFixContentException(op, s, reg);\n        }\n    }\n\n    static void checkRegAAAA(Op op, String s, int reg) {\n        if (reg > 0xFFFF || reg < 0) {\n            throw new CantNotFixContentException(op, s, reg);\n        }\n    }\n\n    static byte[] copy(ByteBuffer b) {\n        int size = b.position();\n        byte[] data = new byte[size];\n        System.arraycopy(b.array(), 0, data, 0, size);\n        return data;\n    }\n\n    public void add(Insn insn) {\n        ops.add(insn);\n    }\n\n    private byte[] build10x(Op op) {\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) 0);\n\n        return copy(b);\n    }\n\n    // B|A|op\n    private byte[] build11n(Op op, int vA, int B) {\n        checkRegA(op, \"vA\", vA);\n        checkContentS4bit(op, \"#+B\", B);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) ((vA & 0xF) | (B << 4)));\n        return copy(b);\n    }\n\n    // AA|op\n    private byte[] build11x(Op op, int vAA) {\n        checkRegAA(op, \"vAA\", vAA);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA);\n\n        return copy(b);\n    }\n\n    // B|A|op\n    private byte[] build12x(Op op, int vA, int vB) {\n        checkRegA(op, \"vA\", vA);\n        checkRegA(op, \"vB\", vB);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) ((vA & 0xF) | (vB << 4)));\n\n        return copy(b);\n    }\n\n    // AA|op BBBB\n    private byte[] build21h(Op op, int vAA, Number value) {\n        checkRegAA(op, \"vAA\", vAA);\n        int realV;\n        if (op == CONST_HIGH16) { // op vAA, #+BBBB0000\n            int v = ((Number) value).intValue();\n            if ((v & 0xFFFF) != 0) {\n                throw new CantNotFixContentException(op, \"#+BBBB0000\", v);\n            }\n            realV = v >> 16;\n\n        } else { // CONST_WIDE_HIGH16 //op vAA, #+BBBB000000000000\n            long v = ((Number) value).longValue();\n            if ((v & 0x0000FFFFffffFFFFL) != 0) {\n                throw new CantNotFixContentException(op, \"#+BBBB000000000000\", v);\n            }\n            realV = (int) (v >> 48);\n        }\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).putShort((short) realV);\n        return copy(b);\n    }\n\n    // AA|op BBBB\n    private byte[] build21s(Op op, int vAA, Number value) {\n        checkRegAA(op, \"vAA\", vAA);\n        int realV;\n        if (op == CONST_16) {\n            realV = value.intValue();\n            checkContentShort(op, \"#+BBBB\", realV);\n        } else {// CONST_WIDE_16\n            long v = value.longValue();\n            if (v > Short.MAX_VALUE || v < Short.MIN_VALUE) {\n                throw new CantNotFixContentException(op, \"#+BBBB\", v);\n            }\n            realV = (int) v;\n        }\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).putShort((short) realV);\n        return copy(b);\n    }\n\n    // AA|op CC|BB\n    private byte[] build22b(Op op, int vAA, int vBB, int cc) {\n        checkRegAA(op, \"vAA\", vAA);\n        checkRegAA(op, \"vBB\", vBB);\n        checkContentByte(op, \"#+CC\", cc);\n\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).put((byte) vBB).put((byte) cc);\n        return copy(b);\n    }\n\n    // B|A|op CCCC\n    private byte[] build22s(Op op, int A, int B, int CCCC) {\n        checkRegA(op, \"vA\", A);\n        checkRegA(op, \"vB\", B);\n        checkContentShort(op, \"+CCCC\", CCCC);\n\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) ((A & 0xF) | (B << 4))).putShort((short) CCCC);\n        return copy(b);\n    }\n\n    // AA|op BBBB\n    private byte[] build22x(Op op, int vAA, int vBBBB) {\n        checkRegAA(op, \"vAA\", vAA);\n        checkRegAAAA(op, \"vBBBB\", vBBBB);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).putShort((short) vBBBB);\n        return copy(b);\n    }\n\n    // AA|op CC|BB\n    private byte[] build23x(Op op, int vAA, int vBB, int vCC) {\n        checkRegAA(op, \"vAA\", vAA);\n        checkRegAA(op, \"vBB\", vBB);\n        checkRegAA(op, \"vCC\", vCC);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).put((byte) vBB).put((byte) vCC);\n        return copy(b);\n    }\n\n    // AA|op BBBBlo BBBBhi\n    private byte[] build31i(Op op, int vAA, Number value) {\n        checkRegAA(op, \"vAA\", vAA);\n        int realV;\n        if (op == CONST) {\n            realV = value.intValue();\n        } else if (op == CONST_WIDE_32) {\n            long v = value.longValue();\n            if (v > Integer.MAX_VALUE || v < Integer.MIN_VALUE) {\n                throw new CantNotFixContentException(op, \"#+BBBBBBBB\", v);\n            }\n            realV = (int) v;\n        } else {\n            throw new RuntimeException();\n        }\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).putInt(realV);\n        return copy(b);\n    }\n\n    // ØØ|op AAAA BBBB\n    private byte[] build32x(Op op, int vAAAA, int vBBBB) {\n        checkRegAAAA(op, \"vAAAA\", vAAAA);\n        checkRegAAAA(op, \"vBBBB\", vBBBB);\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) 0).putShort((short) vAAAA).putShort((short) vBBBB);\n        return copy(b);\n    }\n\n    // AA|op BBBBlo BBBB BBBB BBBBhi\n    private byte[] build51l(Op op, int vAA, Number value) {\n        checkRegAA(op, \"vAA\", vAA);\n\n        b.position(0);\n        b.put((byte) op.opcode).put((byte) vAA).putLong(value.longValue());\n        return copy(b);\n\n    }\n\n    Label getLabel(DexLabel label) {\n        Label mapped = labelMap.get(label);\n        if (mapped == null) {\n            mapped = new Label();\n            labelMap.put(label, mapped);\n        }\n        return mapped;\n    }\n\n    @Override\n    public void visitFillArrayDataStmt(Op op, int ra, Object value) {\n\n        ByteBuffer b;\n\n        if (value instanceof byte[]) {\n            byte[] data = (byte[]) value;\n            int size = data.length;\n            int element_width = 1;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            b.put(data);\n        } else if (value instanceof short[]) {\n            short[] data = (short[]) value;\n            int size = data.length;\n            int element_width = 2;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            for (short s : data) {\n                b.putShort(s);\n            }\n        } else if (value instanceof int[]) {\n            int[] data = (int[]) value;\n            int size = data.length;\n            int element_width = 4;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            for (int s : data) {\n                b.putInt(s);\n            }\n        } else if (value instanceof float[]) {\n            float[] data = (float[]) value;\n            int size = data.length;\n            int element_width = 4;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            for (float s : data) {\n                b.putInt(Float.floatToIntBits(s));\n            }\n        } else if (value instanceof long[]) {\n            long[] data = (long[]) value;\n            int size = data.length;\n            int element_width = 8;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            for (long s : data) {\n                b.putLong(s);\n            }\n        } else if (value instanceof double[]) {\n            double[] data = (double[]) value;\n            int size = data.length;\n            int element_width = 8;\n            b = ByteBuffer.allocate(((size * element_width + 1) / 2 + 4) * 2).order(ByteOrder.LITTLE_ENDIAN);\n            b.putShort((short) 0x0300);\n            b.putShort((short) element_width);\n            b.putInt(size);\n            for (double s : data) {\n                b.putLong(Double.doubleToLongBits(s));\n            }\n        } else {\n            throw new RuntimeException();\n        }\n        Label d = new Label();\n        ops.add(new JumpOp(op, ra, 0, d));\n\n        tailOps.add(d);\n        tailOps.add(new PreBuildInsn(b.array()));\n\n    }\n\n    /**\n     * kFmt21c,kFmt31c,kFmt11n,kFmt21h,kFmt21s,kFmt31i,kFmt51l\n     * \n     * @param op\n     * @param ra\n     * @param value\n     */\n    @Override\n    public void visitConstStmt(Op op, int ra, Object value) {\n        switch (op.format) {\n        case kFmt21c:// value is field,type,string\n        case kFmt31c:// value is string,\n            value = cp.wrapEncodedItem(value);\n            ops.add(new CodeWriter.IndexedInsn(op, ra, 0, (BaseItem) value));\n            break;\n        case kFmt11n:\n            ops.add(new PreBuildInsn(build11n(op, ra, ((Number) value).intValue())));\n            break;\n        case kFmt21h:\n            ops.add(new PreBuildInsn(build21h(op, ra, ((Number) value))));\n            break;\n        case kFmt21s:\n            ops.add(new PreBuildInsn(build21s(op, ra, ((Number) value))));\n            break;\n        case kFmt31i:\n            ops.add(new PreBuildInsn(build31i(op, ra, ((Number) value))));\n            break;\n        case kFmt51l:\n            ops.add(new PreBuildInsn(build51l(op, ra, ((Number) value))));\n            break;\n\n        }\n    }\n\n    @Override\n    public void visitEnd() {\n        if (ops.size() == 0 && tailOps.size() == 0) {\n            encodedMethod.code = null;\n            return;\n        }\n        cp.addCodeItem(codeItem);\n\n        codeItem.registersSize = this.total_reg;\n        codeItem.outsSize = max_out_reg_size;\n        codeItem.insSize = in_reg_size;\n\n        codeItem.init(ops, tailOps, tryItems);\n\n        if (codeItem.debugInfo != null) {\n            cp.addDebugInfoItem(codeItem.debugInfo);\n            List<DebugInfoItem.DNode> debugNodes = codeItem.debugInfo.debugNodes;\n            Collections.sort(debugNodes, new Comparator<DebugInfoItem.DNode>() {\n                @Override\n                public int compare(DebugInfoItem.DNode o1, DebugInfoItem.DNode o2) {\n                    int x = o1.label.offset - o2.label.offset;\n                    // if (x == 0) {\n                    // if (o1.op == o2.op) {\n                    // x = o1.reg - o2.reg;\n                    // if (x == 0) {\n                    // x = o1.line - o2.line;\n                    // }\n                    // } else {\n                    // //\n                    // }\n                    // }\n                    return x;\n                }\n            });\n        }\n\n        ops = null;\n        tailOps = null;\n        tryItems = null;\n\n    }\n\n    @Override\n    public void visitFieldStmt(Op op, int a, int b, Field field) {\n        ops.add(new CodeWriter.IndexedInsn(op, a, b, cp.uniqField(field)));\n    }\n\n    @Override\n    public void visitFilledNewArrayStmt(Op op, int[] args, String type) {\n        if (op.format == kFmt35c) {\n            ops.add(new CodeWriter.OP35c(op, args, cp.uniqType(type)));\n        } else {\n            ops.add(new CodeWriter.OP3rc(op, args, cp.uniqType(type)));\n        }\n    }\n\n    @Override\n    public void visitJumpStmt(Op op, int a, int b, DexLabel label) {\n\n        ops.add(new JumpOp(op, a, b, getLabel(label)));\n    }\n\n    @Override\n    public void visitLabel(DexLabel label) {\n        ops.add(getLabel(label));\n    }\n\n    @Override\n    public void visitMethodStmt(Op op, int[] args, Method method) {\n        if (op.format == kFmt3rc) {\n            ops.add(new CodeWriter.OP3rc(op, args, cp.uniqMethod(method)));\n        } else if (op.format == kFmt35c) {\n            ops.add(new CodeWriter.OP35c(op, args, cp.uniqMethod(method)));\n        }\n        if (args.length > max_out_reg_size) {\n            max_out_reg_size = args.length;\n        }\n    }\n\n    @Override\n    public void visitPackedSwitchStmt(Op op, int aA, final int first_case, final DexLabel[] labels) {\n        Label switch_data_location = new Label();\n        final JumpOp jumpOp = new JumpOp(op, aA, 0, switch_data_location);\n        ops.add(jumpOp);\n\n        tailOps.add(switch_data_location);\n        tailOps.add(new Insn() {\n\n            @Override\n            public int getCodeUnitSize() {\n                return (labels.length * 2) + 4;\n            }\n\n            @Override\n            public void write(ByteBuffer out) {\n                out.putShort((short) 0x0100).putShort((short) labels.length).putInt(first_case);\n\n                for (int i = 0; i < labels.length; i++) {\n                    out.putInt(getLabel(labels[i]).offset - jumpOp.offset);\n                }\n            }\n        });\n    }\n\n    @Override\n    public void visitRegister(int total) {\n        this.total_reg = total;\n    }\n\n    @Override\n    public void visitSparseSwitchStmt(Op op, int ra, final int[] cases, final DexLabel[] labels) {\n        Label switch_data_location = new Label();\n        final JumpOp jumpOp = new JumpOp(op, ra, 0, switch_data_location);\n        ops.add(jumpOp);\n\n        tailOps.add(switch_data_location);\n        tailOps.add(new Insn() {\n\n            @Override\n            public int getCodeUnitSize() {\n                return (cases.length * 4) + 2;\n            }\n\n            @Override\n            public void write(ByteBuffer out) {\n                out.putShort((short) 0x0200).putShort((short) cases.length);\n                for (int i = 0; i < cases.length; i++) {\n                    out.putInt(cases[i]);\n                }\n                for (int i = 0; i < cases.length; i++) {\n                    out.putInt(getLabel(labels[i]).offset - jumpOp.offset);\n                }\n            }\n        });\n\n    }\n\n    @Override\n    public void visitStmt0R(Op op) {\n        if (op == BAD_OP) {\n            // TODO check\n        } else {\n            if (op.format == kFmt10x) {\n                ops.add(new PreBuildInsn(build10x(op)));\n            } else {\n                // FIXME error\n            }\n        }\n    }\n\n    /**\n     * kFmt11x\n     * \n     * @param op\n     * @param reg\n     */\n    @Override\n    public void visitStmt1R(Op op, int reg) {\n        if (op.format == kFmt11x) {\n            ops.add(new PreBuildInsn(build11x(op, reg)));\n        } else {\n        }\n    }\n\n    /**\n     * kFmt12x,kFmt22x,kFmt32x\n     * \n     * @param op\n     * @param a\n     * @param b\n     */\n    @Override\n    public void visitStmt2R(Op op, int a, int b) {\n        switch (op.format) {\n        case kFmt12x:\n            ops.add(new PreBuildInsn(build12x(op, a, b)));\n            break;\n        case kFmt22x:\n            ops.add(new PreBuildInsn(build22x(op, a, b)));\n            break;\n        case kFmt32x:\n            ops.add(new PreBuildInsn(build32x(op, a, b)));\n            break;\n        }\n    }\n\n    /**\n     * Only kFmt22s, kFmt22b\n     * \n     * @param op\n     * @param distReg\n     * @param srcReg\n     * @param content\n     */\n    @Override\n    public void visitStmt2R1N(Op op, int distReg, int srcReg, int content) {\n        if (op.format == kFmt22s) {\n            ops.add(new PreBuildInsn(build22s(op, distReg, srcReg, content)));\n        } else if (op.format == kFmt22b) {\n            ops.add(new PreBuildInsn(build22b(op, distReg, srcReg, content)));\n        } else {\n        }\n    }\n\n    /**\n     * kFmt23x\n     * \n     * @param op\n     * @param a\n     * @param b\n     * @param c\n     */\n    @Override\n    public void visitStmt3R(Op op, int a, int b, int c) {\n        if (op.format == kFmt23x) {\n            ops.add(new PreBuildInsn(build23x(op, a, b, c)));\n        } else {\n        }\n    }\n\n    @Override\n    public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handlers, String[] types) {\n        CodeItem.TryItem tryItem = new CodeItem.TryItem();\n        tryItem.start = getLabel(start);\n        tryItem.end = getLabel(end);\n        CodeItem.EncodedCatchHandler ech = new CodeItem.EncodedCatchHandler();\n        tryItem.handler = ech;\n        tryItems.add(tryItem);\n        ech.addPairs = new ArrayList<>(types.length);\n        for (int i = 0; i < types.length; i++) {\n            String type = types[i];\n            Label label = getLabel(handlers[i]);\n            if (type == null) {\n                ech.catchAll = label;\n            } else {\n                ech.addPairs.add(new CodeItem.EncodedCatchHandler.AddrPair(cp.uniqType(type), label));\n            }\n        }\n    }\n\n    @Override\n    public void visitTypeStmt(Op op, int a, int b, String type) {\n        ops.add(new CodeWriter.IndexedInsn(op, a, b, cp.uniqType(type)));\n    }\n\n    public static class IndexedInsn extends OpInsn {\n        final int a, b;\n        final BaseItem idxItem;\n\n        public IndexedInsn(Op op, int a, int b, BaseItem idxItem) {\n            super(op);\n            switch (op.format) {\n            case kFmt21c:\n            case kFmt31c:\n                checkRegAA(op, \"vAA\", a);\n                break;\n            case kFmt22c:\n                checkContentU4bit(op, \"A\", a);\n                checkContentU4bit(op, \"B\", b);\n                break;\n            }\n\n            this.a = a;\n            this.b = b;\n            this.idxItem = idxItem;\n        }\n\n        // 21c AA|op BBBB\n        // 31c AA|op BBBBlo BBBBhi\n        // 22c B|A|op CCCC\n        @Override\n        public void write(ByteBuffer out) {\n            out.put((byte) op.opcode);\n            switch (op.format) {\n            case kFmt21c:\n                checkContentUShort(op, \"?@BBBB\", idxItem.index);\n                out.put((byte) a).putShort((short) idxItem.index);\n                break;\n            case kFmt31c:\n                out.put((byte) a).putInt(idxItem.index);\n                break;\n            case kFmt22c: // B|A|op CCCC\n                checkContentUShort(op, \"?@CCCC\", idxItem.index);\n                out.put((byte) ((a & 0xF) | (b << 4))).putShort((short) idxItem.index);\n                break;\n            }\n        }\n\n        public void fit() {\n            if (op == CONST_STRING && (idxItem.index > 0xFFFF || idxItem.index < 0)) {\n                op = CONST_STRING_JUMBO;\n            }\n        }\n    }\n\n    public static class OP35c extends OpInsn {\n        final BaseItem item;\n        int A, C, D, E, F, G;\n\n        public OP35c(Op op, int[] args, BaseItem item) {\n            super(op);\n            int A = args.length;\n            if (A > 5) {\n                throw new CantNotFixContentException(op, \"A\", A);\n            }\n            this.A = A;\n            switch (A) { // [A=5] op {vC, vD, vE, vF, vG},\n            case 5:\n                G = args[4];\n                checkContentU4bit(op, \"vG\", G);\n            case 4:\n                F = args[3];\n                checkContentU4bit(op, \"vF\", F);\n            case 3:\n                E = args[2];\n                checkContentU4bit(op, \"vE\", E);\n            case 2:\n                D = args[1];\n                checkContentU4bit(op, \"vD\", D);\n            case 1:\n                C = args[0];\n                checkContentU4bit(op, \"vC\", C);\n                break;\n            }\n            this.item = item;\n        }\n\n        @Override\n        public void write(ByteBuffer out) { // A|G|op BBBB F|E|D|C\n            checkContentUShort(op, \"@BBBB\", item.index);\n            out.put((byte) op.opcode).put((byte) ((A << 4) | (G & 0xF))).putShort((short) item.index)\n                    .put((byte) ((D << 4) | (C & 0xF))).put((byte) ((F << 4) | (E & 0xF)));\n        }\n    }\n\n    // AA|op BBBB CCCC\n    public static class OP3rc extends OpInsn {\n        final BaseItem item;\n        final int length;\n        final int start;\n\n        public OP3rc(Op op, int[] args, BaseItem item) {\n            super(op);\n            this.item = item;\n            length = args.length;\n            checkContentUByte(op, \"AA\", length);\n            if (length > 0) {\n                start = args[0];\n                checkContentUShort(op, \"CCCC\", start);\n                for (int i = 1; i < args.length; i++) {\n                    if (start + i != args[i]) {\n                        throw new CantNotFixContentException(op, \"a\", args[i]);\n                    }\n                }\n            } else {\n                start = 0;\n            }\n\n        }\n\n        @Override\n        public void write(ByteBuffer out) {\n            checkContentUShort(op, \"@BBBB\", item.index);\n            out.put((byte) op.opcode).put((byte) length).putShort((short) item.index).putShort((short) start);\n        }\n    }\n\n    @Override\n    public DexDebugVisitor visitDebug() {\n\n        if (codeItem.debugInfo == null) {\n            codeItem.debugInfo = new DebugInfoItem();\n            codeItem.debugInfo.parameterNames=new StringIdItem[owner.getParameterTypes().length];\n        }\n        final DebugInfoItem debugInfoItem = codeItem.debugInfo;\n        return new DexDebugVisitor() {\n\n            @Override\n            public void visitParameterName(int parameterIndex, String name) {\n                if (name == null) {\n                    return;\n                }\n                if (parameterIndex >= debugInfoItem.parameterNames.length) {\n                    return;\n                }\n                debugInfoItem.parameterNames[parameterIndex] = cp.uniqString(name);\n            }\n\n            @Override\n            public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) {\n                if (signature == null) {\n                    debugInfoItem.debugNodes.add(DebugInfoItem.DNode.startLocal(reg, getLabel(label),\n                            cp.uniqString(name), cp.uniqType(type)));\n                } else {\n                    debugInfoItem.debugNodes.add(DebugInfoItem.DNode.startLocalEx(reg, getLabel(label),\n                            cp.uniqString(name), cp.uniqType(type), cp.uniqString(signature)));\n                }\n            }\n\n            int miniLine = 0;\n\n            @Override\n            public void visitLineNumber(int line, DexLabel label) {\n                if ((0x00000000FFFFffffL & line) < miniLine) {\n                    miniLine = line;\n                }\n                debugInfoItem.debugNodes.add(DebugInfoItem.DNode.line(line, getLabel(label)));\n            }\n\n            @Override\n            public void visitPrologue(DexLabel dexLabel) {\n                debugInfoItem.debugNodes.add(DebugInfoItem.DNode.prologue( getLabel(dexLabel)));\n            }\n\n            @Override\n            public void visitEpiogue(DexLabel dexLabel) {\n                debugInfoItem.debugNodes.add(DebugInfoItem.DNode.epiogue( getLabel(dexLabel)));\n            }\n\n            @Override\n            public void visitEndLocal(int reg, DexLabel label) {\n                debugInfoItem.debugNodes.add(DebugInfoItem.DNode.endLocal(reg, getLabel(label)));\n            }\n\n            @Override\n            public void visitSetFile(String file) {\n                debugInfoItem.fileName = cp.uniqString(file);\n            }\n\n            @Override\n            public void visitRestartLocal(int reg, DexLabel label) {\n                debugInfoItem.debugNodes.add(DebugInfoItem.DNode.restartLocal(reg, getLabel(label)));\n            }\n\n            @Override\n            public void visitEnd() {\n                debugInfoItem.firstLine = miniLine;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/DexFileWriter.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\nimport com.googlecode.d2j.dex.writer.io.ByteBufferOut;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.*;\nimport com.googlecode.d2j.dex.writer.item.SectionItem.SectionType;\nimport com.googlecode.d2j.visitors.DexClassVisitor;\nimport com.googlecode.d2j.visitors.DexFileVisitor;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.nio.ByteBuffer;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.zip.Adler32;\n\npublic class DexFileWriter extends DexFileVisitor {\n    private static final boolean DEBUG = false;\n    MapListItem mapItem;\n    HeadItem headItem;\n    public ConstPool cp = new ConstPool();\n\n    static private DataOut wrapDumpOut(final DataOut out0) {\n        return (DataOut) Proxy.newProxyInstance(\n                DexFileWriter.class.getClassLoader(),\n                new Class[]{DataOut.class}, new InvocationHandler() {\n            int indent = 0;\n\n            @Override\n            public Object invoke(Object proxy, Method method,\n                                 Object[] args) throws Throwable {\n\n                if (method.getParameterTypes().length > 0\n                        && method.getParameterTypes()[0]\n                        .equals(String.class)) {\n                    StringBuilder sb = new StringBuilder();\n                    for (int i = 0; i < indent; i++) {\n                        sb.append(\"  \");\n                    }\n                    sb.append(String.format(\"%05d \", out0.offset()));\n                    sb.append(method.getName() + \" [\");\n                    for (Object arg : args) {\n                        if (arg instanceof byte[]) {\n                            byte[] data = (byte[]) arg;\n                            sb.append(\"0x[\");\n                            int start = 0;\n                            int size = data.length;\n                            if (args.length > 2) {\n                                start = (Integer) args[2];\n                                size = (Integer) args[3];\n                            }\n                            for (int i = 0; i < size; i++) {\n                                sb.append(String.format(\"%02x\",\n                                        data[start + i] & 0xff));\n                                if (i != size - 1) {\n                                    sb.append(\", \");\n                                }\n                            }\n\n                            sb.append(\"], \");\n                        } else {\n                            sb.append(arg).append(\", \");\n                        }\n\n                    }\n                    sb.append(\"]\");\n                    System.out.println(sb);\n                }\n                if (method.getName().equals(\"begin\")) {\n                    indent++;\n                }\n                if (method.getName().equals(\"end\")) {\n                    indent--;\n                }\n                return method.invoke(out0, args);\n            }\n        });\n\n    }\n\n    void buildMapListItem() {\n\n        // begin ===========\n        // satisfy 'bool DexFileVerifier::CheckMap()' on art/runtime/dex_file_verifier.cc\n        // make sure the items are not empty\n        if (cp.classDefs.isEmpty()) {\n            System.err.println(\"WARN: no classdef on the dex\");\n        }\n        if (cp.methods.isEmpty()) {\n            cp.uniqMethod(\"Ljava/lang/Object;\", \"<init>\", new String[0], \"V\");\n        }\n        if (cp.fields.isEmpty()) {\n            cp.uniqField(\"Ljava/lang/System;\", \"out\", \"Ljava/io/PrintStream;\");\n        }\n        if (cp.protos.isEmpty()) {\n            cp.uniqProto(new String[0], \"V\");\n        }\n        if (cp.types.isEmpty()) {\n            cp.uniqType(\"V\");\n        }\n        if (cp.strings.isEmpty()) {\n            cp.uniqString(\"V\");\n        }\n        // end ===========\n\n        mapItem = new MapListItem();\n        headItem = new HeadItem();\n        SectionItem<HeadItem> headSection = new SectionItem<>(SectionType.TYPE_HEADER_ITEM);\n        headSection.items.add(headItem);\n        SectionItem<MapListItem> mapSection = new SectionItem<MapListItem>(SectionType.TYPE_MAP_LIST);\n        mapSection.items.add(mapItem);\n        SectionItem<StringIdItem> stringIdSection = new SectionItem<>(\n                SectionType.TYPE_STRING_ID_ITEM, cp.strings.values());\n        SectionItem<TypeIdItem> typeIdSection = new SectionItem<>(\n                SectionType.TYPE_TYPE_ID_ITEM, cp.types.values());\n        SectionItem<ProtoIdItem> protoIdSection = new SectionItem<>(\n                SectionType.TYPE_PROTO_ID_ITEM, cp.protos.values());\n        SectionItem<FieldIdItem> fieldIdSection = new SectionItem<>(\n                SectionType.TYPE_FIELD_ID_ITEM, cp.fields.values());\n        SectionItem<MethodIdItem> methodIdSection = new SectionItem<>(\n                SectionType.TYPE_METHOD_ID_ITEM, cp.methods.values());\n        SectionItem<ClassDefItem> classDefSection = new SectionItem<>(\n                SectionType.TYPE_CLASS_DEF_ITEM, cp.buildSortedClassDefItems());\n        SectionItem<TypeListItem> typeListSection = new SectionItem<>(\n                SectionType.TYPE_TYPE_LIST, cp.typeLists.values());\n        SectionItem<AnnotationSetRefListItem> annotationSetRefListItemSection = new SectionItem<>(\n                SectionType.TYPE_ANNOTATION_SET_REF_LIST,\n                cp.annotationSetRefListItems.values());\n        SectionItem<AnnotationSetItem> annotationSetSection = new SectionItem<>(\n                SectionType.TYPE_ANNOTATION_SET_ITEM,\n                cp.annotationSetItems.values());\n        SectionItem<ClassDataItem> classDataItemSection = new SectionItem<>(\n                SectionType.TYPE_CLASS_DATA_ITEM, cp.classDataItems);\n        SectionItem<CodeItem> codeItemSection = new SectionItem<>(\n                SectionType.TYPE_CODE_ITEM, cp.codeItems);\n        SectionItem<StringDataItem> stringDataItemSection = new SectionItem<>(\n                SectionType.TYPE_STRING_DATA_ITEM, cp.stringDatas);\n        SectionItem<DebugInfoItem> debugInfoSection = new SectionItem<>(\n                SectionType.TYPE_DEBUG_INFO_ITEM, cp.debugInfoItems);\n        SectionItem<AnnotationItem> annotationItemSection = new SectionItem<>(\n                SectionType.TYPE_ANNOTATION_ITEM, cp.annotationItems.values());\n        SectionItem<EncodedArrayItem> encodedArrayItemSection = new SectionItem<>(\n                SectionType.TYPE_ENCODED_ARRAY_ITEM, cp.encodedArrayItems);\n        SectionItem<AnnotationsDirectoryItem> annotationsDirectoryItemSection = new SectionItem<>(\n                SectionType.TYPE_ANNOTATIONS_DIRECTORY_ITEM,\n                cp.annotationsDirectoryItems);\n\n        {\n            headItem.mapSection = mapSection;\n            headItem.stringIdSection = stringIdSection;\n            headItem.typeIdSection = typeIdSection;\n            headItem.protoIdSection = protoIdSection;\n            headItem.fieldIdSection = fieldIdSection;\n            headItem.methodIdSection = methodIdSection;\n            headItem.classDefSection = classDefSection;\n        }\n\n        List<SectionItem<?>> dataSectionItems = new ArrayList<>();\n        {\n            dataSectionItems.add(mapSection); // data section\n            dataSectionItems.add(typeListSection);// data section\n            dataSectionItems.add(annotationSetRefListItemSection);// data\n            // section\n            dataSectionItems.add(annotationSetSection);// data section\n            // make codeItem Before classDataItem\n            dataSectionItems.add(codeItemSection);// data section\n            dataSectionItems.add(classDataItemSection);// data section\n            dataSectionItems.add(stringDataItemSection);// data section\n            dataSectionItems.add(debugInfoSection);// data section\n            dataSectionItems.add(annotationItemSection);// data section\n            dataSectionItems.add(encodedArrayItemSection);// data section\n            dataSectionItems.add(annotationsDirectoryItemSection);// data\n            // section\n        }\n\n        List<SectionItem<?>> items = mapItem.items;\n        {\n            items.add(headSection);\n            items.add(stringIdSection);\n            items.add(typeIdSection);\n            items.add(protoIdSection);\n            items.add(fieldIdSection);\n            items.add(methodIdSection);\n            items.add(classDefSection);\n\n            items.addAll(dataSectionItems);\n        }\n        // cp is useless now since all value are copied now\n        cp.clean();\n        cp = null;\n    }\n\n    public byte[] toByteArray() {\n\n        // init structure for writing\n        buildMapListItem();\n\n        // place all item into file, we can know the size now\n        final int size = place();\n\n        ByteBuffer buffer = ByteBuffer.allocate(size);\n        DataOut out = new ByteBufferOut(buffer);\n\n        if (DEBUG) {\n            out = wrapDumpOut(out);\n        }\n        // write it\n        write(out);\n\n        if (size != buffer.position()) {\n            throw new RuntimeException(\"generated different file size, planned \" + size + \", but is \" + buffer.position());\n        }\n\n        // update the CRC/ sha1 checksum in dex header\n        updateChecksum(buffer, size);\n\n        return buffer.array();\n    }\n\n    public static void updateChecksum(ByteBuffer buffer, int size) {\n        byte[] data = buffer.array();\n        MessageDigest digest;\n        try {\n            digest = MessageDigest.getInstance(\"SHA-1\");\n        } catch (NoSuchAlgorithmException e) {\n            throw new AssertionError();\n        }\n\n        digest.update(data, 32, size - 32);\n        byte[] sha1 = digest.digest();\n        System.arraycopy(sha1, 0, data, 12, sha1.length);\n\n        Adler32 adler32 = new Adler32();\n        adler32.update(data, 12, size - 12);\n        int v = (int) adler32.getValue();\n        buffer.position(8);\n        buffer.putInt(v);\n    }\n\n    private void write(DataOut out) {\n        List<SectionItem<?>> list = new ArrayList<>(mapItem.items);\n        // mapItem is useless now\n        this.mapItem = null;\n        for (int i = 0; i < list.size(); i++) {\n            SectionItem<?> section = list.get(i);\n            list.set(i, null);\n            BaseItem.addPadding(out, out.offset(),\n                    section.sectionType.alignment);\n            if (out.offset() != section.offset) {\n                throw new RuntimeException(section.sectionType\n                        + \" start with different position, planned:\"\n                        + section.offset + \", but is:\" + out.offset());\n            }\n            section.write(out);\n        }\n    }\n\n    private int place() {\n        // 2. order\n        mapItem.cleanZeroSizeEntry();\n\n        // 3. place\n        int offset = 0;\n        // int index = 0;\n        for (SectionItem<?> section : mapItem.items) {\n\n            offset = BaseItem.padding(offset, section.sectionType.alignment);\n            section.offset = offset;\n            // section.index = index;\n            // index++;\n            offset = section.place(offset);\n        }\n        int size = offset;\n        { // fix size\n            headItem.fileSize = size;\n            // headItem is useless now\n            this.headItem = null;\n        }\n        return size;\n    }\n\n    @Override\n    public DexClassVisitor visit(int accessFlag, String name,\n                                 String superClass, String[] itfClass) {\n        ClassDefItem defItem = cp.putClassDefItem(accessFlag, name, superClass,\n                itfClass);\n        return new ClassWriter(defItem, cp);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/DexWriteException.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer;\n\npublic class DexWriteException extends RuntimeException {\n\n    private static final long serialVersionUID = 1L;\n\n    public DexWriteException() {\n        super();\n\n    }\n\n    public DexWriteException(String message) {\n        super(message);\n\n    }\n\n    public DexWriteException(String message, Throwable cause) {\n        super(message, cause);\n\n    }\n\n    public DexWriteException(String message, Throwable cause,\n                             boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n\n    }\n\n    public DexWriteException(Throwable cause) {\n        super(cause);\n\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/FieldWriter.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.dex.writer;\r\n\r\nimport com.googlecode.d2j.Visibility;\r\nimport com.googlecode.d2j.dex.writer.item.AnnotationItem;\r\nimport com.googlecode.d2j.dex.writer.item.AnnotationSetItem;\r\nimport com.googlecode.d2j.dex.writer.item.ClassDataItem;\r\nimport com.googlecode.d2j.dex.writer.item.ConstPool;\r\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\r\nimport com.googlecode.d2j.visitors.DexFieldVisitor;\r\n\r\n/*package*/class FieldWriter extends DexFieldVisitor {\r\n    final public ConstPool cp;\r\n    private final ClassDataItem.EncodedField encodedField;\r\n\r\n    public FieldWriter(ClassDataItem.EncodedField encodedField, ConstPool cp) {\r\n        this.encodedField = encodedField;\r\n        this.cp = cp;\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitAnnotation(String name,\r\n                                                Visibility visibility) {\r\n        final AnnotationItem annItem = new AnnotationItem(cp.uniqType(name),\r\n                visibility);\r\n        AnnotationSetItem asi = encodedField.annotationSetItem;\r\n        if (asi == null) {\r\n            asi = new AnnotationSetItem();\r\n            encodedField.annotationSetItem = asi;\r\n        }\r\n        asi.annotations.add(annItem);\r\n        return new AnnotationWriter(annItem.annotation.elements, cp);\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/MethodWriter.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.dex.writer;\r\n\r\nimport com.googlecode.d2j.Method;\r\nimport com.googlecode.d2j.Visibility;\r\nimport com.googlecode.d2j.dex.writer.item.*;\r\nimport com.googlecode.d2j.visitors.DexAnnotationAble;\r\nimport com.googlecode.d2j.visitors.DexAnnotationVisitor;\r\nimport com.googlecode.d2j.visitors.DexCodeVisitor;\r\nimport com.googlecode.d2j.visitors.DexMethodVisitor;\r\n\r\n/*package*/class MethodWriter extends DexMethodVisitor {\r\n    final public ConstPool cp;\r\n    private final ClassDataItem.EncodedMethod encodedMethod;\r\n    final boolean isStatic;\r\n    final Method method;\r\n    private final int parameterSize;\r\n\r\n    public MethodWriter(ClassDataItem.EncodedMethod encodedMethod, Method m,\r\n                        boolean isStatic, ConstPool cp) {\r\n        this.encodedMethod = encodedMethod;\r\n        this.parameterSize = m.getParameterTypes().length;\r\n        this.cp = cp;\r\n        this.method = m;\r\n        this.isStatic = isStatic;\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationVisitor visitAnnotation(String name,\r\n                                                Visibility visibility) {\r\n        final AnnotationItem annItem = new AnnotationItem(cp.uniqType(name),\r\n                visibility);\r\n        AnnotationSetItem asi = encodedMethod.annotationSetItem;\r\n        if (asi == null) {\r\n            asi = new AnnotationSetItem();\r\n            encodedMethod.annotationSetItem = asi;\r\n        }\r\n        asi.annotations.add(annItem);\r\n        return new AnnotationWriter(annItem.annotation.elements, cp);\r\n    }\r\n\r\n    @Override\r\n    public DexCodeVisitor visitCode() {\r\n        encodedMethod.code = new CodeItem();\r\n        return new CodeWriter(encodedMethod, encodedMethod.code, method, isStatic, cp);\r\n    }\r\n\r\n    @Override\r\n    public DexAnnotationAble visitParameterAnnotation(final int index) {\r\n        return new DexAnnotationAble() {\r\n            @Override\r\n            public DexAnnotationVisitor visitAnnotation(String name,\r\n                                                        Visibility visibility) {\r\n                AnnotationSetRefListItem asrl = encodedMethod.parameterAnnotation;\r\n                if (asrl == null) {\r\n                    asrl = new AnnotationSetRefListItem(parameterSize);\r\n                    encodedMethod.parameterAnnotation = asrl;\r\n                }\r\n                AnnotationSetItem asi = asrl.annotationSets[index];\r\n                if (asi == null) {\r\n                    asi = new AnnotationSetItem();\r\n                    asrl.annotationSets[index] = asi;\r\n                }\r\n                final AnnotationItem annItem = new AnnotationItem(\r\n                        cp.uniqType(name), visibility);\r\n                asi.annotations.add(annItem);\r\n                return new AnnotationWriter(annItem.annotation.elements, cp);\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ann/Alignment.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ann;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.SOURCE)\npublic @interface Alignment {\n    int value();\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ann/Idx.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ann;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.SOURCE)\npublic @interface Idx {\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ann/Off.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ann;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.SOURCE)\npublic @interface Off {\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ev/EncodedAnnotation.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ev;\n\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.BaseItem;\nimport com.googlecode.d2j.dex.writer.item.StringIdItem;\nimport com.googlecode.d2j.dex.writer.item.TypeIdItem;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class EncodedAnnotation {\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        EncodedAnnotation that = (EncodedAnnotation) o;\n\n        if (!elements.equals(that.elements)) return false;\n        if (!type.equals(that.type)) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = type.hashCode();\n        result = 31 * result + elements.hashCode();\n        return result;\n    }\n\n    public static class AnnotationElement {\n        public StringIdItem name;\n        public EncodedValue value;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            AnnotationElement that = (AnnotationElement) o;\n\n            if (!name.equals(that.name)) return false;\n            if (!value.equals(that.value)) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = name.hashCode();\n            result = 31 * result + value.hashCode();\n            return result;\n        }\n    }\n\n    @Idx\n    public TypeIdItem type;\n    final public List<AnnotationElement> elements = new ArrayList<>(5);\n\n    public int place(int offset) {\n        offset += BaseItem.lengthOfUleb128(type.index);\n        offset += BaseItem.lengthOfUleb128(elements.size());\n        for (AnnotationElement ae : elements) {\n            offset += BaseItem.lengthOfUleb128(ae.name.index);\n            offset = ae.value.place(offset);\n        }\n        return offset;\n    }\n\n    public void write(DataOut out) {\n        out.uleb128(\"type_idx\", type.index);\n        out.uleb128(\"size\", elements.size());\n        for (AnnotationElement ae : elements) {\n            out.uleb128(\"name_idx\", ae.name.index);\n            ae.value.write(out);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ev/EncodedArray.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ev;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.BaseItem;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class EncodedArray {\n\n    public List<EncodedValue> values = new ArrayList<>(5);\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        EncodedArray that = (EncodedArray) o;\n\n        if (!values.equals(that.values)) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        return values.hashCode();\n    }\n\n    public int place(int offset) {\n        offset += BaseItem.lengthOfUleb128(values.size());\n        for (EncodedValue ev : values) {\n            offset = ev.place(offset);\n        }\n        return offset;\n    }\n\n    public void write(DataOut out) {\n        out.uleb128(\"size\", values.size());\n        for (EncodedValue ev : values) {\n            ev.write(out);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/ev/EncodedValue.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.ev;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.*;\n\npublic class EncodedValue {\n\n    public final static int VALUE_ANNOTATION = 0x1d;\n    public final static int VALUE_ARRAY = 0x1c;\n    public final static int VALUE_BOOLEAN = 0x1f;\n    public final static int VALUE_BYTE = 0x00;\n    public final static int VALUE_CHAR = 0x03;\n    public final static int VALUE_DOUBLE = 0x11;\n    public final static int VALUE_ENUM = 0x1b;\n    public final static int VALUE_FIELD = 0x19;\n    public final static int VALUE_FLOAT = 0x10;\n    public final static int VALUE_INT = 0x04;\n    public final static int VALUE_LONG = 0x06;\n    public final static int VALUE_METHOD = 0x1a;\n    public final static int VALUE_NULL = 0x1e;\n    public final static int VALUE_SHORT = 0x02;\n    public final static int VALUE_STRING = 0x17;\n    public final static int VALUE_TYPE = 0x18;\n    public final int valueType;\n    public Object value;\n\n    public EncodedValue(int valueType, Object value) {\n        this.valueType = valueType;\n        this.value = value;\n    }\n\n    public static int lengthOfDouble(double value) {\n        int requiredBits = 64 - Long.numberOfTrailingZeros(Double.doubleToRawLongBits(value));\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n        return (requiredBits + 0x07) >> 3;\n    }\n\n    public static int lengthOfFloat(float value) {\n        int requiredBits = 64 - Long.numberOfTrailingZeros(((long) (Float.floatToRawIntBits(value))) << 32);\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n        return (requiredBits + 0x07) >> 3;\n    }\n\n    public static int lengthOfSint(int value) {\n        int nbBits = 33 - Integer.numberOfLeadingZeros(value ^ (value >> 31));\n        return (nbBits + 0x07) >> 3;\n    }\n\n    public static int lengthOfSint(long value) {\n        int nbBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));\n        return (nbBits + 0x07) >> 3;\n    }\n\n    public final static int lengthOfUint(int val) {\n        int size = 1;\n        if (val != 0) {\n            val = val >>> 8;\n            if (val != 0) {\n                size++;\n                val = val >>> 8;\n                if (val != 0) {\n                    size++;\n                    val = val >>> 8;\n                    if (val != 0) {\n                        size++;\n                    }\n                }\n            }\n        }\n        return size;\n    }\n\n    public static EncodedValue wrap(Object v) {\n        if (v == null) {\n            return new EncodedValue(VALUE_NULL, null);\n        }\n        if (v instanceof Integer) {\n            return new EncodedValue(VALUE_INT, v);\n        } else if (v instanceof Short) {\n            return new EncodedValue(VALUE_SHORT, v);\n        } else if (v instanceof Character) {\n            return new EncodedValue(VALUE_CHAR, v);\n        } else if (v instanceof Long) {\n            return new EncodedValue(VALUE_LONG, v);\n        } else if (v instanceof Float) {\n            return new EncodedValue(VALUE_FLOAT, v);\n        } else if (v instanceof Double) {\n            return new EncodedValue(VALUE_DOUBLE, v);\n        } else if (v instanceof Boolean) {\n            return new EncodedValue(VALUE_BOOLEAN, v);\n        } else if (v instanceof Byte) {\n            return new EncodedValue(VALUE_BYTE, v);\n        } else if (v instanceof TypeIdItem) {\n            return new EncodedValue(VALUE_TYPE, v);\n        } else if (v instanceof StringIdItem) {\n            return new EncodedValue(VALUE_STRING, v);\n        } else if (v instanceof FieldIdItem) {\n            return new EncodedValue(VALUE_FIELD, v);\n        } else if (v instanceof MethodIdItem) {\n            return new EncodedValue(VALUE_METHOD, v);\n        }\n\n\n        throw new RuntimeException(\"not support\");\n    }\n\n    public static EncodedValue defaultValueForType(String typeString) {\n        switch (typeString.charAt(0)) {\n            case '[':\n            case 'L':\n                return new EncodedValue(VALUE_NULL, null);\n            case 'B':\n                return new EncodedValue(VALUE_BYTE, (byte) 0);\n            case 'Z':\n                return new EncodedValue(VALUE_BOOLEAN, false);\n            case 'S':\n                return new EncodedValue(VALUE_SHORT, (short) 0);\n            case 'C':\n                return new EncodedValue(VALUE_CHAR, (char) 0);\n            case 'I':\n                return new EncodedValue(VALUE_INT, (int) 0);\n            case 'F':\n                return new EncodedValue(VALUE_FLOAT, (float) 0);\n            case 'D':\n                return new EncodedValue(VALUE_DOUBLE, (double) 0);\n            case 'J':\n                return new EncodedValue(VALUE_LONG, (long) 0);\n            default:\n                throw new RuntimeException();\n        }\n    }\n\n    static byte[] encodeLong(int length, long value) {\n        byte[] data = new byte[length];\n        switch (length) {\n            case 8:\n                data[7] = (byte) (value >> 56);\n            case 7:\n                data[6] = (byte) (value >> 48);\n            case 6:\n                data[5] = (byte) (value >> 40);\n            case 5:\n                data[4] = (byte) (value >> 32);\n            case 4:\n                data[3] = (byte) (value >> 24);\n            case 3:\n                data[2] = (byte) (value >> 16);\n            case 2:\n                data[1] = (byte) (value >> 8);\n            case 1:\n                data[0] = (byte) (value >> 0);\n                break;\n            default:\n                throw new RuntimeException();\n\n        }\n        return data;\n    }\n\n    static byte[] encodeSint(int length, int value) {\n        byte[] data = new byte[length];\n        switch (length) {\n            case 4:\n                data[3] = (byte) (value >> 24);\n            case 3:\n                data[2] = (byte) (value >> 16);\n            case 2:\n                data[1] = (byte) (value >> 8);\n            case 1:\n                data[0] = (byte) (value >> 0);\n                break;\n            default:\n                throw new RuntimeException();\n        }\n        return data;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        EncodedValue that = (EncodedValue) o;\n\n        if (valueType != that.valueType) return false;\n        if (value != null ? !value.equals(that.value) : that.value != null) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = valueType;\n        result = 31 * result + (value != null ? value.hashCode() : 0);\n        return result;\n    }\n\n    public boolean isDefaultValueForType() {\n        if (valueType == VALUE_NULL) {\n            return true;\n        }\n        switch (valueType) {\n            case VALUE_CHAR:\n                Character c = (Character) this.value;\n                return c.charValue() == 0;\n            case VALUE_BYTE:\n            case VALUE_INT:\n            case VALUE_SHORT:\n                return ((Number) this.value).intValue() == 0;\n            case VALUE_LONG:\n                return ((Number) this.value).longValue() == 0;\n            case VALUE_FLOAT:\n                return ((Number) this.value).floatValue() == 0.0f;\n            case VALUE_DOUBLE:\n                return ((Number) this.value).doubleValue() == 0.0;\n            case VALUE_BOOLEAN:\n                Boolean z = (Boolean) this.value;\n                return Boolean.FALSE.equals(z);\n        }\n        return false;\n    }\n\n    protected int doPlace(int offset) {\n        switch (valueType) {\n            case VALUE_NULL:\n            case VALUE_BOOLEAN:\n                return offset;\n            case VALUE_ARRAY: {\n                EncodedArray ea = (EncodedArray) value;\n                return ea.place(offset);\n            }\n            case VALUE_ANNOTATION: {\n                EncodedAnnotation ea = (EncodedAnnotation) value;\n                return ea.place(offset);\n            }\n            case VALUE_STRING:\n            case VALUE_TYPE:\n            case VALUE_FIELD:\n            case VALUE_METHOD:\n            case VALUE_ENUM:\n            default:\n                return offset + getValueArg() + 1;\n        }\n    }\n\n    protected int getValueArg() {\n        switch (valueType) {\n            case VALUE_NULL:\n            case VALUE_ANNOTATION:\n            case VALUE_ARRAY:\n                return 0;\n            case VALUE_BOOLEAN:\n                return Boolean.TRUE.equals(value) ? 1 : 0;\n            case VALUE_BYTE:\n                return 0;\n            case VALUE_SHORT:\n            case VALUE_INT:\n                return lengthOfSint(((Number) value).intValue()) - 1;\n            case VALUE_CHAR:\n                return lengthOfUint(((Character) value).charValue()) - 1;\n            case VALUE_LONG:\n                return lengthOfSint(((Number) value).longValue()) - 1;\n            case VALUE_DOUBLE:\n                return lengthOfDouble(((Number) value).doubleValue()) - 1;\n            case VALUE_FLOAT:\n                return lengthOfFloat(((Number) value).floatValue()) - 1;\n            case VALUE_STRING:\n            case VALUE_TYPE:\n            case VALUE_FIELD:\n            case VALUE_METHOD:\n            case VALUE_ENUM:\n                BaseItem bi = (BaseItem) value;\n                return lengthOfUint(bi.index) - 1;\n        }\n        return 0;\n    }\n\n    final public int place(int offset) {\n        offset += 1;\n        return doPlace(offset);\n    }\n\n    public void write(DataOut out) {\n        int valueArg = getValueArg();\n        out.ubyte(\"(value_arg << 5 | value_type\", valueArg << 5 | valueType);\n        switch (valueType) {\n            case VALUE_NULL:\n            case VALUE_BOOLEAN:\n                // nop\n                break;\n            case VALUE_SHORT:\n                out.bytes(\"value_short\", encodeSint(valueArg + 1, (Short) value));\n                break;\n            case VALUE_CHAR:\n                out.bytes(\"value_char\", encodeSint(valueArg + 1, (Character) value));\n                break;\n            case VALUE_INT:\n                out.bytes(\"value_int\", encodeSint(valueArg + 1, (Integer) value));\n                break;\n            case VALUE_LONG:\n                out.bytes(\"value_long\", encodeLong(valueArg + 1, (Long) value));\n                break;\n            case VALUE_DOUBLE:\n                out.bytes(\"value_double\", writeRightZeroExtendedValue(valueArg+1,Double.doubleToLongBits( ((Number) value).doubleValue())));\n                break;\n            case VALUE_FLOAT:\n                out.bytes(\"value_float\", writeRightZeroExtendedValue(valueArg+1,((long)Float.floatToIntBits((((Number) value).floatValue())))<<32));\n                break;\n            case VALUE_STRING:\n            case VALUE_TYPE:\n            case VALUE_FIELD:\n            case VALUE_METHOD:\n            case VALUE_ENUM:\n                out.bytes(\"value_xidx\", encodeLong(valueArg + 1, ((BaseItem) value).index));\n                break;\n            case VALUE_ARRAY: {\n                EncodedArray ea = (EncodedArray) value;\n                ea.write(out);\n            }\n            break;\n            case VALUE_ANNOTATION: {\n                EncodedAnnotation ea = (EncodedAnnotation) value;\n                ea.write(out);\n            }\n            break;\n            case VALUE_BYTE: {\n                out.ubyte(\"value_byte\", (Byte) value);\n                break;\n            }\n            default:\n                throw new RuntimeException();\n\n        }\n    }\n\n    private byte[] writeRightZeroExtendedValue(int requiredBytes, long value) {\n        value >>= 64 - (requiredBytes * 8);\n        byte[] s = new byte[requiredBytes];\n        for (int i = 0; i < requiredBytes; i++) {\n            s[i] = ((byte) value);\n            value >>= 8;\n        }\n        return s;\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/insn/Insn.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.insn;\n\nimport java.nio.ByteBuffer;\n\npublic abstract class Insn {\n    protected static final boolean DEBUG = false;\n    /**\n     * offset in codeUnit\n     */\n    public int offset;\n\n    /**\n     * size in codeUnit\n     *\n     * @return\n     */\n    abstract public int getCodeUnitSize();\n\n    public void write(ByteBuffer out) {\n        // TODO Auto-generated method stub\n\n    }\n\n    boolean isLabel() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/insn/JumpOp.java",
    "content": "package com.googlecode.d2j.dex.writer.insn;\n\nimport java.nio.ByteBuffer;\n\nimport com.googlecode.d2j.dex.writer.CodeWriter;\nimport com.googlecode.d2j.reader.Op;\n\npublic class JumpOp extends OpInsn {\n    final int a;\n    final int b;\n    final Label label;\n\n    public JumpOp(Op op, int a, int b, Label label) {\n        super(op);\n        switch (op.format) {\n            case kFmt31t:\n            case kFmt21t:\n                CodeWriter.checkRegAA(op, \"vAA\", a);\n                break;\n            case kFmt22t:\n                CodeWriter.checkRegA(op, \"vA\", a);\n                CodeWriter.checkRegA(op, \"vB\", b);\n                break;\n            default:\n        }\n        this.label = label;\n        this.a = a;\n        this.b = b;\n    }\n\n    @Override\n    public void write(ByteBuffer out) {\n        out.put((byte) op.opcode);\n        int offset = label.offset - this.offset;\n        switch (op.format) {\n            case kFmt10t: // AA|op\n                CodeWriter.checkContentByte(op, \"+AA\", offset);\n                out.put((byte) offset);\n                break;\n            case kFmt20t: // ØØ|op AAAA\n                CodeWriter.checkContentShort(op, \"+AAAA\", offset);\n                out.put((byte) 0).putShort((short) offset);\n                break;\n            case kFmt30t: // ØØ|op AAAAlo AAAAhi\n                out.put((byte) 0).putInt(offset);\n                break;\n            case kFmt31t: // AA|op BBBBlo BBBBhi\n                out.put((byte) a).putInt(offset);\n                break;\n            case kFmt22t: // B|A|op CCCC\n                CodeWriter.checkContentShort(op, \"+CCCC\", offset);\n                out.put((byte) ((a & 0xF) | (b << 4))).putShort((short) offset);\n                break;\n            case kFmt21t: // AA|op BBBB\n                CodeWriter.checkContentShort(op, \"+BBBB\", offset);\n                out.put((byte) a).putShort((short) offset);\n                break;\n            default:\n                throw new RuntimeException(\"not support\");\n        }\n    }\n\n    public boolean fit() {\n        int offset = label.offset - this.offset;\n        if ((op == Op.GOTO && (offset > Byte.MAX_VALUE || offset < Byte.MIN_VALUE)) ||\n                (op == Op.GOTO_16 && (offset > Short.MAX_VALUE || offset < Short.MIN_VALUE))\n                ) {\n            if ((offset > Short.MAX_VALUE || offset < Short.MIN_VALUE)) {\n                op = Op.GOTO_32;\n            } else {\n                op = Op.GOTO_16;\n            }\n            return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/insn/Label.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.insn;\n\n\npublic class Label extends Insn {\n\n    @Override\n    public int getCodeUnitSize() {\n        return 0;\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/insn/OpInsn.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.insn;\n\nimport com.googlecode.d2j.reader.Op;\n\npublic abstract class OpInsn extends Insn {\n    public Op op;\n\n\n    public OpInsn(Op op) {\n        this.op = op;\n    }\n\n    final public boolean isLabel() {\n        return true;\n    }\n\n    @Override\n    public int getCodeUnitSize() {\n        return op.format.size;\n    }\n}"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/insn/PreBuildInsn.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.insn;\n\nimport java.nio.ByteBuffer;\n\npublic class PreBuildInsn extends Insn {\n\n    final public byte[] data;\n\n    public PreBuildInsn(byte[] data) {\n\n        this.data = data;\n    }\n\n\n    @Override\n    public int getCodeUnitSize() {\n        return data.length / 2;\n    }\n\n    @Override\n    public void write(ByteBuffer out) {\n        out.put(data);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/io/ByteBufferOut.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.io;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\npublic class ByteBufferOut implements DataOut {\n    public final ByteBuffer buffer;\n\n    public ByteBufferOut(ByteBuffer buffer) {\n        this.buffer = buffer;\n        buffer.order(ByteOrder.LITTLE_ENDIAN);\n    }\n\n    @Override\n    public void begin(String s) {\n    }\n\n    @Override\n    public void bytes(String s, byte[] bs) {\n        buffer.put(bs);\n    }\n\n    @Override\n    public void bytes(String string, byte[] buf, int offset, int size) {\n        buffer.put(buf, offset, size);\n    }\n\n    public void doUleb128(int value) {\n        int remaining = value >>> 7;\n\n        while (remaining != 0) {\n            buffer.put((byte) ((value & 0x7f) | 0x80));\n            value = remaining;\n            remaining >>>= 7;\n        }\n\n        buffer.put((byte) (value & 0x7f));\n    }\n\n    @Override\n    public void end() {\n    }\n\n    @Override\n    public int offset() {\n        return buffer.position();\n    }\n\n    @Override\n    public void sbyte(String s, int b) {\n        buffer.put((byte) b);\n    }\n\n    @Override\n    public void sint(String s, int i) {\n        buffer.putInt(i);\n    }\n\n    @Override\n    public void skip(String s, int n) {\n        buffer.position(buffer.position() + n);\n    }\n\n    @Override\n    public void skip4(String s) {\n        buffer.putInt(0);\n    }\n\n    @Override\n    public void sleb128(String s, int value) {\n        int remaining = value >> 7;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n\n        while (hasMore) {\n            hasMore = (remaining != end)\n                    || ((remaining & 1) != ((value >> 6) & 1));\n\n            buffer.put((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));\n            value = remaining;\n            remaining >>= 7;\n        }\n\n    }\n\n    @Override\n    public void sshort(String s, int i) {\n        buffer.putShort((short) i);\n    }\n\n    @Override\n    public void ubyte(String s, int b) {\n        buffer.put((byte) b);\n    }\n\n    @Override\n    public void uint(String s, int i) {\n        buffer.putInt(i);\n    }\n\n    @Override\n    public void uleb128(String s, int value) {\n        doUleb128(value);\n    }\n\n    @Override\n    public void uleb128p1(String s, int i) {\n        doUleb128(i + 1);\n    }\n\n    @Override\n    public void ushort(String s, int i) {\n        buffer.putShort((short) i);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/io/DataOut.java",
    "content": "/*\r\n * dex2jar - Tools to work with android .dex and java .class files\r\n * Copyright (c) 2009-2013 Panxiaobo\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage com.googlecode.d2j.dex.writer.io;\r\n\r\npublic interface DataOut {\r\n\r\n    void begin(String s);\r\n\r\n    void bytes(String s, byte[] bs);\r\n\r\n    void bytes(String string, byte[] buf, int offset, int size);\r\n\r\n    void end();\r\n\r\n    int offset();\r\n\r\n    void sbyte(String s, int b);\r\n\r\n    void sint(String s, int i);\r\n\r\n    void skip(String s, int n);\r\n\r\n    void skip4(String s);\r\n\r\n    void sleb128(String s, int i);\r\n\r\n    void sshort(String s, int i);\r\n\r\n    void ubyte(String s, int b);\r\n\r\n    void uint(String s, int i);\r\n\r\n    void uleb128(String s, int i);\r\n\r\n    void uleb128p1(String s, int i);\r\n\r\n    void ushort(String s, int i);\r\n}\r\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/AnnotationItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.dex.writer.ev.EncodedAnnotation;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic class AnnotationItem extends BaseItem {\n    final public Visibility visibility;\n    final public EncodedAnnotation annotation = new EncodedAnnotation();\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AnnotationItem that = (AnnotationItem) o;\n\n        if (!annotation.equals(that.annotation)) return false;\n        if (visibility != that.visibility) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = visibility.hashCode();\n        result = 31 * result + annotation.hashCode();\n        return result;\n    }\n\n    public AnnotationItem(TypeIdItem type, Visibility visibility) {\n        this.visibility = visibility;\n        annotation.type = type;\n    }\n\n    @Override\n    public int place(int offset) {\n        offset += 1;\n        return annotation.place(offset);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.ubyte(\"visibility\", visibility.value);\n        annotation.write(out);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/AnnotationSetItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class AnnotationSetItem extends BaseItem {\n    public List<AnnotationItem> annotations = new ArrayList<>(3);\n    private static final Comparator<AnnotationItem> cmp = new Comparator<AnnotationItem>() {\n        @Override\n        public int compare(AnnotationItem o1, AnnotationItem o2) {\n            return o1.annotation.type.compareTo(o2.annotation.type);\n        }\n    };\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AnnotationSetItem that = (AnnotationSetItem) o;\n\n        if (!annotations.equals(that.annotations)) return false;\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        return annotations.hashCode();\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 4 + annotations.size() * 4;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        Collections.sort(annotations, cmp);\n        out.uint(\"size\", annotations.size());\n        for (AnnotationItem item : annotations) {\n            out.uint(\"annotation_off\", item.offset);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/AnnotationSetRefListItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic class AnnotationSetRefListItem extends BaseItem {\n    @Off\n    final public AnnotationSetItem[] annotationSets;\n\n    public AnnotationSetRefListItem(int size) {\n        this.annotationSets = new AnnotationSetItem[size];\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 4 + annotationSets.length * 4;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"size\", annotationSets.length);\n        for (AnnotationSetItem item : annotationSets) {\n            out.uint(\"annotations_off\", item == null ? 0 : item.offset);\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/AnnotationsDirectoryItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.Map;\nimport java.util.Map.Entry;\n\npublic class AnnotationsDirectoryItem extends BaseItem {\n    @Off\n    public AnnotationSetItem classAnnotations;\n    public Map<FieldIdItem, AnnotationSetItem> fieldAnnotations;\n    public Map<MethodIdItem, AnnotationSetItem> methodAnnotations;\n    public Map<MethodIdItem, AnnotationSetRefListItem> parameterAnnotations;\n\n    @Override\n    public int place(int offset) {\n        offset += 16;\n        if (fieldAnnotations != null) {\n            offset += fieldAnnotations.size() * 8;\n        }\n        if (methodAnnotations != null) {\n            offset += methodAnnotations.size() * 8;\n        }\n        if (parameterAnnotations != null) {\n            offset += parameterAnnotations.size() * 8;\n        }\n        return offset;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"class_annotations_off\", classAnnotations == null ? 0 : classAnnotations.offset);\n        out.uint(\"fields_size\", fieldAnnotations == null ? 0 : fieldAnnotations.size());\n        out.uint(\"annotated_methods_size\", methodAnnotations == null ? 0 : methodAnnotations.size());\n        out.uint(\"annotated_parameter_size\", parameterAnnotations == null ? 0 : parameterAnnotations.size());\n        if (fieldAnnotations != null) {\n            for (Entry<FieldIdItem, AnnotationSetItem> fe : fieldAnnotations.entrySet()) {\n                out.uint(\"field_idx\", fe.getKey().index);\n                out.uint(\"annotations_off\", fe.getValue().offset);\n            }\n        }\n        if (methodAnnotations != null) {\n            for (Entry<MethodIdItem, AnnotationSetItem> fe : methodAnnotations.entrySet()) {\n                out.uint(\"method_idx\", fe.getKey().index);\n                out.uint(\"annotations_off\", fe.getValue().offset);\n            }\n        }\n        if (parameterAnnotations != null) {\n            for (Entry<MethodIdItem, AnnotationSetRefListItem> fe : parameterAnnotations.entrySet()) {\n                out.uint(\"method_idx\", fe.getKey().index);\n                out.uint(\"annotations_off\", fe.getValue().offset);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/BaseItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic abstract class BaseItem {\n    public static final int NO_INDEX = -1;\n    public int index;\n    public int offset;\n\n    static protected void addPadding(DataOut out, int alignment) {\n        int x = out.offset() % alignment;\n        if (x != 0) {\n            out.skip(\"padding\", alignment - x);// Padding\n        }\n    }\n\n    static public void addPadding(DataOut out, int offset, int alignment) {\n        int x = offset % alignment;\n        if (x != 0) {\n            out.skip(\"padding\", alignment - x);// Padding\n        }\n    }\n\n    public static int padding(int offset, int alignment) {\n        int x = offset % alignment;\n        if (x != 0) {\n            offset += alignment - x;// Padding\n        }\n        return offset;\n    }\n\n    public static int lengthOfSleb128(int value) {\n        int remaining = value >> 7;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n        int count = 0;\n        while (hasMore) {\n            hasMore = (remaining != end)\n                    || ((remaining & 1) != ((value >> 6) & 1));\n            count++;\n            value = remaining;\n            remaining >>= 7;\n        }\n        return count;\n    }\n\n    public static int lengthOfUleb128(int value) {\n        int remaining = value >>> 7;\n        int length = 1;\n        while (remaining != 0) {\n            length++;\n            remaining >>>= 7;\n        }\n        return length;\n    }\n\n    public abstract void write(DataOut out);\n\n    public abstract int place(int offset);\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/ClassDataItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.ev.EncodedValue;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class ClassDataItem extends BaseItem {\n    public final List<EncodedField> staticFields = new ArrayList<>(5);\n    public final List<EncodedField> instanceFields = new ArrayList<>(5);\n    public final List<EncodedMethod> directMethods = new ArrayList<>(5);\n    public final List<EncodedMethod> virtualMethods = new ArrayList<>(5);\n\n    @Override\n    public int place(int offset) {\n        offset += lengthOfUleb128(staticFields.size());\n        offset += lengthOfUleb128(instanceFields.size());\n        offset += lengthOfUleb128(directMethods.size());\n        offset += lengthOfUleb128(virtualMethods.size());\n        offset = placeField(offset, staticFields);\n        offset = placeField(offset, instanceFields);\n        offset = placeMethod(offset, directMethods);\n        offset = placeMethod(offset, virtualMethods);\n        return offset;\n    }\n\n    private int placeMethod(int offset, List<EncodedMethod> methods) {\n        if (methods.size() == 0) {\n            return offset;\n        }\n        int lastIdx = 0;\n        for (EncodedMethod f : methods) {\n            offset += lengthOfUleb128(f.method.index - lastIdx);\n            offset += lengthOfUleb128(f.accessFlags);\n            offset += lengthOfUleb128(f.code == null ? 0 : f.code.offset);\n            lastIdx = f.method.index;\n        }\n        return offset;\n    }\n\n    private int placeField(int offset, List<EncodedField> fields) {\n        if (fields.size() == 0) {\n            return offset;\n        }\n        int lastIdx = 0;\n        for (EncodedField f : fields) {\n            offset += lengthOfUleb128(f.field.index - lastIdx);\n            offset += lengthOfUleb128(f.accessFlags);\n\n            lastIdx = f.field.index;\n        }\n        return offset;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uleb128(\"static_fields_size\", staticFields.size());\n        out.uleb128(\"instance_fields_size\", instanceFields.size());\n        out.uleb128(\"ditect_methods_size\", directMethods.size());\n        out.uleb128(\"virtual_methods_size\", virtualMethods.size());\n        writeField(out, staticFields);\n        writeField(out, instanceFields);\n        writeMethod(out, directMethods);\n        writeMethod(out, virtualMethods);\n    }\n\n    private void writeMethod(DataOut out, List<EncodedMethod> methods) {\n        if (methods == null || methods.size() == 0) {\n            return;\n        }\n        int lastIdx = 0;\n        for (EncodedMethod f : methods) {\n            out.uleb128(\"method_idx_diff\", f.method.index - lastIdx);\n            out.uleb128(\"access_flags\", f.accessFlags);\n            out.uleb128(\"code_off\", f.code == null ? 0 : f.code.offset);\n            lastIdx = f.method.index;\n        }\n    }\n\n    private void writeField(DataOut out, List<EncodedField> fields) {\n        if (fields == null || fields.size() == 0) {\n            return;\n        }\n        int lastIdx = 0;\n        for (EncodedField f : fields) {\n            out.uleb128(\"field_idx_diff\", f.field.index - lastIdx);\n            out.uleb128(\"access_flags\", f.accessFlags);\n            lastIdx = f.field.index;\n        }\n    }\n\n    public int getMemberSize() {\n        return instanceFields.size() + staticFields.size() + directMethods.size() + virtualMethods.size();\n    }\n\n    public void prepare(ConstPool cp) {\n        Comparator<EncodedField> fc = new Comparator<EncodedField>() {\n\n            @Override\n            public int compare(EncodedField arg0, EncodedField arg1) {\n                return arg0.field.compareTo(arg1.field);\n            }\n        };\n        Comparator<EncodedMethod> mc = new\n\n                Comparator<EncodedMethod>() {\n\n                    @Override\n                    public int compare(EncodedMethod arg0, EncodedMethod arg1) {\n                        return arg0.method.compareTo(arg1.method);\n                    }\n                };\n        Collections.sort(instanceFields, fc);\n        Collections.sort(staticFields, fc);\n        Collections.sort(directMethods, mc);\n        Collections.sort(virtualMethods, mc);\n\n    }\n\n    public static class EncodedField {\n        public int accessFlags;\n        @Idx\n        public FieldIdItem field;\n        public EncodedValue staticValue;\n        public AnnotationSetItem annotationSetItem;\n    }\n\n    public static class EncodedMethod {\n        public int accessFlags;\n        @Idx\n        public MethodIdItem method;\n        @Off\n        public CodeItem code;\n        //\n        public AnnotationSetItem annotationSetItem;\n        public AnnotationSetRefListItem parameterAnnotation;\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/ClassDefItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.ev.EncodedArray;\nimport com.googlecode.d2j.dex.writer.ev.EncodedValue;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.ClassDataItem.EncodedField;\nimport com.googlecode.d2j.dex.writer.item.ClassDataItem.EncodedMethod;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.TreeMap;\n\npublic class ClassDefItem extends BaseItem {\n    @Idx\n    public TypeIdItem clazz;\n    public int accessFlags;\n    @Idx\n    public TypeIdItem superclazz;\n    @Off\n    public TypeListItem interfaces;\n    @Idx\n    public StringIdItem sourceFile;\n    @Off\n    public ClassDataItem classData;\n    //\n    public AnnotationSetItem classAnnotations;\n    @Off\n    private AnnotationsDirectoryItem annotations;// Build later\n    @Off\n    private EncodedArrayItem staticValues; // Build later\n\n    @Override\n    public int place(int offset) {\n        return offset + 0x20;\n    }\n\n    public void prepare(ConstPool cp) {\n        if (classData != null) {\n            classData.prepare(cp);\n        }\n        preparteAnnotationsDirectoryItem(cp);\n        prepareEncodedArrayItem(cp);\n    }\n\n    private void prepareEncodedArrayItem(ConstPool cp) {\n        if (classData == null) {\n            return;\n        }\n        List<EncodedField> fs = classData.staticFields;\n        int count = -1;\n        for (int i = 0; i < fs.size(); i++) {\n            EncodedField f = fs.get(i);\n            EncodedValue ev = f.staticValue;\n            if (ev != null) {\n                if (!ev.isDefaultValueForType()) {\n                    count = i;\n                }\n            }\n        }\n\n        if (count >= 0) {\n            EncodedArrayItem encodedArrayItem = cp.putEnCodedArrayItem();\n            EncodedArray array = encodedArrayItem.value;\n            for (int i = 0; i <= count; i++) {\n                EncodedField f = fs.get(i);\n                EncodedValue ev = f.staticValue;\n                if (ev == null) {\n                    array.values.add(EncodedValue.defaultValueForType(f.field.getTypeString()));\n                } else {\n                    array.values.add(ev);\n                }\n            }\n            staticValues = encodedArrayItem;\n        }\n    }\n\n    private void preparteAnnotationsDirectoryItem(ConstPool cp) {\n        Map<FieldIdItem, AnnotationSetItem> fieldAnnotations = new TreeMap<>();\n        Map<MethodIdItem, AnnotationSetItem> methodAnnotations = new TreeMap<>();\n        Map<MethodIdItem, AnnotationSetRefListItem> parameterAnnotations = new TreeMap<>();\n        if (classData != null) {\n            collectField(fieldAnnotations, classData.staticFields, cp);\n            collectField(fieldAnnotations, classData.instanceFields, cp);\n            collectMethod(methodAnnotations, parameterAnnotations, classData.directMethods, cp);\n            collectMethod(methodAnnotations, parameterAnnotations, classData.virtualMethods, cp);\n        }\n        if (this.classAnnotations != null || fieldAnnotations.size() > 0 || methodAnnotations.size() > 0\n                || parameterAnnotations.size() > 0) {\n            AnnotationsDirectoryItem annotationsDirectoryItem = cp.putAnnotationDirectoryItem();\n            this.annotations = annotationsDirectoryItem;\n            if (classAnnotations != null) {\n                annotationsDirectoryItem.classAnnotations = cp.uniqAnnotationSetItem(classAnnotations);\n            }\n            if (fieldAnnotations.size() > 0) {\n                annotationsDirectoryItem.fieldAnnotations = fieldAnnotations;\n            }\n            if (methodAnnotations.size() > 0) {\n                annotationsDirectoryItem.methodAnnotations = methodAnnotations;\n            }\n            if (parameterAnnotations.size() > 0) {\n                annotationsDirectoryItem.parameterAnnotations = parameterAnnotations;\n            }\n        }\n    }\n\n    private void collectMethod(Map<MethodIdItem, AnnotationSetItem> methodAnnotations,\n                               Map<MethodIdItem, AnnotationSetRefListItem> parameterAnnotations, List<EncodedMethod> ms, ConstPool cp) {\n        for (EncodedMethod m : ms) {\n            if (m.annotationSetItem != null) {\n                methodAnnotations.put(m.method, cp.uniqAnnotationSetItem(m.annotationSetItem));\n            }\n            if (m.parameterAnnotation != null) {\n                parameterAnnotations.put(m.method, cp.uniqAnnotationSetRefListItem(m.parameterAnnotation));\n            }\n        }\n    }\n\n    private void collectField(Map<FieldIdItem, AnnotationSetItem> fieldAnnotations, List<EncodedField> fs, ConstPool cp) {\n        for (EncodedField f : fs) {\n            if (f.annotationSetItem != null) {\n                fieldAnnotations.put(f.field, cp.uniqAnnotationSetItem(f.annotationSetItem));\n            }\n        }\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"class_idx\", clazz.index);\n        out.uint(\"access_flags\", this.accessFlags);\n        out.uint(\"superclass_idx\", superclazz == null ? NO_INDEX : superclazz.index);\n        out.uint(\"interfaces_off\", (interfaces == null || interfaces.items.size() == 0) ? 0 : interfaces.offset);\n        out.uint(\"source_file_idx\", sourceFile == null ? NO_INDEX : sourceFile.index);\n        out.uint(\"annotations_off\", annotations == null ? 0 : annotations.offset);\n        out.uint(\"class_data_off\", classData == null ? 0 : classData.offset);\n        out.uint(\"static_values_off\", staticValues == null ? 0 : staticValues.offset);\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/CodeItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.CodeWriter;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.insn.Insn;\nimport com.googlecode.d2j.dex.writer.insn.JumpOp;\nimport com.googlecode.d2j.dex.writer.insn.Label;\nimport com.googlecode.d2j.dex.writer.insn.PreBuildInsn;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.CodeItem.EncodedCatchHandler.AddrPair;\nimport com.googlecode.d2j.reader.Op;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.*;\n\npublic class CodeItem extends BaseItem {\n\n    public int registersSize;\n    public int insSize;\n    public int outsSize;\n    public int insn_size;\n    public List<TryItem> tries;\n    @Off\n    public DebugInfoItem debugInfo;\n    public List<Insn> insns;\n    public List<EncodedCatchHandler> handlers;\n\n    List<TryItem> _tryItems;\n    List<Insn> _ops;\n    List<Insn> _tailOps;\n    @Override\n    public int place(int offset) {\n        prepareInsns();\n        prepareTries();\n\n        offset += 16 + insn_size * 2;\n        if (tries != null && tries.size() > 0) {\n            if ((insn_size & 0x01) != 0) {// padding\n                offset += 2;\n            }\n            offset += 8 * tries.size();\n            if (handlers.size() > 0) {\n                int base = offset;\n                offset += lengthOfUleb128(handlers.size());\n\n                for (EncodedCatchHandler h : handlers) {\n                    h.handler_off = offset - base;\n                    int size = h.addPairs.size();\n                    offset += lengthOfSleb128(h.catchAll != null ? -size : size);\n                    for (AddrPair ap : h.addPairs) {\n                        offset += lengthOfUleb128(ap.type.index) + lengthOfUleb128(ap.addr.offset);\n                    }\n                    if (h.catchAll != null) {\n                        offset += lengthOfUleb128(h.catchAll.offset);\n                    }\n                }\n            }\n\n        }\n        return offset;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.ushort(\"registers_size\", registersSize);\n        out.ushort(\"ins_size\", insSize);\n        out.ushort(\"outs_size\", outsSize);\n        out.ushort(\"tries_size\", tries == null ? 0 : tries.size());\n        out.uint(\"debug_info_off\", debugInfo == null ? 0 : debugInfo.offset);\n        out.uint(\"insn_size\", insn_size);\n        ByteBuffer b = ByteBuffer.allocate(insn_size * 2).order(ByteOrder.LITTLE_ENDIAN);\n        for (Insn insn : insns) {\n            insn.write(b);\n        }\n        out.bytes(\"insn\", b.array());\n        if (tries != null && tries.size() > 0) {\n            if ((insn_size & 0x01) != 0) {// padding\n                out.skip(\"padding\", 2);\n            }\n            int lastEnd = 0;\n            for (TryItem ti : tries) {\n                if (ti.start.offset < lastEnd) {\n                    System.err.println(\"'Out-of-order try' may throwed by libdex\");\n                }\n                out.uint(\"start_addr\", ti.start.offset);\n                out.ushort(\"insn_count\", ti.end.offset - ti.start.offset);\n                lastEnd = ti.end.offset;\n                out.ushort(\"handler_off\", ti.handler.handler_off);\n            }\n            if (handlers.size() > 0) {\n                out.uleb128(\"size\", handlers.size());\n                for (EncodedCatchHandler h : handlers) {\n\n                    int size = h.addPairs.size();\n                    out.sleb128(\"size\", (h.catchAll != null ? -size : size));\n                    for (AddrPair ap : h.addPairs) {\n                        out.uleb128(\"type_idx\", (ap.type.index));\n                        out.uleb128(\"addr\", (ap.addr.offset));\n                    }\n                    if (h.catchAll != null) {\n                        out.uleb128(\"catch_all_addr\", (h.catchAll.offset));\n                    }\n                }\n            }\n        }\n    }\n\n    public void init(List<Insn> ops, List<Insn> tailOps, List<TryItem> tryItems) {\n        this._ops = ops;\n        this._tailOps = tailOps;\n        this._tryItems = tryItems;\n    }\n    private void prepareTries() {\n        if (_tryItems.size() > 0) {\n            List<CodeItem.TryItem> uniqTrys = new ArrayList<>();\n            { // merge dup trys\n                Set<TryItem> set = new HashSet<>();\n                for (CodeItem.TryItem tryItem : _tryItems) {\n                    if (!set.contains(tryItem)) {\n                        uniqTrys.add(tryItem);\n                        set.add(tryItem);\n                    } else {\n                        for (TryItem t : uniqTrys) {\n                            if (t.equals(tryItem)) {\n                                mergeExceptionHandler(t.handler, tryItem.handler);\n                            }\n                        }\n                    }\n                }\n                set.clear();\n                this.tries = uniqTrys;\n                if (uniqTrys.size() > 0) {\n                    Collections.sort(uniqTrys, new Comparator<TryItem>() {\n                        @Override\n                        public int compare(TryItem o1, TryItem o2) {\n                            int x = o1.start.offset - o2.start.offset;\n                            if (x == 0) {\n                                x = o1.end.offset - o2.end.offset;\n                            }\n                            return x;\n                        }\n                    });\n                }\n            }\n            { // merge dup handlers\n                List<CodeItem.EncodedCatchHandler> uniqHanders = new ArrayList<>();\n                Map<EncodedCatchHandler, EncodedCatchHandler> map = new HashMap<>();\n                for (CodeItem.TryItem tryItem : uniqTrys) {\n                    CodeItem.EncodedCatchHandler d = tryItem.handler;\n                    CodeItem.EncodedCatchHandler uH = map.get(d);\n                    if (uH != null) {\n                        tryItem.handler = uH;\n                    } else {\n                        uniqHanders.add(d);\n                        map.put(d, d);\n                    }\n                }\n                this.handlers = uniqHanders;\n                map.clear();\n            }\n\n        }\n    }\n\n    private void mergeExceptionHandler(EncodedCatchHandler to, EncodedCatchHandler from) {\n        for (AddrPair pair : from.addPairs) {\n            if (!to.addPairs.contains(pair)) {\n                to.addPairs.add(pair);\n            }\n        }\n        if (to.catchAll == null) {\n            to.catchAll = from.catchAll;\n        }\n    }\n\n    private void prepareInsns() {\n        List<JumpOp> jumpOps=new ArrayList<>();\n        for (Insn insn : _ops) {\n            if (insn instanceof CodeWriter.IndexedInsn) {\n                ((CodeWriter.IndexedInsn) insn).fit();\n            } else  if(insn instanceof JumpOp){\n                jumpOps.add((JumpOp)insn);\n            }\n        }\n\n        int codeSize = 0;\n        while (true) {\n            for (Insn insn : _ops) {\n                insn.offset = codeSize;\n                codeSize += insn.getCodeUnitSize();\n            }\n            boolean allfit = true;\n            for (JumpOp jop : jumpOps) {\n                if (!jop.fit()) {\n                    allfit = false;\n                }\n            }\n            if (allfit) {\n                break;\n            }\n            codeSize = 0;\n        }\n        for (Insn insn : _tailOps) {\n            if ((codeSize & 1) != 0) { // not 32bit alignment\n                Insn nop = new PreBuildInsn(new byte[] { (byte) Op.NOP.opcode, 0 }); // f10x\n                insn.offset = codeSize;\n                codeSize += nop.getCodeUnitSize();\n                _ops.add(nop);\n            }\n            insn.offset = codeSize;\n            codeSize += insn.getCodeUnitSize();\n            _ops.add(insn);\n        }\n        _tailOps.clear();\n        this.insns = _ops;\n        this.insn_size = codeSize;\n    }\n\n    public static class EncodedCatchHandler {\n        public int handler_off;\n        public List<AddrPair> addPairs;\n        public Label catchAll;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o)\n                return true;\n            if (o == null || getClass() != o.getClass())\n                return false;\n\n            EncodedCatchHandler that = (EncodedCatchHandler) o;\n\n            if (!addPairs.equals(that.addPairs))\n                return false;\n            if (catchAll != null ? !catchAll.equals(that.catchAll) : that.catchAll != null)\n                return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = addPairs.hashCode();\n            result = 31 * result + (catchAll != null ? catchAll.offset : 0);\n            return result;\n        }\n\n        public static class AddrPair {\n            final public TypeIdItem type;\n            final public Label addr;\n\n            public AddrPair(TypeIdItem type, Label addr) {\n                this.type = type;\n                this.addr = addr;\n            }\n\n            @Override\n            public boolean equals(Object o) {\n                if (this == o)\n                    return true;\n                if (o == null || getClass() != o.getClass())\n                    return false;\n\n                AddrPair addrPair = (AddrPair) o;\n\n                if (addr.offset != addrPair.addr.offset)\n                    return false;\n                if (!type.equals(addrPair.type))\n                    return false;\n\n                return true;\n            }\n\n            @Override\n            public int hashCode() {\n                int result = type.hashCode();\n                result = 31 * result + addr.offset;\n                return result;\n            }\n        }\n    }\n\n    public static class TryItem {\n        public Label start;\n        public Label end;\n        public EncodedCatchHandler handler;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o)\n                return true;\n            if (o == null || getClass() != o.getClass())\n                return false;\n\n            TryItem tryItem = (TryItem) o;\n\n            if (end.offset != tryItem.end.offset)\n                return false;\n            if (start.offset != tryItem.start.offset)\n                return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = start.offset;\n            result = 31 * result + end.offset;\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/ConstPool.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.DexType;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.dex.writer.DexWriteException;\n\nimport java.util.*;\n\npublic class ConstPool {\n    public List<EncodedArrayItem> encodedArrayItems = new ArrayList<>();\n    public Map<AnnotationSetRefListItem, AnnotationSetRefListItem> annotationSetRefListItems = new HashMap<>();\n    public List<CodeItem> codeItems = new ArrayList<>();\n    public List<ClassDataItem> classDataItems = new ArrayList<>();\n    public List<DebugInfoItem> debugInfoItems = new ArrayList<>();\n    public Map<AnnotationItem, AnnotationItem> annotationItems = new HashMap<>();\n    public List<AnnotationsDirectoryItem> annotationsDirectoryItems = new ArrayList<>();\n    public Map<AnnotationSetItem, AnnotationSetItem> annotationSetItems = new HashMap<>();\n    public Map<FieldIdItem, FieldIdItem> fields = new TreeMap<>();\n    public Map<MethodIdItem, MethodIdItem> methods = new TreeMap<>();\n    public Map<ProtoIdItem, ProtoIdItem> protos = new TreeMap<>();\n    public List<StringDataItem> stringDatas = new ArrayList<>(100);\n    public Map<String, StringIdItem> strings = new TreeMap<>();\n    public Map<TypeListItem, TypeListItem> typeLists = new TreeMap<>();\n    public Map<String, TypeIdItem> types = new TreeMap<>();\n    public Map<TypeIdItem, ClassDefItem> classDefs = new HashMap<>();\n\n    public Object wrapEncodedItem(Object value) {\n        if (value instanceof DexType) {\n            value = uniqType(((DexType) value).desc);\n        } else if (value instanceof Field) {\n            value = uniqField((Field) value);\n        } else if (value instanceof String) {\n            value = uniqString((String) value);\n        } else if (value instanceof Method) {\n            value = uniqMethod((Method) value);\n        }\n        return value;\n    }\n\n    public void clean() {\n        encodedArrayItems.clear();\n        annotationSetRefListItems.clear();\n        codeItems.clear();\n        classDataItems.clear();\n        debugInfoItems.clear();\n        annotationItems.clear();\n        annotationsDirectoryItems.clear();\n        annotationSetItems.clear();\n        fields.clear();\n        methods.clear();\n        protos.clear();\n        stringDatas.clear();\n        typeLists.clear();\n        types.clear();\n        classDefs.clear();\n    }\n\n    private String buildShorty(String ret, String[] types2) {\n        StringBuilder sb = new StringBuilder();\n        if (ret.length() == 1) {\n            sb.append(ret);\n        } else {\n            sb.append(\"L\");\n        }\n        for (String s : types2) {\n            if (s.length() == 1) {\n                sb.append(s);\n            } else {\n                sb.append(\"L\");\n            }\n        }\n        return sb.toString();\n    }\n\n    PE iterateParent(ClassDefItem p) {\n        List<TypeIdItem> list = new ArrayList<>(6);\n        list.add(p.superclazz);\n        if (p.interfaces != null) {\n            list.addAll(p.interfaces.items);\n        }\n        return new PE(p, list.iterator());\n    }\n\n    public void addDebugInfoItem(DebugInfoItem debugInfoItem) {\n        debugInfoItems.add(debugInfoItem);\n    }\n\n    static class PE {\n        final ClassDefItem owner;\n        final Iterator<TypeIdItem> it;\n\n        PE(ClassDefItem owner, Iterator<TypeIdItem> it) {\n            this.owner = owner;\n            this.it = it;\n        }\n    }\n\n    public List<ClassDefItem> buildSortedClassDefItems() {\n        List<ClassDefItem> added = new ArrayList<>();\n        Stack<PE> stack1 = new Stack<>();\n        Set<ClassDefItem> children = new HashSet<>();\n\n        for (ClassDefItem c : classDefs.values()) {\n            if (added.contains(c)) {\n                continue;\n            }\n            children.add(c);\n            stack1.push(iterateParent(c));\n\n            while (!stack1.empty()) {\n                PE e = stack1.peek();\n                boolean canPop = true;\n                while (e.it.hasNext()) {\n                    TypeIdItem tid = e.it.next();\n                    if (tid == null) {\n                        continue;\n                    }\n                    ClassDefItem superDef = classDefs.get(tid);\n                    if (superDef != null && !added.contains(superDef)) {\n                        if (children.contains(superDef)) {\n                            System.err.println(\"WARN: dep-loop \" + e.owner.clazz.descriptor.stringData.string + \" -> \"\n                                    + superDef.clazz.descriptor.stringData.string);\n                        } else {\n                            canPop = false;\n                            children.add(superDef);\n                            stack1.push(iterateParent(superDef));\n                            break;\n                        }\n                    }\n                }\n                if (canPop) {\n                    stack1.pop();\n                    added.add(e.owner);\n                    children.remove(e.owner);\n                }\n            }\n            children.clear();\n        }\n        return added;\n    }\n\n    public AnnotationsDirectoryItem putAnnotationDirectoryItem() {\n        AnnotationsDirectoryItem aDirectoryItem = new AnnotationsDirectoryItem();\n        annotationsDirectoryItems.add(aDirectoryItem);\n        return aDirectoryItem;\n    }\n\n    public AnnotationItem uniqAnnotationItem(AnnotationItem key) {\n        AnnotationItem v = annotationItems.get(key);\n        if (v == null) {\n            annotationItems.put(key, key);\n            return key;\n        }\n        return v;\n    }\n\n    public ClassDefItem putClassDefItem(int accessFlag, String name, String superClass, String[] itfClass) {\n        TypeIdItem type = uniqType(name);\n        if (classDefs.containsKey(type)) {\n            throw new DexWriteException(\"dup clz: \" + name);\n        }\n        ClassDefItem classDefItem = new ClassDefItem();\n        classDefItem.accessFlags = accessFlag;\n        classDefItem.clazz = type;\n        if (superClass != null) {\n            classDefItem.superclazz = uniqType(superClass);\n        }\n        if (itfClass != null && itfClass.length > 0) {\n            classDefItem.interfaces = putTypeList(Arrays.asList(itfClass));\n        }\n        classDefs.put(type, classDefItem);\n        return classDefItem;\n    }\n\n    public FieldIdItem uniqField(Field field) {\n        return uniqField(field.getOwner(), field.getName(), field.getType());\n    }\n\n    public FieldIdItem uniqField(String owner, String name, String type) {\n        FieldIdItem key = new FieldIdItem(uniqType(owner), uniqString(name), uniqType(type));\n        FieldIdItem item = fields.get(key);\n        if (item != null) {\n            return item;\n        }\n        fields.put(key, key);\n        return key;\n    }\n\n    public MethodIdItem uniqMethod(Method method) {\n        MethodIdItem key = new MethodIdItem(uniqType(method.getOwner()), uniqString(method.getName()), uniqProto(method));\n        return uniqMethod(key);\n    }\n\n    public MethodIdItem uniqMethod(String owner, String name, String parms[], String ret) {\n        MethodIdItem key = new MethodIdItem(uniqType(owner), uniqString(name), uniqProto(parms, ret));\n        return uniqMethod(key);\n    }\n\n    public MethodIdItem uniqMethod(MethodIdItem key) {\n        MethodIdItem item = methods.get(key);\n        if (item != null) {\n            return item;\n        }\n        methods.put(key, key);\n        return key;\n    }\n\n    private ProtoIdItem uniqProto(Method method) {\n        return uniqProto(method.getParameterTypes(), method.getReturnType());\n    }\n\n    public ProtoIdItem uniqProto(String[] types, String retDesc) {\n        TypeIdItem ret = uniqType(retDesc);\n        StringIdItem shorty = uniqString(buildShorty(retDesc, types));\n        TypeListItem params = putTypeList(types);\n        ProtoIdItem key = new ProtoIdItem(params, ret, shorty);\n        ProtoIdItem item = protos.get(key);\n        if (item != null) {\n            return item;\n        } else {\n            protos.put(key, key);\n            return key;\n        }\n    }\n\n    public StringIdItem uniqString(String data) {\n        StringIdItem item = strings.get(data);\n        if (item != null) {\n            return item;\n        }\n        StringDataItem sd = new StringDataItem(data);\n        stringDatas.add(sd);\n        item = new StringIdItem(sd);\n        strings.put(data, item);\n        return item;\n    }\n\n    public TypeIdItem uniqType(String type) {\n        TypeIdItem item = types.get(type);\n        if (item != null) {\n            return item;\n        }\n        item = new TypeIdItem(uniqString(type));\n        types.put(type, item);\n        return item;\n    }\n\n    private TypeListItem putTypeList(String... subList) {\n        if (subList.length == 0) {\n            return ZERO_SIZE_TYPE_LIST;\n        }\n        List<TypeIdItem> idItems = new ArrayList<>(subList.length);\n        for (String s : subList) {\n            idItems.add(uniqType(s));\n        }\n        TypeListItem key = new TypeListItem(idItems);\n        TypeListItem item = typeLists.get(key);\n        if (item != null) {\n            return item;\n        }\n        typeLists.put(key, key);\n        return key;\n    }\n\n    private static final TypeListItem ZERO_SIZE_TYPE_LIST = new TypeListItem(Collections.EMPTY_LIST);\n    static {\n        // make sure the offset is 0\n        ZERO_SIZE_TYPE_LIST.offset = 0;\n    }\n\n    private TypeListItem putTypeList(List<String> subList) {\n        if (subList.size() == 0) {\n            return ZERO_SIZE_TYPE_LIST;\n        }\n        List<TypeIdItem> idItems = new ArrayList<>(subList.size());\n        for (String s : subList) {\n            idItems.add(uniqType(s));\n        }\n        TypeListItem key = new TypeListItem(idItems);\n        TypeListItem item = typeLists.get(key);\n        if (item != null) {\n            return item;\n        }\n        typeLists.put(key, key);\n        return key;\n    }\n\n    public ClassDataItem addClassDataItem(ClassDataItem dataItem) {\n        classDataItems.add(dataItem);\n        return dataItem;\n    }\n\n    // TODO change EncodedArrayItem to uniq\n    public EncodedArrayItem putEnCodedArrayItem() {\n        EncodedArrayItem arrayItem = new EncodedArrayItem();\n        encodedArrayItems.add(arrayItem);\n        return arrayItem;\n    }\n\n    public AnnotationSetItem uniqAnnotationSetItem(AnnotationSetItem key) {\n        List<AnnotationItem> copy = new ArrayList<AnnotationItem>(key.annotations);\n        key.annotations.clear();\n        for (AnnotationItem annotationItem : copy) {\n            key.annotations.add(uniqAnnotationItem(annotationItem));\n        }\n        AnnotationSetItem v = annotationSetItems.get(key);\n        if (v != null) {\n            return v;\n        }\n        annotationSetItems.put(key, key);\n        return key;\n    }\n\n    public AnnotationSetRefListItem uniqAnnotationSetRefListItem(AnnotationSetRefListItem key) {\n        for (int i = 0; i < key.annotationSets.length; i++) {\n            AnnotationSetItem anno = key.annotationSets[i];\n            if (anno != null) {\n                key.annotationSets[i] = uniqAnnotationSetItem(anno);\n            }\n        }\n        AnnotationSetRefListItem v = annotationSetRefListItems.get(key);\n        if (v == null) {\n            annotationSetRefListItems.put(key, key);\n            return key;\n        }\n        return v;\n    }\n\n    public void addCodeItem(CodeItem code) {\n        codeItems.add(code);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/DebugInfoItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.insn.Label;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class DebugInfoItem extends BaseItem {\n    public List<DNode> debugNodes = new ArrayList<>();\n    public StringIdItem parameterNames[];\n    public int firstLine;\n    public StringIdItem fileName;\n\n    public static class DNode {\n        public int op;\n        public int reg;\n        public int line;\n        public Label label;\n        StringIdItem name;\n        TypeIdItem type;\n        StringIdItem sig;\n\n        public static DNode startLocal(int reg, Label label, StringIdItem name, TypeIdItem type) {\n            DNode node = new DNode();\n            node.reg = reg;\n            node.label = label;\n            node.name = name;\n            node.type = type;\n            node.op = DBG_START_LOCAL;\n            return node;\n        }\n\n        public static DNode line(int line, Label label) {\n            DNode node = new DNode();\n            node.line = line;\n            node.label = label;\n            node.op = 99999;\n            return node;\n        }\n\n        public static DNode startLocalEx(int reg, Label label, StringIdItem name, TypeIdItem type, StringIdItem sig) {\n            DNode node = new DNode();\n            node.reg = reg;\n            node.label = label;\n            node.name = name;\n            node.type = type;\n            node.sig = sig;\n            node.op = DBG_START_LOCAL_EXTENDED;\n            return node;\n        }\n\n        public static DNode endLocal(int reg, Label label) {\n            DNode node = new DNode();\n            node.reg = reg;\n            node.label = label;\n            node.op = DBG_END_LOCAL;\n            return node;\n        }\n\n        public static DNode restartLocal(int reg, Label label) {\n            DNode node = new DNode();\n            node.reg = reg;\n            node.label = label;\n            node.op = DBG_RESTART_LOCAL;\n            return node;\n        }\n\n        public static DNode epiogue(Label label) {\n            DNode node = new DNode();\n            node.label = label;\n            node.op = DBG_SET_EPILOGUE_BEGIN;\n            return node;\n        }\n\n        public static DNode prologue(Label label) {\n            DNode node = new DNode();\n            node.label = label;\n            node.op = DBG_SET_PROLOGUE_END;\n            return node;\n        }\n    }\n\n    static final int DBG_END_SEQUENCE = 0x00;\n    static final int DBG_ADVANCE_PC = 0x01;\n    static final int DBG_ADVANCE_LINE = 0x02;\n    static final int DBG_START_LOCAL = 0x03;\n    static final int DBG_START_LOCAL_EXTENDED = 0x04;\n    static final int DBG_END_LOCAL = 0x05;\n    static final int DBG_RESTART_LOCAL = 0x06;\n    static final int DBG_SET_PROLOGUE_END = 0x07;\n    static final int DBG_SET_EPILOGUE_BEGIN = 0x08;\n    static final int DBG_SET_FILE = 0x09;\n    static final int DBG_FIRST_SPECIAL = 0x0a;\n    static final int DBG_LINE_BASE = -4;\n    static final int DBG_LINE_RANGE = 15;\n\n    @Override\n    public int place(int offset) {\n        offset += lengthOfUleb128(firstLine);\n        if (parameterNames == null) {\n            offset += lengthOfUleb128(0);\n        } else {\n            offset += lengthOfUleb128(parameterNames.length);\n            for (StringIdItem s : parameterNames) {\n                offset += lengthOfUleb128(1 + (s == null ? -1 : s.index));\n            }\n\n        }\n        int line = firstLine;\n        int addr = 0;\n\n        if (fileName != null) {\n            offset += 1;\n            offset += lengthOfUleb128(fileName.index + 1);\n        }\n        for (DNode opNode : debugNodes) {\n            switch (opNode.op) {\n            case DBG_START_LOCAL_EXTENDED:\n                offset += lengthOfUleb128(opNode.sig.index + 1);\n                // through;\n            case DBG_START_LOCAL: {\n                int pcData = opNode.label.offset - addr;\n                if (pcData < 0) {\n                    throw new RuntimeException();\n                } else if (pcData > 0) {\n                    // add an addvance_PC\n                    offset += 1;\n                    offset += lengthOfUleb128(pcData);\n                }\n                addr = opNode.label.offset;\n            }\n                offset += 1;// op;\n                offset += lengthOfUleb128(opNode.reg);\n                offset += lengthOfUleb128(opNode.name.index + 1);\n                offset += lengthOfUleb128(opNode.type.index + 1);\n                break;\n            case DBG_RESTART_LOCAL:\n            case DBG_END_LOCAL: {\n                int pcData = opNode.label.offset - addr;\n                if (pcData < 0) {\n                    throw new RuntimeException();\n                } else if (pcData > 0) {\n                    // add an addvance_PC\n                    offset += 1;\n                    offset += lengthOfUleb128(pcData);\n                }\n                addr = opNode.label.offset;\n            }\n                offset += 1;// op;\n                offset += lengthOfUleb128(opNode.reg);\n                break;\n            case DBG_SET_EPILOGUE_BEGIN:\n            case DBG_SET_PROLOGUE_END:\n                offset += 1;\n                break;\n            case DBG_SET_FILE:\n                throw new RuntimeException();\n            default:\n                int lineDelta = opNode.line - line;\n                int addrDelta = opNode.label.offset - addr;\n                if (addrDelta < 0) {\n                    throw new RuntimeException();\n                }\n                if (opNode.label.offset == 0 && lineDelta == 0 && addrDelta == 0) { // first line;\n                    break;\n                }\n                if ((lineDelta >= -4 && lineDelta <= 10) && addrDelta <= 15) {\n                    // do nothing\n                } else {\n                    if (addrDelta > 15) { // pc not ok, add addvance_PC\n                        offset += 1;\n                        offset += lengthOfUleb128(addrDelta);\n                        addrDelta = 0;\n                    }\n                    if (lineDelta < -4 || lineDelta > 10) { // line not ok, add DBG_ADVANCE_LINE\n                        offset += 1;\n                        offset += lengthOfSleb128(lineDelta);\n                        lineDelta = 0;\n                    }\n                }\n                // int op = lineDelta + 4 + addrDelta * DBG_LINE_RANGE + DBG_FIRST_SPECIAL;\n                offset += 1;\n                line = opNode.line;\n                addr = opNode.label.offset;\n                break;\n            }\n\n        }\n        offset += 1;// end sequence;\n\n        return offset;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uleb128(\"startline\", firstLine);\n        if (parameterNames == null) {\n            out.uleb128(\"szParams\", 0);\n        } else {\n            out.uleb128(\"szParams\", parameterNames.length);\n            for (StringIdItem s : parameterNames) {\n                out.uleb128p1(\"param_name_index\", s == null ? -1 : s.index);\n            }\n        }\n        int line = firstLine;\n        int addr = 0;\n\n        if (fileName != null) {\n            out.sbyte(\"DBG_SET_FILE\", DBG_SET_FILE);\n            out.uleb128p1(\"filename\", fileName.index);\n        }\n        for (DNode opNode : debugNodes) {\n            switch (opNode.op) {\n            case DBG_START_LOCAL_EXTENDED: {\n                int pcDelta = opNode.label.offset - addr;\n                if (pcDelta < 0) {\n                    throw new RuntimeException();\n                } else if (pcDelta > 0) {\n                    addAdvancePC(out, pcDelta);\n                }\n                addr = opNode.label.offset;\n            }\n                out.sbyte(\"DBG_START_LOCAL_EXTENDED\", DBG_START_LOCAL_EXTENDED);\n                out.uleb128(\"reg\", opNode.reg);\n                out.uleb128p1(\"name\", opNode.name.index);\n                out.uleb128p1(\"type\", opNode.type.index);\n                out.uleb128p1(\"sig\", opNode.sig.index);\n                break;\n            case DBG_START_LOCAL: {\n                int pcDelta = opNode.label.offset - addr;\n                if (pcDelta < 0) {\n                    throw new RuntimeException();\n                } else if (pcDelta > 0) {\n                    addAdvancePC(out, pcDelta);\n                }\n                addr = opNode.label.offset;\n            }\n                out.sbyte(\"DBG_START_LOCAL\", DBG_START_LOCAL);\n                out.uleb128(\"reg\", opNode.reg);\n                out.uleb128p1(\"name\", opNode.name.index);\n                out.uleb128p1(\"type\", opNode.type.index);\n\n                break;\n            case DBG_RESTART_LOCAL: {\n                int pcDelta = opNode.label.offset - addr;\n                if (pcDelta < 0) {\n                    throw new RuntimeException();\n                } else if (pcDelta > 0) {\n                    addAdvancePC(out, pcDelta);\n                }\n                addr = opNode.label.offset;\n            }\n\n                out.sbyte(\"DBG_RESTART_LOCAL\", DBG_RESTART_LOCAL);\n                out.uleb128(\"reg\", opNode.reg);\n                break;\n            case DBG_END_LOCAL: {\n                int pcDelta = opNode.label.offset - addr;\n                if (pcDelta < 0) {\n                    throw new RuntimeException();\n                } else if (pcDelta > 0) {\n                    addAdvancePC(out, pcDelta);\n                }\n                addr = opNode.label.offset;\n            }\n\n                out.sbyte(\"DBG_END_LOCAL\", DBG_END_LOCAL);\n                out.uleb128(\"reg\", opNode.reg);\n                break;\n            case DBG_SET_EPILOGUE_BEGIN:\n                out.sbyte(\"DBG_SET_EPILOGUE_BEGIN\", DBG_SET_EPILOGUE_BEGIN);\n                break;\n            case DBG_SET_PROLOGUE_END:\n                out.sbyte(\"DBG_SET_PROLOGUE_END\", DBG_SET_PROLOGUE_END);\n                break;\n            case DBG_SET_FILE:\n                throw new RuntimeException();\n            default:\n                int lineDelta = opNode.line - line;\n                int addrDelta = opNode.label.offset - addr;\n                if (addrDelta < 0) {\n                    throw new RuntimeException();\n                }\n                if (opNode.label.offset == 0 && lineDelta == 0 && addrDelta == 0) { // first line;\n                    break;\n                }\n                if ((lineDelta >= -4 && lineDelta <= 10) && addrDelta <= 15) {\n                    // do nothing\n                } else {\n                    if (addrDelta > 15) { // pc not ok, add addvance_PC\n                        addAdvancePC(out, addrDelta);\n                        addrDelta = 0;\n                    }\n                    if (lineDelta < -4 || lineDelta > 10) { // line not ok, add DBG_ADVANCE_LINE\n                        addAdvanceLine(out, lineDelta);\n                        lineDelta = 0;\n                    }\n                }\n                int op = lineDelta + 4 + addrDelta * DBG_LINE_RANGE + DBG_FIRST_SPECIAL;\n                out.sbyte(\"DEBUG_OP_X\", op);\n                line = opNode.line;\n                addr = opNode.label.offset;\n                break;\n            }\n        }\n        out.sbyte(\"DBG_END_SEQUENCE\", DBG_END_SEQUENCE);\n    }\n\n    private void addAdvanceLine(DataOut out, int lineDelta) {\n        out.sbyte(\"DBG_ADVANCE_LINE\", DBG_ADVANCE_LINE);\n        out.sleb128(\"offset\", lineDelta);\n    }\n\n    private void addAdvancePC(DataOut out, int delta) {\n        out.sbyte(\"DBG_ADVANCE_PC\", DBG_ADVANCE_PC);\n        out.uleb128(\"offset\", delta);\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/EncodedArrayItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ev.EncodedArray;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic class EncodedArrayItem extends BaseItem {\n    public EncodedArray value = new EncodedArray();\n\n    @Override\n    public int place(int offset) {\n        return value.place(offset);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        value.write(out);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/FieldIdItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\n@Alignment(4)\n\npublic class FieldIdItem extends BaseItem implements Comparable<FieldIdItem> {\n    @Idx\n    public final TypeIdItem clazz;\n    @Idx\n    public final TypeIdItem type;\n    @Idx\n    public final StringIdItem name;\n\n    public String getTypeString() {\n        return type.descriptor.stringData.string;\n    }\n\n    public FieldIdItem(TypeIdItem clazz, StringIdItem name, TypeIdItem type) {\n        super();\n        this.clazz = clazz;\n        this.name = name;\n        this.type = type;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());\n        result = prime * result + ((name == null) ? 0 : name.hashCode());\n        result = prime * result + ((type == null) ? 0 : type.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        FieldIdItem other = (FieldIdItem) obj;\n        if (clazz == null) {\n            if (other.clazz != null)\n                return false;\n        } else if (!clazz.equals(other.clazz))\n            return false;\n        if (name == null) {\n            if (other.name != null)\n                return false;\n        } else if (!name.equals(other.name))\n            return false;\n        if (type == null) {\n            if (other.type != null)\n                return false;\n        } else if (!type.equals(other.type))\n            return false;\n        return true;\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 8;\n    }\n\n    @Override\n    public int compareTo(FieldIdItem o) {\n        int x = clazz.compareTo(o.clazz);\n        if (x != 0) {\n            return x;\n        }\n        x = name.compareTo(o.name);\n        if (x != 0) {\n            return x;\n        }\n        return type.compareTo(o.type);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.ushort(\"class_idx\", clazz.index);\n        out.ushort(\"proto_idx\", type.index);\n        out.uint(\"name_idx\", name.index);\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/HeadItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic class HeadItem extends BaseItem {\n\n    public static final int V035 = 0x00353330;\n    public static final int V036 = 0x00363330;\n    public int version = V035;\n    public SectionItem<MapListItem> mapSection;\n    public SectionItem<StringIdItem> stringIdSection;\n    public SectionItem<TypeIdItem> typeIdSection;\n    public SectionItem<ProtoIdItem> protoIdSection;\n    public SectionItem<FieldIdItem> fieldIdSection;\n    public SectionItem<MethodIdItem> methodIdSection;\n    public SectionItem<ClassDefItem> classDefSection;\n    public int fileSize = -1;\n\n    public void write(DataOut out) {\n        out.uint(\"magic\", 0x0A786564);\n        out.uint(\"version\", version);\n        out.skip4(\"checksum\");\n        out.skip(\"signature\", 20);\n        out.uint(\"file_size\", fileSize);\n        out.uint(\"head_size\", 0x70);\n        out.uint(\"endian_tag\", 0x12345678);\n        out.skip(\"link_size,link_off\", 8);\n        out.uint(\"map_off\", mapSection.items.size() == 0 ? 0 : mapSection.offset);\n        out.uint(\"string_ids_size\", stringIdSection.items.size());\n        out.uint(\"string_ids_off\", stringIdSection.items.size() == 0 ? 0 : stringIdSection.offset);\n\n        out.uint(\"type_ids_size\", typeIdSection.items.size());\n        out.uint(\"type_ids_off\", typeIdSection.items.size() == 0 ? 0 : typeIdSection.offset);\n\n        out.uint(\"proto_ids_size\", protoIdSection.items.size());\n        out.uint(\"proto_ids_off\", protoIdSection.items.size() == 0 ? 0 : protoIdSection.offset);\n\n        out.uint(\"field_ids_size\", fieldIdSection.items.size());\n        out.uint(\"field_ids_off\", fieldIdSection.items.size() == 0 ? 0 : fieldIdSection.offset);\n\n        out.uint(\"method_ids_size\", methodIdSection.items.size());\n        out.uint(\"method_ids_off\", methodIdSection.items.size() == 0 ? 0 : methodIdSection.offset);\n        out.uint(\"class_defs_size\", classDefSection.items.size());\n        out.uint(\"class_defs_off\", classDefSection.items.size() == 0 ? 0 : classDefSection.offset);\n\n        out.uint(\"data_size\", fileSize - mapSection.offset);   // every thing after map is data section\n        out.uint(\"data_off\", mapSection.offset);// map is the first in data section\n\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 0x70;\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/MapListItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\npublic class MapListItem extends BaseItem {\n    final public List<SectionItem<?>> items = new ArrayList<>();\n\n    public int getSize() {\n        return 4 + items.size() * 12;\n    }\n\n    public void writeMapItem(DataOut out, int type, int size, int offset) {\n        out.begin(\"map_item\");\n        out.ushort(\"type\", type);\n        out.ushort(\"unused\", 0);\n        out.uint(\"size\", size);\n        out.uint(\"offset\", offset);\n        out.end();\n    }\n\n    public void cleanZeroSizeEntry() {\n        for (Iterator<SectionItem<?>> it = items.iterator(); it.hasNext(); ) {\n            SectionItem<?> i = it.next();\n            if (i == null || i.items.size() < 1) {\n                it.remove();\n            }\n        }\n    }\n\n    public void write(DataOut out) {\n        out.begin(\"map_list\");\n        out.uint(\"size\", items.size());\n        for (SectionItem<?> t : items) {\n            writeMapItem(out, t.sectionType.code, t.items.size(), t.offset);\n        }\n        out.end();\n        items.clear();\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 4 + items.size() * 12;\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/MethodIdItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\n@Alignment(4)\npublic class MethodIdItem extends BaseItem implements Comparable<MethodIdItem> {\n\n    public MethodIdItem(TypeIdItem typeItem, StringIdItem nameItem, ProtoIdItem protoIdItem) {\n        super();\n        this.clazz = typeItem;\n        this.name = nameItem;\n        this.proto = protoIdItem;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((name == null) ? 0 : name.hashCode());\n        result = prime * result + ((proto == null) ? 0 : proto.hashCode());\n        result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        MethodIdItem other = (MethodIdItem) obj;\n        if (name == null) {\n            if (other.name != null)\n                return false;\n        } else if (!name.equals(other.name))\n            return false;\n        if (proto == null) {\n            if (other.proto != null)\n                return false;\n        } else if (!proto.equals(other.proto))\n            return false;\n        if (clazz == null) {\n            if (other.clazz != null)\n                return false;\n        } else if (!clazz.equals(other.clazz))\n            return false;\n        return true;\n    }\n\n    @Idx\n    public final StringIdItem name;\n    @Idx\n    public final TypeIdItem clazz;\n    @Idx\n    public final ProtoIdItem proto;\n\n    @Override\n    public int place(int offset) {\n        return offset + 0x08;\n    }\n\n    @Override\n    public int compareTo(MethodIdItem o) {\n        int x = clazz.compareTo(o.clazz);\n        if (x != 0) {\n            return x;\n        }\n        x = name.compareTo(o.name);\n        if (x != 0) {\n            return x;\n        }\n        return proto.compareTo(o.proto);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.ushort(\"class_idx\", clazz.index);\n        out.ushort(\"proto_idx\", proto.index);\n        out.uint(\"name_idx\", name.index);\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/ProtoIdItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\npublic class ProtoIdItem extends BaseItem implements Comparable<ProtoIdItem> {\n    @Idx\n    public final StringIdItem shorty;\n    @Idx\n    public final TypeIdItem ret;\n    @Off\n    public final TypeListItem parameters;\n\n    public ProtoIdItem(TypeListItem parameters, TypeIdItem ret, StringIdItem shorty) {\n        super();\n        this.parameters = parameters;\n        this.ret = ret;\n        this.shorty = shorty;\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());\n        result = prime * result + ((ret == null) ? 0 : ret.hashCode());\n        result = prime * result + ((shorty == null) ? 0 : shorty.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        ProtoIdItem other = (ProtoIdItem) obj;\n        if (parameters == null) {\n            if (other.parameters != null)\n                return false;\n        } else if (!parameters.equals(other.parameters))\n            return false;\n        if (ret == null) {\n            if (other.ret != null)\n                return false;\n        } else if (!ret.equals(other.ret))\n            return false;\n        if (shorty == null) {\n            if (other.shorty != null)\n                return false;\n        } else if (!shorty.equals(other.shorty))\n            return false;\n        return true;\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 0x0c;\n    }\n\n    @Override\n    public int compareTo(ProtoIdItem o) {\n        int x = ret.compareTo(o.ret);\n        if (x != 0) {\n            return x;\n        }\n        return parameters.compareTo(o.parameters);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"shorty_idx\", shorty.index);\n        out.uint(\"return_type_idx\", ret.index);\n        // can't use zero-size type_list_item in libart\n        out.uint(\"parameters_off\", (parameters == null || parameters.items.size() == 0) ? 0 : parameters.offset);\n    }\n\n}"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/SectionItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.io.DataOut;\nimport com.googlecode.d2j.dex.writer.item.StringDataItem.Buffer;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\npublic class SectionItem<T extends BaseItem> extends BaseItem {\n    final public SectionType sectionType;\n    public final List<T> items = new ArrayList<>();\n    int size = 0;\n\n    public SectionItem(SectionType typeCode) {\n        super();\n        this.sectionType = typeCode;\n\n    }\n\n    public SectionItem(SectionType typeCode, Collection<T> itms) {\n        super();\n        this.sectionType = typeCode;\n        this.items.addAll(itms);\n    }\n\n    public static void main(String... strings) throws IllegalArgumentException, IllegalAccessException {\n        for (Field f : SectionItem.class.getFields()) {\n            if (f.getType().equals(int.class)) {\n                if (0 != (f.getModifiers() & Modifier.STATIC)) {\n                    System.out.printf(\"%s(0x%04x,0,0),//\\n\", f.getName(), f.get(null));\n                }\n            }\n        }\n    }\n\n    public int size() {\n        return size;\n    }\n\n    public int place(int offset) {\n        final int startOffset = offset;\n        int index = 0;\n        for (T t : items) {\n            offset = padding(offset, sectionType.alignment);\n            t.offset = offset;\n            t.index = index;\n            index++;\n            offset = t.place(offset);\n        }\n        size = offset - startOffset;\n        return offset;\n    }\n\n    public void write(DataOut out) {\n        out.begin(\"Section:\" + sectionType);\n        List<T> items = this.items;\n        if (sectionType == SectionType.TYPE_STRING_DATA_ITEM) {\n            Buffer buff = new Buffer();\n\n            for (int i = 0; i < items.size(); i++) {\n                T t = items.get(i);\n                items.set(i, null);\n                addPadding(out, sectionType.alignment);\n                if (out.offset() != t.offset) {\n                    throw new RuntimeException();\n                }\n                StringDataItem stringDataItem = (StringDataItem) t;\n                stringDataItem.write(out, buff);\n                buff.reset();\n            }\n        } else {\n            for (int i = 0; i < items.size(); i++) {\n                T t = items.get(i);\n                items.set(i, null);\n                addPadding(out, sectionType.alignment);\n                if (out.offset() != t.offset) {\n                    System.err.println(\"Error for type:\" + this.sectionType + \", \" + t.index);\n                    throw new RuntimeException();\n                }\n                t.write(out);\n            }\n        }\n        out.end();\n    }\n\n    public enum SectionType {\n        TYPE_HEADER_ITEM(0x0000, 1, 0), //\n        TYPE_STRING_ID_ITEM(0x0001, 4, 0), //\n        TYPE_TYPE_ID_ITEM(0x0002, 4, 0), //\n        TYPE_PROTO_ID_ITEM(0x0003, 4, 0), //\n        TYPE_FIELD_ID_ITEM(0x0004, 4, 0), //\n        TYPE_METHOD_ID_ITEM(0x0005, 1, 0), //\n        TYPE_CLASS_DEF_ITEM(0x0006, 4, 0), //\n        TYPE_MAP_LIST(0x1000, 4, 0), //\n        TYPE_TYPE_LIST(0x1001, 4, 0), //\n        TYPE_ANNOTATION_SET_REF_LIST(0x1002, 4, 0), //\n        TYPE_ANNOTATION_SET_ITEM(0x1003, 4, 0), //\n        TYPE_CLASS_DATA_ITEM(0x2000, 1, 0), //\n        TYPE_CODE_ITEM(0x2001, 4, 0), //\n        TYPE_STRING_DATA_ITEM(0x2002, 1, 0), //\n        TYPE_DEBUG_INFO_ITEM(0x2003, 1, 0), //\n        TYPE_ANNOTATION_ITEM(0x2004, 1, 0), //\n        TYPE_ENCODED_ARRAY_ITEM(0x2005, 1, 0), //\n        TYPE_ANNOTATIONS_DIRECTORY_ITEM(0x2006, 4, 0), //\n        ;\n        public int code;\n        public int alignment;\n\n        SectionType(int typeCode, int alignment, int size) {\n            this.code = typeCode;\n            this.alignment = alignment;\n        }\n    }\n\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/StringDataItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.io.ByteArrayOutputStream;\n\n@Alignment(1)\npublic class StringDataItem extends BaseItem implements Comparable<StringDataItem> {\n    static public class Buffer extends ByteArrayOutputStream {\n        public byte[] getBuf() {\n            return buf;\n        }\n    }\n\n    public static void encode(ByteArrayOutputStream out, String s) {\n        final int length = s.length();\n        for (int i = 0; i < length; i++) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                out.write(ch);\n            } else if (ch <= 2047) {\n                out.write((0xc0 | (0x1f & (ch >> 6))));\n                out.write((0x80 | (0x3f & ch)));\n            } else {\n                out.write((0xe0 | (0x0f & (ch >> 12))));\n                out.write((0x80 | (0x3f & (ch >> 6))));\n                out.write((0x80 | (0x3f & ch)));\n            }\n        }\n    }\n\n    public static int lengthOfMutf8(String s) {\n        int result = 0;\n        final int length = s.length();\n        for (int i = 0; i < length; ++i) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                ++result;\n            } else if (ch <= 2047) {\n                result += 2;\n            } else {\n                result += 3;\n            }\n        }\n        return result;\n    }\n\n    public final String string;\n\n    public StringDataItem(String data) {\n        this.string = data;\n    }\n\n    @Override\n    public int compareTo(StringDataItem o) {\n        return string.compareTo(o.string);\n    }\n\n    @Override\n    public int place(int offset) {\n        int length = lengthOfMutf8(string);\n        return offset + lengthOfUleb128(string.length()) + length + 1; // 1 for tailing 0\n    }\n\n    @Override\n    public String toString() {\n        return \"StringDataItem [string=\" + string + \"]\";\n    }\n\n    @Override\n    public void write(DataOut out) {\n        write(out, new Buffer());\n    }\n\n    public void write(DataOut out, Buffer buff) {\n        out.uleb128(\"string_data_length\", string.length());\n        encode(buff, string);\n        buff.write(0);\n        out.bytes(\"mutf8-string\", buff.getBuf(), 0, buff.size());\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/StringIdItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\n@Alignment(4)\npublic class StringIdItem extends BaseItem implements Comparable<StringIdItem> {\n    public StringIdItem(StringDataItem stringDataItem) {\n        this.stringData = stringDataItem;\n    }\n\n    @Override\n    public String toString() {\n        return \"StringIdItem [stringData=\" + stringData + \"]\";\n    }\n\n    @Off\n    public final StringDataItem stringData;\n\n    @Override\n    public int place(int offset) {\n        return offset + 4;\n    }\n\n    @Override\n    public int compareTo(StringIdItem o) {\n        return stringData.compareTo(o.stringData);\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"string_data_off\", stringData.offset);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/TypeIdItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.ann.Idx;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\n@Alignment(4)\npublic class TypeIdItem extends BaseItem implements Comparable<TypeIdItem> {\n    public TypeIdItem(StringIdItem stringIdItem) {\n        super();\n        this.descriptor = stringIdItem;\n    }\n\n    @Idx\n    public final StringIdItem descriptor;\n\n    @Override\n    public int place(int offset) {\n        return offset + 0x04;\n    }\n\n    @Override\n    public String toString() {\n        return \"TypeIdItem [descriptor=\" + descriptor + \"]\";\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"descriptor_idx\", this.descriptor.index);\n    }\n\n    @Override\n    public int compareTo(TypeIdItem o) {\n        return descriptor.compareTo(o.descriptor);\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/main/java/com/googlecode/d2j/dex/writer/item/TypeListItem.java",
    "content": "/*\n * dex2jar - Tools to work with android .dex and java .class files\n * Copyright (c) 2009-2013 Panxiaobo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.d2j.dex.writer.item;\n\nimport com.googlecode.d2j.dex.writer.ann.Alignment;\nimport com.googlecode.d2j.dex.writer.ann.Off;\nimport com.googlecode.d2j.dex.writer.io.DataOut;\n\nimport java.util.List;\n\n@Alignment(4)\npublic class TypeListItem extends BaseItem implements Comparable<TypeListItem> {\n    public TypeListItem(List<TypeIdItem> items) {\n        super();\n        this.items = items;\n    }\n\n    @Off\n    public final List<TypeIdItem> items;\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + ((items == null) ? 0 : items.hashCode());\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        TypeListItem other = (TypeListItem) obj;\n        if (items == null) {\n            if (other.items != null)\n                return false;\n        } else if (!items.equals(other.items))\n            return false;\n        return true;\n    }\n\n    @Override\n    public int place(int offset) {\n        return offset + 4 + items.size() * 2;\n    }\n\n    @Override\n    public void write(DataOut out) {\n        out.uint(\"size\", items.size());\n        for (TypeIdItem idItem : items) {\n            out.ushort(\"type_idx\", idItem.index);\n        }\n    }\n\n    @Override\n    public int compareTo(TypeListItem o) {\n        int min = Math.min(items.size(), o.items.size());\n        for (int i = 0; i < min; i++) {\n            int x = items.get(i).compareTo(o.items.get(i));\n            if (x != 0) {\n                return x;\n            }\n        }\n        return (items.size() == o.items.size() ? 0 : (items.size() < o.items.size() ? -1 : 1));\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/test/java/a/AppWriterTest.java",
    "content": "package a;\n\nimport com.googlecode.d2j.DexConstants;\nimport com.googlecode.d2j.Field;\nimport com.googlecode.d2j.Method;\nimport com.googlecode.d2j.Visibility;\nimport com.googlecode.d2j.dex.writer.DexFileWriter;\nimport com.googlecode.d2j.dex.writer.DexWriteException;\nimport com.googlecode.d2j.reader.DexFileReader;\nimport com.googlecode.d2j.reader.Op;\nimport com.googlecode.d2j.visitors.*;\n\nimport org.junit.Test;\n\nimport java.io.File;\nimport java.io.IOException;\n\npublic class AppWriterTest implements DexConstants {\n    @Test(expected = DexWriteException.class)\n    public void testDupClz() {\n        DexFileWriter w = new DexFileWriter();\n        DexClassVisitor cv = w.visit(0, \"La/b;\", null, null);\n        cv.visitEnd();\n        cv = w.visit(0, \"La/b;\", null, null);\n        cv.visitEnd();\n        w.visitEnd();\n    }\n\n    @Test\n    public void test3() {\n        DexFileWriter w = new DexFileWriter();\n        DexClassVisitor cv = w.visit(0x1, \"La/c;\", null, new String[]{\"Ljava/lang/Comparable;\"});\n        cv.visitSource(\"c.java\");\n        cv.visitAnnotation(\"LAnn;\", Visibility.SYSTEM).visitEnd();\n        DexFieldVisitor fv = cv.visitField(ACC_PUBLIC | ACC_STATIC, new Field(\"La/c;\", \"a\", \"I\"), 55);\n        fv.visitAnnotation(\"LE;\", Visibility.RUNTIME).visitEnd();\n        fv.visitEnd();\n\n        DexMethodVisitor mv = cv.visitMethod(ACC_STATIC, new Method(\"La/c;\", \"bb\", new String[]{\"I\"}, \"V\"));\n        mv.visitAnnotation(\"Laaa;\", Visibility.RUNTIME).visitEnd();\n        DexAnnotationVisitor dav = mv.visitParameterAnnotation(0).visitAnnotation(\"Laaa;\", Visibility.RUNTIME);\n        dav.visit(\"abc\", true);\n        DexAnnotationVisitor dav2 = dav.visitArray(\"efg\");\n        dav2.visit(\"\", \"123\");\n        dav2.visit(\"\", \"456\");\n        dav2.visitEnd();\n        dav.visitEnd();\n\n        DexCodeVisitor code = mv.visitCode();\n        code.visitRegister(2);\n\n        code.visitStmt0R(Op.RETURN_VOID);\n        code.visitEnd();\n        mv.visitEnd();\n\n        cv.visitEnd();\n\n\n        w.visitEnd();\n        w.toByteArray();\n    }\n\n    @Test\n    public void test4() throws IOException {\n        DexFileWriter w = new DexFileWriter();\n        DexFileReader dexFileReader = new DexFileReader(new File(\"../dex-translator/src/test/resources/dexes/i_jetty.dex\"));\n        dexFileReader.accept(w);\n        w.toByteArray();\n    }\n}\n"
  },
  {
    "path": "dex-writer/src/test/java/a/CpStringTest.java",
    "content": "package a;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport com.googlecode.d2j.dex.writer.item.ConstPool;\n\npublic class CpStringTest {\n    @Test\n    public void test() {\n        ConstPool cp = new ConstPool();\n        Assert.assertTrue(cp.uniqString(\"b\").compareTo(cp.uniqString(\"a\")) > 0);\n        Assert.assertTrue(cp.uniqType(\"Lb;\").compareTo(cp.uniqType(\"La;\")) > 0);\n    }\n\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Apr 02 11:30:39 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.0-bin.zip\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# 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\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    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# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "settings.gradle",
    "content": "rootProject.name = 'dex2jar'\ninclude ':dex-reader-api',':dex-reader', ':dex-writer', ':dex-translator', ':dex-ir', ':dex-tools', ':d2j-smali', ':d2j-base-cmd', ':d2j-jasmin', ':d2j-j6'\n"
  }
]