int ldb_msg_normalize(struct ldb_context *ldb,
		      TALLOC_CTX *mem_ctx,
		      const struct ldb_message *msg,
		      struct ldb_message **_msg_out)
{
	unsigned int i;
	struct ldb_message *msg2;

	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (msg2 == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ldb_msg_sort_elements(msg2);

	for (i=1; i < msg2->num_elements; i++) {
		struct ldb_message_element *el1 = &msg2->elements[i-1];
		struct ldb_message_element *el2 = &msg2->elements[i];

		if (ldb_msg_element_compare_name(el1, el2) == 0) {
			el1->values = talloc_realloc(msg2->elements,
			                             el1->values, struct ldb_val,
			                             el1->num_values + el2->num_values);
			if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
				talloc_free(msg2);
				return LDB_ERR_OPERATIONS_ERROR;
			}
			memcpy(el1->values + el1->num_values,
			       el2->values,
			       sizeof(struct ldb_val) * el2->num_values);
			el1->num_values += el2->num_values;
			talloc_free(discard_const_p(char, el2->name));
			if ((i+1) < msg2->num_elements) {
				memmove(el2, el2+1, sizeof(struct ldb_message_element) *
					(msg2->num_elements - (i+1)));
			}
			msg2->num_elements--;
			i--;
		}
	}

	*_msg_out = msg2;
	return LDB_SUCCESS;
}
int ldb_msg_normalize(struct ldb_context *ldb,
		      TALLOC_CTX *mem_ctx,
		      const struct ldb_message *msg,
		      struct ldb_message **_msg_out)
{
	unsigned int i;
	struct ldb_message *msg2;

	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (msg2 == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ldb_msg_sort_elements(msg2);

	for (i=1; i < msg2->num_elements; i++) {
		struct ldb_message_element *el1 = &msg2->elements[i-1];
		struct ldb_message_element *el2 = &msg2->elements[i];

		if (ldb_msg_element_compare_name(el1, el2) == 0) {
			el1->values = talloc_realloc(msg2->elements,
			                             el1->values, struct ldb_val,
			                             el1->num_values + el2->num_values);
			if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
				talloc_free(msg2);
				return LDB_ERR_OPERATIONS_ERROR;
			}
			memcpy(el1->values + el1->num_values,
			       el2->values,
			       sizeof(struct ldb_val) * el2->num_values);
			el1->num_values += el2->num_values;
			talloc_free(discard_const_p(char, el2->name));
			if ((i+1) < msg2->num_elements) {
				memmove(el2, el2+1, sizeof(struct ldb_message_element) *
					(msg2->num_elements - (i+1)));
			}
			msg2->num_elements--;
			i--;
		}
	}

	*_msg_out = msg2;
	return LDB_SUCCESS;
}