/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard.optimize.evaluation;

import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.ClassConstant;
import proguard.classfile.instruction.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
import proguard.evaluation.*;
import proguard.evaluation.value.*;
import proguard.optimize.peephole.BranchTargetFinder;

import java.util.Arrays;

/**
 * This AttributeVisitor performs partial evaluation on the code attributes
 * that it visits.
 *
 * @author Eric Lafortune
 */
public class PartialEvaluator
extends      SimplifiedVisitor
implements   AttributeVisitor,
             ExceptionInfoVisitor
{
    //*
    private static final boolean DEBUG         = false;
    private static final boolean DEBUG_RESULTS = false;
    /*/
    private static boolean DEBUG         = true;
    private static boolean DEBUG_RESULTS = true;
    //*/

    private static final int MAXIMUM_EVALUATION_COUNT = 5;

    public static final int NONE            = -2;
    public static final int AT_METHOD_ENTRY = -1;
    public static final int AT_CATCH_ENTRY  = -1;

    private final ValueFactory   valueFactory;
    private final InvocationUnit invocationUnit;
    private final boolean        evaluateAllCode;

    private InstructionOffsetValue[] branchOriginValues   = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];
    private InstructionOffsetValue[] branchTargetValues   = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH];
    private TracedVariables[]        variablesBefore      = new TracedVariables[ClassConstants.TYPICAL_CODE_LENGTH];
    private TracedStack[]            stacksBefore         = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];
    private TracedVariables[]        variablesAfter       = new TracedVariables[ClassConstants.TYPICAL_CODE_LENGTH];
    private TracedStack[]            stacksAfter          = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];
    private boolean[]                generalizedContexts  = new boolean[ClassConstants.TYPICAL_CODE_LENGTH];
    private int[]                    evaluationCounts     = new int[ClassConstants.TYPICAL_CODE_LENGTH];
    private boolean                  evaluateExceptions;

    private final BasicBranchUnit    branchUnit;
    private final BranchTargetFinder branchTargetFinder;

    private final java.util.Stack callingInstructionBlockStack;
    private final java.util.Stack instructionBlockStack = new java.util.Stack();


    /**
     * Creates a simple PartialEvaluator.
     */
    public PartialEvaluator()
    {
        this(new ValueFactory(),
             new BasicInvocationUnit(new ValueFactory()),
             true);
    }


    /**
     * Creates a new PartialEvaluator.
     * @param valueFactory    the value factory that will create all values
     *                        during evaluation.
     * @param invocationUnit  the invocation unit that will handle all
     *                        communication with other fields and methods.
     * @param evaluateAllCode a flag that specifies whether all branch targets
     *                        and exception handlers should be evaluated,
     *                        even if they are unreachable.
     */
    public PartialEvaluator(ValueFactory   valueFactory,
                            InvocationUnit invocationUnit,
                            boolean        evaluateAllCode)
    {
        this(valueFactory,
             invocationUnit,
             evaluateAllCode,
             evaluateAllCode ?
                 new BasicBranchUnit() :
                 new TracedBranchUnit(),
             new BranchTargetFinder(),
             null);
    }


    /**
     * Creates a new PartialEvaluator, based on an existing one.
     * @param partialEvaluator the subroutine calling partial evaluator.
     */
    private PartialEvaluator(PartialEvaluator partialEvaluator)
    {
        this(partialEvaluator.valueFactory,
             partialEvaluator.invocationUnit,
             partialEvaluator.evaluateAllCode,
             partialEvaluator.branchUnit,
             partialEvaluator.branchTargetFinder,
             partialEvaluator.instructionBlockStack);
    }


    /**
     * Creates a new PartialEvaluator.
     * @param valueFactory            the value factory that will create all
     *                                values during evaluation.
     * @param invocationUnit          the invocation unit that will handle all
     *                                communication with other fields and methods.
     * @param evaluateAllCode         a flag that specifies whether all branch
     *                                targets and exception handlers should be
     *                                evaluated, even if they are unreachable.
     * @param branchUnit              the branch unit that will handle all
     *                                branches.
     * @param branchTargetFinder      the utility class that will find all
     *                                branches.
     */
    private PartialEvaluator(ValueFactory       valueFactory,
                             InvocationUnit     invocationUnit,
                             boolean            evaluateAllCode,
                             BasicBranchUnit    branchUnit,
                             BranchTargetFinder branchTargetFinder,
                             java.util.Stack    callingInstructionBlockStack)
    {
        this.valueFactory       = valueFactory;
        this.invocationUnit     = invocationUnit;
        this.evaluateAllCode    = evaluateAllCode;
        this.branchUnit         = branchUnit;
        this.branchTargetFinder = branchTargetFinder;
        this.callingInstructionBlockStack = callingInstructionBlockStack == null ?
            this.instructionBlockStack :
            callingInstructionBlockStack;
    }


    // Implementations for AttributeVisitor.

    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}


    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
