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.repatch;
  /*
   *
   *
   *                                  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.taobao.android.repatch.Utils.DefineUtils;
  import com.taobao.android.repatch.processor.ClassProcessor;
  import com.taobao.android.tpatch.utils.SmaliUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.jf.dexlib2.iface.Annotation;
  import org.jf.dexlib2.iface.AnnotationElement;
  import org.jf.dexlib2.iface.Field;
  import org.jf.dexlib2.iface.Method;
  import org.jf.dexlib2.iface.reference.MethodReference;
  import org.jf.dexlib2.iface.value.*;
  import org.jf.dexlib2.immutable.ImmutableAnnotation;
  import org.jf.dexlib2.immutable.ImmutableAnnotationElement;
  import org.jf.dexlib2.immutable.ImmutableField;
  import org.jf.dexlib2.immutable.reference.ImmutableMethodReference;
  import org.jf.dexlib2.immutable.value.ImmutableArrayEncodedValue;
  import org.jf.dexlib2.immutable.value.ImmutableMethodEncodedValue;
  import org.jf.dexlib2.immutable.value.ImmutableStringEncodedValue;
  import org.jf.dexlib2.immutable.value.ImmutableTypeEncodedValue;
  
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  /**
   * Created by lilong on 16/7/1.
   */
  public abstract class ClassReIClassDef extends AbIClassDef {
  
      protected ClassProcessor classProcessor;
  
      public ClassReIClassDef(ClassProcessor classProcessor) {
  
          this.classProcessor = classProcessor;
  
      }
  
      @Override
      protected String reType(String type) {
  
          return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(type)).className, false);
      }
  
      @Override
      protected String reSuperClass(String superClass) {
          return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(superClass)).className, false);
      }
  
      @Override
      protected String reInterface(String inter) {
  
          return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(inter)).className, false);
      }
  
      @Override
      protected Annotation reAnnotation(Annotation annotation) {
          String type = annotation.getType();
          boolean isArray = false;
          if (type.startsWith("[")) {
              isArray = true;
          }
          String newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, isArray);
          Set<? extends AnnotationElement> sets = annotation.getElements();
          Set<ImmutableAnnotationElement> newAnnotationElement = new HashSet<ImmutableAnnotationElement>();
          for (AnnotationElement annotationElement : sets) {
              String name = annotationElement.getName();
              EncodedValue encodedValue = annotationElement.getValue();
              if (encodedValue instanceof ArrayEncodedValue) {
                  List<EncodedValue> lists = new ArrayList<EncodedValue>();
                  for (EncodedValue encodedValueSub : ((ArrayEncodedValue) encodedValue).getValue()) {
                      if (encodedValueSub instanceof StringEncodedValue) {
                          String newValue = null;
                          boolean isArray1 = false;
                          String value = ((StringEncodedValue) encodedValueSub).getValue();
                          if (value.startsWith("[")) {
                              isArray1 = true;
                          }
                          if (basicValue.contains(value)) {
                              newValue = value;
                          } else if (value.startsWith("Ljava/util/") || value.startsWith("Ljava/lang/") || !value.startsWith("L")) {
                              newValue = value;
                          } else {
                              if (value.endsWith(";")) {
                                  newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray1);
                              }else {
                                  newValue = DefineUtils.getDotDefineClassName(classProcessor.classProcess(DefineUtils.getDotDalvikClassName(value)).className, isArray1);
  
                              }
                          }
                          ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);
                          lists.add(immutableStringEncodedValue);
                      } else if (encodedValueSub instanceof TypeEncodedValue) {
                          String newValueSub = null;
                          String value = ((TypeEncodedValue) encodedValueSub).getValue();
                          boolean isArray2 = false;
                          if (value.startsWith("[")) {
                              isArray2 = true;
                          }
                          if (basicValue.contains(value)) {
                              newValueSub = value;
                          } else if (value.startsWith("Ljava/util/") || !value.endsWith(";")) {
                              newValueSub = value;
                          } else {
                              newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);
                          }
                          ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);
                          lists.add(immutableTypeEncodedValue);
  
                      } else {
                          lists.add(encodedValue);
                      }
                  }
                  ImmutableArrayEncodedValue immutableArrayEncodedValue = new ImmutableArrayEncodedValue(lists);
                  ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableArrayEncodedValue);
                  newAnnotationElement.add(immutableAnnotationElement);
  
              } else if (encodedValue instanceof StringEncodedValue) {
                  String value = ((StringEncodedValue) encodedValue).getValue();
                  String newValue = null;
                  isArray = false;
                  if (value.startsWith("[")) {
                      isArray = true;
                  }
                  if (basicValue.contains(value)) {
                      newValue = value;
                  } else if (value.startsWith("Ljava/util/") || value.startsWith("Ljava/lang/") || !value.startsWith("L")) {
                      newValue = value;
                  } else {
                      if (value.endsWith(";")) {
                          newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray);
                      }else {
                          newValue = DefineUtils.getDotDefineClassName(classProcessor.classProcess(DefineUtils.getDotDalvikClassName(value)).className, isArray);
  
                      }
                  }
                  ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);
                  ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableStringEncodedValue);
                  newAnnotationElement.add(immutableAnnotationElement);
              } else if (encodedValue instanceof TypeEncodedValue) {
                  String newValue = null;
                  String value = ((TypeEncodedValue) encodedValue).getValue();
                  boolean isArray2 = false;
                  if (value.startsWith("[")) {
                      isArray2 = true;
                  }
                  if (basicValue.contains(value)) {
                      newValue = value;
                  } else if (value.startsWith("Ljava/util/") || !value.endsWith(";")) {
                      newValue = value;
                  } else {
                      newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);
                  }
                  ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValue);
                  ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableTypeEncodedValue);
  
                  newAnnotationElement.add(immutableAnnotationElement);
              } else if (encodedValue instanceof MethodEncodedValue) {
                  MethodReference methodReference = ((MethodEncodedValue) encodedValue).getValue();
                  String returnType = methodReference.getReturnType();
                  boolean isArray3 = false;
  
                  if (returnType.startsWith("[")){
                      isArray3 = true;
                  }
                  boolean isBasic = basicType.containsKey(returnType);
                  List<? extends CharSequence> paramTypes = methodReference.getParameterTypes();
                  List<CharSequence> dalvikParamTypes = new ArrayList<CharSequence>();
  
                  List<CharSequence> newParamTypes = new ArrayList<CharSequence>();
  
                  for (CharSequence charSequence : paramTypes) {
                      boolean isArray1 = false;
                      if (charSequence.toString().startsWith("[")){
                          isArray1 = true;
                      }
                      if (basicType.containsKey(charSequence.toString())) {
                          newParamTypes.add(charSequence);
                          dalvikParamTypes.add(basicType.get(charSequence.toString()));
                          continue;
                      }
                      dalvikParamTypes.add(DefineUtils.getDalvikClassName(charSequence.toString()) + (isArray1 ? "[]" : ""));
                      newParamTypes.add(
                              DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(charSequence.toString())).className, isArray1));
                  }
                  final ImmutableMethodReference immutableReference = new ImmutableMethodReference(
                          DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass())).className, false),
  
                          classProcessor.methodProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass()),
                                  methodReference.getName(),
                                  isBasic ? basicType.get(methodReference.getReturnType()) : DefineUtils.getDalvikClassName(methodReference.getReturnType()) + (isArray3 ? "[]" : ""),
                                  StringUtils.join(dalvikParamTypes.toArray(), ",")).methodName,
                          newParamTypes,
  
                          isBasic ? returnType : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getReturnType())).className, methodReference.getReturnType().startsWith("["))
                  );
                  ImmutableMethodEncodedValue immutableMethodEncodedValue = new ImmutableMethodEncodedValue(immutableReference);
                  ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableMethodEncodedValue);
  
                  newAnnotationElement.add(immutableAnnotationElement);
  
              } else {
                  newAnnotationElement.add(ImmutableAnnotationElement.of(annotationElement));
              }
          }
          return new ImmutableAnnotation(annotation.getVisibility(), newType, newAnnotationElement);
  
  
      }
  
      @Override
      protected Field reField(Field field) {
          String name = field.getName();
          String newType;
          boolean isBasic = false;
          boolean isArray = false;
          if (field.getType().startsWith("[")) {
              isArray = true;
          }
          if (basicType.containsKey(field.getType())) {
              newType = field.getType();
              isBasic = true;
          } else {
  
              newType = DefineUtils.getDalvikClassName(field.getType());
          }
          String defineClass = DefineUtils.getDalvikClassName(field.getDefiningClass());
          return new ImmutableField(
                  reType,
                  classProcessor.filedProcess(defineClass, isBasic ? basicType.get(newType) : newType + (isArray ? "[]" : ""), name).fieldName,
                  isBasic ? newType :
                          DefineUtils.getDefineClassName(classProcessor.classProcess(isBasic ? basicType.get(newType) : newType).className, isArray),
                  field.getAccessFlags(),
                  field.getInitialValue(),
                  getAnnotation(field.getAnnotations()));
      }
  
      @Override
      public abstract Method reMethod(Method method);
  
  
      public Set<? extends Annotation> getAnnotation(Set<? extends Annotation> annotations) {
          Set<ImmutableAnnotation> newAnnotations = new HashSet<ImmutableAnnotation>();
          for (Annotation annotation : annotations) {
              String type = annotation.getType();
              boolean isArray = false;
              if (type.startsWith("[")) {
                  isArray = true;
              }
              String newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, isArray);
              Set<? extends AnnotationElement> sets = annotation.getElements();
              Set<ImmutableAnnotationElement> newAnnotationElement = new HashSet<ImmutableAnnotationElement>();
              for (AnnotationElement annotationElement : sets) {
                  String name = annotationElement.getName();
                  EncodedValue encodedValue = annotationElement.getValue();
                  if (encodedValue instanceof ArrayEncodedValue) {
                      List<EncodedValue> lists = new ArrayList<EncodedValue>();
                      for (EncodedValue encodedValueSub : ((ArrayEncodedValue) encodedValue).getValue()) {
                          if (encodedValueSub instanceof StringEncodedValue) {
                              String newValue = null;
                              boolean isArray1 = false;
                              String value = ((StringEncodedValue) encodedValueSub).getValue();
                              if (value.startsWith("[")) {
                                  isArray1 = true;
                              }
                              if (basicValue.contains(value)) {
                                  newValue = value;
                              } else if (value.startsWith("Ljava/util/") || !value.endsWith(";") || value.startsWith("Ljava/lang/")||!value.startsWith("L")) {
                                  newValue = value;
                              } else {
                                  newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray1);
                              }
                              ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);
                              lists.add(immutableStringEncodedValue);
                          } else if (encodedValueSub instanceof TypeEncodedValue) {
                              String newValueSub = null;
                              String value = ((TypeEncodedValue) encodedValueSub).getValue();
                              boolean isArray2 = false;
                              if (value.startsWith("[")) {
                                  isArray2 = true;
                              }
                              if (basicValue.contains(value)) {
                                  newValueSub = value;
                              } else if (value.startsWith("Ljava/util/") || value.startsWith("Ljava/lang/") || !value.endsWith(";")) {
                                  newValueSub = value;
                              } else {
                                  newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);
                              }
                              ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);
                              lists.add(immutableTypeEncodedValue);
  
                          } else {
                              lists.add(encodedValue);
                          }
                      }
                      ImmutableArrayEncodedValue immutableArrayEncodedValue = new ImmutableArrayEncodedValue(lists);
                      ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableArrayEncodedValue);
                      newAnnotationElement.add(immutableAnnotationElement);
  
                  } else if (encodedValue instanceof StringEncodedValue) {
                      String value = ((StringEncodedValue) encodedValue).getValue();
                      boolean isArray3 = false;
                      if (value.startsWith("[")) {
                          isArray3 = true;
                      }
                      String newValue = null;
                      if (basicValue.contains(value)) {
                          newValue = value;
                      } else if (value.startsWith("Ljava/util/") || value.startsWith("Ljava/lang/") || !value.endsWith(";")) {
                          newValue = value;
                      } else {
                          newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray3);
                      }
                      ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);
                      ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableStringEncodedValue);
                      newAnnotationElement.add(immutableAnnotationElement);
  
  
                  } else if (encodedValue instanceof MethodEncodedValue) {
                      MethodReference methodReference = ((MethodEncodedValue) encodedValue).getValue();
                      String returnType = methodReference.getReturnType();
                      boolean isBasic = false;
                      List<? extends CharSequence> paramTypes = methodReference.getParameterTypes();
                      List<CharSequence> dalvikParamTypes = new ArrayList<CharSequence>();
  
                      List<CharSequence> newParamTypes = new ArrayList<CharSequence>();
  
                      for (CharSequence charSequence : paramTypes) {
                          if (basicType.containsKey(charSequence.toString())) {
                              newParamTypes.add(charSequence);
                              dalvikParamTypes.add(basicType.get(charSequence.toString()));
                              continue;
                          }
                          dalvikParamTypes.add(DefineUtils.getDalvikClassName(charSequence.toString()) + (isArray ? "[]" : ""));
                          newParamTypes.add(
                                  DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(charSequence.toString())).className, isArray));
                      }
                      final ImmutableMethodReference immutableReference = new ImmutableMethodReference(
                              DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass())).className, false),
  
                              classProcessor.methodProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass()),
                                      methodReference.getName(),
                                      isBasic ? basicType.get(methodReference.getReturnType()) : DefineUtils.getDalvikClassName(methodReference.getReturnType()) + (isArray ? "[]" : ""),
                                      StringUtils.join(dalvikParamTypes.toArray(), ",")).methodName,
                              newParamTypes,
  
                              isBasic ? returnType : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getReturnType())).className, methodReference.getReturnType().startsWith("["))
                      );
                      ImmutableMethodEncodedValue immutableMethodEncodedValue = new ImmutableMethodEncodedValue(immutableReference);
                      ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableMethodEncodedValue);
  
                      newAnnotationElement.add(immutableAnnotationElement);
  
  
                  } else if (encodedValue instanceof TypeEncodedValue) {
                      String newValueSub = null;
                      String value = ((TypeEncodedValue) encodedValue).getValue();
                      boolean isArray2 = false;
                      if (value.startsWith("[")) {
                          isArray2 = true;
                      }
                      if (basicValue.contains(value)) {
                          newValueSub = value;
                      } else if (value.startsWith("Ljava/util/") || value.startsWith("Ljava/lang/") || !value.endsWith(";")) {
                          newValueSub = value;
                      } else {
                          newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);
                      }
                      ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);
                      ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableTypeEncodedValue);
                      newAnnotationElement.add(immutableAnnotationElement);
  
                  } else {
                      newAnnotationElement.add(ImmutableAnnotationElement.of(annotationElement));
                  }
              }
  
              ImmutableAnnotation immutableAnnotation = new ImmutableAnnotation(annotation.getVisibility(), newType, newAnnotationElement);
              newAnnotations.add(immutableAnnotation);
          }
          return newAnnotations;
      }
  }
  