/*
 * Copyright (c) 2013, Werner Hahn
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. The name of the author may not 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 HOLDER 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 ONANY 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 com.github.musikk.classreader.attributes;

import java.util.SortedMap;
import java.util.TreeMap;

import com.github.musikk.classreader.ClassReader;
import com.github.musikk.classreader.ClassReaderContext;
import com.github.musikk.classreader.instructions.Instruction;

public class Code {

	private final SortedMap<Integer, Instruction> instructions;

	private Code(SortedMap<Integer, Instruction> instructions) {
		this.instructions = instructions;
	}

	public SortedMap<Integer, Instruction> getInstructions() {
		return instructions;
	}

	protected static Code getCode(ClassReaderContext ctxt) {
		ClassReader reader = ctxt.getClassReader();

		SortedMap<Integer, Instruction> instructions = new TreeMap<>();

		int currentByte = 0;
		int codeLength = reader.readInt();

		while (currentByte < codeLength) {
			Instruction instruction = Instruction.getNextInstruction(reader, currentByte);

			int instructionSize = instruction.getInstructionSize();
			instructions.put(currentByte, instruction);
			currentByte += instructionSize;
		}

		return new Code(instructions);
	}
}

@@ -1563,16 +1563,53 @@
 butes;%0A%0A
+import java.io.ByteArrayInputStream;%0A
 import j
@@ -1762,16 +1762,70 @@
 ontext;%0A
+import com.github.musikk.classreader.ClassReaderImpl;%0A
 import c
@@ -1914,61 +1914,73 @@
 ate 
-final SortedMap%3CInteger, Instruction%3E instruction
+boolean instructionsAreParsed;%0A%0A%09private final byte%5B%5D codeByte
 s;%0A
-%0A
 %09pri
@@ -1984,21 +1984,22 @@
 private 
-Code(
+final 
 SortedMa
@@ -2038,45 +2038,90 @@
 ions
-) %7B%0A%09%09this.instructions = instruction
+ = new TreeMap%3C%3E();%0A%0A%09private Code(byte%5B%5D codeBytes) %7B%0A%09%09this.codeBytes = codeByte
 s;%0A%09
@@ -2185,23 +2185,21 @@
 s() %7B%0A%09%09
-return 
+if (!
 instruct
@@ -2206,247 +2206,247 @@
 ions
-;%0A%09%7D%0A%0A%09protected static Code getCode(ClassReaderContext ctxt) %7B%0A%09%09ClassReader reader = ctxt.getClassReader();%0A%0A%09%09SortedMap%3CInteger, Instruction%3E instructions = new TreeMap%3C%3E();%0A%0A%09%09int currentByte = 0;%0A%09%09int codeLength = reader.readInt(
+AreParsed) %7B%0A%09%09%09readInstructions();%0A%09%09%09instructionsAreParsed = true;%0A%09%09%7D%0A%09%09return instructions;%0A%09%7D%0A%0A%09private void readInstructions() %7B%0A%09%09int currentByte = 0;%0A%09%09ClassReader reader = new ClassReaderImpl(new ByteArrayInputStream(codeBytes)
 );%0A
-%0A
 %09%09wh
@@ -2468,17 +2468,23 @@
 e %3C code
-L
+Bytes.l
 ength) %7B
@@ -2716,38 +2716,260 @@
 %09%09%7D%0A
-%0A%09%09return new Code(instruction
+%09%7D%0A%0A%09protected static Code getCode(ClassReaderContext ctxt) %7B%0A%09%09ClassReader reader = ctxt.getClassReader();%0A%0A%09%09int codeLength = reader.readInt();%0A%09%09byte%5B%5D codeBytes = new byte%5BcodeLength%5D;%0A%09%09reader.readBytesFully(codeBytes);%0A%0A%09%09return new Code(codeByte
 s);%0A

make code parsing of the code attribute lazy