void CommandLineToolParameterSource::parseLibReconstructionParameters()
{
    // Options Group Hardware
    parseStringParameter("hardware.openclVendor");
    parseStringParameter("hardware.openclDeviceType");
    parseIntParameter("hardware.openclDeviceId");
    parseBoolParameter("hardware.disableImageSupport");
    parseUIntParameter("hardware.subVolumeCount");
}
KviKvsTreeNodeExpression * KviKvsParser::parseExpressionOperandCore(char terminator)
{
	KviPointerList<KviKvsTreeNodeData> * pDataList = new KviPointerList<KviKvsTreeNodeData>;
	pDataList->setAutoDelete(true);

	static QString szStaticSingleSpace(" ");

	const QChar * pOperandBegin = KVSP_curCharPointer;

	bool bHaveVariable = false;

	for(;;)
	{
		switch(KVSP_curCharUnicode)
		{
			case 0:
			case '\r':
			case '\n':
				error(KVSP_curCharPointer, __tr2qs_ctx("Unexpected end of script in expression", "kvs"));
				delete pDataList;
				return nullptr;
				break;
			case ' ':
			case '\t':
				skipSpaces();
				if((KVSP_curCharUnicode == terminator) || parseExpressionMightPointToOperator())
					goto postprocess_operand;
				// separate by single spaces
				pDataList->append(new KviKvsTreeNodeConstantData(KVSP_curCharPointer, new KviKvsVariant(szStaticSingleSpace)));
				break;
			case '"':
			{
				// a string
				bHaveVariable = true;
				KviKvsTreeNodeData * d = parseStringParameter();
				if(!d)
				{
					delete pDataList;
					return nullptr;
				}
				pDataList->append(d);
			}
			break;
			case '%':
			case '$':
			case '@':
			{
				bHaveVariable = true;
				KviKvsTreeNodeData * d = parseParameterPercentOrDollar();
				if(!d)
				{
					delete pDataList;
					return nullptr;
				}
				pDataList->append(d);
			}
			break;
			default:
				// literal ?
				if(KVSP_curCharIsLetterOrNumber || (KVSP_curCharUnicode == '.') || (KVSP_curCharUnicode == '_'))
				{
					const QChar * pBegin = KVSP_curCharPointer;
					while(KVSP_curCharIsLetterOrNumber || (KVSP_curCharUnicode == '.') || (KVSP_curCharUnicode == '_'))
						KVSP_skipChar;
					QString tmp(pBegin, KVSP_curCharPointer - pBegin);
					bool bOk;
					kvs_int_t iVal = tmp.toLong(&bOk);
					if(bOk)
					{
						pDataList->append(new KviKvsTreeNodeConstantData(pBegin, new KviKvsVariant(iVal)));
					}
					else
					{
						// bOk is false
						if(pBegin->unicode() == '0')
						{
							if(tmp.length() > 2)
							{
								if((tmp[1] == 'x') || (tmp[1] == 'X'))
								{
									// hexadecimal constant ?
									QString hex = tmp.right(tmp.length() - 2);
									iVal = hex.toLong(&bOk, 16);
									if(bOk)
									{
										pDataList->append(new KviKvsTreeNodeConstantData(pBegin, new KviKvsVariant(iVal)));
									}
								}
							}
						}
						if(!bOk)
						{
							kvs_real_t dVal = tmp.toDouble(&bOk);
							if(bOk)
							{
								pDataList->append(new KviKvsTreeNodeConstantData(pBegin, new KviKvsVariant(dVal)));
							}
							else
							{
								pDataList->append(new KviKvsTreeNodeConstantData(pBegin, new KviKvsVariant(tmp)));
							}
						}
					}
				}
				else
				{
					error(KVSP_curCharPointer, __tr2qs_ctx("Unexpected character %q (Unicode %h) in expression. If it meant to be a string use the quotes.", "kvs"), KVSP_curCharPointer, KVSP_curCharUnicode);
					delete pDataList;
					return nullptr;
				}
				break;
		}

		if((KVSP_curCharUnicode == terminator) || parseExpressionMightPointToOperator())
			break;
	}

postprocess_operand:

	if(pDataList->count() == 0)
	{
		delete pDataList;
		error(KVSP_curCharPointer, __tr2qs_ctx("Unexpected empty expression operand", "kvs"));
		return nullptr;
	}

	if(pDataList->count() > 1)
		return new KviKvsTreeNodeExpressionVariableOperand(pOperandBegin, new KviKvsTreeNodeCompositeData(pOperandBegin, pDataList));

	KviKvsTreeNodeData * pUniqueData = pDataList->first();

	if(bHaveVariable)
	{
		pDataList->setAutoDelete(false);
		delete pDataList;
		return new KviKvsTreeNodeExpressionVariableOperand(pOperandBegin, pUniqueData);
	}

	// a single constant data element
	KviKvsTreeNodeExpressionConstantOperand * op = new KviKvsTreeNodeExpressionConstantOperand(pOperandBegin, new KviKvsVariant(*(((KviKvsTreeNodeConstantData *)pUniqueData)->value())));
	delete pDataList; // auto delete is true
	return op;
}