simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
{
	struct berval tmp;
	ber_len_t len;
	int undef;

	if ( vrf == NULL ) {
		ber_str2bv_x( "No filter!", STRLENOF("No filter!"), 1, fstr,
			op->o_tmpmemctx );
		return;
	}
	undef = vrf->vrf_choice & SLAPD_FILTER_UNDEFINED;

	switch ( vrf->vrf_choice & SLAPD_FILTER_MASK ) {
	case LDAP_FILTER_EQUALITY:
		filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );

		fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
			tmp.bv_len + STRLENOF("(=)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
			vrf->vrf_av_desc->ad_cname.bv_val,
			tmp.bv_val );

		ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_GE:
		filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );

		fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
			tmp.bv_len + STRLENOF("(>=)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
			vrf->vrf_av_desc->ad_cname.bv_val,
			tmp.bv_val );

		ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_LE:
		filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );

		fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
			tmp.bv_len + STRLENOF("(<=)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
			vrf->vrf_av_desc->ad_cname.bv_val,
			tmp.bv_val );

		ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_APPROX:
		filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );

		fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
			tmp.bv_len + STRLENOF("(~=)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
			vrf->vrf_av_desc->ad_cname.bv_val,
			tmp.bv_val );
		ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_SUBSTRINGS:
		fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
			STRLENOF("(=*)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			vrf->vrf_sub_desc->ad_cname.bv_val );

		if ( vrf->vrf_sub_initial.bv_val != NULL ) {
			len = fstr->bv_len;

			filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );

			fstr->bv_len += tmp.bv_len;
			fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
				op->o_tmpmemctx );

			snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
				/* "(attr=" */ "%s*)",
				tmp.bv_val );

			ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		}

		if ( vrf->vrf_sub_any != NULL ) {
			int i;
			for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) {
				len = fstr->bv_len;
				filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp,
					op->o_tmpmemctx );

				fstr->bv_len += tmp.bv_len + 1;
				fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
					fstr->bv_len + 1, op->o_tmpmemctx );

				snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
					/* "(attr=[init]*[any*]" */ "%s*)",
					tmp.bv_val );
				ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
			}
		}

		if ( vrf->vrf_sub_final.bv_val != NULL ) {
			len = fstr->bv_len;

			filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );

			fstr->bv_len += tmp.bv_len;
			fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
				op->o_tmpmemctx );

			snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
				/* "(attr=[init*][any*]" */ "%s)",
				tmp.bv_val );

			ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		}

		break;

	case LDAP_FILTER_PRESENT:
		fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
			STRLENOF("(=*)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			vrf->vrf_desc->ad_cname.bv_val );
		break;

	case LDAP_FILTER_EXT: {
		struct berval ad;
		filter_escape_value_x( &vrf->vrf_mr_value, &tmp, op->o_tmpmemctx );

		if ( vrf->vrf_mr_desc ) {
			ad = vrf->vrf_mr_desc->ad_cname;
		} else {
			ad.bv_len = 0;
			ad.bv_val = "";
		}
			
		fstr->bv_len = ad.bv_len +
			( vrf->vrf_mr_dnattrs ? STRLENOF(":dn") : 0 ) +
			( vrf->vrf_mr_rule_text.bv_len
				? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
			tmp.bv_len + STRLENOF("(:=)");
		if ( undef ) fstr->bv_len++;
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
			ad.bv_val,
			vrf->vrf_mr_dnattrs ? ":dn" : "",
			vrf->vrf_mr_rule_text.bv_len ? ":" : "",
			vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "",
			tmp.bv_val );

		ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
		} break;

	case SLAPD_FILTER_COMPUTED:
		ber_str2bv_x(
			vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" :
			vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
			vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
				? "(?=undefined)" : "(?=error)",
			vrf->vrf_result == LDAP_COMPARE_FALSE ? STRLENOF("(?=false)") :
			vrf->vrf_result == LDAP_COMPARE_TRUE ? STRLENOF("(?=true)") :
			vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
				? STRLENOF("(?=undefined)") : STRLENOF("(?=error)"),
			1, fstr, op->o_tmpmemctx );
		break;

	default:
		ber_str2bv_x( "(?=unknown)", STRLENOF("(?=unknown)"),
			1, fstr, op->o_tmpmemctx );
		break;
	}
}