public void read() throws Exception {
		System.out.println(name+"\n{");
		if (data == null && file != null) {
			readFileData();
		}
		
		magic |= ((byte) data.get() & 0xCA) << 24;
		magic |= ((byte) data.get() & 0xFE) << 16;
		magic |= ((byte) data.get() & 0xBA) << 8;
		magic |= ((byte) data.get() & 0xBE);
		if (magic == MAGIC_NUMBER) {
			System.out.println("\tMagic number: " + Integer.toHexString(magic));
		} else {
			System.out.println("\tIncorrect magic number: " + Integer.toHexString(magic));
			throw new Exception();
		}
		
		minorVersion = data.getShort();
		System.out.println("\tClass minor version: " + minorVersion);
		
		majorVersion |= data.get() << 8;
		majorVersion |= data.get();
		System.out.println("\tClass major version: " + majorVersion);
		
		//Entries start at index 1 therefore size is always greater than actual entries
		int cSize = data.getShort();
		constantPool = new ConstantPool(cSize);
		System.out.println("\tConstant pool size: " + cSize);
		
		for (int ind = 1; ind < constantPool.getSize();) {
			byte tag = data.get();	
			System.out.print("\t\tEntry index " + ind + ", tag " + tag);
			EntryType type = EntryType.valueOf(tag);
			ConstantPoolEntry entry = type.getEntryClass().newInstance();
			entry.read(data);
			System.out.print(" > " + entry.toString() + "\n");
			constantPool.addEntry(entry);
			ind += entry.getIndexIncrement();
		}
		
		accessFlags = data.getShort();
		isPublic = (accessFlags & Flags.PUBLIC) > 0;
		isFinal = (accessFlags & Flags.FINAL) > 0;
		isSuper = (accessFlags & Flags.CLASS_SUPER) > 0;
		isInterface = (accessFlags & Flags.CLASS_INTERFACE) > 0;
		isAbstract = (accessFlags & Flags.CLASS_ABSTRACT) > 0;
		System.out.print("\tAccess flags: " + Integer.toHexString(accessFlags) + " - ");
		System.out.println("public=" + isPublic + ", final=" + isFinal + ", super=" + isSuper +
				", interface=" + isInterface + ", abstract=" + isAbstract);
		
		thisClassIndex = data.getShort();
		superClassIndex = data.getShort();
		System.out.println("\tClass pool indexes: this=" + thisClassIndex + " super=" + superClassIndex);
		
		int iTableSize = data.getShort();
		interfaceTable = new int[iTableSize];
		System.out.println("\tInterface table size: " + iTableSize);
		for (int i = 0; i < interfaceTable.length; i++) {
			int iPoolIndex = data.getShort();
			interfaceTable[i] = iPoolIndex;
			System.out.println("\t\tInterface pool index: " + iPoolIndex);
		}
		
		int fieldTableSize = data.getShort();
		fieldTable = new FieldInfo[fieldTableSize];
		System.out.println("\tField table size: " + fieldTableSize);
		for (int i = 0; i < fieldTable.length; i++) {
			FieldInfo fi = new FieldInfo().read(constantPool, data);
			fi.print(2);
			fieldTable[i] = fi;
		}
		
		int methodTableSize = data.getShort();
		methodTable = new MethodInfo[methodTableSize];
		System.out.println("\tMethod table size: " + methodTableSize);
		for (int i = 0; i < methodTable.length; i++) {
			MethodInfo mi = new MethodInfo().read(constantPool, data);
			mi.print(2);
			methodTable[i] = mi;
		}
		
		attributesCount = data.getShort();
		attributes = new AttributeInfo[attributesCount];
		System.out.println("\tClass attributes count: " + attributesCount);
		for (int i = 0; i < attributes.length; i++) {
			AttributeInfo ai = new AttributeInfo().read(constantPool, data);
			ai.print(2);
			attributes[i] = ai;
		}
		System.out.println("}\n");
	}