VALUE IValue::readValue(int offset, KIND type) {

	int byte;
	VALUE value;

	DEBUG_STDOUT("\t"
				 << " Reading from IValue object: " << toString());
	DEBUG_STDOUT("\t"
				 << " Reading for type: " << KIND_ToString(type));

	byte = KIND_GetSize(type);

	if (offset == 0 && KIND_GetSize(getIPtrValue(index).getType()) == byte) {

		//
		// trivial reading case
		//

		DEBUG_STDOUT("\t"
					 << "Trivial reading.");
		value = getIPtrValue(index).getValue();

	} else {

		//
		// off the shelf reading case
		//

		DEBUG_STDOUT("\t"
					 << "Off the shelf reading.");

		unsigned nextIndex;
		int totalByte, tocInx, trcInx;
		uint8_t* totalContent, *truncContent;

		nextIndex = index;
		totalByte = 0;

		// TODO: review the condition nextIndex < length
		while (totalByte < offset + byte && nextIndex < length) {
			IValue value;

			value = getIPtrValue(nextIndex);
			totalByte += KIND_GetSize(value.getType());  // TODO: can the value's type change while iterating?
			nextIndex++;
		}

		//
		// totalContent stores the accumulative content from IValue at index
		// to IValue at nextIndex-1
		//
		totalContent = (uint8_t*)malloc(totalByte * sizeof(uint8_t));
		tocInx = 0;

		for (unsigned i = index; i < nextIndex; i++) {
			IValue value;
			KIND type;
			int size;
			VALUE valValue;
			uint8_t* valueContent;

			value = getIPtrValue(i);
			type = value.getType();
			size = KIND_GetSize(type);  // TODO: can the value's type change while iterating?
			valValue = value.getValue();
			valueContent = (uint8_t*)&valValue;

			for (int j = 0; j < size; j++) {
				totalContent[tocInx] = valueContent[j];
				tocInx++;
			}
		}

		//
		// truncate content from total content
		//
		truncContent = (uint8_t*)calloc(8, sizeof(uint8_t));  // TODO: magic number 8 is 64/8
		trcInx = 0;

		for (int i = offset; i < offset + byte; i++) {
			truncContent[trcInx] = totalContent[i];
			trcInx++;
		}

		//
		// cast truncate content array to an actual value
		//
		switch (type) {
			case FLP32_KIND: {
				float* truncValue = (float*)truncContent;
				value.as_flp = *truncValue;
				break;
			}
			case FLP64_KIND: {
				double* truncValue = (double*)truncContent;
				value.as_flp = *truncValue;
				break;
			}
			default: {
				int64_t* truncValue = (int64_t*)truncContent;
				value.as_int = *truncValue;
				break;
			}
		}
	}

	return value;
}