uint16_t groupListAddGroup(char *groupNameStr)
{
	groupRecord_t *exsistingGroup;
	groupRecord_t newGroup;
	char rec[MAX_SUPPORTED_RECORD_SIZE];

	//printf("groupListAddGroup++\n");

	exsistingGroup = groupListGetGroupByName(groupNameStr);

	if (exsistingGroup != NULL)
	{
		return exsistingGroup->id;
	}

	newGroup.id = groupListGetUnusedGroupId();
	newGroup.name = groupNameStr;
	newGroup.members = NULL;

	groupListComposeRecord(&newGroup, rec);

	sdb_add_record(db, rec);

	//printf("groupListAddGroup--\n");

	return newGroup.id;
}
uint16_t groupListAddDeviceToGroup(char *groupNameStr, uint16_t nwkAddr,
		uint8_t endpoint)
{
	groupRecord_t *group;
	groupRecord_t newGroup;
	char rec[MAX_SUPPORTED_RECORD_SIZE];
	groupMembersRecord_t ** nextMemberPtr;
	groupMembersRecord_t newMember;
	bool memberExists = FALSE;
	uint16_t groupId;

	//printf("groupListAddGroup++\n");

	group = groupListGetGroupByName(groupNameStr);

	if (group == NULL)
	{
		group = &newGroup;
		group->id = groupListGetUnusedGroupId();
		group->name = groupNameStr;
		group->members = NULL;
	}

	groupId = group->id;

	nextMemberPtr = &(group->members);
	while ((*nextMemberPtr != NULL) && (!memberExists))
	{
		if (((*nextMemberPtr)->nwkAddr == nwkAddr)
				&& ((*nextMemberPtr)->endpoint == endpoint))
		{
			memberExists = TRUE;
		}
		else
		{
			nextMemberPtr = &((*nextMemberPtr)->next);
		}
	}

	if (!memberExists)
	{
		*nextMemberPtr = &newMember;
		newMember.nwkAddr = nwkAddr;
		newMember.endpoint = endpoint;
		newMember.next = NULL;
		groupListComposeRecord(group, rec);
		groupListRemoveGroupByName(groupNameStr);
		sdb_add_record(db, rec);
	}

	//printf("groupListAddGroup--\n");

	return groupId;
}
bool sdb_consolidate_db(db_descriptor ** _db)
{
	_db_descriptor * db = *_db;
	_db_descriptor * tempDb;
	void * rec;
	uint32_t context;
	int rc;

	char tempfilename[MAX_SUPPORTED_FILENAME + TEMP_FILENAME_EXTENTION_LENGTH + 1];


	strcpy(tempfilename, db->name);
	strcat(tempfilename, ".tmp");

	rc = remove(tempfilename);
	if ((rc != 0) && (errno != ENOENT))
	{
		return FALSE;
	}

	tempDb = sdb_init_db(tempfilename, db->get_record_size, db->check_deleted, db->check_ignore, db->mark_deleted, db->consolidation_processing, db->type, db->bin_header_size);

	if (tempDb == NULL)
	{
		return FALSE;
	}

	db->check_ignore = NULL; //only deleted lines should be removed. Ignored lines should stay.
	
	rec = SDB_GET_FIRST_RECORD(db, &context);
	rc = TRUE;
	while ((rec != NULL) && (rc == TRUE))
	{

		if (db->consolidation_processing != NULL)
		{
			rc = db->consolidation_processing(tempDb, rec);
//			devListErrorComment(tempDb, rec);
		}
		else
		{
			rc = sdb_add_record(tempDb, rec);
		}
		
		rec = SDB_GET_NEXT_RECORD(db, &context);
	}

	strcpy(tempfilename, db->name);

	sdb_release_db(_db);
	(*_db) = tempDb;

	rc = remove(tempfilename);

	if (rc != 0)
	{
		return FALSE;
	}
	
	rc = sdb_rename_db(*_db, tempfilename);
	
	return rc;
}
bool sdbtErrorComment(db_descriptor * db, char * record)
{
	parsingResult_t parsingResult = {SDB_TXT_PARSER_RESULT_OK, 0};
	char * pBuf = record + 1;
	char comment[MAX_SUPPORTED_RECORD_SIZE];
	uint8_t errorCode;
	uint16_t errorOffset;
	bool rc;
	char tempstr[3] = {SDBT_BAD_FORMAT_CHARACTER, '\n', '\0'};

	if (record[0] == SDBT_PENDING_COMMENT_FORMAT_CHARACTER)
	{
		record[0] = SDBT_BAD_FORMAT_CHARACTER;
		sprintf(comment,"%c-------\n", SDBT_BAD_FORMAT_CHARACTER);
		rc = sdb_add_record(db, comment) &&
			sdb_add_record(db, record);
		
		if (rc == TRUE)
		{
//			printf("here&\n");
			sdb_txt_parser_get_numeric_field(&pBuf, &errorCode, 1, FALSE, &parsingResult);
			if (errorCode > SDB_TXT_PARSER_RESULT_MAX)
			{
//printf("here0\n");
				parsingResult.code = SDB_TXT_PARSER_RESULT_VALUE_OUT_OF_RANGE;
				parsingResult.errorLocation = pBuf - 2;
			}
			else
			{
//printf("here1 %d \n", parsingResult.code);
				sdb_txt_parser_get_numeric_field(&pBuf, (uint8_t *)&errorOffset, 2, FALSE, &parsingResult);
				if (errorOffset >= strlen(record))
				{
					parsingResult.code = SDB_TXT_PARSER_RESULT_VALUE_OUT_OF_RANGE;
					parsingResult.errorLocation = pBuf - 2;
				}
			}
//			printf("here2\n");
			if (parsingResult.code == SDB_TXT_PARSER_RESULT_OK)
			{
//				printf("here3\n");
//				printf("%s\n%d %d\n", record, errorOffset - 7 + 1, errorCode);
				sprintf(comment,"%cERROR:%*s %s\n", SDBT_BAD_FORMAT_CHARACTER, errorOffset - 7 + 1, "^", parsingErrorStrings[errorCode]);
			}
			else
			{
//				printf("here4\n");
//				printf("%s\n%d %d\n", record, parsingResult.errorLocation - record - 1 + 1, parsingResult.code);
				sprintf(comment,"%c%*s %s (%s)\n", SDBT_BAD_FORMAT_CHARACTER, parsingResult.errorLocation - record - 1 + 1, "^", "BAD_ERROR_DESCRIPTION_HEADER", parsingErrorStrings[parsingResult.code]);
			}
//			printf("here5\n");

			rc = sdb_add_record(db, comment)
				&& sdb_add_record(db, tempstr);
		}
	}
	else
	{
		rc = sdb_add_record(db, record);
	}

	return rc;
}