//        DEBUG = DEBUG_RESULTS =
//            clazz.getName().equals("abc/Def") &&
//            method.getName(clazz).equals("abc");

        // TODO: Remove this when the partial evaluator has stabilized.
        // Catch any unexpected exceptions from the actual visiting method.
        try
        {
            // Process the code.
            visitCodeAttribute0(clazz, method, codeAttribute);
        }
        catch (RuntimeException ex)
        {
            System.err.println("Unexpected error while performing partial evaluation:");
            System.err.println("  Class       = ["+clazz.getName()+"]");
            System.err.println("  Method      = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
            System.err.println("  Exception   = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");

            if (DEBUG)
            {
                method.accept(clazz, new ClassPrinter());

                System.out.println("Evaluation results:");

                int offset = 0;
                do
                {
                    if (isBranchOrExceptionTarget(offset))
                    {
                        System.out.println("Branch target from ["+branchOriginValues[offset]+"]:");
                        if (isTraced(offset))
                        {
                            System.out.println("  Vars:  "+variablesBefore[offset]);
                            System.out.println("  Stack: "+stacksBefore[offset]);
                        }
                    }

                    Instruction instruction = InstructionFactory.create(codeAttribute.code,
                                                                        offset);
                    System.out.println(instruction.toString(offset));

                    if (isTraced(offset))
                    {
                        int initializationOffset = branchTargetFinder.initializationOffset(offset);
                        if (initializationOffset != NONE)
                        {
                            System.out.println("     is to be initialized at ["+initializationOffset+"]");
                        }

                        InstructionOffsetValue branchTargets = branchTargets(offset);
                        if (branchTargets != null)
                        {
                            System.out.println("     has overall been branching to "+branchTargets);
                        }

                        System.out.println("  Vars:  "+variablesAfter[offset]);
                        System.out.println("  Stack: "+stacksAfter[offset]);
                    }

                    offset += instruction.length(offset);
                }
                while (offset < codeAttribute.u4codeLength);
            }

            throw ex;
        }
    }


    public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
        // Evaluate the instructions, starting at the entry point.
        if (DEBUG)
        {
            System.out.println();
            System.out.println("Partial evaluation: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
            System.out.println("  Max locals = "+codeAttribute.u2maxLocals);
            System.out.println("  Max stack  = "+codeAttribute.u2maxStack);
        }

        // Reuse the existing variables and stack objects, ensuring the right size.
        TracedVariables variables = new TracedVariables(codeAttribute.u2maxLocals);
        TracedStack     stack     = new TracedStack(codeAttribute.u2maxStack);

        // Initialize the reusable arrays and variables.
        initializeArrays(codeAttribute);
        initializeParameters(clazz, method, codeAttribute, variables);

        // Find all instruction offsets,...
        codeAttribute.accept(clazz, method, branchTargetFinder);

        // Start executing the first instruction block.
        evaluateInstructionBlockAndExceptionHandlers(clazz,
                                                     method,
                                                     codeAttribute,
                                                     variables,
                                                     stack,
                                                     0,
                                                     codeAttribute.u4codeLength);

        if (DEBUG_RESULTS)
        {
            System.out.println("Evaluation results:");

            int offset = 0;
            do
            {
                if (isBranchOrExceptionTarget(offset))
                {
                    System.out.println("Branch target from ["+branchOriginValues[offset]+"]:");
                    if (isTraced(offset))
                    {
                        System.out.println("  Vars:  "+variablesBefore[offset]);
                        System.out.println("  Stack: "+stacksBefore[offset]);
                    }
                }

                Instruction instruction = InstructionFactory.create(codeAttribute.code,
                                                                    offset);
                System.out.println(instruction.toString(offset));

                if (isTraced(offset))
                {
                    int initializationOffset = branchTargetFinder.initializationOffset(offset);
                    if (initializationOffset != NONE)
                    {
                        System.out.println("     is to be initialized at ["+initializationOffset+"]");
                    }

                    InstructionOffsetValue branchTargets = branchTargets(offset);
                    if (branchTargets != null)
                    {
                        System.out.println("     has overall been branching to "+branchTargets);
                    }

                    System.out.println("  Vars:  "+variablesAfter[offset]);
                    System.out.println("  Stack: "+stacksAfter[offset]);
                }

                offset += instruction.length(offset);
            }
            while (offset < codeAttribute.u4codeLength);
        }
    }


    /**
     * Returns whether a block of instructions is ever used.
     */
    public boolean isTraced(int startOffset, int endOffset)
    {
        for (int index = startOffset; index < endOffset; index++)
        {
            if (isTraced(index))
            {
                return true;
            }
        }

        return false;
    }


    /**
     * Returns whether the instruction at the given offset has ever been
     * executed during the partial evaluation.
     */
    public boolean isTraced(int instructionOffset)
    {
        return evaluationCounts[instructionOffset] > 0;
    }


    /**
     * Returns whether there is an instruction at the given offset.
     */
    public boolean isInstruction(int instructionOffset)
    {
        return branchTargetFinder.isInstruction(instructionOffset);
    }


    /**
     * Returns whether the instruction at the given offset is the target of a
     * branch instruction or an exception.
     */
    public boolean isBranchOrExceptionTarget(int instructionOffset)
    {
        return branchTargetFinder.isBranchTarget(instructionOffset) ||
               branchTargetFinder.isExceptionHandler(instructionOffset);
    }


    /**
     * Returns whether the instruction at the given offset is the start of a
     * subroutine.
     */
    public boolean isSubroutineStart(int instructionOffset)
    {
        return branchTargetFinder.isSubroutineStart(instructionOffset);
    }


    /**
     * Returns whether the instruction at the given offset is a subroutine
     * invocation.
     */
    public boolean isSubroutineInvocation(int instructionOffset)
    {
        return branchTargetFinder.isSubroutineInvocation(instructionOffset);
    }


    /**
     * Returns whether the instruction at the given offset is part of a
     * subroutine.
     */
    public boolean isSubroutine(int instructionOffset)
    {
        return branchTargetFinder.isSubroutine(instructionOffset);
    }


    /**
     * Returns whether the subroutine at the given offset is ever returning
     * by means of a regular 'ret' instruction.
     */
    public boolean isSubroutineReturning(int instructionOffset)
    {
        return branchTargetFinder.isSubroutineReturning(instructionOffset);
    }


    /**
     * Returns the offset after the subroutine that starts at the given
     * offset.
     */
    public int subroutineEnd(int instructionOffset)
    {
        return branchTargetFinder.subroutineEnd(instructionOffset);
    }


    /**
     * Returns the instruction offset at which the object instance that is
     * created at the given 'new' instruction offset is initialized, or
     * <code>NONE</code> if it is not being created.
     */
    public int initializationOffset(int instructionOffset)
    {
        return branchTargetFinder.initializationOffset(instructionOffset);
    }


    /**
     * Returns whether the method is an instance initializer.
     */
    public boolean isInitializer()
    {
        return branchTargetFinder.isInitializer();
    }


    /**
     * Returns the instruction offset at which this initializer is calling
     * the "super" or "this" initializer method, or <code>NONE</code> if it is
     * not an initializer.
     */
    public int superInitializationOffset()
    {
        return branchTargetFinder.superInitializationOffset();
    }


    /**
     * Returns the offset of the 'new' instruction that corresponds to the
     * invocation of the instance initializer at the given offset, or
     * <code>AT_METHOD_ENTRY</code> if the invocation is calling the "super" or
     * "this" initializer method, , or <code>NONE</code> if it is not a 'new'
     * instruction.
     */
    public int creationOffset(int offset)
    {
        return branchTargetFinder.creationOffset(offset);
    }


    /**
     * Returns the variables before execution of the instruction at the given
     * offset.
     */
    public TracedVariables getVariablesBefore(int instructionOffset)
    {
        return variablesBefore[instructionOffset];
    }


    /**
     * Returns the variables after execution of the instruction at the given
     * offset.
     */
    public TracedVariables getVariablesAfter(int instructionOffset)
    {
        return variablesAfter[instructionOffset];
    }


    /**
     * Returns the stack before execution of the instruction at the given
     * offset.
     */
    public TracedStack getStackBefore(int instructionOffset)
    {
        return stacksBefore[instructionOffset];
    }


    /**
     * Returns the stack after execution of the instruction at the given
     * offset.
     */
    public TracedStack getStackAfter(int instructionOffset)
    {
        return stacksAfter[instructionOffset];
    }


    /**
     * Returns the instruction offsets that branch to the given instruction
     * offset.
     */
    public InstructionOffsetValue branchOrigins(int instructionOffset)
    {
        return branchOriginValues[instructionOffset];
    }


    /**
     * Returns the instruction offsets to which the given instruction offset
     * branches.
     */
    public InstructionOffsetValue branchTargets(int instructionOffset)
    {
        return branchTargetValues[instructionOffset];
    }


    // Utility methods to evaluate instruction blocks.

    /**
     * Pushes block of instructions to be executed in the calling partial
     * evaluator.
     */
    private void pushCallingInstructionBlock(TracedVariables variables,
                                             TracedStack     stack,
                                             int             startOffset)
    {
        callingInstructionBlockStack.push(new MyInstructionBlock(variables,
                                                                 stack,
                                                                 startOffset));
    }


    /**
     * Pushes block of instructions to be executed in this partial evaluator.
     */
    private void pushInstructionBlock(TracedVariables variables,
                                      TracedStack     stack,
                                      int             startOffset)
    {
        instructionBlockStack.push(new MyInstructionBlock(variables,
                                                          stack,
                                                          startOffset));
    }


    /**
     * Evaluates the instruction block and the exception handlers covering the
     * given instruction range in the given code.
     */
    private void evaluateInstructionBlockAndExceptionHandlers(Clazz           clazz,
                                                              Method          method,
                                                              CodeAttribute   codeAttribute,
                                                              TracedVariables variables,
                                                              TracedStack     stack,
                                                              int             startOffset,
                                                              int             endOffset)
    {
        evaluateInstructionBlock(clazz,
                                 method,
                                 codeAttribute,
                                 variables,
                                 stack,
                                 startOffset);

        evaluateExceptionHandlers(clazz,
                                  method,
                                  codeAttribute,
                                  startOffset,
                                  endOffset);
    }


    /**
     * Evaluates a block of instructions, starting at the given offset and ending
     * at a branch instruction, a return instruction, or a throw instruction.
     */
    private void evaluateInstructionBlock(Clazz           clazz,
                                          Method          method,
                                          CodeAttribute   codeAttribute,
                                          TracedVariables variables,
                                          TracedStack     stack,
                                          int             startOffset)
    {
        // Execute the initial instruction block.
        evaluateSingleInstructionBlock(clazz,
                                       method,
                                       codeAttribute,
                                       variables,
                                       stack,
                                       startOffset);

        // Execute all resulting instruction blocks on the execution stack.
        while (!instructionBlockStack.empty())
        {
            if (DEBUG) System.out.println("Popping alternative branch out of "+instructionBlockStack.size()+" blocks");

            MyInstructionBlock instructionBlock =
                (MyInstructionBlock)instructionBlockStack.pop();

            evaluateSingleInstructionBlock(clazz,
                                           method,
                                           codeAttribute,
                                           instructionBlock.variables,
                                           instructionBlock.stack,
                                           instructionBlock.startOffset);
        }
    }


    /**
     * Evaluates a block of instructions, starting at the given offset and ending
     * at a branch instruction, a return instruction, or a throw instruction.
     * Instruction blocks that are to be evaluated as a result are pushed on
     * the given stack.
     */
    private void evaluateSingleInstructionBlock(Clazz            clazz,
                                                Method           method,
                                                CodeAttribute    codeAttribute,
                                                TracedVariables  variables,
                                                TracedStack      stack,
                                                int              startOffset)
    {
        byte[] code = codeAttribute.code;

        if (DEBUG)
        {
             System.out.println("Instruction block starting at ["+startOffset+"] in "+
                                ClassUtil.externalFullMethodDescription(clazz.getName(),
                                                                        0,
                                                                        method.getName(clazz),
                                                                        method.getDescriptor(clazz)));
             System.out.println("Init vars:  "+variables);
             System.out.println("Init stack: "+stack);
        }

        Processor processor = new Processor(variables,
                                            stack,
                                            valueFactory,
                                            branchUnit,
                                            invocationUnit);

        int instructionOffset = startOffset;

        int maxOffset = startOffset;

        // Evaluate the subsequent instructions.
        while (true)
        {
            if (maxOffset < instructionOffset)
            {
                maxOffset = instructionOffset;
            }

            // Maintain a generalized local variable frame and stack at this
            // instruction offset, before execution.
            int evaluationCount = evaluationCounts[instructionOffset];
            if (evaluationCount == 0)
            {
                // First time we're passing by this instruction.
                if (variablesBefore[instructionOffset] == null)
                {
                    // There's not even a context at this index yet.
                    variablesBefore[instructionOffset] = new TracedVariables(variables);
                    stacksBefore[instructionOffset]    = new TracedStack(stack);
                }
                else
                {
                    // Reuse the context objects at this index.
                    variablesBefore[instructionOffset].initialize(variables);
                    stacksBefore[instructionOffset].copy(stack);
                }

                // We'll execute in the generalized context, because it is
                // the same as the current context.
                generalizedContexts[instructionOffset] = true;
            }
            else
            {
                // Merge in the current context.
                boolean variablesChanged = variablesBefore[instructionOffset].generalize(variables, true);
                boolean stackChanged     = stacksBefore[instructionOffset].generalize(stack);

                //System.out.println("GVars:  "+variablesBefore[instructionOffset]);
                //System.out.println("GStack: "+stacksBefore[instructionOffset]);

                // Bail out if the current context is the same as last time.
                if (!variablesChanged &&
                    !stackChanged     &&
                    generalizedContexts[instructionOffset])
                {
                    if (DEBUG) System.out.println("Repeated variables, stack, and branch targets");

                    break;
                }

                // See if this instruction has been evaluated an excessive number
                // of times.
                if (evaluationCount >= MAXIMUM_EVALUATION_COUNT)
                {
                    if (DEBUG) System.out.println("Generalizing current context after "+evaluationCount+" evaluations");

                    // Continue, but generalize the current context.
                    // Note that the most recent variable values have to remain
                    // last in the generalizations, for the sake of the ret
                    // instruction.
                    variables.generalize(variablesBefore[instructionOffset], false);
                    stack.generalize(stacksBefore[instructionOffset]);

                    // We'll execute in the generalized context.
                    generalizedContexts[instructionOffset] = true;
                }
                else
                {
                    // We'll execute in the current context.
                    generalizedContexts[instructionOffset] = false;
                }
            }

            // We'll evaluate this instruction.
            evaluationCounts[instructionOffset]++;

            // Remember this instruction's offset with any stored value.
            Value storeValue = new InstructionOffsetValue(instructionOffset);
            variables.setProducerValue(storeValue);
            stack.setProducerValue(storeValue);

            // Reset the trace value.
            InstructionOffsetValue traceValue = InstructionOffsetValue.EMPTY_VALUE;

            // Note that the instruction is only volatile.
            Instruction instruction = InstructionFactory.create(code, instructionOffset);

            // By default, the next instruction will be the one after this
            // instruction.
            int nextInstructionOffset = instructionOffset +
                                        instruction.length(instructionOffset);
            InstructionOffsetValue nextInstructionOffsetValue = new InstructionOffsetValue(nextInstructionOffset);
            branchUnit.resetCalled();
            branchUnit.setTraceBranchTargets(nextInstructionOffsetValue);

            if (DEBUG)
            {
                System.out.println(instruction.toString(instructionOffset));
            }

            try
            {
                // Process the instruction. The processor may modify the
                // variables and the stack, and it may call the branch unit
                // and the invocation unit.
                instruction.accept(clazz,
                                   method,
                                   codeAttribute,
                                   instructionOffset,
                                   processor);
            }
            catch (RuntimeException ex)
            {
                System.err.println("Unexpected error while evaluating instruction:");
                System.err.println("  Class       = ["+clazz.getName()+"]");
                System.err.println("  Method      = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
                System.err.println("  Instruction = "+instruction.toString(instructionOffset));
                System.err.println("  Exception   = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");

                throw ex;
            }

            // Collect the branch targets from the branch unit.
            InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets();
            int branchTargetCount = branchTargets.instructionOffsetCount();

            // Stop tracing.
            branchUnit.setTraceBranchTargets(traceValue);

            if (DEBUG)
            {
                if (branchUnit.wasCalled())
                {
                    System.out.println("     is branching to "+branchTargets);
                }
                if (branchTargetValues[instructionOffset] != null)
                {
                    System.out.println("     has up till now been branching to "+branchTargetValues[instructionOffset]);
                }

                System.out.println(" Vars:  "+variables);
                System.out.println(" Stack: "+stack);
            }

            // Maintain a generalized local variable frame and stack at this
            // instruction offset, after execution.
            if (evaluationCount == 0)
            {
                // First time we're passing by this instruction.
                if (variablesAfter[instructionOffset] == null)
                {
                    // There's not even a context at this index yet.
                    variablesAfter[instructionOffset] = new TracedVariables(variables);
                    stacksAfter[instructionOffset]    = new TracedStack(stack);
                }
                else
                {
                    // Reuse the context objects at this index.
                    variablesAfter[instructionOffset].initialize(variables);
                    stacksAfter[instructionOffset].copy(stack);
                }
            }
            else
            {
                // Merge in the current context.
                variablesAfter[instructionOffset].generalize(variables, true);
                stacksAfter[instructionOffset].generalize(stack);
            }

            // Did the branch unit get called?
            if (branchUnit.wasCalled())
            {
                // Accumulate the branch targets at this offset.
                branchTargetValues[instructionOffset] = branchTargetValues[instructionOffset] == null ?
                    branchTargets :
                    branchTargetValues[instructionOffset].generalize(branchTargets).instructionOffsetValue();

                // Are there no branch targets at all?
                if (branchTargetCount == 0)
                {
                    // Exit from this code block.
                    break;
                }

                // Accumulate the branch origins at the branch target offsets.
                InstructionOffsetValue instructionOffsetValue = new InstructionOffsetValue(instructionOffset);
                for (int index = 0; index < branchTargetCount; index++)
                {
                    int branchTarget = branchTargets.instructionOffset(index);
                    branchOriginValues[branchTarget] = branchOriginValues[branchTarget] == null ?
                        instructionOffsetValue:
                        branchOriginValues[branchTarget].generalize(instructionOffsetValue).instructionOffsetValue();
                }

                // Are there multiple branch targets?
                if (branchTargetCount > 1)
                {
                    // Push them on the execution stack and exit from this block.
                    for (int index = 0; index < branchTargetCount; index++)
                    {
                        if (DEBUG) System.out.println("Pushing alternative branch #"+index+" out of "+branchTargetCount+", from ["+instructionOffset+"] to ["+branchTargets.instructionOffset(index)+"]");

                        pushInstructionBlock(new TracedVariables(variables),
                                             new TracedStack(stack),
                                             branchTargets.instructionOffset(index));
                    }

                    break;
                }

                if (DEBUG) System.out.println("Definite branch from ["+instructionOffset+"] to ["+branchTargets.instructionOffset(0)+"]");
            }

            // Just continue with the next instruction.
            instructionOffset = branchTargets.instructionOffset(0);

            // Is this a subroutine invocation?
            if (instruction.opcode == InstructionConstants.OP_JSR ||
                instruction.opcode == InstructionConstants.OP_JSR_W)
            {
                // Evaluate the subroutine, possibly in another partial
                // evaluator.
                evaluateSubroutine(clazz,
                                   method,
                                   codeAttribute,
                                   variables,
                                   stack,
                                   instructionOffset,
                                   instructionBlockStack);

                break;
            }
            else if (instruction.opcode == InstructionConstants.OP_RET)
            {
                // Let the partial evaluator that has called the subroutine
                // handle the evaluation after the return.
                pushCallingInstructionBlock(new TracedVariables(variables),
                                            new TracedStack(stack),
                                            instructionOffset);
                break;
            }
        }

        if (DEBUG) System.out.println("Ending processing of instruction block starting at ["+startOffset+"]");
    }


    /**
     * Evaluates a subroutine and its exception handlers, starting at the given
     * offset and ending at a subroutine return instruction.
     */
    private void evaluateSubroutine(Clazz           clazz,
                                    Method          method,
                                    CodeAttribute   codeAttribute,
                                    TracedVariables variables,
                                    TracedStack     stack,
                                    int             subroutineStart,
                                    java.util.Stack instructionBlockStack)
    {
        int subroutineEnd = branchTargetFinder.subroutineEnd(subroutineStart);

        if (DEBUG) System.out.println("Evaluating subroutine from "+subroutineStart+" to "+subroutineEnd);

        PartialEvaluator subroutinePartialEvaluator = this;

        // Create a temporary partial evaluator if necessary.
        if (evaluationCounts[subroutineStart] > 0)
        {
            if (DEBUG) System.out.println("Creating new partial evaluator for subroutine");

            subroutinePartialEvaluator = new PartialEvaluator(this);

            subroutinePartialEvaluator.initializeArrays(codeAttribute);
        }

        // Evaluate the subroutine.
        subroutinePartialEvaluator.evaluateInstructionBlockAndExceptionHandlers(clazz,
                                                                                method,
                                                                                codeAttribute,
                                                                                variables,
                                                                                stack,
                                                                                subroutineStart,
                                                                                subroutineEnd);

        // Merge back the temporary partial evaluator if necessary.
        if (subroutinePartialEvaluator != this)
        {
            generalize(subroutinePartialEvaluator, 0, codeAttribute.u4codeLength);
        }

        if (DEBUG) System.out.println("Ending subroutine from "+subroutineStart+" to "+subroutineEnd);
    }


    /**
     * Generalizes the results of this partial evaluator with those of another
     * given partial evaluator, over a given range of instructions.
     */
    private void generalize(PartialEvaluator other,
                            int              codeStart,
                            int              codeEnd)
    {
        if (DEBUG) System.out.println("Generalizing with temporary partial evaluation");

        for (int offset = codeStart; offset < codeEnd; offset++)
        {
            if (other.branchOriginValues[offset] != null)
            {
                branchOriginValues[offset] = branchOriginValues[offset] == null ?
                    other.branchOriginValues[offset] :
                    branchOriginValues[offset].generalize(other.branchOriginValues[offset]).instructionOffsetValue();
            }

            if (other.isTraced(offset))
            {
                if (other.branchTargetValues[offset] != null)
                {
                    branchTargetValues[offset] = branchTargetValues[offset] == null ?
                        other.branchTargetValues[offset] :
                        branchTargetValues[offset].generalize(other.branchTargetValues[offset]).instructionOffsetValue();
                }

                if (evaluationCounts[offset] == 0)
                {
                    variablesBefore[offset]     = other.variablesBefore[offset];
                    stacksBefore[offset]        = other.stacksBefore[offset];
                    variablesAfter[offset]      = other.variablesAfter[offset];
                    stacksAfter[offset]         = other.stacksAfter[offset];
                    generalizedContexts[offset] = other.generalizedContexts[offset];
                    evaluationCounts[offset]    = other.evaluationCounts[offset];
                }
                else
                {
                    variablesBefore[offset].generalize(other.variablesBefore[offset], false);
                    stacksBefore[offset]   .generalize(other.stacksBefore[offset]);
                    variablesAfter[offset] .generalize(other.variablesAfter[offset], false);
                    stacksAfter[offset]    .generalize(other.stacksAfter[offset]);
                    //generalizedContexts[offset]
                    evaluationCounts[offset] += other.evaluationCounts[offset];
                }
            }
        }
    }


    /**
     * Evaluates the exception handlers covering and targeting the given
     * instruction range in the given code.
     */
    private void evaluateExceptionHandlers(Clazz         clazz,
                                           Method        method,
                                           CodeAttribute codeAttribute,
                                           int           startOffset,
                                           int           endOffset)
    {
        if (DEBUG) System.out.println("Evaluating exceptions covering ["+startOffset+" -> "+endOffset+"]:");

        ExceptionHandlerFilter exceptionEvaluator =
            new ExceptionHandlerFilter(startOffset,
                                       endOffset,
                                       this);

        // Evaluate the exception catch blocks, until their entry variables
        // have stabilized.
        do
        {
            // Reset the flag to stop evaluating.
            evaluateExceptions = false;

            // Evaluate all relevant exception catch blocks once.
            codeAttribute.exceptionsAccept(clazz,
                                           method,
                                           startOffset,
                                           endOffset,
                                           exceptionEvaluator);
        }
        while (evaluateExceptions);
    }


    // Implementations for ExceptionInfoVisitor.

    public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
    {
        int startPC = exceptionInfo.u2startPC;
        int endPC   = exceptionInfo.u2endPC;

        // Do we have to evaluate this exception catch block?
        if (isTraced(startPC, endPC))
        {
            int handlerPC = exceptionInfo.u2handlerPC;
            int catchType = exceptionInfo.u2catchType;

            if (DEBUG) System.out.println("Evaluating exception ["+startPC +" -> "+endPC +": "+handlerPC+"]:");

            // Reuse the existing variables and stack objects, ensuring the
            // right size.
            TracedVariables variables = new TracedVariables(codeAttribute.u2maxLocals);
            TracedStack     stack     = new TracedStack(codeAttribute.u2maxStack);

            // Initialize the trace values.
            Value storeValue = new InstructionOffsetValue(AT_CATCH_ENTRY);
            variables.setProducerValue(storeValue);
            stack.setProducerValue(storeValue);

            // Initialize the variables by generalizing the variables of the
            // try block. Make sure to include the results of the last
            // instruction for preverification.
            generalizeVariables(startPC,
                                endPC,
                                evaluateAllCode,
                                variables);

            // Initialize the the stack.
            //stack.push(valueFactory.createReference((ClassConstant)((ProgramClass)clazz).getConstant(exceptionInfo.u2catchType), false));
            String catchClassName = catchType != 0 ?
                 clazz.getClassName(catchType) :
                 ClassConstants.INTERNAL_NAME_JAVA_LANG_THROWABLE;

            Clazz catchClass = catchType != 0 ?
                ((ClassConstant)((ProgramClass)clazz).getConstant(catchType)).referencedClass :
                null;

            stack.push(valueFactory.createReferenceValue(catchClassName,
                                                         catchClass,
                                                         false));

            int evaluationCount = evaluationCounts[handlerPC];

            // Evaluate the instructions, starting at the entry point.
            evaluateInstructionBlock(clazz,
                                     method,
                                     codeAttribute,
                                     variables,
                                     stack,
                                     handlerPC);

            // Remember to evaluate all exception handlers once more.
            if (!evaluateExceptions)
            {
                evaluateExceptions = evaluationCount < evaluationCounts[handlerPC];
            }
        }
//        else if (evaluateAllCode)
//        {
//            if (DEBUG) System.out.println("No information for partial evaluation of exception ["+startPC +" -> "+endPC +": "+exceptionInfo.u2handlerPC+"] yet");
//
//            // We don't have any information on the try block yet, but we do
//            // have to evaluate the exception handler.
//            // Remember to evaluate all exception handlers once more.
//            evaluateExceptions = true;
//        }
        else
        {
            if (DEBUG) System.out.println("No information for partial evaluation of exception ["+startPC +" -> "+endPC +": "+exceptionInfo.u2handlerPC+"]");
        }
    }


    // Small utility methods.

    /**
     * Initializes the data structures for the variables, stack, etc.
     */
    private void initializeArrays(CodeAttribute codeAttribute)
    {
        int codeLength = codeAttribute.u4codeLength;

        // Create new arrays for storing information at each instruction offset.
        if (variablesAfter.length < codeLength)
        {
            // Create new arrays.
            branchOriginValues  = new InstructionOffsetValue[codeLength];
            branchTargetValues  = new InstructionOffsetValue[codeLength];
            variablesBefore     = new TracedVariables[codeLength];
            stacksBefore        = new TracedStack[codeLength];
            variablesAfter      = new TracedVariables[codeLength];
            stacksAfter         = new TracedStack[codeLength];
            generalizedContexts = new boolean[codeLength];
            evaluationCounts    = new int[codeLength];
        }
        else
        {
            // Reset the arrays.
            Arrays.fill(branchOriginValues,  null);
            Arrays.fill(branchTargetValues,  null);
            Arrays.fill(generalizedContexts, false);
            Arrays.fill(evaluationCounts,    0);

            for (int index = 0; index < codeLength; index++)
            {
                if (variablesBefore[index] != null)
                {
                    variablesBefore[index].reset(codeAttribute.u2maxLocals);
                }

                if (stacksBefore[index] != null)
                {
                    stacksBefore[index].reset(codeAttribute.u2maxStack);
                }

                if (variablesAfter[index] != null)
                {
                    variablesAfter[index].reset(codeAttribute.u2maxLocals);
                }

                if (stacksAfter[index] != null)
                {
                    stacksAfter[index].reset(codeAttribute.u2maxStack);
                }
            }
        }
    }


    /**
     * Initializes the data structures for the variables, stack, etc.
     */
    private void initializeParameters(Clazz           clazz,
                                      Method          method,
                                      CodeAttribute   codeAttribute,
                                      TracedVariables variables)
    {
        // Create the method parameters.
        TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals);

        // Remember this instruction's offset with any stored value.
        Value storeValue = new InstructionOffsetValue(AT_METHOD_ENTRY);
        parameters.setProducerValue(storeValue);

        // Initialize the method parameters.
        invocationUnit.enterMethod(clazz, method, parameters);

        if (DEBUG)
        {
            System.out.println("  Params: "+parameters);
        }

        // Initialize the variables with the parameters.
        variables.initialize(parameters);

        // Set the store value of each parameter variable.
        InstructionOffsetValue atMethodEntry = new InstructionOffsetValue(AT_METHOD_ENTRY);

        for (int index = 0; index < parameters.size(); index++)
        {
            variables.setProducerValue(index, atMethodEntry);
        }
    }


    /**
     * Generalize the local variable frames of a block of instructions.
     */
    private void generalizeVariables(int             startOffset,
                                     int             endOffset,
                                     boolean         includeAfterLastInstruction,
                                     TracedVariables generalizedVariables)
    {
        boolean first     = true;
        int     lastIndex = -1;

        // Generalize the variables before each of the instructions in the block.
        for (int index = startOffset; index < endOffset; index++)
        {
            if (isTraced(index))
            {
                TracedVariables tracedVariables = variablesBefore[index];

                if (first)
                {
                    // Initialize the variables with the first traced local
                    // variable frame.
                    generalizedVariables.initialize(tracedVariables);

                    first = false;
                }
                else
                {
                    // Generalize the variables with the traced local variable
                    // frame. We can't use the return value, because local
                    // generalization can be different a couple of times,
                    // with the global generalization being the same.
                    generalizedVariables.generalize(tracedVariables, false);
                }

                lastIndex = index;
            }
        }

        // Generalize the variables after the last instruction in the block,
        // if required.
        if (includeAfterLastInstruction &&
            lastIndex >= 0)
        {
            TracedVariables tracedVariables = variablesAfter[lastIndex];

            if (first)
            {
                // Initialize the variables with the local variable frame.
                generalizedVariables.initialize(tracedVariables);
            }
            else
            {
                // Generalize the variables with the local variable frame.
                generalizedVariables.generalize(tracedVariables, false);
            }
        }

        // Just clear the variables if there aren't any traced instructions
        // in the block.
        if (first)
        {
            generalizedVariables.reset(generalizedVariables.size());
        }
    }


    private static class MyInstructionBlock
    {
        private TracedVariables variables;
        private TracedStack     stack;
        private int             startOffset;


        private MyInstructionBlock(TracedVariables variables,
                                   TracedStack     stack,
                                   int             startOffset)
        {
            this.variables   = variables;
            this.stack       = stack;
            this.startOffset = startOffset;
        }
    }
}
