// Path: dex-translator/src/main/java/org/objectweb/asm/AsmBridge.java
// public class AsmBridge {
//     public static MethodVisitor searchMethodWriter(MethodVisitor mv) {
//         while (mv != null && !(mv instanceof MethodWriter)) {
//             mv = mv.mv;
//         }
//         return mv;
//     }
// 
//     public static int sizeOfMethodWriter(MethodVisitor mv) {
//         MethodWriter mw = (MethodWriter) mv;
//         return mw.getSize();
//     }
// 
//     private static void removeMethodWriter(MethodWriter mw) {
//         // mv must be the last element
//         ClassWriter cw = mw.cw;
//         MethodWriter p = cw.firstMethod;
//         if (p == mw) {
//             cw.firstMethod = null;
//             if (cw.lastMethod == mw) {
//                 cw.lastMethod = null;
//             }
//         } else {
//             while (p != null) {
//                 if (p.mv == mw) {
//                     p.mv = mw.mv;
//                     if (cw.lastMethod == mw) {
//                         cw.lastMethod = p;
//                     }
//                     break;
//                 } else {
//                     p = (MethodWriter) p.mv;
//                 }
//             }
//         }
//     }
// 
//     public static void replaceMethodWriter(MethodVisitor mv, MethodNode mn) {
//         MethodWriter mw = (MethodWriter) mv;
//         ClassWriter cw = mw.cw;
//         mn.accept(cw);
//         removeMethodWriter(mw);
//     }
// }
// 
// Path: dex-reader-api/src/main/java/com/googlecode/d2j/node/DexMethodNode.java
// public class DexMethodNode extends DexMethodVisitor {
//     public int access;
//     public List<DexAnnotationNode> anns;
//     public DexCodeNode codeNode;
//     public Method method;
//     public List<DexAnnotationNode> parameterAnns[];
// 
//     public DexMethodNode(DexMethodVisitor mv, int access, Method method) {
//         super(mv);
//         this.access = access;
//         this.method = method;
//     }
// 
//     public DexMethodNode(int access, Method method) {
//         super();
//         this.access = access;
//         this.method = method;
//     }
// 
//     public void accept(DexClassVisitor dcv) {
//         DexMethodVisitor mv = dcv.visitMethod(access, method);
//         if (mv != null) {
//             accept(mv);
//             mv.visitEnd();
//         }
// 
//     }
// 
//     public void accept(DexMethodVisitor mv) {
//         if (anns != null) {
//             for (DexAnnotationNode ann : anns) {
//                 ann.accept(mv);
//             }
//         }
// 
//         if (parameterAnns != null) {
//             for (int i = 0; i < parameterAnns.length; i++) {
//                 List<DexAnnotationNode> ps = parameterAnns[i];
//                 if (ps != null) {
//                     DexAnnotationAble av = mv.visitParameterAnnotation(i);
//                     if (av != null) {
//                         for (DexAnnotationNode p : ps) {
//                             p.accept(av);
//                         }
//                     }
//                 }
//             }
//         }
//         if (codeNode != null) {
//             codeNode.accept(mv);
//         }
//     }
// 
//     @Override
//     public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {
//         if (anns == null) {
//             anns = new ArrayList<DexAnnotationNode>(5);
//         }
//         DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);
//         anns.add(annotation);
//         return annotation;
//     }
// 
//     @Override
//     public DexCodeVisitor visitCode() {
//         DexCodeNode codeNode = new DexCodeNode(super.visitCode());
//         this.codeNode = codeNode;
//         return codeNode;
//     }
// 
//     @SuppressWarnings("unchecked")
//     @Override
//     public DexAnnotationAble visitParameterAnnotation(final int index) {
//         if (parameterAnns == null) {
//             parameterAnns = new List[method.getParameterTypes().length];
//         }
// 
// 
//         // https://github.com/pxb1988/dex2jar/issues/485
//         // skip param annotation if out of range
//         if (index >= parameterAnns.length) {
//             System.err.println("WARN: parameter out-of-range in " + method);
//             return null;
//         }
// 
//         return new DexAnnotationAble() {
// 
//             @Override
//             public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {
//                 List<DexAnnotationNode> pas = parameterAnns[index];
//                 if (pas == null) {
//                     pas = new ArrayList<DexAnnotationNode>(5);
//                     parameterAnns[index] = pas;
//                 }
//                 DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);
//                 pas.add(annotation);
//                 return annotation;
//             }
//         };
//     }
// 
// }


