class ArffDatasetAdapter implements IDatasetDeserializer<ILabeledDataset<ILabeledInstance>> {

	protected static Object parseInstance(final boolean sparseData, final List<IAttribute> attributes, final int targetIndex, final String line) {
		if (line.trim().startsWith("%")) {
			throw new IllegalArgumentException("Cannot create object for commented line!");
		}

		boolean sparseMode = sparseData;
		String curLine = line;
		if (curLine.trim().startsWith("{") && curLine.trim().endsWith("}")) {
			curLine = curLine.substring(1, curLine.length() - 1);
			if (curLine.trim().isEmpty()) { // the instance does not mention any explicit values => return an empty map.
				return new HashMap<>();
			}
		}

		String[] lineSplit = curLine.split(",");
		if (!(lineSplit[0].startsWith("'") && lineSplit[0].endsWith("'") || lineSplit[0].startsWith("\"") && lineSplit[0].endsWith("\"")) && lineSplit[0].contains(" ") && tryParseInt(lineSplit[0].split(" ")[0])) {
			sparseMode = true;
		}

		if (!sparseMode) {
			if (lineSplit.length != attributes.size()) {
				throw new IllegalArgumentException("Cannot parse instance as this is not a sparse instance but has less columns than there are attributes defined. Expected values: " + attributes.size() + ". Actual number of values: "
						+ lineSplit.length + ". Values: " + Arrays.toString(lineSplit));
			}
			Object[] parsedDenseInstance = new Object[lineSplit.length - 1];
			Object target = null;
			int cI = 0;
			for (int i = 0; i < lineSplit.length; i++) {
				final Object value;
				if (lineSplit[i].trim().equals(V_MISSING_VALUE)) {
					value = null;
				} else {
					value = attributes.get(i).deserializeAttributeValue(lineSplit[i]);
				}

				if (i == targetIndex) {
					target = value;
				} else {
					parsedDenseInstance[cI++] = value;
				}
			}
			return Arrays.asList(parsedDenseInstance, target);
		} else {
			Map<Integer, Object> parsedSparseInstance = new HashMap<>();
			for (String sparseValue : lineSplit) {
				sparseValue = sparseValue.trim(); // remove leading or trailing white spaces.
				int indexOfFirstSpace = sparseValue.indexOf(' ');
				int indexOfAttribute = Integer.parseInt(sparseValue.substring(0, indexOfFirstSpace));
				if (indexOfAttribute > targetIndex) {
					indexOfAttribute--;
				}
				String attributeValue = sparseValue.substring(indexOfFirstSpace + 1);
				parsedSparseInstance.put(indexOfAttribute, attributes.get(indexOfAttribute).deserializeAttributeValue(attributeValue));
			}
			return parsedSparseInstance;
		}
	}

	public  ArffDatasetAdapter(final boolean sparseMode, final IDatasetDescriptor datasetDescriptor);
	public  ArffDatasetAdapter(final boolean sparseMode);
	public  ArffDatasetAdapter();

}