def add_filter(self, field, lookup_type, negated, value):
        """
        This function is used by the default add_filters()
        implementation.
        """
        if lookup_type == 'ancestor':
            self.ancestor_key = Key.from_path(value._meta.db_table, value.pk)
            return

        if lookup_type not in OPERATORS_MAP:
            raise DatabaseError("Lookup type %r isn't supported." %
                                lookup_type)

        # GAE does not let you store empty lists, so we can tell
        # upfront that queriying for one will return nothing.
        if value in ([], ()) and not negated:
            self.included_pks = []
            return

        # Optimization: batch-get by key; this is only suitable for
        # primary keys, not for anything that uses the key type.
        if field.primary_key and lookup_type in ('exact', 'in'):
            if self.included_pks is not None:
                raise DatabaseError("You can't apply multiple AND "
                                    "filters on the primary key. "
                                    "Did you mean __in=[...]?")
            if not isinstance(value, (tuple, list)):
                value = [value]
            pks = [pk for pk in value if pk is not None]

            if field.rel:
                pks = [ Key.from_path(self.db_table, pk.id_or_name()) for pk in pks ]

            if negated:
                self.excluded_pks = pks
            else:
                self.included_pks = pks
            return

        # We check for negation after lookup_type isnull because it
        # simplifies the code. All following lookup_type checks assume
        # that they're not negated.
        if lookup_type == 'isnull':
            if (negated and value) or not value:
                # TODO/XXX: Is everything greater than None?
                op = '>'
            else:
                op = '='
            value = None
        elif negated and lookup_type == 'exact':
            if self.has_negated_exact_filter:
                raise DatabaseError("You can't exclude more than one __exact "
                                    "filter.")
            self.has_negated_exact_filter = True
            self._combine_filters(field, (('<', value), ('>', value)))
            return
        elif negated:
            try:
                op = NEGATION_MAP[lookup_type]
            except KeyError:
                raise DatabaseError("Lookup type %r can't be negated." %
                                    lookup_type)
            if self.inequality_field and field != self.inequality_field:
                raise DatabaseError("Can't have inequality filters on "
                                    "multiple fields (here: %r and %r)." %
                                    (field, self.inequality_field))
            self.inequality_field = field
        elif lookup_type == 'in':
            # Create sub-query combinations, one for each value.
            if len(self.gae_query) * len(value) > 30:
                raise DatabaseError("You can't query against more than "
                                    "30 __in filter value combinations.")
            op_values = [('=', v) for v in value]
            self._combine_filters(field, op_values)
            return
        elif lookup_type == 'startswith':
            # Lookup argument was converted to [arg, arg + u'\ufffd'].
            self._add_filter(field, '>=', value[0])
            self._add_filter(field, '<=', value[1])
            return
        elif lookup_type in ('range', 'year'):
            self._add_filter(field, '>=', value[0])
            op = '<=' if lookup_type == 'range' else '<'
            self._add_filter(field, op, value[1])
            return
        else:
            op = OPERATORS_MAP[lookup_type]

        self._add_filter(field, op, value)