static int new_partition_set_replicated_metadata(struct ldb_context *ldb, 
						 struct ldb_module *module, struct ldb_request *last_req, 
						 struct partition_private_data *data, 
						 struct dsdb_partition *partition)
{
	unsigned int i;
	int ret;
	/* for each replicate, copy from main partition.  If we get an error, we report it up the chain */
	for (i=0; data->replicate && data->replicate[i]; i++) {
		struct ldb_result *replicate_res;
		struct ldb_request *add_req;
		ret = dsdb_module_search_dn(module, last_req, &replicate_res, 
					    data->replicate[i],
					    NULL,
					    DSDB_FLAG_NEXT_MODULE, NULL);
		if (ret == LDB_ERR_NO_SUCH_OBJECT) {
			continue;
		}
		if (ret != LDB_SUCCESS) {
			ldb_asprintf_errstring(ldb,
					       "Failed to search for %s from " DSDB_PARTITION_DN 
					       " replicateEntries for new partition at %s on %s: %s", 
					       ldb_dn_get_linearized(data->replicate[i]), 
					       partition->backend_url,
					       ldb_dn_get_linearized(partition->ctrl->dn), 
					       ldb_errstring(ldb));
			return ret;
		}

		/* Build add request */
		ret = ldb_build_add_req(&add_req, ldb, replicate_res, 
					replicate_res->msgs[0], NULL, NULL, 
					ldb_op_default_callback, last_req);
		LDB_REQ_SET_LOCATION(add_req);
		last_req = add_req;
		if (ret != LDB_SUCCESS) {
			/* return directly, this is a very unlikely error */
			return ret;
		}
		/* do request */
		ret = ldb_next_request(partition->module, add_req);
		/* wait */
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
		}
		
		switch (ret) {
		case LDB_SUCCESS:
			break;

		case LDB_ERR_ENTRY_ALREADY_EXISTS:
			/* Handle this case specially - if the
			 * metadata already exists, replace it */
		{
			struct ldb_request *del_req;
			
			/* Don't leave a confusing string in the ldb_errstring() */
			ldb_reset_err_string(ldb);
			/* Build del request */
			ret = ldb_build_del_req(&del_req, ldb, replicate_res, replicate_res->msgs[0]->dn, NULL, NULL, 
						ldb_op_default_callback, last_req);
			LDB_REQ_SET_LOCATION(del_req);
			last_req = del_req;
			if (ret != LDB_SUCCESS) {
				/* return directly, this is a very unlikely error */
				return ret;
			}
			/* do request */
			ret = ldb_next_request(partition->module, del_req);
			
			/* wait */
			if (ret == LDB_SUCCESS) {
				ret = ldb_wait(del_req->handle, LDB_WAIT_ALL);
			}
			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb,
						       "Failed to delete  (for re-add) %s from " DSDB_PARTITION_DN 
						       " replicateEntries in new partition at %s on %s: %s", 
						       ldb_dn_get_linearized(data->replicate[i]), 
						       partition->backend_url,
						       ldb_dn_get_linearized(partition->ctrl->dn), 
						       ldb_errstring(ldb));
				return ret;
			}
			
			/* Build add request */
			ret = ldb_build_add_req(&add_req, ldb, replicate_res, replicate_res->msgs[0], NULL, NULL, 
						ldb_op_default_callback, last_req);
			LDB_REQ_SET_LOCATION(add_req);
			last_req = add_req;
			if (ret != LDB_SUCCESS) {
				/* return directly, this is a very unlikely error */
				return ret;
			}
			
			/* do the add again */
			ret = ldb_next_request(partition->module, add_req);
			
			/* wait */
			if (ret == LDB_SUCCESS) {
				ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
			}

			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb,
						       "Failed to add (after delete) %s from " DSDB_PARTITION_DN 
						       " replicateEntries to new partition at %s on %s: %s", 
						       ldb_dn_get_linearized(data->replicate[i]), 
						       partition->backend_url,
						       ldb_dn_get_linearized(partition->ctrl->dn), 
						       ldb_errstring(ldb));
				return ret;
			}
			break;
		}
		default: 
		{
			ldb_asprintf_errstring(ldb,
					       "Failed to add %s from " DSDB_PARTITION_DN 
					       " replicateEntries to new partition at %s on %s: %s", 
					       ldb_dn_get_linearized(data->replicate[i]), 
					       partition->backend_url,
					       ldb_dn_get_linearized(partition->ctrl->dn), 
					       ldb_errstring(ldb));
			return ret;
		}
		}

		/* And around again, for the next thing we must merge */
	}
	return LDB_SUCCESS;
}
static int new_partition_set_replicated_metadata(struct ldb_context *ldb, 
						 struct ldb_module *module, struct ldb_request *last_req, 
						 struct partition_private_data *data, 
						 struct dsdb_partition *partition)
{
	unsigned int i;
	int ret;
	 
