/*
 * Copyright 2013, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.jf.dexlib2.analysis;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.instruction.*;
import org.jf.dexlib2.iface.instruction.formats.*;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.immutable.instruction.*;
import org.jf.dexlib2.immutable.reference.ImmutableFieldReference;
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference;
import org.jf.dexlib2.util.MethodUtil;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.dexlib2.util.TypeUtils;
import org.jf.dexlib2.writer.util.TryListBuilder;
import org.jf.util.BitSetUtils;
import org.jf.util.ExceptionWithContext;
import org.jf.util.SparseArray;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.BitSet;
import java.util.List;

/**
 * The MethodAnalyzer performs several functions. It "analyzes" the instructions and infers the register types
 * for each register, it can deodex odexed instructions, and it can verify the bytecode. The analysis and verification
 * are done in two separate passes, because the analysis has to process instructions multiple times in some cases, and
 * there's no need to perform the verification multiple times, so we wait until the method is fully analyzed and then
 * verify it.
 *
 * Before calling the analyze() method, you must have initialized the ClassPath by calling
 * ClassPath.InitializeClassPath
 */
public class MethodAnalyzer {
    @Nonnull private final Method method;
    @Nonnull private final MethodImplementation methodImpl;

    private final boolean normalizeVirtualMethods;

    private final int paramRegisterCount;

    @Nonnull private final ClassPath classPath;
    @Nullable private final InlineMethodResolver inlineResolver;

    // This contains all the AnalyzedInstruction instances, keyed by the code unit address of the instruction
    @Nonnull private final SparseArray<AnalyzedInstruction> analyzedInstructions =
            new SparseArray<AnalyzedInstruction>(0);

    // Which instructions have been analyzed, keyed by instruction index
    @Nonnull private final BitSet analyzedState;

    @Nullable private AnalysisException analysisException = null;

    // This is a dummy instruction that occurs immediately before the first real instruction. We can initialize the
    // register types for this instruction to the parameter types, in order to have them propagate to all of its
    // successors, e.g. the first real instruction, the first instructions in any exception handlers covering the first
    // instruction, etc.
    private final AnalyzedInstruction startOfMethod;

    public MethodAnalyzer(@Nonnull ClassPath classPath, @Nonnull Method method,
                          @Nullable InlineMethodResolver inlineResolver, boolean normalizeVirtualMethods) {
        this.classPath = classPath;
        this.inlineResolver = inlineResolver;
        this.normalizeVirtualMethods = normalizeVirtualMethods;

        this.method = method;

        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            throw new IllegalArgumentException("The method has no implementation");
        }

        this.methodImpl = methodImpl;

        // Override AnalyzedInstruction and provide custom implementations of some of the methods, so that we don't
        // have to handle the case this special case of instruction being null, in the main class
        startOfMethod = new AnalyzedInstruction(this, new ImmutableInstruction10x(Opcode.NOP), -1, methodImpl.getRegisterCount()) {
            @Override protected boolean addPredecessor(AnalyzedInstruction predecessor) {
                throw new UnsupportedOperationException();
            }

            @Override @Nonnull
            public RegisterType getPredecessorRegisterType(@Nonnull AnalyzedInstruction predecessor, int registerNumber) {
                throw new UnsupportedOperationException();
            }
        };

        buildInstructionList();

