content: /*
   *
   *
   *                                  Apache License
   *                            Version 2.0, January 2004
   *                         http://www.apache.org/licenses/
   *
   *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
   *
   *    1. Definitions.
   *
   *       "License" shall mean the terms and conditions for use, reproduction,
   *       and distribution as defined by Sections 1 through 9 of this document.
   *
   *       "Licensor" shall mean the copyright owner or entity authorized by
   *       the copyright owner that is granting the License.
   *
   *       "Legal Entity" shall mean the union of the acting entity and all
   *       other entities that control, are controlled by, or are under common
   *       control with that entity. For the purposes of this definition,
   *       "control" means (i) the power, direct or indirect, to cause the
   *       direction or management of such entity, whether by contract or
   *       otherwise, or (ii) ownership of fifty percent (50%) or more of the
   *       outstanding shares, or (iii) beneficial ownership of such entity.
   *
   *       "You" (or "Your") shall mean an individual or Legal Entity
   *       exercising permissions granted by this License.
   *
   *       "Source" form shall mean the preferred form for making modifications,
   *       including but not limited to software source code, documentation
   *       source, and configuration files.
   *
   *       "Object" form shall mean any form resulting from mechanical
   *       transformation or translation of a Source form, including but
   *       not limited to compiled object code, generated documentation,
   *       and conversions to other media types.
   *
   *       "Work" shall mean the work of authorship, whether in Source or
   *       Object form, made available under the License, as indicated by a
   *       copyright notice that is included in or attached to the work
   *       (an example is provided in the Appendix below).
   *
   *       "Derivative Works" shall mean any work, whether in Source or Object
   *       form, that is based on (or derived from) the Work and for which the
   *       editorial revisions, annotations, elaborations, or other modifications
   *       represent, as a whole, an original work of authorship. For the purposes
   *       of this License, Derivative Works shall not include works that remain
   *       separable from, or merely link (or bind by name) to the interfaces of,
   *       the Work and Derivative Works thereof.
   *
   *       "Contribution" shall mean any work of authorship, including
   *       the original version of the Work and any modifications or additions
   *       to that Work or Derivative Works thereof, that is intentionally
   *       submitted to Licensor for inclusion in the Work by the copyright owner
   *       or by an individual or Legal Entity authorized to submit on behalf of
   *       the copyright owner. For the purposes of this definition, "submitted"
   *       means any form of electronic, verbal, or written communication sent
   *       to the Licensor or its representatives, including but not limited to
   *       communication on electronic mailing lists, source code control systems,
   *       and issue tracking systems that are managed by, or on behalf of, the
   *       Licensor for the purpose of discussing and improving the Work, but
   *       excluding communication that is conspicuously marked or otherwise
   *       designated in writing by the copyright owner as "Not a Contribution."
   *
   *       "Contributor" shall mean Licensor and any individual or Legal Entity
   *       on behalf of whom a Contribution has been received by Licensor and
   *       subsequently incorporated within the Work.
   *
   *    2. Grant of Copyright License. Subject to the terms and conditions of
   *       this License, each Contributor hereby grants to You a perpetual,
   *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   *       copyright license to reproduce, prepare Derivative Works of,
   *       publicly display, publicly perform, sublicense, and distribute the
   *       Work and such Derivative Works in Source or Object form.
   *
   *    3. Grant of Patent License. Subject to the terms and conditions of
   *       this License, each Contributor hereby grants to You a perpetual,
   *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   *       (except as stated in this section) patent license to make, have made,
   *       use, offer to sell, sell, import, and otherwise transfer the Work,
   *       where such license applies only to those patent claims licensable
   *       by such Contributor that are necessarily infringed by their
   *       Contribution(s) alone or by combination of their Contribution(s)
   *       with the Work to which such Contribution(s) was submitted. If You
   *       institute patent litigation against any entity (including a
   *       cross-claim or counterclaim in a lawsuit) alleging that the Work
   *       or a Contribution incorporated within the Work constitutes direct
   *       or contributory patent infringement, then any patent licenses
   *       granted to You under this License for that Work shall terminate
   *       as of the date such litigation is filed.
   *
   *    4. Redistribution. You may reproduce and distribute copies of the
   *       Work or Derivative Works thereof in any medium, with or without
   *       modifications, and in Source or Object form, provided that You
   *       meet the following conditions:
   *
   *       (a) You must give any other recipients of the Work or
   *           Derivative Works a copy of this License; and
   *
   *       (b) You must cause any modified files to carry prominent notices
   *           stating that You changed the files; and
   *
   *       (c) You must retain, in the Source form of any Derivative Works
   *           that You distribute, all copyright, patent, trademark, and
   *           attribution notices from the Source form of the Work,
   *           excluding those notices that do not pertain to any part of
   *           the Derivative Works; and
   *
   *       (d) If the Work includes a "NOTICE" text file as part of its
   *           distribution, then any Derivative Works that You distribute must
   *           include a readable copy of the attribution notices contained
   *           within such NOTICE file, excluding those notices that do not
   *           pertain to any part of the Derivative Works, in at least one
   *           of the following places: within a NOTICE text file distributed
   *           as part of the Derivative Works; within the Source form or
   *           documentation, if provided along with the Derivative Works; or,
   *           within a display generated by the Derivative Works, if and
   *           wherever such third-party notices normally appear. The contents
   *           of the NOTICE file are for informational purposes only and
   *           do not modify the License. You may add Your own attribution
   *           notices within Derivative Works that You distribute, alongside
   *           or as an addendum to the NOTICE text from the Work, provided
   *           that such additional attribution notices cannot be construed
   *           as modifying the License.
   *
   *       You may add Your own copyright statement to Your modifications and
   *       may provide additional or different license terms and conditions
   *       for use, reproduction, or distribution of Your modifications, or
   *       for any such Derivative Works as a whole, provided Your use,
   *       reproduction, and distribution of the Work otherwise complies with
   *       the conditions stated in this License.
   *
   *    5. Submission of Contributions. Unless You explicitly state otherwise,
   *       any Contribution intentionally submitted for inclusion in the Work
   *       by You to the Licensor shall be under the terms and conditions of
   *       this License, without any additional terms or conditions.
   *       Notwithstanding the above, nothing herein shall supersede or modify
   *       the terms of any separate license agreement you may have executed
   *       with Licensor regarding such Contributions.
   *
   *    6. Trademarks. This License does not grant permission to use the trade
   *       names, trademarks, service marks, or product names of the Licensor,
   *       except as required for reasonable and customary use in describing the
   *       origin of the Work and reproducing the content of the NOTICE file.
   *
   *    7. Disclaimer of Warranty. Unless required by applicable law or
   *       agreed to in writing, Licensor provides the Work (and each
   *       Contributor provides its Contributions) on an "AS IS" BASIS,
   *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   *       implied, including, without limitation, any warranties or conditions
   *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   *       PARTICULAR PURPOSE. You are solely responsible for determining the
   *       appropriateness of using or redistributing the Work and assume any
   *       risks associated with Your exercise of permissions under this License.
   *
   *    8. Limitation of Liability. In no event and under no legal theory,
   *       whether in tort (including negligence), contract, or otherwise,
   *       unless required by applicable law (such as deliberate and grossly
   *       negligent acts) or agreed to in writing, shall any Contributor be
   *       liable to You for damages, including any direct, indirect, special,
   *       incidental, or consequential damages of any character arising as a
   *       result of this License or out of the use or inability to use the
   *       Work (including but not limited to damages for loss of goodwill,
   *       work stoppage, computer failure or malfunction, or any and all
   *       other commercial damages or losses), even if such Contributor
   *       has been advised of the possibility of such damages.
   *
   *    9. Accepting Warranty or Additional Liability. While redistributing
   *       the Work or Derivative Works thereof, You may choose to offer,
   *       and charge a fee for, acceptance of support, warranty, indemnity,
   *       or other liability obligations and/or rights consistent with this
   *       License. However, in accepting such obligations, You may act only
   *       on Your own behalf and on Your sole responsibility, not on behalf
   *       of any other Contributor, and only if You agree to indemnify,
   *       defend, and hold each Contributor harmless for any liability
   *       incurred by, or claims asserted against, such Contributor by reason
   *       of your accepting any such warranty or additional liability.
   *
   *    END OF TERMS AND CONDITIONS
   *
   *    APPENDIX: How to apply the Apache License to your work.
   *
   *       To apply the Apache License to your work, attach the following
   *       boilerplate notice, with the fields enclosed by brackets "[]"
   *       replaced with your own identifying information. (Don't include
   *       the brackets!)  The text should be enclosed in the appropriate
   *       comment syntax for the file format. We also recommend that a
   *       file or class name and description of purpose be included on the
   *       same "printed page" as the copyright notice for easier
   *       identification within third-party archives.
   *
   *    Copyright 2016 Alibaba Group
   *
   *    Licensed under the Apache License, Version 2.0 (the "License");
   *    you may not use this file except in compliance with the License.
   *    You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *    Unless required by applicable law or agreed to in writing, software
   *    distributed under the License is distributed on an "AS IS" BASIS,
   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *    See the License for the specific language governing permissions and
   *    limitations under the License.
   *
   *
   */
  package com.taobao.android.differ.dex;
  /*
   *
   *
   *                                  Apache License
   *                            Version 2.0, January 2004
   *                         http://www.apache.org/licenses/
   *
   *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
   *
   *    1. Definitions.
   *
   *       "License" shall mean the terms and conditions for use, reproduction,
   *       and distribution as defined by Sections 1 through 9 of this document.
   *
   *       "Licensor" shall mean the copyright owner or entity authorized by
   *       the copyright owner that is granting the License.
   *
   *       "Legal Entity" shall mean the union of the acting entity and all
   *       other entities that control, are controlled by, or are under common
   *       control with that entity. For the purposes of this definition,
   *       "control" means (i) the power, direct or indirect, to cause the
   *       direction or management of such entity, whether by contract or
   *       otherwise, or (ii) ownership of fifty percent (50%) or more of the
   *       outstanding shares, or (iii) beneficial ownership of such entity.
   *
   *       "You" (or "Your") shall mean an individual or Legal Entity
   *       exercising permissions granted by this License.
   *
   *       "Source" form shall mean the preferred form for making modifications,
   *       including but not limited to software source code, documentation
   *       source, and configuration files.
   *
   *       "Object" form shall mean any form resulting from mechanical
   *       transformation or translation of a Source form, including but
   *       not limited to compiled object code, generated documentation,
   *       and conversions to other media types.
   *
   *       "Work" shall mean the work of authorship, whether in Source or
   *       Object form, made available under the License, as indicated by a
   *       copyright notice that is included in or attached to the work
   *       (an example is provided in the Appendix below).
   *
   *       "Derivative Works" shall mean any work, whether in Source or Object
   *       form, that is based on (or derived from) the Work and for which the
   *       editorial revisions, annotations, elaborations, or other modifications
   *       represent, as a whole, an original work of authorship. For the purposes
   *       of this License, Derivative Works shall not include works that remain
   *       separable from, or merely link (or bind by name) to the interfaces of,
   *       the Work and Derivative Works thereof.
   *
   *       "Contribution" shall mean any work of authorship, including
   *       the original version of the Work and any modifications or additions
   *       to that Work or Derivative Works thereof, that is intentionally
   *       submitted to Licensor for inclusion in the Work by the copyright owner
   *       or by an individual or Legal Entity authorized to submit on behalf of
   *       the copyright owner. For the purposes of this definition, "submitted"
   *       means any form of electronic, verbal, or written communication sent
   *       to the Licensor or its representatives, including but not limited to
   *       communication on electronic mailing lists, source code control systems,
   *       and issue tracking systems that are managed by, or on behalf of, the
   *       Licensor for the purpose of discussing and improving the Work, but
   *       excluding communication that is conspicuously marked or otherwise
   *       designated in writing by the copyright owner as "Not a Contribution."
   *
   *       "Contributor" shall mean Licensor and any individual or Legal Entity
   *       on behalf of whom a Contribution has been received by Licensor and
   *       subsequently incorporated within the Work.
   *
   *    2. Grant of Copyright License. Subject to the terms and conditions of
   *       this License, each Contributor hereby grants to You a perpetual,
   *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   *       copyright license to reproduce, prepare Derivative Works of,
   *       publicly display, publicly perform, sublicense, and distribute the
   *       Work and such Derivative Works in Source or Object form.
   *
   *    3. Grant of Patent License. Subject to the terms and conditions of
   *       this License, each Contributor hereby grants to You a perpetual,
   *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   *       (except as stated in this section) patent license to make, have made,
   *       use, offer to sell, sell, import, and otherwise transfer the Work,
   *       where such license applies only to those patent claims licensable
   *       by such Contributor that are necessarily infringed by their
   *       Contribution(s) alone or by combination of their Contribution(s)
   *       with the Work to which such Contribution(s) was submitted. If You
   *       institute patent litigation against any entity (including a
   *       cross-claim or counterclaim in a lawsuit) alleging that the Work
   *       or a Contribution incorporated within the Work constitutes direct
   *       or contributory patent infringement, then any patent licenses
   *       granted to You under this License for that Work shall terminate
   *       as of the date such litigation is filed.
   *
   *    4. Redistribution. You may reproduce and distribute copies of the
   *       Work or Derivative Works thereof in any medium, with or without
   *       modifications, and in Source or Object form, provided that You
   *       meet the following conditions:
   *
   *       (a) You must give any other recipients of the Work or
   *           Derivative Works a copy of this License; and
   *
   *       (b) You must cause any modified files to carry prominent notices
   *           stating that You changed the files; and
   *
   *       (c) You must retain, in the Source form of any Derivative Works
   *           that You distribute, all copyright, patent, trademark, and
   *           attribution notices from the Source form of the Work,
   *           excluding those notices that do not pertain to any part of
   *           the Derivative Works; and
   *
   *       (d) If the Work includes a "NOTICE" text file as part of its
   *           distribution, then any Derivative Works that You distribute must
   *           include a readable copy of the attribution notices contained
   *           within such NOTICE file, excluding those notices that do not
   *           pertain to any part of the Derivative Works, in at least one
   *           of the following places: within a NOTICE text file distributed
   *           as part of the Derivative Works; within the Source form or
   *           documentation, if provided along with the Derivative Works; or,
   *           within a display generated by the Derivative Works, if and
   *           wherever such third-party notices normally appear. The contents
   *           of the NOTICE file are for informational purposes only and
   *           do not modify the License. You may add Your own attribution
   *           notices within Derivative Works that You distribute, alongside
   *           or as an addendum to the NOTICE text from the Work, provided
   *           that such additional attribution notices cannot be construed
   *           as modifying the License.
   *
   *       You may add Your own copyright statement to Your modifications and
   *       may provide additional or different license terms and conditions
   *       for use, reproduction, or distribution of Your modifications, or
   *       for any such Derivative Works as a whole, provided Your use,
   *       reproduction, and distribution of the Work otherwise complies with
   *       the conditions stated in this License.
   *
   *    5. Submission of Contributions. Unless You explicitly state otherwise,
   *       any Contribution intentionally submitted for inclusion in the Work
   *       by You to the Licensor shall be under the terms and conditions of
   *       this License, without any additional terms or conditions.
   *       Notwithstanding the above, nothing herein shall supersede or modify
   *       the terms of any separate license agreement you may have executed
   *       with Licensor regarding such Contributions.
   *
   *    6. Trademarks. This License does not grant permission to use the trade
   *       names, trademarks, service marks, or product names of the Licensor,
   *       except as required for reasonable and customary use in describing the
   *       origin of the Work and reproducing the content of the NOTICE file.
   *
   *    7. Disclaimer of Warranty. Unless required by applicable law or
   *       agreed to in writing, Licensor provides the Work (and each
   *       Contributor provides its Contributions) on an "AS IS" BASIS,
   *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   *       implied, including, without limitation, any warranties or conditions
   *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   *       PARTICULAR PURPOSE. You are solely responsible for determining the
   *       appropriateness of using or redistributing the Work and assume any
   *       risks associated with Your exercise of permissions under this License.
   *
   *    8. Limitation of Liability. In no event and under no legal theory,
   *       whether in tort (including negligence), contract, or otherwise,
   *       unless required by applicable law (such as deliberate and grossly
   *       negligent acts) or agreed to in writing, shall any Contributor be
   *       liable to You for damages, including any direct, indirect, special,
   *       incidental, or consequential damages of any character arising as a
   *       result of this License or out of the use or inability to use the
   *       Work (including but not limited to damages for loss of goodwill,
   *       work stoppage, computer failure or malfunction, or any and all
   *       other commercial damages or losses), even if such Contributor
   *       has been advised of the possibility of such damages.
   *
   *    9. Accepting Warranty or Additional Liability. While redistributing
   *       the Work or Derivative Works thereof, You may choose to offer,
   *       and charge a fee for, acceptance of support, warranty, indemnity,
   *       or other liability obligations and/or rights consistent with this
   *       License. However, in accepting such obligations, You may act only
   *       on Your own behalf and on Your sole responsibility, not on behalf
   *       of any other Contributor, and only if You agree to indemnify,
   *       defend, and hold each Contributor harmless for any liability
   *       incurred by, or claims asserted against, such Contributor by reason
   *       of your accepting any such warranty or additional liability.
   *
   *    END OF TERMS AND CONDITIONS
   *
   *    APPENDIX: How to apply the Apache License to your work.
   *
   *       To apply the Apache License to your work, attach the following
   *       boilerplate notice, with the fields enclosed by brackets "[]"
   *       replaced with your own identifying information. (Don't include
   *       the brackets!)  The text should be enclosed in the appropriate
   *       comment syntax for the file format. We also recommend that a
   *       file or class name and description of purpose be included on the
   *       same "printed page" as the copyright notice for easier
   *       identification within third-party archives.
   *
   *    Copyright 2016 Alibaba Group
   *
   *    Licensed under the Apache License, Version 2.0 (the "License");
   *    you may not use this file except in compliance with the License.
   *    You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *    Unless required by applicable law or agreed to in writing, software
   *    distributed under the License is distributed on an "AS IS" BASIS,
   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *    See the License for the specific language governing permissions and
   *    limitations under the License.
   *
   *
   */
  
  import com.google.common.base.Objects;
  import com.google.common.collect.Lists;
  import com.google.common.collect.Maps;
  import com.google.common.collect.Sets;
  import com.taobao.android.filter.DexDiffFilter;
  import com.taobao.android.filter.Filter;
  import com.taobao.android.object.*;
  import com.taobao.android.utils.DexCompareUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.jf.dexlib2.DexFileFactory;
  import org.jf.dexlib2.Opcodes;
  import org.jf.dexlib2.dexbacked.*;
  import org.jf.dexlib2.iface.Annotation;
  import org.jf.dexlib2.iface.value.EncodedValue;
  import org.jf.dexlib2.util.ReferenceUtil;
  
  import javax.annotation.Nullable;
  import java.io.File;
  import java.io.IOException;
  import java.util.*;
  import java.util.function.Consumer;
  
  public class DexDiffer {
  
      private List<File> baseDexFiles = Lists.newArrayList();
      private List<File> newDexFiles = Lists.newArrayList();
      private int apiLevel;
  
      public String getNoPatchDexNum() {
          return noPatchDexNum;
      }
  
      private String noPatchDexNum;
  
      private static final String NO_PATCH_DEX = "NO_PATCH_DEX";
  
  
      private static final String PATCH_VERSION = "PATCH_VERSION";
  
  
      public boolean isNewPatch() {
          return newPatch;
      }
  
      public void setNewPatch(boolean newPatch) {
          this.newPatch = newPatch;
      }
  
      private boolean newPatch = true;
  
  
      private Map<String, org.jf.dexlib2.iface.ClassDef>lastBundleClassMap = new HashMap<String, org.jf.dexlib2.iface.ClassDef>();
      private DexDiffInfo dexDiffInfo = new DexDiffInfo();
  
      public List<DiffClass> getDiffClasses() {
          return diffClasses;
      }
  
      private List<DiffClass>diffClasses = new ArrayList<>();
  
      public Set<String> getExludeClasses() {
          return exludeClasses;
      }
  
      public void setExludeClasses(Set<String> exludeClasses) {
          this.exludeClasses = exludeClasses;
      }
  
      private Set<String>exludeClasses = new HashSet<>();
  
      public Set<String> getPatchClasses() {
          return patchClasses;
      }
  
      public void setPatchClasses(Set<String> patchClasses) {
          this.patchClasses = patchClasses;
      }
  
      private Set<String>patchClasses = new HashSet<>();
  
      //dex filter
      private DexDiffFilter dexDiffFilter;
      //
      private Filter filter;
  
      public void setTpatch(boolean tpatch) {
          this.tpatch = tpatch;
      }
  
      private boolean tpatch;
  
      private Map<String, DexBackedClassDef> baseClassDefMap = new HashMap<String, DexBackedClassDef>();
  
      public DexDiffer(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel) {
          this.baseDexFiles = baseDexFiles;
          this.newDexFiles = newDexFiles;
          this.apiLevel = apiLevel;
      }
  
      public DexDiffer(File baseDex, File newDex, int apiLevel) {
          baseDexFiles.add(baseDex);
          newDexFiles.add(newDex);
          this.apiLevel = apiLevel;
      }
  
  
      public void setDexDiffFilter(DexDiffFilter dexDiffFilter) {
          this.dexDiffFilter = dexDiffFilter;
      }
  
      public void setLastBundleClassMap(Map<String, org.jf.dexlib2.iface.ClassDef> map){
          this.lastBundleClassMap = map;
      }
  
  
      public void createFilter(String filterPath) {
          this.filter = new Filter(filterPath);
      }
  
  
      /**
       * 获取二个dex文件的diff差异
       *
       * @return
       */
      public DexDiffInfo doDiff() throws IOException, PatchException {
          scanBaseDexFile();
          Set<DexBackedClassDef> newDexClassDefs = Sets.newHashSet();
          for (File newDexFile : newDexFiles) {
              DexBackedDexFile newBackedDexFile = DexFileFactory.loadDexFile(newDexFile, Opcodes.getDefault());
              newDexClassDefs.addAll(newBackedDexFile.getClasses());
              dexDiffInfo.setNewClasses(newDexClassDefs);
          }
          for (DexBackedClassDef newClassDef : newDexClassDefs) {
              if (filter != null) {
                  if (filter.isFiltered(newClassDef.getType())) {
                      System.out.println("filter class:"+newClassDef.getType());
                      continue;
                  }
              }
              String className = getDalvikClassName(newClassDef.getType());
              if (!tpatch&&exludeClasses.contains(newClassDef.getType())){
                  continue;
              }
  
              if (!tpatch&&patchClasses.size() > 0 && !patchClasses.contains(newClassDef.getType())){
                  continue;
              }
  
              if (!tpatch &&(newClassDef.getType().contains("/R$")||newClassDef.getType().contains("/R;"))){
                  continue;
              }
              DexBackedClassDef baseClassDef = baseClassDefMap.get(className);
              ClassDiffInfo classDiffInfo = compareClassDef(baseClassDef, newClassDef);
              if (DiffType.MODIFY.equals(classDiffInfo.getType())){
                  DiffClass diffClass = new DiffClass(baseClassDef.getType(),dexDiffInfo.getBaseClassDefNum(baseClassDef));
                  diffClasses.add(diffClass);
                  dexDiffInfo.getClassDiffInfoMap().put(className, classDiffInfo);
              } else if (DiffType.ADD.equals(classDiffInfo.getType())) {
                  dexDiffInfo.getClassDiffInfoMap().put(className, classDiffInfo);
              }else if (DiffType.NONE.equals(classDiffInfo.getType())){
                  if (lastBundleClassMap.containsKey(newClassDef.getType())&&tpatch){
                      System.out.println("overide class:"+className);
  //                    ClassDiffInfo classDiffInfo = new ClassDiffInfo();
                      classDiffInfo.setType(DiffType.OVERRIDE);
                      classDiffInfo.setClassDef(baseClassDef);
                      dexDiffInfo.getClassDiffInfoMap().put(className,classDiffInfo);
                      DiffClass diffClass = new DiffClass(baseClassDef.getType(),dexDiffInfo.getBaseClassDefNum(baseClassDef));
                      diffClasses.add(diffClass);
                  }
  
              }
          }
  
          if (noPatchDexNum != null){
              diffClasses.add(new DiffClass(NO_PATCH_DEX,Integer.valueOf(noPatchDexNum)));
          }
  
          diffClasses.add(new DiffClass(PATCH_VERSION,newPatch ? 2:1));
          return dexDiffInfo;
      }
  
  
  
      public void dexFilter() throws PatchException {
          if (dexDiffFilter != null) {
              dexDiffFilter.filterDex();
          }
  
      }
  
      /**
       * scan base Dex,get base Dex info
       */
      private void scanBaseDexFile() throws IOException {
          for (File baseDexFile : baseDexFiles) {
              String s = baseDexFile.getName().substring(7);
              String dexNum = s.startsWith(".")? "0":s.substring(0,s.indexOf("."));
              DexBackedDexFile baseBackedDexFile = DexFileFactory.loadDexFile(baseDexFile, Opcodes.getDefault());
              final Set<? extends DexBackedClassDef> baseClassDefs = baseBackedDexFile.getClasses();
              baseClassDefs.forEach(new Consumer<DexBackedClassDef>() {
                  @Override
                  public void accept(DexBackedClassDef dexBackedClassDef) {
                      if (dexBackedClassDef.getType().equals("Lcom/ali/mobisecenhance/ReflectMap;")){
                          noPatchDexNum = dexNum;
                      }
                  }
              });
              dexDiffInfo.setOldClasses(dexNum,baseClassDefs);
              for (DexBackedClassDef baseClassDef : baseClassDefs) {
                  String className = getDalvikClassName(baseClassDef.getType());
                  baseClassDefMap.put(className, baseClassDef);
              }
          }
      }
  
      /**
       * compare two classDef
       *
       * @param baseClassDef
       * @param newClassDef
       * @return
       */
      private ClassDiffInfo compareClassDef(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef) throws PatchException {
          ClassDiffInfo classDiffInfo = new ClassDiffInfo();
          String className = null;
          if (null == baseClassDef && null != newClassDef) {
              className = getDalvikClassName(newClassDef.getType());
              classDiffInfo.setName(className);
              classDiffInfo.setClassDef(newClassDef);
              classDiffInfo.setType(DiffType.ADD);
          } else if (null != baseClassDef && null == newClassDef) {
              className = getDalvikClassName(baseClassDef.getType());
              classDiffInfo.setName(className);
              classDiffInfo.setClassDef(baseClassDef);
              classDiffInfo.setType(DiffType.REMOVE);
          } else {// 比较是否有变更
              className = getDalvikClassName(baseClassDef.getType());
              classDiffInfo.setName(className);
              classDiffInfo.setClassDef(newClassDef);
              boolean classDefModify = compareClassDef_(baseClassDef, newClassDef);
              boolean methodDefModify = false;
              boolean fieldDefModify = false;
              if (classDefModify) {
                  classDiffInfo.setType(DiffType.MODIFY);
                  // 1. 比较类里面的方法
                  compareMethods(baseClassDef, newClassDef, classDiffInfo);
                  // 2. 比较类里面的字段
                  compareFields(baseClassDef, newClassDef, classDiffInfo);
              } else {
                  // 1. 比较类里面的方法
                  methodDefModify = compareMethods(baseClassDef, newClassDef, classDiffInfo);
                  // 2. 比较类里面的字段
                  fieldDefModify = compareFields(baseClassDef, newClassDef, classDiffInfo);
                  if (methodDefModify || fieldDefModify) {
                      classDiffInfo.setType(DiffType.MODIFY);
                  } else {
                      classDiffInfo.setType(DiffType.NONE);
                  }
              }
  
          }
          return classDiffInfo;
      }
  
      /**
       * 得到这个类的字符串化的定义
       *
       * @param baseClassDef
       * @param newClassDef
       * @return 2个类的定义是否变更
       */
      private boolean compareClassDef_(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef) {
          if (null == baseClassDef || null == newClassDef) {
              return false;
          }
          if (baseClassDef.equals(newClassDef)) {
              // compare access flag
              if (baseClassDef.getAccessFlags() != newClassDef.getAccessFlags()) {
                  return true;
              }
              // compare super class
              if (!StringUtils.equals(baseClassDef.getSuperclass(), newClassDef.getSuperclass())) {
                  return true;
              }
              // compare interfaces
              if (!equalsImpl(baseClassDef.getInterfaces(), newClassDef.getInterfaces())) {
                  return true;
              }
              // compare annotations
              if (!equalsImpl(baseClassDef.getAnnotations(), newClassDef.getAnnotations())) {
                  return true;
              }
              // 不考虑sourceFile
              return false;
          }
          return true;
      }
  
      private boolean equalsImpl(Collection<?> s, @Nullable Object object) {
          if (s == object) {
              return true;
          } else if (object instanceof Collection){
              Collection o = (Collection) object;
              try {
                  return s.size() == o.size() && s.containsAll(o);
              } catch (NullPointerException var4) {
                  return false;
              } catch (ClassCastException var5) {
                  return false;
              }
          } else {
              return false;
          }
      }
  
      /**
       * compare two methods
       * FIXME:
       *
       * @param baseClassDef
       * @param newClassDef
       * @param classDiffInfo
       */
      private boolean compareMethods(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef,
                                     ClassDiffInfo classDiffInfo) throws PatchException {
          Map<String, DexBackedMethod> baseMethodDefMaps = Maps.newHashMap();
          for (DexBackedMethod dexBackedMethod : baseClassDef.getMethods()) {
              String baseMethodDesc = ReferenceUtil.getMethodDescriptor(dexBackedMethod);
              baseMethodDefMaps.put(baseMethodDesc, dexBackedMethod);
          }
          for (DexBackedMethod newMethod : newClassDef.getMethods()) {
              MethodDiffInfo methodDiffInfo = new MethodDiffInfo();
              String newethodDesc = ReferenceUtil.getMethodDescriptor(newMethod);
              methodDiffInfo.setBackedMethod(newMethod);
              DexBackedMethod baseMethod = baseMethodDefMaps.get(newethodDesc);
              if (null == baseMethod) {
                  methodDiffInfo.setType(DiffType.ADD);
                  classDiffInfo.getModifyMethods().add(methodDiffInfo);
                  continue;
              }
              // TODO:
  
              Set<? extends Annotation>newAnnotations = newMethod.getAnnotations();
              Set<? extends Annotation>baseAnnotations = baseMethod.getAnnotations();
              int newAcc = newMethod.getAccessFlags();
              int baseAcc = baseMethod.getAccessFlags();
  
              DexBackedMethodImplementation newMethodImplementation = newMethod.getImplementation();
              DexBackedMethodImplementation baseMethodImplementation = baseMethod.getImplementation();
              if (!DexCompareUtils.compareMethod(newMethodImplementation, baseMethodImplementation)||
                      !equalsImpl(baseAnnotations,newAnnotations)||newAcc!=baseAcc) {
                  methodDiffInfo.setType(DiffType.MODIFY);
                  classDiffInfo.getModifyMethods().add(methodDiffInfo);
  
              }
              baseMethodDefMaps.remove(newethodDesc);
          }
          // 如果方法已经移除
          if (baseMethodDefMaps.size() > 0) {
              for (Map.Entry<String, DexBackedMethod> entry : baseMethodDefMaps.entrySet()) {
                  MethodDiffInfo methodDiffInfo = new MethodDiffInfo();
                  methodDiffInfo.setType(DiffType.REMOVE);
                  methodDiffInfo.setBackedMethod(entry.getValue());
                  classDiffInfo.getModifyMethods().add(methodDiffInfo);
              }
          }
          if (classDiffInfo.getModifyMethods().size() > 0) {
              return true;
          }
          return false;
      }
  
  
      /**
       * compare filed in two dex Files
       *
       * @param baseClassDef
       * @param newClassDef
       * @param classDiffInfo
       */
      private boolean compareFields(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef,
                                    ClassDiffInfo classDiffInfo) throws PatchException {
          Map<String, DexBackedField> baseFieldMaps = Maps.newHashMap();
          for (DexBackedField backedField : baseClassDef.getFields()) {
              baseFieldMaps.put(ReferenceUtil.getFieldDescriptor(backedField), backedField);
          }
          for (DexBackedField newField : newClassDef.getFields()) {
              FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();
              fieldDiffInfo.setBackedField(newField);
              String fieldDesc = ReferenceUtil.getFieldDescriptor(newField);
              DexBackedField baseField = baseFieldMaps.get(fieldDesc);
              if (null == baseField) {
                  fieldDiffInfo.setType(DiffType.ADD);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
                  continue;
              }
  
  
              // init value
              EncodedValue baseInitaValue = baseField.getInitialValue();
              EncodedValue newInitaValue = newField.getInitialValue();
              if (!Objects.equal(baseInitaValue, newInitaValue)) {
                  fieldDiffInfo.setType(DiffType.MODIFY);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
                  baseFieldMaps.remove(fieldDesc);
                  continue;
              }
              //annotation
              Set<? extends DexBackedAnnotation> backedAnnotations = baseField.getAnnotations();
              if (!equalsImpl(backedAnnotations,newField.getAnnotations())){
                  fieldDiffInfo.setType(DiffType.MODIFY);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
                  baseFieldMaps.remove(fieldDesc);
                  continue;
              }
              //type
              if (!baseField.getType().equals(newField.getType())){
                  fieldDiffInfo.setType(DiffType.MODIFY);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
                  baseFieldMaps.remove(fieldDesc);
                  continue;
              }
              //accessflag
  
              if (baseField.getAccessFlags() != newField.getAccessFlags()){
                  fieldDiffInfo.setType(DiffType.MODIFY);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
                  baseFieldMaps.remove(fieldDesc);
                  continue;
              }
  
              baseFieldMaps.remove(fieldDesc);
  
          }
          // if member is removed
          if (baseFieldMaps.size() > 0) {
              for (Map.Entry<String, DexBackedField> entry : baseFieldMaps.entrySet()) {
                  FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();
                  fieldDiffInfo.setBackedField(entry.getValue());
                  fieldDiffInfo.setType(DiffType.REMOVE);
                  classDiffInfo.getModifyFields().add(fieldDiffInfo);
              }
          }
          if (classDiffInfo.getModifyFields().size() > 0) {
              return true;
          }
          return false;
      }
  
      /**
       * get dalvik className
       *
       * @param className
       * @return
       */
      public static String getDalvikClassName(String className) {
          if (className.charAt(0) != 'L' || className.charAt(className.length() - 1) != ';') {
              throw new RuntimeException("Not a valid dalvik class name");
          }
          return StringUtils.replace(className.substring(1, className.length() - 1), "/", ".");
      }
  
      private static class DiffClass implements Comparable<DiffClass>{
          public String className;
          public Integer dexNumber;
  
          public DiffClass(String className, Integer dexNumber) {
              this.className = className;
              this.dexNumber = dexNumber;
          }
  
  
          @Override
          public String toString() {
              return dexNumber+"-"+className;
          }
  
          @Override
          public int compareTo(DiffClass o) {
              return Integer.valueOf(dexNumber)-Integer.valueOf(o.dexNumber);
          }
      }
  
  
  }
  