import org.objectweb.asm.AsmBridge;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.MethodNode;
import com.googlecode.d2j.DexException;
import com.googlecode.d2j.node.DexMethodNode;
/*
 * dex2jar - Tools to work with android .dex and java .class files
 * Copyright (c) 2009-2014 Panxiaobo
 *
 * 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.googlecode.d2j.dex;



public class ExDex2Asm extends Dex2Asm {
    final protected DexExceptionHandler exceptionHandler;

    public ExDex2Asm(DexExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    @Override
// Path: dex-translator/src/main/java/org/objectweb/asm/AsmBridge.java
// public class AsmBridge {
//     public static MethodVisitor searchMethodWriter(MethodVisitor mv) {
//         while (mv != null && !(mv instanceof MethodWriter)) {
//             mv = mv.mv;
//         }
//         return mv;
//     }
// 
//     public static int sizeOfMethodWriter(MethodVisitor mv) {
//         MethodWriter mw = (MethodWriter) mv;
//         return mw.getSize();
//     }
// 
//     private static void removeMethodWriter(MethodWriter mw) {
//         // mv must be the last element
//         ClassWriter cw = mw.cw;
//         MethodWriter p = cw.firstMethod;
//         if (p == mw) {
//             cw.firstMethod = null;
//             if (cw.lastMethod == mw) {
//                 cw.lastMethod = null;
//             }
//         } else {
//             while (p != null) {
//                 if (p.mv == mw) {
//                     p.mv = mw.mv;
//                     if (cw.lastMethod == mw) {
//                         cw.lastMethod = p;
//                     }
//                     break;
//                 } else {
//                     p = (MethodWriter) p.mv;
//                 }
//             }
//         }
//     }
// 
//     public static void replaceMethodWriter(MethodVisitor mv, MethodNode mn) {
//         MethodWriter mw = (MethodWriter) mv;
//         ClassWriter cw = mw.cw;
//         mn.accept(cw);
//         removeMethodWriter(mw);
//     }
// }
// 
// Path: dex-reader-api/src/main/java/com/googlecode/d2j/node/DexMethodNode.java
// public class DexMethodNode extends DexMethodVisitor {
//     public int access;
//     public List<DexAnnotationNode> anns;
//     public DexCodeNode codeNode;
//     public Method method;
//     public List<DexAnnotationNode> parameterAnns[];
// 
//     public DexMethodNode(DexMethodVisitor mv, int access, Method method) {
//         super(mv);
//         this.access = access;
//         this.method = method;
//     }
// 
//     public DexMethodNode(int access, Method method) {
//         super();
//         this.access = access;
//         this.method = method;
//     }
// 
//     public void accept(DexClassVisitor dcv) {
//         DexMethodVisitor mv = dcv.visitMethod(access, method);
//         if (mv != null) {
//             accept(mv);
//             mv.visitEnd();
//         }
// 
//     }
// 
//     public void accept(DexMethodVisitor mv) {
//         if (anns != null) {
//             for (DexAnnotationNode ann : anns) {
//                 ann.accept(mv);
//             }
//         }
// 
//         if (parameterAnns != null) {
//             for (int i = 0; i < parameterAnns.length; i++) {
//                 List<DexAnnotationNode> ps = parameterAnns[i];
//                 if (ps != null) {
//                     DexAnnotationAble av = mv.visitParameterAnnotation(i);
//                     if (av != null) {
//                         for (DexAnnotationNode p : ps) {
//                             p.accept(av);
//                         }
//                     }
//                 }
//             }
//         }
//         if (codeNode != null) {
//             codeNode.accept(mv);
//         }
//     }
// 
//     @Override
//     public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {
//         if (anns == null) {
//             anns = new ArrayList<DexAnnotationNode>(5);
//         }
//         DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);
//         anns.add(annotation);
//         return annotation;
//     }
// 
//     @Override
//     public DexCodeVisitor visitCode() {
//         DexCodeNode codeNode = new DexCodeNode(super.visitCode());
//         this.codeNode = codeNode;
//         return codeNode;
//     }
// 
//     @SuppressWarnings("unchecked")
//     @Override
//     public DexAnnotationAble visitParameterAnnotation(final int index) {
//         if (parameterAnns == null) {
//             parameterAnns = new List[method.getParameterTypes().length];
//         }
// 
// 
//         // https://github.com/pxb1988/dex2jar/issues/485
//         // skip param annotation if out of range
//         if (index >= parameterAnns.length) {
//             System.err.println("WARN: parameter out-of-range in " + method);
//             return null;
//         }
// 
//         return new DexAnnotationAble() {
// 
//             @Override
//             public DexAnnotationVisitor visitAnnotation(String name, Visibility visibility) {
//                 List<DexAnnotationNode> pas = parameterAnns[index];
//                 if (pas == null) {
//                     pas = new ArrayList<DexAnnotationNode>(5);
//                     parameterAnns[index] = pas;
//                 }
//                 DexAnnotationNode annotation = new DexAnnotationNode(name, visibility);
//                 pas.add(annotation);
//                 return annotation;
//             }
//         };
//     }
// 
// }


// Path: dex-translator/src/main/java/com/googlecode/d2j/dex/ExDex2Asm.java
import org.objectweb.asm.AsmBridge;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.MethodNode;
import com.googlecode.d2j.DexException;
import com.googlecode.d2j.node.DexMethodNode;

/*
 * dex2jar - Tools to work with android .dex and java .class files
 * Copyright (c) 2009-2014 Panxiaobo
 *
 * 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.googlecode.d2j.dex;



public class ExDex2Asm extends Dex2Asm {
    final protected DexExceptionHandler exceptionHandler;

    public ExDex2Asm(DexExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    @Override
    public void convertCode(DexMethodNode methodNode, MethodVisitor mv, ClzCtx clzCtx) {