	for (i=0; data->replicate && data->replicate[i]; i++) {
		struct ldb_result *replicate_res;
		struct ldb_request *add_req;
		ret = dsdb_module_search_dn(module, last_req, &replicate_res, 
					    data->replicate[i],
					    NULL,
					    DSDB_FLAG_NEXT_MODULE, NULL);
		if (ret == LDB_ERR_NO_SUCH_OBJECT) {
			continue;
		}
		if (ret != LDB_SUCCESS) {
			ldb_asprintf_errstring(ldb,
					       "Failed to search for %s from " DSDB_PARTITION_DN 
					       " replicateEntries for new partition at %s on %s: %s", 
					       ldb_dn_get_linearized(data->replicate[i]), 
					       partition->backend_url,
					       ldb_dn_get_linearized(partition->ctrl->dn), 
					       ldb_errstring(ldb));
			return ret;
		}

		 
		ret = ldb_build_add_req(&add_req, ldb, replicate_res, 
					replicate_res->msgs[0], NULL, NULL, 
					ldb_op_default_callback, last_req);
		LDB_REQ_SET_LOCATION(add_req);
		last_req = add_req;
		if (ret != LDB_SUCCESS) {
			 
			return ret;
		}
		 
		ret = ldb_next_request(partition->module, add_req);
		 
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
		}
		
		switch (ret) {
		case LDB_SUCCESS:
			break;

		case LDB_ERR_ENTRY_ALREADY_EXISTS:
			 
		{
			struct ldb_request *del_req;
			
			 
			ldb_reset_err_string(ldb);
			 
			ret = ldb_build_del_req(&del_req, ldb, replicate_res, replicate_res->msgs[0]->dn, NULL, NULL, 
						ldb_op_default_callback, last_req);
			LDB_REQ_SET_LOCATION(del_req);
			last_req = del_req;
			if (ret != LDB_SUCCESS) {
				 
				return ret;
			}
			 
			ret = ldb_next_request(partition->module, del_req);
			
			 
			if (ret == LDB_SUCCESS) {
				ret = ldb_wait(del_req->handle, LDB_WAIT_ALL);
			}
			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb,
						       "Failed to delete  (for re-add) %s from " DSDB_PARTITION_DN 
						       " replicateEntries in new partition at %s on %s: %s", 
						       ldb_dn_get_linearized(data->replicate[i]), 
						       partition->backend_url,
						       ldb_dn_get_linearized(partition->ctrl->dn), 
						       ldb_errstring(ldb));
				return ret;
			}
			
			 
			ret = ldb_build_add_req(&add_req, ldb, replicate_res, replicate_res->msgs[0], NULL, NULL, 
						ldb_op_default_callback, last_req);
			LDB_REQ_SET_LOCATION(add_req);
			last_req = add_req;
			if (ret != LDB_SUCCESS) {
				 
				return ret;
			}
			
			 
			ret = ldb_next_request(partition->module, add_req);
			
			 
			if (ret == LDB_SUCCESS) {
				ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
			}

			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb,
						       "Failed to add (after delete) %s from " DSDB_PARTITION_DN 
						       " replicateEntries to new partition at %s on %s: %s", 
						       ldb_dn_get_linearized(data->replicate[i]), 
						       partition->backend_url,
						       ldb_dn_get_linearized(partition->ctrl->dn), 
						       ldb_errstring(ldb));
				return ret;
			}
			break;
		}
		default: 
		{
			ldb_asprintf_errstring(ldb,
					       "Failed to add %s from " DSDB_PARTITION_DN 
					       " replicateEntries to new partition at %s on %s: %s", 
					       ldb_dn_get_linearized(data->replicate[i]), 
					       partition->backend_url,
					       ldb_dn_get_linearized(partition->ctrl->dn), 
					       ldb_errstring(ldb));
			return ret;
		}
		}

		 
	}
	return LDB_SUCCESS;
}