        analyzedState = new BitSet(analyzedInstructions.size());
        paramRegisterCount = MethodUtil.getParameterRegisterCount(method);
        analyze();
    }

    @Nonnull
    public ClassPath getClassPath() {
        return classPath;
    }

    private void analyze() {
        Method method = this.method;
        MethodImplementation methodImpl = this.methodImpl;

        int totalRegisters = methodImpl.getRegisterCount();
        int parameterRegisters = paramRegisterCount;

        int nonParameterRegisters = totalRegisters - parameterRegisters;

        //if this isn't a static method, determine which register is the "this" register and set the type to the
        //current class
        if (!MethodUtil.isStatic(method)) {
            int thisRegister = totalRegisters - parameterRegisters;

            //if this is a constructor, then set the "this" register to an uninitialized reference of the current class
            if (MethodUtil.isConstructor(method)) {
                setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister,
                        RegisterType.getRegisterType(RegisterType.UNINIT_THIS,
                                classPath.getClass(method.getDefiningClass())));
            } else {
                setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister,
                        RegisterType.getRegisterType(RegisterType.REFERENCE,
                                classPath.getClass(method.getDefiningClass())));
            }

            propagateParameterTypes(totalRegisters-parameterRegisters+1);
        } else {
            propagateParameterTypes(totalRegisters-parameterRegisters);
        }

        RegisterType uninit = RegisterType.getRegisterType(RegisterType.UNINIT, null);
        for (int i=0; i<nonParameterRegisters; i++) {
            setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit);
        }

        BitSet instructionsToAnalyze = new BitSet(analyzedInstructions.size());

        //make sure all of the "first instructions" are marked for processing
        for (AnalyzedInstruction successor: startOfMethod.successors) {
            instructionsToAnalyze.set(successor.instructionIndex);
        }

        BitSet undeodexedInstructions = new BitSet(analyzedInstructions.size());

        do {
            boolean didSomething = false;

            while (!instructionsToAnalyze.isEmpty()) {
                for(int i=instructionsToAnalyze.nextSetBit(0); i>=0; i=instructionsToAnalyze.nextSetBit(i+1)) {
                    instructionsToAnalyze.clear(i);
                    if (analyzedState.get(i)) {
                        continue;
                    }
                    AnalyzedInstruction instructionToAnalyze = analyzedInstructions.valueAt(i);
                    try {
                        if (instructionToAnalyze.originalInstruction.getOpcode().odexOnly()) {
                            //if we had deodexed an odex instruction in a previous pass, we might have more specific
                            //register information now, so let's restore the original odexed instruction and
                            //re-deodex it
                            instructionToAnalyze.restoreOdexedInstruction();
                        }

                        if (!analyzeInstruction(instructionToAnalyze)) {
                            undeodexedInstructions.set(i);
                            continue;
                        } else {
                            didSomething = true;
                            undeodexedInstructions.clear(i);
                        }
                    } catch (AnalysisException ex) {
                        this.analysisException = ex;
                        int codeAddress = getInstructionAddress(instructionToAnalyze);
                        ex.codeAddress = codeAddress;
                        ex.addContext(String.format("opcode: %s", instructionToAnalyze.instruction.getOpcode().name));
                        ex.addContext(String.format("code address: %d", codeAddress));
                        ex.addContext(String.format("method: %s", ReferenceUtil.getReferenceString(method)));
                        break;
                    }

                    analyzedState.set(instructionToAnalyze.getInstructionIndex());

                    for (AnalyzedInstruction successor: instructionToAnalyze.successors) {
                        instructionsToAnalyze.set(successor.getInstructionIndex());
                    }
                }
                if (analysisException != null) {
                    break;
                }
            }

            if (!didSomething) {
                break;
            }

            if (!undeodexedInstructions.isEmpty()) {
                for (int i=undeodexedInstructions.nextSetBit(0); i>=0; i=undeodexedInstructions.nextSetBit(i+1)) {
                    instructionsToAnalyze.set(i);
                }
            }
        } while (true);

        //Now, go through and fix up any unresolvable odex instructions. These are usually odex instructions
        //that operate on a null register, and thus always throw an NPE. They can also be any sort of odex instruction
        //that occurs after an unresolvable odex instruction. We deodex if possible, or replace with an
        //UnresolvableOdexInstruction
        for (int i=0; i< analyzedInstructions.size(); i++) {
            AnalyzedInstruction analyzedInstruction = analyzedInstructions.valueAt(i);

            Instruction instruction = analyzedInstruction.getInstruction();

            if (instruction.getOpcode().odexOnly()) {
                int objectRegisterNumber;
                switch (instruction.getOpcode().format) {
                    case Format10x:
                        analyzeOdexReturnVoid(analyzedInstruction, false);
                        continue;
                    case Format21c:
                    case Format22c:
                        analyzePutGetVolatile(analyzedInstruction, false);
                        continue;
                    case Format35c:
                        analyzeInvokeDirectEmpty(analyzedInstruction, false);
                        continue;
                    case Format3rc:
                        analyzeInvokeObjectInitRange(analyzedInstruction, false);
                        continue;
                    case Format22cs:
                        objectRegisterNumber = ((Instruction22cs)instruction).getRegisterB();
                        break;
                    case Format35mi:
                    case Format35ms:
                        objectRegisterNumber = ((FiveRegisterInstruction)instruction).getRegisterC();
                        break;
                    case Format3rmi:
                    case Format3rms:
                        objectRegisterNumber = ((RegisterRangeInstruction)instruction).getStartRegister();
                        break;
                    default:
                        continue;
                }

                analyzedInstruction.setDeodexedInstruction(
                        new UnresolvedOdexInstruction(instruction, objectRegisterNumber));
            }
        }
    }

    private void propagateParameterTypes(int parameterStartRegister) {
        int i=0;
        for (MethodParameter parameter: method.getParameters()) {
            if (TypeUtils.isWideType(parameter)) {
                setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++,
                        RegisterType.getWideRegisterType(parameter, true));
                setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++,
                        RegisterType.getWideRegisterType(parameter, false));
            } else {
                setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++,
                        RegisterType.getRegisterType(classPath, parameter));
            }
        }
    }

    public List<AnalyzedInstruction> getAnalyzedInstructions() {
        return analyzedInstructions.getValues();
    }

    public List<Instruction> getInstructions() {
        return Lists.transform(analyzedInstructions.getValues(), new Function<AnalyzedInstruction, Instruction>() {
            @Nullable @Override public Instruction apply(@Nullable AnalyzedInstruction input) {
                if (input == null) {
                    return null;
                }
                return input.instruction;
            }
        });
    }

    @Nullable
    public AnalysisException getAnalysisException() {
        return analysisException;
    }

    public int getParamRegisterCount() {
        return paramRegisterCount;
    }

    public int getInstructionAddress(@Nonnull AnalyzedInstruction instruction) {
        return analyzedInstructions.keyAt(instruction.instructionIndex);
    }

    private void setDestinationRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction,
                                                               @Nonnull RegisterType registerType) {
        setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(),
                registerType);
    }

    private void propagateChanges(@Nonnull BitSet changedInstructions, int registerNumber, boolean override) {
        //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction
        //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on
        //the next iteration of the while loop.
        //This could also be done recursively, but in large methods it would likely cause very deep recursion.
        while (!changedInstructions.isEmpty()) {
            for (int instructionIndex=changedInstructions.nextSetBit(0);
                 instructionIndex>=0;
                 instructionIndex=changedInstructions.nextSetBit(instructionIndex+1)) {

                changedInstructions.clear(instructionIndex);

                propagateRegisterToSuccessors(analyzedInstructions.valueAt(instructionIndex), registerNumber,
                        changedInstructions, override);
            }
        }
    }

    private void overridePredecessorRegisterTypeAndPropagateChanges(
            @Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull AnalyzedInstruction predecessor,
            int registerNumber, @Nonnull RegisterType registerType) {
        BitSet changedInstructions = new BitSet(analyzedInstructions.size());

        if (!analyzedInstruction.overridePredecessorRegisterType(
                predecessor, registerNumber, registerType, analyzedState)) {
            return;
        }
        changedInstructions.set(analyzedInstruction.instructionIndex);

        propagateChanges(changedInstructions, registerNumber, true);

        if (registerType.category == RegisterType.LONG_LO) {
            checkWidePair(registerNumber, analyzedInstruction);
            overridePredecessorRegisterTypeAndPropagateChanges(analyzedInstruction, predecessor, registerNumber + 1,
                    RegisterType.LONG_HI_TYPE);
        } else if (registerType.category == RegisterType.DOUBLE_LO) {
            checkWidePair(registerNumber, analyzedInstruction);
            overridePredecessorRegisterTypeAndPropagateChanges(analyzedInstruction, predecessor, registerNumber + 1,
                    RegisterType.DOUBLE_HI_TYPE);
        }
    }

    private void setPostRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction,
                                                        int registerNumber, @Nonnull RegisterType registerType) {

        BitSet changedInstructions = new BitSet(analyzedInstructions.size());

        if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) {
            return;
        }

        propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false);

        propagateChanges(changedInstructions, registerNumber, false);

        if (registerType.category == RegisterType.LONG_LO) {
            checkWidePair(registerNumber, analyzedInstruction);
            setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE);
        } else if (registerType.category == RegisterType.DOUBLE_LO) {
            checkWidePair(registerNumber, analyzedInstruction);
            setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE);
        }
    }

    private void propagateRegisterToSuccessors(@Nonnull AnalyzedInstruction instruction, int registerNumber,
                                               @Nonnull BitSet changedInstructions, boolean override) {
        RegisterType postRegisterType = instruction.getPostInstructionRegisterType(registerNumber);
        for (AnalyzedInstruction successor: instruction.successors) {
            if (successor.mergeRegister(registerNumber, postRegisterType, analyzedState, override)) {
                changedInstructions.set(successor.instructionIndex);
            }
        }
    }

    private void buildInstructionList() {
        int registerCount = methodImpl.getRegisterCount();

        ImmutableList<Instruction> instructions = ImmutableList.copyOf(methodImpl.getInstructions());

        analyzedInstructions.ensureCapacity(instructions.size());

        //first, create all the instructions and populate the instructionAddresses array
        int currentCodeAddress = 0;
        for (int i=0; i<instructions.size(); i++) {
            Instruction instruction = instructions.get(i);
            analyzedInstructions.append(currentCodeAddress,
                    new AnalyzedInstruction(this, instruction, i, registerCount));
            assert analyzedInstructions.indexOfKey(currentCodeAddress) == i;
            currentCodeAddress += instruction.getCodeUnits();
        }

        //next, populate the exceptionHandlers array. The array item for each instruction that can throw an exception
        //and is covered by a try block should be set to a list of the first instructions of each exception handler
        //for the try block covering the instruction
        List<? extends TryBlock<? extends ExceptionHandler>> tries = methodImpl.getTryBlocks();
        tries = TryListBuilder.massageTryBlocks(tries);
        int triesIndex = 0;
        TryBlock currentTry = null;
        AnalyzedInstruction[] currentExceptionHandlers = null;
        AnalyzedInstruction[][] exceptionHandlers = new AnalyzedInstruction[instructions.size()][];

        if (tries != null) {
            for (int i=0; i< analyzedInstructions.size(); i++) {
                AnalyzedInstruction instruction = analyzedInstructions.valueAt(i);
                Opcode instructionOpcode = instruction.instruction.getOpcode();
                currentCodeAddress = getInstructionAddress(instruction);

                //check if we have gone past the end of the current try
                if (currentTry != null) {
                    if (currentTry.getStartCodeAddress() + currentTry.getCodeUnitCount()  <= currentCodeAddress) {
                        currentTry = null;
                        triesIndex++;
                    }
                }

                //check if the next try is applicable yet
                if (currentTry == null && triesIndex < tries.size()) {
                    TryBlock<? extends ExceptionHandler> tryBlock = tries.get(triesIndex);
                    if (tryBlock.getStartCodeAddress() <= currentCodeAddress) {
                        assert(tryBlock.getStartCodeAddress() + tryBlock.getCodeUnitCount() > currentCodeAddress);

                        currentTry = tryBlock;

                        currentExceptionHandlers = buildExceptionHandlerArray(tryBlock);
                    }
                }

                //if we're inside a try block, and the instruction can throw an exception, then add the exception handlers
                //for the current instruction
                if (currentTry != null && instructionOpcode.canThrow()) {
                    exceptionHandlers[i] = currentExceptionHandlers;
                }
            }
        }

        //finally, populate the successors and predecessors for each instruction. We start at the fake "StartOfMethod"
        //instruction and follow the execution path. Any unreachable code won't have any predecessors or successors,
        //and no reachable code will have an unreachable predessor or successor
        assert analyzedInstructions.size() > 0;
        BitSet instructionsToProcess = new BitSet(instructions.size());

        addPredecessorSuccessor(startOfMethod, analyzedInstructions.valueAt(0), exceptionHandlers, instructionsToProcess);
        while (!instructionsToProcess.isEmpty()) {
            int currentInstructionIndex = instructionsToProcess.nextSetBit(0);
            instructionsToProcess.clear(currentInstructionIndex);

            AnalyzedInstruction instruction = analyzedInstructions.valueAt(currentInstructionIndex);
            Opcode instructionOpcode = instruction.instruction.getOpcode();
            int instructionCodeAddress = getInstructionAddress(instruction);

            if (instruction.instruction.getOpcode().canContinue()) {
                if (currentInstructionIndex == analyzedInstructions.size() - 1) {
                    throw new AnalysisException("Execution can continue past the last instruction");
                }

                AnalyzedInstruction nextInstruction = analyzedInstructions.valueAt(currentInstructionIndex+1);
                addPredecessorSuccessor(instruction, nextInstruction, exceptionHandlers, instructionsToProcess);
            }

            if (instruction.instruction instanceof OffsetInstruction) {
                OffsetInstruction offsetInstruction = (OffsetInstruction)instruction.instruction;

                if (instructionOpcode == Opcode.PACKED_SWITCH || instructionOpcode == Opcode.SPARSE_SWITCH) {
                    AnalyzedInstruction analyzedSwitchPayload = analyzedInstructions.get(
                            instructionCodeAddress + offsetInstruction.getCodeOffset());
                    if (analyzedSwitchPayload == null) {
                        throw new AnalysisException("Invalid switch payload offset");
                    }
                    SwitchPayload switchPayload = (SwitchPayload)analyzedSwitchPayload.instruction;

                    for (SwitchElement switchElement: switchPayload.getSwitchElements()) {
                        AnalyzedInstruction targetInstruction = analyzedInstructions.get(instructionCodeAddress +
                                switchElement.getOffset());
                        if (targetInstruction == null) {
                            throw new AnalysisException("Invalid switch target offset");
                        }

                        addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers,
                                instructionsToProcess);
                    }
                } else if (instructionOpcode != Opcode.FILL_ARRAY_DATA) {
                    int targetAddressOffset = offsetInstruction.getCodeOffset();
                    AnalyzedInstruction targetInstruction = analyzedInstructions.get(instructionCodeAddress +
                            targetAddressOffset);
                    addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, instructionsToProcess);
                }
            }
        }
    }

    private void addPredecessorSuccessor(@Nonnull AnalyzedInstruction predecessor,
                                         @Nonnull AnalyzedInstruction successor,
                                         @Nonnull AnalyzedInstruction[][] exceptionHandlers,
                                         @Nonnull BitSet instructionsToProcess) {
        addPredecessorSuccessor(predecessor, successor, exceptionHandlers, instructionsToProcess, false);
    }

    private void addPredecessorSuccessor(@Nonnull AnalyzedInstruction predecessor,
                                         @Nonnull AnalyzedInstruction successor,
                                         @Nonnull AnalyzedInstruction[][] exceptionHandlers,
                                         @Nonnull BitSet instructionsToProcess, boolean allowMoveException) {

        if (!allowMoveException && successor.instruction.getOpcode() == Opcode.MOVE_EXCEPTION) {
            throw new AnalysisException("Execution can pass from the " + predecessor.instruction.getOpcode().name +
                    " instruction at code address 0x" + Integer.toHexString(getInstructionAddress(predecessor)) +
                    " to the move-exception instruction at address 0x" +
                    Integer.toHexString(getInstructionAddress(successor)));
        }

        if (!successor.addPredecessor(predecessor)) {
            return;
        }

        predecessor.addSuccessor(successor);
        instructionsToProcess.set(successor.getInstructionIndex());


        //if the successor can throw an instruction, then we need to add the exception handlers as additional
        //successors to the predecessor (and then apply this same logic recursively if needed)
        //Technically, we should handle the monitor-exit instruction as a special case. The exception is actually
        //thrown *after* the instruction executes, instead of "before" the instruction executes, lke for any other
        //instruction. But since it doesn't modify any registers, we can treat it like any other instruction.
        AnalyzedInstruction[] exceptionHandlersForSuccessor = exceptionHandlers[successor.instructionIndex];
        if (exceptionHandlersForSuccessor != null) {
            //the item for this instruction in exceptionHandlersForSuccessor should only be set if this instruction
            //can throw an exception
            assert successor.instruction.getOpcode().canThrow();

            for (AnalyzedInstruction exceptionHandler: exceptionHandlersForSuccessor) {
                addPredecessorSuccessor(predecessor, exceptionHandler, exceptionHandlers, instructionsToProcess, true);
            }
        }
    }

    @Nonnull
    private AnalyzedInstruction[] buildExceptionHandlerArray(@Nonnull TryBlock<? extends ExceptionHandler> tryBlock) {
        List<? extends ExceptionHandler> exceptionHandlers = tryBlock.getExceptionHandlers();

        AnalyzedInstruction[] handlerInstructions = new AnalyzedInstruction[exceptionHandlers.size()];
        for (int i=0; i<exceptionHandlers.size(); i++) {
            handlerInstructions[i] = analyzedInstructions.get(exceptionHandlers.get(i).getHandlerCodeAddress());
        }

        return handlerInstructions;
    }

    /**
     * @return false if analyzedInstruction is an odex instruction that couldn't be deodexed, due to its
     * object register being null
     */
    private boolean analyzeInstruction(@Nonnull AnalyzedInstruction analyzedInstruction) {
        Instruction instruction = analyzedInstruction.instruction;

        switch (instruction.getOpcode()) {
            case NOP:
                return true;
            case MOVE:
            case MOVE_FROM16:
            case MOVE_16:
            case MOVE_WIDE:
            case MOVE_WIDE_FROM16:
            case MOVE_WIDE_16:
            case MOVE_OBJECT:
            case MOVE_OBJECT_FROM16:
            case MOVE_OBJECT_16:
                analyzeMove(analyzedInstruction);
                return true;
            case MOVE_RESULT:
            case MOVE_RESULT_WIDE:
            case MOVE_RESULT_OBJECT:
                analyzeMoveResult(analyzedInstruction);
                return true;
            case MOVE_EXCEPTION:
                analyzeMoveException(analyzedInstruction);
                return true;
            case RETURN_VOID:
            case RETURN:
            case RETURN_WIDE:
            case RETURN_OBJECT:
                return true;
            case RETURN_VOID_BARRIER:
            case RETURN_VOID_NO_BARRIER:
                analyzeOdexReturnVoid(analyzedInstruction);
                return true;
            case CONST_4:
            case CONST_16:
            case CONST:
            case CONST_HIGH16:
                analyzeConst(analyzedInstruction);
                return true;
            case CONST_WIDE_16:
            case CONST_WIDE_32:
            case CONST_WIDE:
            case CONST_WIDE_HIGH16:
                analyzeWideConst(analyzedInstruction);
                return true;
            case CONST_STRING:
            case CONST_STRING_JUMBO:
                analyzeConstString(analyzedInstruction);
                return true;
            case CONST_CLASS:
                analyzeConstClass(analyzedInstruction);
                return true;
            case MONITOR_ENTER:
            case MONITOR_EXIT:
                return true;
            case CHECK_CAST:
                analyzeCheckCast(analyzedInstruction);
                return true;
            case INSTANCE_OF:
                analyzeInstanceOf(analyzedInstruction);
                return true;
            case ARRAY_LENGTH:
                analyzeArrayLength(analyzedInstruction);
                return true;
            case NEW_INSTANCE:
                analyzeNewInstance(analyzedInstruction);
                return true;
            case NEW_ARRAY:
                analyzeNewArray(analyzedInstruction);
                return true;
            case FILLED_NEW_ARRAY:
            case FILLED_NEW_ARRAY_RANGE:
                return true;
            case FILL_ARRAY_DATA:
                return true;
            case THROW:
            case GOTO:
            case GOTO_16:
            case GOTO_32:
                return true;
            case PACKED_SWITCH:
            case SPARSE_SWITCH:
                return true;
            case CMPL_FLOAT:
            case CMPG_FLOAT:
            case CMPL_DOUBLE:
            case CMPG_DOUBLE:
            case CMP_LONG:
                analyzeFloatWideCmp(analyzedInstruction);
                return true;
            case IF_EQ:
            case IF_NE:
            case IF_LT:
            case IF_GE:
            case IF_GT:
            case IF_LE:
            case IF_LTZ:
            case IF_GEZ:
            case IF_GTZ:
            case IF_LEZ:
                return true;
            case IF_EQZ:
            case IF_NEZ:
                analyzeIfEqzNez(analyzedInstruction);
                return true;
            case AGET:
                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case AGET_BOOLEAN:
                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.BOOLEAN_TYPE);
                return true;
            case AGET_BYTE:
                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.BYTE_TYPE);
                return true;
            case AGET_CHAR:
                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.CHAR_TYPE);
                return true;
            case AGET_SHORT:
                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.SHORT_TYPE);
                return true;
            case AGET_WIDE:
                analyzeAgetWide(analyzedInstruction);
                return true;
            case AGET_OBJECT:
                analyzeAgetObject(analyzedInstruction);
                return true;
            case APUT:
            case APUT_BOOLEAN:
            case APUT_BYTE:
            case APUT_CHAR:
            case APUT_SHORT:
            case APUT_WIDE:
            case APUT_OBJECT:
                return true;
            case IGET:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case IGET_BOOLEAN:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.BOOLEAN_TYPE);
                return true;
            case IGET_BYTE:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.BYTE_TYPE);
                return true;
            case IGET_CHAR:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.CHAR_TYPE);
                return true;
            case IGET_SHORT:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.SHORT_TYPE);
                return true;
            case IGET_WIDE:
            case IGET_OBJECT:
                analyzeIgetSgetWideObject(analyzedInstruction);
                return true;
            case IPUT:
            case IPUT_BOOLEAN:
            case IPUT_BYTE:
            case IPUT_CHAR:
            case IPUT_SHORT:
            case IPUT_WIDE:
            case IPUT_OBJECT:
                return true;
            case SGET:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case SGET_BOOLEAN:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.BOOLEAN_TYPE);
                return true;
            case SGET_BYTE:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.BYTE_TYPE);
                return true;
            case SGET_CHAR:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.CHAR_TYPE);
                return true;
            case SGET_SHORT:
                analyze32BitPrimitiveIgetSget(analyzedInstruction, RegisterType.SHORT_TYPE);
                return true;
            case SGET_WIDE:
            case SGET_OBJECT:
                analyzeIgetSgetWideObject(analyzedInstruction);
                return true;
            case SPUT:
            case SPUT_BOOLEAN:
            case SPUT_BYTE:
            case SPUT_CHAR:
            case SPUT_SHORT:
            case SPUT_WIDE:
            case SPUT_OBJECT:
                return true;
            case INVOKE_VIRTUAL:
                analyzeInvokeVirtual(analyzedInstruction, false);
                return true;
            case INVOKE_SUPER:
                analyzeInvokeVirtual(analyzedInstruction, false);
                return true;
            case INVOKE_DIRECT:
                analyzeInvokeDirect(analyzedInstruction);
                return true;
            case INVOKE_STATIC:
                return true;
            case INVOKE_INTERFACE:
                // TODO: normalize interfaces
                return true;
            case INVOKE_VIRTUAL_RANGE:
                analyzeInvokeVirtual(analyzedInstruction, true);
                return true;
            case INVOKE_SUPER_RANGE:
                analyzeInvokeVirtual(analyzedInstruction, true);
                return true;
            case INVOKE_DIRECT_RANGE:
                analyzeInvokeDirectRange(analyzedInstruction);
                return true;
            case INVOKE_STATIC_RANGE:
                return true;
            case INVOKE_INTERFACE_RANGE:
                // TODO: normalize interfaces
                return true;
            case NEG_INT:
            case NOT_INT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case NEG_LONG:
            case NOT_LONG:
                analyzeUnaryOp(analyzedInstruction, RegisterType.LONG_LO_TYPE);
                return true;
            case NEG_FLOAT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.FLOAT_TYPE);
                return true;
            case NEG_DOUBLE:
                analyzeUnaryOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE);
                return true;
            case INT_TO_LONG:
                analyzeUnaryOp(analyzedInstruction, RegisterType.LONG_LO_TYPE);
                return true;
            case INT_TO_FLOAT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.FLOAT_TYPE);
                return true;
            case INT_TO_DOUBLE:
                analyzeUnaryOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE);
                return true;
            case LONG_TO_INT:
            case DOUBLE_TO_INT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case LONG_TO_FLOAT:
            case DOUBLE_TO_FLOAT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.FLOAT_TYPE);
                return true;
            case LONG_TO_DOUBLE:
                analyzeUnaryOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE);
                return true;
            case FLOAT_TO_INT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE);
                return true;
            case FLOAT_TO_LONG:
                analyzeUnaryOp(analyzedInstruction, RegisterType.LONG_LO_TYPE);
                return true;
            case FLOAT_TO_DOUBLE:
                analyzeUnaryOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE);
                return true;
            case DOUBLE_TO_LONG:
                analyzeUnaryOp(analyzedInstruction, RegisterType.LONG_LO_TYPE);
                return true;
            case INT_TO_BYTE:
                analyzeUnaryOp(analyzedInstruction, RegisterType.BYTE_TYPE);
                return true;
            case INT_TO_CHAR:
                analyzeUnaryOp(analyzedInstruction, RegisterType.CHAR_TYPE);
                return true;
            case INT_TO_SHORT:
                analyzeUnaryOp(analyzedInstruction, RegisterType.SHORT_TYPE);
                return true;
            case ADD_INT:
            case SUB_INT:
            case MUL_INT:
            case DIV_INT:
            case REM_INT:
            case SHL_INT:
            case SHR_INT:
            case USHR_INT:
                analyzeBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, false);
                return true;
            case AND_INT:
            case OR_INT:
            case XOR_INT:
                analyzeBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, true);
                return true;
            case ADD_LONG:
            case SUB_LONG:
            case MUL_LONG:
            case DIV_LONG:
            case REM_LONG:
            case AND_LONG:
            case OR_LONG:
            case XOR_LONG:
            case SHL_LONG:
            case SHR_LONG:
            case USHR_LONG:
                analyzeBinaryOp(analyzedInstruction, RegisterType.LONG_LO_TYPE, false);
                return true;
            case ADD_FLOAT:
            case SUB_FLOAT:
            case MUL_FLOAT:
            case DIV_FLOAT:
            case REM_FLOAT:
                analyzeBinaryOp(analyzedInstruction, RegisterType.FLOAT_TYPE, false);
                return true;
            case ADD_DOUBLE:
            case SUB_DOUBLE:
            case MUL_DOUBLE:
            case DIV_DOUBLE:
            case REM_DOUBLE:
                analyzeBinaryOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE, false);
                return true;
            case ADD_INT_2ADDR:
            case SUB_INT_2ADDR:
            case MUL_INT_2ADDR:
            case DIV_INT_2ADDR:
            case REM_INT_2ADDR:
            case SHL_INT_2ADDR:
            case SHR_INT_2ADDR:
            case USHR_INT_2ADDR:
                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.INTEGER_TYPE, false);
                return true;
            case AND_INT_2ADDR:
            case OR_INT_2ADDR:
            case XOR_INT_2ADDR:
                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.INTEGER_TYPE, true);
                return true;
            case ADD_LONG_2ADDR:
            case SUB_LONG_2ADDR:
            case MUL_LONG_2ADDR:
            case DIV_LONG_2ADDR:
            case REM_LONG_2ADDR:
            case AND_LONG_2ADDR:
            case OR_LONG_2ADDR:
            case XOR_LONG_2ADDR:
            case SHL_LONG_2ADDR:
            case SHR_LONG_2ADDR:
            case USHR_LONG_2ADDR:
                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.LONG_LO_TYPE, false);
                return true;
            case ADD_FLOAT_2ADDR:
            case SUB_FLOAT_2ADDR:
            case MUL_FLOAT_2ADDR:
            case DIV_FLOAT_2ADDR:
            case REM_FLOAT_2ADDR:
                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.FLOAT_TYPE, false);
                return true;
            case ADD_DOUBLE_2ADDR:
            case SUB_DOUBLE_2ADDR:
            case MUL_DOUBLE_2ADDR:
            case DIV_DOUBLE_2ADDR:
            case REM_DOUBLE_2ADDR:
                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE, false);
                return true;
            case ADD_INT_LIT16:
            case RSUB_INT:
            case MUL_INT_LIT16:
            case DIV_INT_LIT16:
            case REM_INT_LIT16:
                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, false);
                return true;
            case AND_INT_LIT16:
            case OR_INT_LIT16:
            case XOR_INT_LIT16:
                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, true);
                return true;
            case ADD_INT_LIT8:
            case RSUB_INT_LIT8:
            case MUL_INT_LIT8:
            case DIV_INT_LIT8:
            case REM_INT_LIT8:
            case SHL_INT_LIT8:
                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, false);
                return true;
            case AND_INT_LIT8:
            case OR_INT_LIT8:
            case XOR_INT_LIT8:
                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.INTEGER_TYPE, true);
                return true;
            case SHR_INT_LIT8:
                analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, true),
                        false);
                return true;
            case USHR_INT_LIT8:
                analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, false),
                        false);
                return true;

            /*odexed instructions*/
            case IGET_VOLATILE:
            case IPUT_VOLATILE:
            case SGET_VOLATILE:
            case SPUT_VOLATILE:
            case IGET_OBJECT_VOLATILE:
            case IGET_WIDE_VOLATILE:
            case IPUT_WIDE_VOLATILE:
            case SGET_WIDE_VOLATILE:
            case SPUT_WIDE_VOLATILE:
                analyzePutGetVolatile(analyzedInstruction);
                return true;
            case THROW_VERIFICATION_ERROR:
                return true;
            case EXECUTE_INLINE:
                analyzeExecuteInline(analyzedInstruction);
                return true;
            case EXECUTE_INLINE_RANGE:
                analyzeExecuteInlineRange(analyzedInstruction);
                return true;
            case INVOKE_DIRECT_EMPTY:
                analyzeInvokeDirectEmpty(analyzedInstruction);
                return true;
            case INVOKE_OBJECT_INIT_RANGE:
                analyzeInvokeObjectInitRange(analyzedInstruction);
                return true;
            case IGET_QUICK:
            case IGET_WIDE_QUICK:
            case IGET_OBJECT_QUICK:
            case IPUT_QUICK:
            case IPUT_WIDE_QUICK:
            case IPUT_OBJECT_QUICK:
            case IPUT_BOOLEAN_QUICK:
            case IPUT_BYTE_QUICK:
            case IPUT_CHAR_QUICK:
            case IPUT_SHORT_QUICK:
            case IGET_BOOLEAN_QUICK:
            case IGET_BYTE_QUICK:
            case IGET_CHAR_QUICK:
            case IGET_SHORT_QUICK:
                return analyzeIputIgetQuick(analyzedInstruction);
            case INVOKE_VIRTUAL_QUICK:
                return analyzeInvokeVirtualQuick(analyzedInstruction, false, false);
            case INVOKE_SUPER_QUICK:
                return analyzeInvokeVirtualQuick(analyzedInstruction, true, false);
            case INVOKE_VIRTUAL_QUICK_RANGE:
                return analyzeInvokeVirtualQuick(analyzedInstruction, false, true);
            case INVOKE_SUPER_QUICK_RANGE:
                return analyzeInvokeVirtualQuick(analyzedInstruction, true, true);
            case IPUT_OBJECT_VOLATILE:
            case SGET_OBJECT_VOLATILE:
            case SPUT_OBJECT_VOLATILE:
                analyzePutGetVolatile(analyzedInstruction);
                return true;
            default:
                assert false;
                return true;
        }
    }

    private static final BitSet Primitive32BitCategories = BitSetUtils.bitSetOfIndexes(
            RegisterType.NULL,
            RegisterType.ONE,
            RegisterType.BOOLEAN,
            RegisterType.BYTE,
            RegisterType.POS_BYTE,
            RegisterType.SHORT,
            RegisterType.POS_SHORT,
            RegisterType.CHAR,
            RegisterType.INTEGER,
            RegisterType.FLOAT);

    private static final BitSet WideLowCategories = BitSetUtils.bitSetOfIndexes(
            RegisterType.LONG_LO,
            RegisterType.DOUBLE_LO);

    private static final BitSet WideHighCategories = BitSetUtils.bitSetOfIndexes(
            RegisterType.LONG_HI,
            RegisterType.DOUBLE_HI);

    private static final BitSet ReferenceOrUninitCategories = BitSetUtils.bitSetOfIndexes(
            RegisterType.NULL,
            RegisterType.UNINIT_REF,
            RegisterType.UNINIT_THIS,
            RegisterType.REFERENCE);

    private static final BitSet BooleanCategories = BitSetUtils.bitSetOfIndexes(
            RegisterType.NULL,
            RegisterType.ONE,
            RegisterType.BOOLEAN);

    private void analyzeMove(@Nonnull AnalyzedInstruction analyzedInstruction) {
        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;

        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType);
    }

    private void analyzeMoveResult(@Nonnull AnalyzedInstruction analyzedInstruction) {
        AnalyzedInstruction previousInstruction = null;
        if (analyzedInstruction.instructionIndex > 0) {
            previousInstruction = analyzedInstructions.valueAt(analyzedInstruction.instructionIndex-1);
        }
        if (previousInstruction == null || !previousInstruction.instruction.getOpcode().setsResult()) {
            throw new AnalysisException(analyzedInstruction.instruction.getOpcode().name + " must occur after an " +
                    "invoke-*/fill-new-array instruction");
        }

        RegisterType resultRegisterType;
        ReferenceInstruction invokeInstruction = (ReferenceInstruction)previousInstruction.instruction;
        Reference reference = invokeInstruction.getReference();

        if (reference instanceof MethodReference) {
            resultRegisterType = RegisterType.getRegisterType(classPath, ((MethodReference)reference).getReturnType());
        } else {
            resultRegisterType = RegisterType.getRegisterType(classPath, (TypeReference)reference);
        }

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, resultRegisterType);
    }

    private void analyzeMoveException(@Nonnull AnalyzedInstruction analyzedInstruction) {
        int instructionAddress = getInstructionAddress(analyzedInstruction);

        RegisterType exceptionType = RegisterType.UNKNOWN_TYPE;

        for (TryBlock<? extends ExceptionHandler> tryBlock: methodImpl.getTryBlocks()) {
            for (ExceptionHandler handler: tryBlock.getExceptionHandlers()) {

                if (handler.getHandlerCodeAddress() == instructionAddress) {
                    String type = handler.getExceptionType();
                    if (type == null) {
                        exceptionType = RegisterType.getRegisterType(RegisterType.REFERENCE,
                                classPath.getClass("Ljava/lang/Throwable;"));
                    } else {
                        exceptionType = RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(type))
                                .merge(exceptionType);
                    }
                }
            }
        }

        if (exceptionType.category == RegisterType.UNKNOWN) {
            throw new AnalysisException("move-exception must be the first instruction in an exception handler block");
        }

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType);
    }

    private void analyzeOdexReturnVoid(AnalyzedInstruction analyzedInstruction) {
        analyzeOdexReturnVoid(analyzedInstruction, true);
    }

    private void analyzeOdexReturnVoid(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
        Instruction10x deodexedInstruction = new ImmutableInstruction10x(Opcode.RETURN_VOID);

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

        if (analyzeResult) {
            analyzeInstruction(analyzedInstruction);
        }
    }

    private void analyzeConst(@Nonnull AnalyzedInstruction analyzedInstruction) {
        NarrowLiteralInstruction instruction = (NarrowLiteralInstruction)analyzedInstruction.instruction;

        //we assume that the literal value is a valid value for the given instruction type, because it's impossible
        //to store an invalid literal with the instruction. so we don't need to check the type of the literal
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
                RegisterType.getRegisterTypeForLiteral(instruction.getNarrowLiteral()));
    }

    private void analyzeWideConst(@Nonnull AnalyzedInstruction analyzedInstruction) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE);
    }

    private void analyzeConstString(@Nonnull AnalyzedInstruction analyzedInstruction) {
        TypeProto stringClass = classPath.getClass("Ljava/lang/String;");
        RegisterType stringType = RegisterType.getRegisterType(RegisterType.REFERENCE, stringClass);
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType);
    }

    private void analyzeConstClass(@Nonnull AnalyzedInstruction analyzedInstruction) {
        TypeProto classClass = classPath.getClass("Ljava/lang/Class;");
        RegisterType classType = RegisterType.getRegisterType(RegisterType.REFERENCE, classClass);
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType);
    }

    private void analyzeCheckCast(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction;
        TypeReference reference = (TypeReference)instruction.getReference();
        RegisterType castRegisterType = RegisterType.getRegisterType(classPath, reference);
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType);
    }

    private static boolean isNarrowingConversion(RegisterType originalType, RegisterType newType) {
        if (originalType.type == null || newType.type == null) {
            return false;
        }
        if (originalType.type.isInterface()) {
            return newType.type.implementsInterface(originalType.type.getType());
        } else {
            TypeProto commonSuperclass = newType.type.getCommonSuperclass(originalType.type);
            return commonSuperclass.getType().equals(originalType.type.getType());
        }
    }

    static boolean canNarrowAfterInstanceOf(AnalyzedInstruction analyzedInstanceOfInstruction,
                                            AnalyzedInstruction analyzedIfInstruction, ClassPath classPath) {
        if (!classPath.isArt()) {
            return false;
        }

        Instruction ifInstruction = analyzedIfInstruction.instruction;
        if (((Instruction21t)ifInstruction).getRegisterA() == analyzedInstanceOfInstruction.getDestinationRegister()) {
            Reference reference = ((Instruction22c)analyzedInstanceOfInstruction.getInstruction()).getReference();
            RegisterType registerType = RegisterType.getRegisterType(classPath, (TypeReference)reference);

            try {
                if (registerType.type != null && !registerType.type.isInterface()) {
                    int objectRegister = ((TwoRegisterInstruction)analyzedInstanceOfInstruction.getInstruction())
                            .getRegisterB();

                    RegisterType originalType = analyzedIfInstruction.getPreInstructionRegisterType(objectRegister);

                    return isNarrowingConversion(originalType, registerType);
                }
            } catch (UnresolvedClassException ex) {
                return false;
            }
        }
        return false;
    }

    /**
     * Art uses a peephole optimization for an if-eqz or if-nez that occur immediately after an instance-of. It will
     * narrow the type if possible, and then NOP out any corresponding check-cast instruction later on
     */
    private void analyzeIfEqzNez(@Nonnull AnalyzedInstruction analyzedInstruction) {
        if (classPath.isArt()) {
            int instructionIndex = analyzedInstruction.getInstructionIndex();
            if (instructionIndex > 0) {
                if (analyzedInstruction.getPredecessorCount() != 1) {
                    return;
                }
                AnalyzedInstruction prevAnalyzedInstruction = analyzedInstruction.getPredecessors().first();
                if (prevAnalyzedInstruction.instruction.getOpcode() == Opcode.INSTANCE_OF) {
                    Instruction22c instanceOfInstruction = (Instruction22c)prevAnalyzedInstruction.instruction;
                    if (canNarrowAfterInstanceOf(prevAnalyzedInstruction, analyzedInstruction, classPath)) {
                        List<Integer> narrowingRegisters = Lists.newArrayList();

                        RegisterType newType = RegisterType.getRegisterType(classPath,
                                (TypeReference)instanceOfInstruction.getReference());

                        if (instructionIndex > 1) {
                            // If we have something like:
                            //   move-object/from16 v0, p1
                            //   instance-of v2, v0, Lblah;
                            //   if-eqz v2, :target
                            // Then we need to narrow both v0 AND p1, but only if all predecessors of instance-of are a
                            // move-object for the same registers

                            int additionalNarrowingRegister = -1;
                            for (AnalyzedInstruction prevPrevAnalyzedInstruction : prevAnalyzedInstruction.predecessors) {
                                Opcode opcode = prevPrevAnalyzedInstruction.instruction.getOpcode();
                                if (opcode == Opcode.MOVE_OBJECT || opcode == Opcode.MOVE_OBJECT_16 ||
                                        opcode == Opcode.MOVE_OBJECT_FROM16) {
                                    TwoRegisterInstruction moveInstruction =
                                            ((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction);
                                    RegisterType originalType =
                                            prevPrevAnalyzedInstruction.getPostInstructionRegisterType(
                                                    moveInstruction.getRegisterB());
                                    if (moveInstruction.getRegisterA() != instanceOfInstruction.getRegisterB()) {
                                        additionalNarrowingRegister = -1;
                                        break;
                                    }
                                    if (originalType.type == null) {
                                        additionalNarrowingRegister = -1;
                                        break;
                                    }
                                    if (isNarrowingConversion(originalType, newType)) {
                                        if (additionalNarrowingRegister != -1) {
                                            if (additionalNarrowingRegister != moveInstruction.getRegisterB()) {
                                                additionalNarrowingRegister = -1;
                                                break;
                                            }
                                        } else {
                                            additionalNarrowingRegister = moveInstruction.getRegisterB();
                                        }
                                    }
                                } else {
                                    additionalNarrowingRegister = -1;
                                    break;
                                }
                            }
                            if (additionalNarrowingRegister != -1) {
                                narrowingRegisters.add(additionalNarrowingRegister);
                            }
                        }

                        // Propagate the original type to the failing branch, and the new type to the successful branch
                        int narrowingRegister = ((Instruction22c)prevAnalyzedInstruction.instruction).getRegisterB();
                        narrowingRegisters.add(narrowingRegister);
                        RegisterType originalType = analyzedInstruction.getPreInstructionRegisterType(narrowingRegister);

                        AnalyzedInstruction fallthroughInstruction = analyzedInstructions.valueAt(
                                analyzedInstruction.getInstructionIndex() + 1);

                        int nextAddress = getInstructionAddress(analyzedInstruction) +
                                ((Instruction21t)analyzedInstruction.instruction).getCodeOffset();
                        AnalyzedInstruction branchInstruction = analyzedInstructions.get(nextAddress);

                        for (int register : narrowingRegisters) {
                            if (analyzedInstruction.instruction.getOpcode() == Opcode.IF_EQZ) {
                                overridePredecessorRegisterTypeAndPropagateChanges(fallthroughInstruction, analyzedInstruction,
                                        register, newType);
                                overridePredecessorRegisterTypeAndPropagateChanges(branchInstruction, analyzedInstruction,
                                        register, originalType);
                            } else {
                                overridePredecessorRegisterTypeAndPropagateChanges(fallthroughInstruction, analyzedInstruction,
                                        register, originalType);
                                overridePredecessorRegisterTypeAndPropagateChanges(branchInstruction, analyzedInstruction,
                                        register, newType);
                            }
                        }
                    }
                }
            }
        }
    }

    private void analyzeInstanceOf(@Nonnull AnalyzedInstruction analyzedInstruction) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.BOOLEAN_TYPE);
    }

    private void analyzeArrayLength(@Nonnull AnalyzedInstruction analyzedInstruction) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.INTEGER_TYPE);
    }

    private void analyzeNewInstance(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction;

        int register = ((OneRegisterInstruction)analyzedInstruction.instruction).getRegisterA();
        RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register);
        if (destRegisterType.category != RegisterType.UNKNOWN) {
            //the post-instruction destination register will only be set if we have already analyzed this instruction
            //at least once. If this is the case, then the uninit reference has already been propagated to all
            //successors and nothing else needs to be done.
            assert destRegisterType.category == RegisterType.UNINIT_REF;
            return;
        }

        TypeReference typeReference = (TypeReference)instruction.getReference();

        RegisterType classType = RegisterType.getRegisterType(classPath, typeReference);

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
                RegisterType.getRegisterType(RegisterType.UNINIT_REF, classType.type));
    }

    private void analyzeNewArray(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction;

        TypeReference type = (TypeReference)instruction.getReference();
        if (type.getType().charAt(0) != '[') {
            throw new AnalysisException("new-array used with non-array type");
        }

        RegisterType arrayType = RegisterType.getRegisterType(classPath, type);

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, arrayType);
    }

    private void analyzeFloatWideCmp(@Nonnull AnalyzedInstruction analyzedInstruction) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.BYTE_TYPE);
    }

    private void analyze32BitPrimitiveAget(@Nonnull AnalyzedInstruction analyzedInstruction,
                                           @Nonnull RegisterType registerType) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, registerType);
    }

    private void analyzeAgetWide(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;

        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
        if (arrayRegisterType.category != RegisterType.NULL) {
            if (arrayRegisterType.category != RegisterType.REFERENCE ||
                    !(arrayRegisterType.type instanceof ArrayProto)) {
                throw new AnalysisException("aget-wide used with non-array register: %s", arrayRegisterType.toString());
            }
            ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type;

            if (arrayProto.dimensions != 1) {
                throw new AnalysisException("aget-wide used with multi-dimensional array: %s",
                        arrayRegisterType.toString());
            }

            char arrayBaseType = arrayProto.getElementType().charAt(0);
            if (arrayBaseType == 'J') {
                setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE);
            } else if (arrayBaseType == 'D') {
                setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.DOUBLE_LO_TYPE);
            } else {
                throw new AnalysisException("aget-wide used with narrow array: %s", arrayRegisterType);
            }
        } else {
            // If the array register is null, we can assume that the destination register was meant to be a wide type.
            // This is the same behavior as dalvik's verifier
            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.LONG_LO_TYPE);
        }
    }

    private void analyzeAgetObject(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;

        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
        if (arrayRegisterType.category != RegisterType.NULL) {
            if (arrayRegisterType.category != RegisterType.REFERENCE ||
                    !(arrayRegisterType.type instanceof ArrayProto)) {
                throw new AnalysisException("aget-object used with non-array register: %s",
                        arrayRegisterType.toString());
            }

            ArrayProto arrayProto = (ArrayProto)arrayRegisterType.type;

            String elementType = arrayProto.getImmediateElementType();

            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
                    RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(elementType)));
        } else {
            // If the array register is null, we can assume that the destination register was meant to be a reference
            // type, so we set the destination to NULL. This is the same behavior as dalvik's verifier
            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.NULL_TYPE);
        }
    }

    private void analyze32BitPrimitiveIgetSget(@Nonnull AnalyzedInstruction analyzedInstruction,
                                               @Nonnull RegisterType registerType) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, registerType);
    }

    private void analyzeIgetSgetWideObject(@Nonnull AnalyzedInstruction analyzedInstruction) {
        ReferenceInstruction referenceInstruction = (ReferenceInstruction)analyzedInstruction.instruction;

        FieldReference fieldReference = (FieldReference)referenceInstruction.getReference();

        RegisterType fieldType = RegisterType.getRegisterType(classPath, fieldReference.getType());
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType);
    }

    private void analyzeInvokeDirect(@Nonnull AnalyzedInstruction analyzedInstruction) {
        FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction;
        analyzeInvokeDirectCommon(analyzedInstruction, instruction.getRegisterC());
    }

    private void analyzeInvokeDirectRange(@Nonnull AnalyzedInstruction analyzedInstruction) {
        RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction;
        analyzeInvokeDirectCommon(analyzedInstruction, instruction.getStartRegister());
    }

    private void analyzeInvokeDirectCommon(@Nonnull AnalyzedInstruction analyzedInstruction, int objectRegister) {
        //the only time that an invoke instruction changes a register type is when using invoke-direct on a
        //constructor (<init>) method, which changes the uninitialized reference (and any register that the same
        //uninit reference has been copied to) to an initialized reference

        ReferenceInstruction instruction = (ReferenceInstruction)analyzedInstruction.instruction;

        MethodReference methodReference = (MethodReference)instruction.getReference();

        if (!methodReference.getName().equals("<init>")) {
            return;
        }

        RegisterType objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister);

        if (objectRegisterType.category != RegisterType.UNINIT_REF &&
                objectRegisterType.category != RegisterType.UNINIT_THIS) {
            return;
        }

        setPostRegisterTypeAndPropagateChanges(analyzedInstruction, objectRegister,
                RegisterType.getRegisterType(RegisterType.REFERENCE, objectRegisterType.type));

        for (int i=0; i<analyzedInstruction.postRegisterMap.length; i++) {
            RegisterType postInstructionRegisterType = analyzedInstruction.postRegisterMap[i];
            if (postInstructionRegisterType.category == RegisterType.UNKNOWN) {
                RegisterType preInstructionRegisterType =
                        analyzedInstruction.getPreInstructionRegisterType(i);

                if (preInstructionRegisterType.category == RegisterType.UNINIT_REF ||
                        preInstructionRegisterType.category == RegisterType.UNINIT_THIS) {
                    RegisterType registerType;
                    if (preInstructionRegisterType.equals(objectRegisterType)) {
                        registerType = analyzedInstruction.postRegisterMap[objectRegister];
                    } else {
                        registerType = preInstructionRegisterType;
                    }

                    setPostRegisterTypeAndPropagateChanges(analyzedInstruction, i, registerType);
                }
            }
        }
    }

    private void analyzeUnaryOp(@Nonnull AnalyzedInstruction analyzedInstruction,
                                @Nonnull RegisterType destRegisterType) {
        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType);
    }

    private void analyzeBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction,
                                 @Nonnull RegisterType destRegisterType, boolean checkForBoolean) {
        if (checkForBoolean) {
            ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;

            RegisterType source1RegisterType =
                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
            RegisterType source2RegisterType =
                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC());

            if (BooleanCategories.get(source1RegisterType.category) &&
                    BooleanCategories.get(source2RegisterType.category)) {
                destRegisterType = RegisterType.BOOLEAN_TYPE;
            }
        }

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType);
    }

    private void analyzeBinary2AddrOp(@Nonnull AnalyzedInstruction analyzedInstruction,
                                      @Nonnull RegisterType destRegisterType, boolean checkForBoolean) {
        if (checkForBoolean) {
            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;

            RegisterType source1RegisterType =
                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
            RegisterType source2RegisterType =
                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());

            if (BooleanCategories.get(source1RegisterType.category) &&
                    BooleanCategories.get(source2RegisterType.category)) {
                destRegisterType = RegisterType.BOOLEAN_TYPE;
            }
        }

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType);
    }

    private void analyzeLiteralBinaryOp(@Nonnull AnalyzedInstruction analyzedInstruction,
                                        @Nonnull RegisterType destRegisterType, boolean checkForBoolean) {
        if (checkForBoolean) {
            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;

            RegisterType sourceRegisterType =
                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());

            if (BooleanCategories.get(sourceRegisterType.category)) {
                int literal = ((NarrowLiteralInstruction)analyzedInstruction.instruction).getNarrowLiteral();
                if (literal == 0 || literal == 1) {
                    destRegisterType = RegisterType.BOOLEAN_TYPE;
                }
            }
        }

        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, destRegisterType);
    }

    private RegisterType getDestTypeForLiteralShiftRight(@Nonnull AnalyzedInstruction analyzedInstruction, boolean signedShift) {
        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;

        RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
                Primitive32BitCategories);
        long literalShift = ((NarrowLiteralInstruction)analyzedInstruction.instruction).getNarrowLiteral();

        if (literalShift == 0) {
            return sourceRegisterType;
        }

        RegisterType destRegisterType;
        if (!signedShift) {
            destRegisterType = RegisterType.INTEGER_TYPE;
        } else {
            destRegisterType = sourceRegisterType;
        }

        literalShift = literalShift & 0x1f;

        switch (sourceRegisterType.category) {
            case RegisterType.INTEGER:
            case RegisterType.FLOAT:
                if (!signedShift) {
                    if (literalShift > 24) {
                        return RegisterType.POS_BYTE_TYPE;
                    }
                    if (literalShift >= 16) {
                        return RegisterType.CHAR_TYPE;
                    }
                } else {
                    if (literalShift >= 24) {
                        return RegisterType.BYTE_TYPE;
                    }
                    if (literalShift >= 16) {
                        return RegisterType.SHORT_TYPE;
                    }
                }
                break;
            case RegisterType.SHORT:
                if (signedShift && literalShift >= 8) {
                    return RegisterType.BYTE_TYPE;
                }
                break;
            case RegisterType.POS_SHORT:
                if (literalShift >= 8) {
                    return RegisterType.POS_BYTE_TYPE;
                }
                break;
            case RegisterType.CHAR:
                if (literalShift > 8) {
                    return RegisterType.POS_BYTE_TYPE;
                }
                break;
            case RegisterType.BYTE:
                break;
            case RegisterType.POS_BYTE:
                return RegisterType.POS_BYTE_TYPE;
            case RegisterType.NULL:
            case RegisterType.ONE:
            case RegisterType.BOOLEAN:
                return RegisterType.NULL_TYPE;
            default:
                assert false;
        }

        return destRegisterType;
    }


    private void analyzeExecuteInline(@Nonnull AnalyzedInstruction analyzedInstruction) {
        if (inlineResolver == null) {
            throw new AnalysisException("Cannot analyze an odexed instruction unless we are deodexing");
        }

        Instruction35mi instruction = (Instruction35mi)analyzedInstruction.instruction;
        Method resolvedMethod = inlineResolver.resolveExecuteInline(analyzedInstruction);

        Opcode deodexedOpcode;
        int acccessFlags = resolvedMethod.getAccessFlags();
        if (AccessFlags.STATIC.isSet(acccessFlags)) {
            deodexedOpcode = Opcode.INVOKE_STATIC;
        } else if (AccessFlags.PRIVATE.isSet(acccessFlags)) {
            deodexedOpcode = Opcode.INVOKE_DIRECT;
        } else {
            deodexedOpcode = Opcode.INVOKE_VIRTUAL;
        }

        Instruction35c deodexedInstruction = new ImmutableInstruction35c(deodexedOpcode, instruction.getRegisterCount(),
                instruction.getRegisterC(), instruction.getRegisterD(), instruction.getRegisterE(),
                instruction.getRegisterF(), instruction.getRegisterG(), resolvedMethod);

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
        analyzeInstruction(analyzedInstruction);
    }

    private void analyzeExecuteInlineRange(@Nonnull AnalyzedInstruction analyzedInstruction) {
        if (inlineResolver == null) {
            throw new AnalysisException("Cannot analyze an odexed instruction unless we are deodexing");
        }

        Instruction3rmi instruction = (Instruction3rmi)analyzedInstruction.instruction;
        Method resolvedMethod = inlineResolver.resolveExecuteInline(analyzedInstruction);

        Opcode deodexedOpcode;
        int acccessFlags = resolvedMethod.getAccessFlags();
        if (AccessFlags.STATIC.isSet(acccessFlags)) {
            deodexedOpcode = Opcode.INVOKE_STATIC_RANGE;
        } else if (AccessFlags.PRIVATE.isSet(acccessFlags)) {
            deodexedOpcode = Opcode.INVOKE_DIRECT_RANGE;
        } else {
            deodexedOpcode = Opcode.INVOKE_VIRTUAL_RANGE;
        }

        Instruction3rc deodexedInstruction = new ImmutableInstruction3rc(deodexedOpcode, instruction.getStartRegister(),
                instruction.getRegisterCount(), resolvedMethod);

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
        analyzeInstruction(analyzedInstruction);
    }

    private void analyzeInvokeDirectEmpty(@Nonnull AnalyzedInstruction analyzedInstruction) {
        analyzeInvokeDirectEmpty(analyzedInstruction, true);
    }

    private void analyzeInvokeDirectEmpty(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
        Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction;

        Instruction35c deodexedInstruction = new ImmutableInstruction35c(Opcode.INVOKE_DIRECT,
                instruction.getRegisterCount(), instruction.getRegisterC(), instruction.getRegisterD(),
                instruction.getRegisterE(), instruction.getRegisterF(), instruction.getRegisterG(),
                instruction.getReference());

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

        if (analyzeResult) {
            analyzeInstruction(analyzedInstruction);
        }
    }

    private void analyzeInvokeObjectInitRange(@Nonnull AnalyzedInstruction analyzedInstruction) {
        analyzeInvokeObjectInitRange(analyzedInstruction, true);
    }

    private void analyzeInvokeObjectInitRange(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
        Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction;

        Instruction deodexedInstruction;

        int startRegister = instruction.getStartRegister();
        // hack: we should be using instruction.getRegisterCount, but some tweaked versions of dalvik appear
        // to generate invoke-object-init/range instructions with an invalid register count. We know it should
        // always be 1, so just use that.
        int registerCount = 1;
        if (startRegister < 16) {
            deodexedInstruction = new ImmutableInstruction35c(Opcode.INVOKE_DIRECT,
                    registerCount, startRegister, 0, 0, 0, 0, instruction.getReference());
        } else {
            deodexedInstruction = new ImmutableInstruction3rc(Opcode.INVOKE_DIRECT_RANGE,
                    startRegister, registerCount, instruction.getReference());
        }

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

        if (analyzeResult) {
            analyzeInstruction(analyzedInstruction);
        }
    }

    private boolean analyzeIputIgetQuick(@Nonnull AnalyzedInstruction analyzedInstruction) {
        Instruction22cs instruction = (Instruction22cs)analyzedInstruction.instruction;

        int fieldOffset = instruction.getFieldOffset();
        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
                ReferenceOrUninitCategories);

        if (objectRegisterType.category == RegisterType.NULL) {
            return false;
        }

        TypeProto objectRegisterTypeProto = objectRegisterType.type;
        assert objectRegisterTypeProto != null;

        TypeProto classTypeProto = classPath.getClass(objectRegisterTypeProto.getType());
        FieldReference resolvedField = classTypeProto.getFieldByOffset(fieldOffset);

        if (resolvedField == null) {
            throw new AnalysisException("Could not resolve the field in class %s at offset %d",
                    objectRegisterType.type.getType(), fieldOffset);
        }

        ClassDef thisClass = classPath.getClassDef(method.getDefiningClass());

        if (!TypeUtils.canAccessClass(thisClass.getType(), classPath.getClassDef(resolvedField.getDefiningClass()))) {

            // the class is not accessible. So we start looking at objectRegisterTypeProto (which may be different
            // than resolvedField.getDefiningClass()), and walk up the class hierarchy.
            ClassDef fieldClass = classPath.getClassDef(objectRegisterTypeProto.getType());
            while (!TypeUtils.canAccessClass(thisClass.getType(), fieldClass)) {
                String superclass = fieldClass.getSuperclass();
                if (superclass == null) {
                    throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
                            ReferenceUtil.getShortFieldDescriptor(resolvedField));
                }

                fieldClass = classPath.getClassDef(superclass);
            }

            // fieldClass is now the first accessible class found. Now. we need to make sure that the field is
            // actually valid for this class
            FieldReference newResolvedField = classPath.getClass(fieldClass.getType()).getFieldByOffset(fieldOffset);
            if (newResolvedField == null) {
                throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
                        ReferenceUtil.getShortFieldDescriptor(resolvedField));
            }
            resolvedField = new ImmutableFieldReference(fieldClass.getType(), newResolvedField.getName(),
                    newResolvedField.getType());
        }

        String fieldType = resolvedField.getType();

        Opcode opcode = classPath.getFieldInstructionMapper().getAndCheckDeodexedOpcode(
                fieldType, instruction.getOpcode());

        Instruction22c deodexedInstruction = new ImmutableInstruction22c(opcode, (byte)instruction.getRegisterA(),
                (byte)instruction.getRegisterB(), resolvedField);
        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

        analyzeInstruction(analyzedInstruction);

        return true;
    }

    private boolean analyzeInvokeVirtual(@Nonnull AnalyzedInstruction analyzedInstruction, boolean isRange) {
        MethodReference targetMethod;

        if (!normalizeVirtualMethods) {
            return true;
        }

        if (isRange) {
            Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction;
            targetMethod = (MethodReference)instruction.getReference();
        } else {
            Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction;
            targetMethod = (MethodReference)instruction.getReference();
        }

        MethodReference replacementMethod = normalizeMethodReference(targetMethod);

        if (replacementMethod == null || replacementMethod.equals(targetMethod)) {
            return true;
        }

        Instruction deodexedInstruction;
        if (isRange) {
            Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction;
            deodexedInstruction = new ImmutableInstruction3rc(instruction.getOpcode(), instruction.getStartRegister(),
                    instruction.getRegisterCount(), replacementMethod);
        } else {
            Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction;
            deodexedInstruction = new ImmutableInstruction35c(instruction.getOpcode(), instruction.getRegisterCount(),
                    instruction.getRegisterC(), instruction.getRegisterD(), instruction.getRegisterE(),
                    instruction.getRegisterF(), instruction.getRegisterG(), replacementMethod);
        }

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
        return true;
    }

    private boolean analyzeInvokeVirtualQuick(@Nonnull AnalyzedInstruction analyzedInstruction, boolean isSuper,
                                              boolean isRange) {
        int methodIndex;
        int objectRegister;

        if (isRange) {
            Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction;
            methodIndex = instruction.getVtableIndex();
            objectRegister = instruction.getStartRegister();
        } else {
            Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction;
            methodIndex = instruction.getVtableIndex();
            objectRegister = instruction.getRegisterC();
        }

        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, objectRegister,
                ReferenceOrUninitCategories);
        TypeProto objectRegisterTypeProto = objectRegisterType.type;

        if (objectRegisterType.category == RegisterType.NULL) {
            return false;
        }

        assert objectRegisterTypeProto != null;

        MethodReference resolvedMethod;
        if (isSuper) {
            // invoke-super is only used for the same class that we're currently in
            TypeProto typeProto = classPath.getClass(method.getDefiningClass());
            TypeProto superType;

            String superclassType = typeProto.getSuperclass();
            if (superclassType != null) {
                superType = classPath.getClass(superclassType);
            } else {
                // This is either java.lang.Object, or an UnknownClassProto
                superType = typeProto;
            }

            resolvedMethod = superType.getMethodByVtableIndex(methodIndex);
        } else {
            resolvedMethod = objectRegisterTypeProto.getMethodByVtableIndex(methodIndex);
        }

        if (resolvedMethod == null) {
            throw new AnalysisException("Could not resolve the method in class %s at index %d",
                    objectRegisterType.type.getType(), methodIndex);
        }

        // no need to check class access for invoke-super. A class can obviously access its superclass.
        ClassDef thisClass = classPath.getClassDef(method.getDefiningClass());

        if (classPath.getClass(resolvedMethod.getDefiningClass()).isInterface()) {
            resolvedMethod = new ReparentedMethodReference(resolvedMethod, objectRegisterTypeProto.getType());
        } else if (!isSuper && !TypeUtils.canAccessClass(
                thisClass.getType(), classPath.getClassDef(resolvedMethod.getDefiningClass()))) {

            // the class is not accessible. So we start looking at objectRegisterTypeProto (which may be different
            // than resolvedMethod.getDefiningClass()), and walk up the class hierarchy.
            ClassDef methodClass = classPath.getClassDef(objectRegisterTypeProto.getType());
            while (!TypeUtils.canAccessClass(thisClass.getType(), methodClass)) {
                String superclass = methodClass.getSuperclass();
                if (superclass == null) {
                    throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s",
                            ReferenceUtil.getMethodDescriptor(resolvedMethod, true));
                }

                methodClass = classPath.getClassDef(superclass);
            }

            // methodClass is now the first accessible class found. Now. we need to make sure that the method is
            // actually valid for this class
            MethodReference newResolvedMethod =
                    classPath.getClass(methodClass.getType()).getMethodByVtableIndex(methodIndex);
            if (newResolvedMethod == null) {
                throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s",
                        ReferenceUtil.getMethodDescriptor(resolvedMethod, true));
            }
            resolvedMethod = newResolvedMethod;
            resolvedMethod = new ImmutableMethodReference(methodClass.getType(), resolvedMethod.getName(),
                    resolvedMethod.getParameterTypes(), resolvedMethod.getReturnType());

        }

        if (normalizeVirtualMethods) {
            MethodReference replacementMethod = normalizeMethodReference(resolvedMethod);
            if (replacementMethod != null) {
                resolvedMethod = replacementMethod;
            }
        }

        Instruction deodexedInstruction;
        if (isRange) {
            Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction;
            Opcode opcode;
            if (isSuper) {
                opcode = Opcode.INVOKE_SUPER_RANGE;
            } else {
                opcode = Opcode.INVOKE_VIRTUAL_RANGE;
            }

            deodexedInstruction = new ImmutableInstruction3rc(opcode, instruction.getStartRegister(),
                    instruction.getRegisterCount(), resolvedMethod);
        } else {
            Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction;
            Opcode opcode;
            if (isSuper) {
                opcode = Opcode.INVOKE_SUPER;
            } else {
                opcode = Opcode.INVOKE_VIRTUAL;
            }

            deodexedInstruction = new ImmutableInstruction35c(opcode, instruction.getRegisterCount(),
                    instruction.getRegisterC(), instruction.getRegisterD(), instruction.getRegisterE(),
                    instruction.getRegisterF(), instruction.getRegisterG(), resolvedMethod);
        }

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
        analyzeInstruction(analyzedInstruction);

        return true;
    }

    private boolean analyzePutGetVolatile(@Nonnull AnalyzedInstruction analyzedInstruction) {
        return analyzePutGetVolatile(analyzedInstruction, true);
    }

    private boolean analyzePutGetVolatile(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
        FieldReference field = (FieldReference)((ReferenceInstruction)analyzedInstruction.instruction).getReference();
        String fieldType = field.getType();

        Opcode originalOpcode = analyzedInstruction.instruction.getOpcode();

        Opcode opcode = classPath.getFieldInstructionMapper().getAndCheckDeodexedOpcode(
                fieldType, originalOpcode);

        Instruction deodexedInstruction;

        if (originalOpcode.isStaticFieldAccessor()) {
            OneRegisterInstruction instruction = (OneRegisterInstruction)analyzedInstruction.instruction;
            deodexedInstruction = new ImmutableInstruction21c(opcode, instruction.getRegisterA(), field);
        } else {
            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;

            deodexedInstruction = new ImmutableInstruction22c(opcode, instruction.getRegisterA(),
                    instruction.getRegisterB(), field);
        }

        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

        if (analyzeResult) {
            analyzeInstruction(analyzedInstruction);
        }
        return true;
    }

    @Nonnull
    private static RegisterType getAndCheckSourceRegister(@Nonnull AnalyzedInstruction analyzedInstruction,
                                                          int registerNumber, BitSet validCategories) {
        assert registerNumber >= 0 && registerNumber < analyzedInstruction.postRegisterMap.length;

        RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNumber);

        checkRegister(registerType, registerNumber, validCategories);

        if (validCategories == WideLowCategories) {
            checkRegister(registerType, registerNumber, WideLowCategories);
            checkWidePair(registerNumber, analyzedInstruction);

            RegisterType secondRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNumber + 1);
            checkRegister(secondRegisterType, registerNumber+1, WideHighCategories);
        }

        return registerType;
    }

    private static void checkRegister(RegisterType registerType, int registerNumber, BitSet validCategories) {
        if (!validCategories.get(registerType.category)) {
            throw new AnalysisException(String.format("Invalid register type %s for register v%d.",
                    registerType.toString(), registerNumber));
        }
    }

    private static void checkWidePair(int registerNumber, AnalyzedInstruction analyzedInstruction) {
        if (registerNumber + 1 >= analyzedInstruction.postRegisterMap.length) {
            throw new AnalysisException(String.format("v%d cannot be used as the first register in a wide register" +
                    "pair because it is the last register.", registerNumber));
        }
    }

    @Nullable
    private MethodReference normalizeMethodReference(@Nonnull MethodReference methodRef) {
        TypeProto typeProto = classPath.getClass(methodRef.getDefiningClass());
        int methodIndex;
        try {
            methodIndex = typeProto.findMethodIndexInVtable(methodRef);
        } catch (UnresolvedClassException ex) {
            return null;
        }

        if (methodIndex < 0) {
            return null;
        }

        ClassProto thisClass = (ClassProto)classPath.getClass(method.getDefiningClass());

        Method replacementMethod = typeProto.getMethodByVtableIndex(methodIndex);
        assert replacementMethod != null;
        while (true) {
            String superType = typeProto.getSuperclass();
            if (superType == null) {
                break;
            }
            typeProto = classPath.getClass(superType);
            Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex);
            if (resolvedMethod == null) {
                break;
            }

            if (!resolvedMethod.equals(replacementMethod)) {
                if (!AnalyzedMethodUtil.canAccess(thisClass, resolvedMethod, false, false, true)) {
                    continue;
                }

                replacementMethod = resolvedMethod;
            }
        }
        return replacementMethod;
    }

    private static class ReparentedMethodReference extends BaseMethodReference {
        private final MethodReference baseReference;
        private final String definingClass;

        public ReparentedMethodReference(MethodReference baseReference, String definingClass) {
            this.baseReference = baseReference;
            this.definingClass = definingClass;
        }

        @Override @Nonnull public String getName() {
            return baseReference.getName();
        }

        @Override @Nonnull public List<? extends CharSequence> getParameterTypes() {
            return baseReference.getParameterTypes();
        }

        @Override @Nonnull public String getReturnType() {
            return baseReference.getReturnType();
        }

        @Nonnull @Override public String getDefiningClass() {
            return definingClass;
        }
    }
}