/*
   Copyright 2011 - 2017 Volker Berlin (i-net software)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
package de.inetsoftware.classparser;

import java.io.DataInputStream;
import java.io.IOException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * @author Volker Berlin
 */
public class LocalVariableTable {

    private LocalVariable[] tablePosition;

    private LocalVariable[] table;

    protected LocalVariableTable() {

    }

    /**
     * @param maxLocals the count of local variables in the memory
     */
    LocalVariableTable( int maxLocals ) {
        table = new LocalVariable[maxLocals];
        tablePosition = new LocalVariable[maxLocals];
    }

    /**
     * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.13
     * http://docs.oracle.com/javase/specs/jvms/se5.0/html/ClassFile.doc.html#5956
     *
     * @param input
     *            the stream of the class
     * @param withPositions a hack if we find a better solution to map the positions LocalVariableTypeTable
     * @throws IOException
     */
    void read( DataInputStream input, boolean withPositions ) throws IOException {
        int count = input.readUnsignedShort();
        if( count > table.length ) {
            table = new LocalVariable[count];
            tablePosition = new LocalVariable[count];
        }
        for( int i = 0; i < count; i++ ) {
            LocalVariable var = new LocalVariable( input );
            int idx = var.getIndex();
            if( withPositions ) {
                tablePosition[i] = var;
            }
            table[idx] = var;
        }
    }


    /**
     * Get the LocalVariable with it position. The position is continue also with double and long variables. Or if a variable is reused from a other block.
     *
     * @param pos
     *            the position
     */
    @Nonnull
    public LocalVariable getPosition( int pos ) {
        return tablePosition[pos];
    }

    /**
     * Get the LocalVariable with it position. The index has empty places with double and long variables.
     *
     * @param idx
     *            the index in the memory
     */
    @Nonnull
    public LocalVariable get( int idx ) {
        return table[idx];
    }

    /**
     * Find a LocalVariable with a given name.
     *
     * @param name
     *            needed for evaluate the name.
     * @param constantPool
     *            current constant pool
     * @return the LocalVariable or null
     */
    @Nullable
    public LocalVariable get( String name, ConstantPool constantPool ) {
        for( int i=0; i<table.length; i++ ){
            if( name.equals( table[i].getName( constantPool ) )) {
                return table[i];
            }
        }
        return null;
    }
}

@@ -966,47 +966,24 @@
   pr
-otected LocalVariableTable() %7B%0D%0A%0D%0A    %7D
+ivate int count;
 %0D%0A%0D%0A
@@ -1707,20 +1707,16 @@
         
-int 
 count = 
@@ -2180,16 +2180,413 @@
    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Get the count of variables.%0D%0A     * @return the count%0D%0A     */%0D%0A    public int getPositionSize() %7B%0D%0A        return count;%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     * Get the count of storage places a 4 bytes for local variables. Double and long variables need 2 of this places.%0D%0A     * %0D%0A     * @return the local stack size%0D%0A     */%0D%0A    public int getSize() %7B%0D%0A        return table.length;%0D%0A    %7D%0D%0A
 %0D%0A    /*
@@ -2960,37 +2960,45 @@
 Variable with it
- posi
+s memory loca
 tion. The index 

add getSize() methods