int ldb_msg_find_duplicate_val(struct ldb_context *ldb,
			       TALLOC_CTX *mem_ctx,
			       const struct ldb_message_element *el,
			       struct ldb_val **duplicate,
			       uint32_t options)
{
	unsigned int i, j;
	struct ldb_val *val;

	if (options != 0) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	*duplicate = NULL;

	/*
	   If there are not many values, it is best to avoid the talloc
	   overhead and just do a brute force search.
	 */
	if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) {
		for (j = 0; j < el->num_values; j++) {
			val = &el->values[j];
			for ( i = j + 1; i < el->num_values; i++) {
				if (ldb_val_equal_exact(val, &el->values[i])) {
					*duplicate = val;
					return LDB_SUCCESS;
				}
			}
		}
	} else {
		struct ldb_val *values;
		values = talloc_array(mem_ctx, struct ldb_val, el->num_values);
		if (values == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}

		memcpy(values, el->values,
		       el->num_values * sizeof(struct ldb_val));
		TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp);
		for (i = 1; i < el->num_values; i++) {
			if (ldb_val_equal_exact(&values[i],
						&values[i - 1])) {
				/* find the original location */
				for (j = 0; j < el->num_values; j++) {
					if (ldb_val_equal_exact(&values[i],
								&el->values[j])
						) {
						*duplicate = &el->values[j];
						break;
					}
				}
				talloc_free(values);
				if (*duplicate == NULL) {
					/* how we got here, I don't know */
					return LDB_ERR_OPERATIONS_ERROR;
				}
				return LDB_SUCCESS;
			}
		}
		talloc_free(values);
	}
	return LDB_SUCCESS;
}
int ldb_msg_find_duplicate_val(struct ldb_context *ldb,
			       TALLOC_CTX *mem_ctx,
			       const struct ldb_message_element *el,
			       struct ldb_val **duplicate,
			       uint32_t options)
{
	unsigned int i, j;
	struct ldb_val *val;

	if (options != 0) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	*duplicate = NULL;

	 
	if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) {
		for (j = 0; j < el->num_values; j++) {
			val = &el->values[j];
			for ( i = j + 1; i < el->num_values; i++) {
				if (ldb_val_equal_exact(val, &el->values[i])) {
					*duplicate = val;
					return LDB_SUCCESS;
				}
			}
		}
	} else {
		struct ldb_val *values;
		values = talloc_array(mem_ctx, struct ldb_val, el->num_values);
		if (values == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}

		memcpy(values, el->values,
		       el->num_values * sizeof(struct ldb_val));
		TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp);
		for (i = 1; i < el->num_values; i++) {
			if (ldb_val_equal_exact(&values[i],
						&values[i - 1])) {
				 
				for (j = 0; j < el->num_values; j++) {
					if (ldb_val_equal_exact(&values[i],
								&el->values[j])
						) {
						*duplicate = &el->values[j];
						break;
					}
				}
				talloc_free(values);
				if (*duplicate == NULL) {
					 
					return LDB_ERR_OPERATIONS_ERROR;
				}
				return LDB_SUCCESS;
			}
		}
		talloc_free(values);
	}
	return LDB_SUCCESS;
}