public static function create($attr_name, $match, $value = '', $escape = true)
    {
        $leaf_filter = new Net_LDAP2_Filter();
        if ($escape) {
            $array = Net_LDAP2_Util::escape_filter_value(array($value));
            $value = $array[0];
        }

        $match = strtolower($match);

        // detect negation
        $neg_matches   = array();
        $negate_filter = false;
        if (preg_match('/^(?:not|!)[\s_-](.+)/', $match, $neg_matches)) {
            $negate_filter = true;
            $match         = $neg_matches[1];
        }

        // build basic filter
        switch ($match) {
        case 'equals':
        case '=':
        case '==':
            $leaf_filter->_filter = '(' . $attr_name . '=' . $value . ')';
            break;
        case 'begins':
            $leaf_filter->_filter = '(' . $attr_name . '=' . $value . '*)';
            break;
        case 'ends':
            $leaf_filter->_filter = '(' . $attr_name . '=*' . $value . ')';
            break;
        case 'contains':
            $leaf_filter->_filter = '(' . $attr_name . '=*' . $value . '*)';
            break;
        case 'greater':
        case '>':
            $leaf_filter->_filter = '(' . $attr_name . '>' . $value . ')';
            break;
        case 'less':
        case '<':
            $leaf_filter->_filter = '(' . $attr_name . '<' . $value . ')';
            break;
        case 'greaterorequal':
        case '>=':
            $leaf_filter->_filter = '(' . $attr_name . '>=' . $value . ')';
            break;
        case 'lessorequal':
        case '<=':
            $leaf_filter->_filter = '(' . $attr_name . '<=' . $value . ')';
            break;
        case 'approx':
        case '~=':
            $leaf_filter->_filter = '(' . $attr_name . '~=' . $value . ')';
            break;
        case 'any':
        case 'present': // alias that may improve user code readability
            $leaf_filter->_filter = '(' . $attr_name . '=*)';
            break;
        default:
            return PEAR::raiseError('Net_LDAP2_Filter create error: matching rule "' . $match . '" not known!');
        }
        
        // negate if requested
        if ($negate_filter) {
           $leaf_filter = Net_LDAP2_Filter::combine('!', $leaf_filter);
        }

        return $leaf_filter;
    }