// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/exceptions/SurgeonException.java
// public class SurgeonException extends Exception {
// 
//     public SurgeonException() {
//         super();
//     }
// 
//     public SurgeonException(String message) {
//         super(message);
//     }
// 
//     public SurgeonException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public SurgeonException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java
// public interface Continue {
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java
// public interface IMaster {
//     /**
//      * @param function The key of SurgeonMethod
//      */
//     SurgeonMethod find(String function);
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java
// public interface ISurgeon {
// 
//     /**
//      * Control current object to singleton.
//      */
//     boolean singleton();
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java
// public interface Replacer<T> {
//     /**
//      * Called before original function called.
//      *
//      * @param params The original function input params.
//      */
//     void before(Object[] params);
// 
//     /**
//      * Replace original function.
//      *
//      * @param params The original function input params.
//      * @return new return result.
//      */
//     T replace(Object[] params) throws Throwable;
// 
//     /**
//      * Called after original function called.
//      *
//      * @param params The original function input params.
//      */
//     void after(Object[] params);
// }


import com.surgeon.weaving.core.exceptions.SurgeonException;
import com.surgeon.weaving.core.interfaces.Continue;
import com.surgeon.weaving.core.interfaces.IMaster;
import com.surgeon.weaving.core.interfaces.ISurgeon;
import com.surgeon.weaving.core.interfaces.Replacer;
import java.lang.reflect.InvocationTargetException;
import static android.text.TextUtils.isEmpty;
import static com.surgeon.weaving.core.ASPConstant.AFTER;
import static com.surgeon.weaving.core.ASPConstant.BEFORE;
                } else if (AFTER.equals(prefix)) {
                    replacer.after(copyOfArgs);
                } else {
                    return replacer.replace(copyOfArgs);
                }
                return null;
            }

            //static repalce
            SurgeonMethod replaceMethod = master.find(prefix + function);
            if (replaceMethod != null) {
                return invoke(replaceMethod, copyOfArgs);
            }
        } catch (ClassNotFoundException ignored) {
            //ignored
        } catch (Exception e) {
            throw new SurgeonException(e);
        }
        return Continue.class;
    }

    private Object invoke(SurgeonMethod method, Object[] args)
            throws IllegalAccessException,
            InstantiationException,
            InvocationTargetException {
        Object ownerInstance = InnerCache.getInstance().getMethodOwner(method.getOwner());
        //cache owner instance
        if (ownerInstance == null) {
            Class clazz = method.getOwner();
            ownerInstance = clazz.newInstance();
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/exceptions/SurgeonException.java
// public class SurgeonException extends Exception {
// 
//     public SurgeonException() {
//         super();
//     }
// 
//     public SurgeonException(String message) {
//         super(message);
//     }
// 
//     public SurgeonException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public SurgeonException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java
// public interface Continue {
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java
// public interface IMaster {
//     /**
//      * @param function The key of SurgeonMethod
//      */
//     SurgeonMethod find(String function);
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java
// public interface ISurgeon {
// 
//     /**
//      * Control current object to singleton.
//      */
//     boolean singleton();
// }
// 
// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java
// public interface Replacer<T> {
//     /**
//      * Called before original function called.
//      *
//      * @param params The original function input params.
//      */
//     void before(Object[] params);
// 
//     /**
//      * Replace original function.
//      *
//      * @param params The original function input params.
//      * @return new return result.
//      */
//     T replace(Object[] params) throws Throwable;
// 
//     /**
//      * Called after original function called.
//      *
//      * @param params The original function input params.
//      */
//     void after(Object[] params);
// }


// Path: surgeon-core/src/main/java/com/surgeon/weaving/core/MasterFinder.java
import com.surgeon.weaving.core.exceptions.SurgeonException;
import com.surgeon.weaving.core.interfaces.Continue;
import com.surgeon.weaving.core.interfaces.IMaster;
import com.surgeon.weaving.core.interfaces.ISurgeon;
import com.surgeon.weaving.core.interfaces.Replacer;
import java.lang.reflect.InvocationTargetException;
import static android.text.TextUtils.isEmpty;
import static com.surgeon.weaving.core.ASPConstant.AFTER;
import static com.surgeon.weaving.core.ASPConstant.BEFORE;

                } else if (AFTER.equals(prefix)) {
                    replacer.after(copyOfArgs);
                } else {
                    return replacer.replace(copyOfArgs);
                }
                return null;
            }

            //static repalce
            SurgeonMethod replaceMethod = master.find(prefix + function);
            if (replaceMethod != null) {
                return invoke(replaceMethod, copyOfArgs);
            }
        } catch (ClassNotFoundException ignored) {
            //ignored
        } catch (Exception e) {
            throw new SurgeonException(e);
        }
        return Continue.class;
    }

    private Object invoke(SurgeonMethod method, Object[] args)
            throws IllegalAccessException,
            InstantiationException,
            InvocationTargetException {
        Object ownerInstance = InnerCache.getInstance().getMethodOwner(method.getOwner());
        //cache owner instance
        if (ownerInstance == null) {
            Class clazz = method.getOwner();
            ownerInstance = clazz.newInstance();
            if (ownerInstance instanceof ISurgeon && ((ISurgeon) ownerInstance).singleton()) {