static void
createNamedVariableListResponse(MmsServerConnection* connection, MmsNamedVariableList namedList,
		int invokeId, ByteBuffer* response, ReadRequest_t* read, VarAccessSpec* accessSpec)
{

	LinkedList /*<MmsValue>*/ values = LinkedList_create();
	LinkedList variables = MmsNamedVariableList_getVariableList(namedList);

	int variableCount = LinkedList_size(variables);

	MmsServer_lockModel(connection->server);

	int i;

	LinkedList variable = LinkedList_getNext(variables);

	for (i = 0; i < variableCount; i++) {

		MmsNamedVariableListEntry variableListEntry = (MmsNamedVariableListEntry) variable->data;

		MmsDomain* variableDomain = MmsNamedVariableListEntry_getDomain(variableListEntry);
		char* variableName = MmsNamedVariableListEntry_getVariableName(variableListEntry);

		MmsTypeSpecification* namedVariable = MmsDomain_getNamedVariable(variableDomain,
				variableName);

		addNamedVariableToResultList(namedVariable, variableDomain, variableName,
								values, connection, NULL);

		variable = LinkedList_getNext(variable);
	}

	if (isSpecWithResult(read)) /* add specification to result */
		encodeReadResponse(connection, invokeId, response, values, accessSpec);
	else
		encodeReadResponse(connection, invokeId, response, values, NULL);

	MmsServer_unlockModel(connection->server);

	deleteValueList(values);
}
/**********************************************************************************************
 * mmsServer_handleWriteRequest
 * возвращает MmsServiceError
 *********************************************************************************************/
int mmsServer_handleWriteRequest( MmsServerConnection* connection,	WriteRequest_t* writeRequest,	int invokeId, ByteBuffer* response)
{
    ListOfVariableSeq_t* varSpec;
    Identifier_t domainId;
    char* domainIdStr;
    MmsDevice* device;
    MmsDomain* domain;
    Identifier_t nameId;
    char* nameIdStr;
    MmsTypeSpecification* variable;
    AlternateAccess_t* alternateAccess;
    Data_t* dataElement;
    MmsValue* value;
    MmsValueIndication valueIndication;

	if (writeRequest->variableAccessSpecification.choice.listOfVariable.list.count != 1)
		return -1;

	varSpec = writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[0];

	if (varSpec->variableSpecification.present != VariableSpecification_PR_name) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

	if (varSpec->variableSpecification.choice.name.present != ObjectName_PR_domainspecific) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

	domainId = varSpec->variableSpecification.choice.name.choice.domainspecific.domainId;
	domainIdStr = createStringFromBuffer(domainId.buf, domainId.size);

	device = MmsServer_getDevice(connection->server);

	domain = MmsDevice_getDomain(device, domainIdStr);

	free(domainIdStr);

	if (domain == NULL) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

	nameId = varSpec->variableSpecification.choice.name.choice.domainspecific.itemId;

    nameIdStr = createStringFromBuffer(nameId.buf, nameId.size);

	variable = MmsDomain_getNamedVariable(domain, nameIdStr);

	if (variable == NULL)
		goto return_access_denied;

	if (writeRequest->listOfData.list.count != 1)
		goto return_access_denied;

	alternateAccess = varSpec->alternateAccess;

	if (alternateAccess != NULL) {
		if (variable->type != MMS_ARRAY)
			goto return_access_denied;

		if (!mmsServer_isIndexAccess(alternateAccess))
			goto return_access_denied;
	}

	dataElement = writeRequest->listOfData.list.array[0];

	value = mmsMsg_parseDataElement(dataElement);

	if (value == NULL)
		goto return_access_denied;

	if (alternateAccess != NULL) {
		MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr);
        int index;
        MmsValue* elementValue;

		if (cachedArray == NULL) {
			MmsValue_delete(value);
			goto return_access_denied;
		}

		index = mmsServer_getLowIndex(alternateAccess);

		elementValue = MmsValue_getElement(cachedArray, index);

		if (elementValue == NULL) {
			MmsValue_delete(value);
			goto return_access_denied;
		}

		if (MmsValue_update(elementValue, value) == false) {
			MmsValue_delete(value);
			goto return_access_denied;
		}
	}

	MmsServer_lockModel(connection->server);

	valueIndication =	mmsServer_setValue(connection->server, domain, nameIdStr, value, connection);

	MmsServer_unlockModel(connection->server);

	createMmsWriteResponse(connection, invokeId, response, valueIndication);

	MmsValue_delete(value);

	free(nameIdStr);
	return 0;

return_access_denied:
	createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
	free(nameIdStr);
	return 0;
}
static void
handleReadListOfVariablesRequest(
		MmsServerConnection* connection,
		ReadRequest_t* read,
		uint32_t invokeId,
		ByteBuffer* response)
{
	int variableCount = read->variableAccessSpecification.choice.listOfVariable.list.count;

	LinkedList /*<MmsValue>*/ values = LinkedList_create();

	if (isSpecWithResult(read)) { /* add specification to result */
		//TODO add va spec to result
	}

	MmsServer_lockModel(connection->server);

	int i;

	for (i = 0; i < variableCount; i++) {
		VariableSpecification_t varSpec =
			read->variableAccessSpecification.choice.listOfVariable.list.array[i]->variableSpecification;

		AlternateAccess_t* alternateAccess =
			read->variableAccessSpecification.choice.listOfVariable.list.array[i]->alternateAccess;

		if (varSpec.present == VariableSpecification_PR_name) {

			if (varSpec.choice.name.present == ObjectName_PR_domainspecific) {
				char* domainIdStr = mmsMsg_createStringFromAsnIdentifier(
						varSpec.choice.name.choice.domainspecific.domainId);


				char* nameIdStr = mmsMsg_createStringFromAsnIdentifier(
						varSpec.choice.name.choice.domainspecific.itemId);

				MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr);

				if (domain == NULL) {
					if (DEBUG) printf("MMS read: domain %s not found!\n", domainIdStr);

					appendErrorToResultList(values, 10 /* object-non-existant*/);
					break;
				}

				MmsTypeSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr);

				addNamedVariableToResultList(namedVariable, domain, nameIdStr,
						values, connection, alternateAccess);

				free(domainIdStr);
				free(nameIdStr);
			}
			else {
                appendErrorToResultList(values, 10 /* object-non-existant*/);

				if (DEBUG) printf("MMS read: object name type not supported!\n");
			}
		}
		else {
			//TODO should we send a ConfirmedErrorPdu here?
			if (DEBUG) printf("MMS read: varspec type not supported!\n");
		}
	}

	encodeReadResponse(connection, invokeId, response, values, NULL);

	MmsServer_unlockModel(connection->server);

exit:
    deleteValueList(values);
}
void
IedServer_unlockDataModel(IedServer self)
{
    MmsServer_unlockModel(self->mmsServer);
}