def parse(self, date, **kwargs):
        '''
        :param **kwargs: any kwargs accepted by dateutil.parse function.
        '''
        qualifiers = []
        if dateutil_parser is None:
            return None
        date = orig_date = date.strip()

        # various normalizations
        # TODO: call .lower() first
        date = date.replace('B.C.E.', 'BC')
        date = date.replace('BCE', 'BC')
        date = date.replace('B.C.', 'BC')
        date = date.replace('A.D.', 'AD')
        date = date.replace('C.E.', 'AD')
        date = date.replace('CE', 'AD')

        # deal with pre 0AD dates
        if date.startswith('-') or 'BC' in date or 'B.C.' in date:
            pre0AD = True
        else:
            pre0AD = False
        # BC seems to mess up parser
        date = date.replace('BC', '')

        # deal with circa: 'c.1950' or 'c1950'
        circa_match = re.match('([^a-zA-Z]*)c\.?\s*(\d+.*)', date)
        if circa_match:
            # remove circa bit
            qualifiers.append("Note 'circa'")
            date = ''.join(circa_match.groups())

        # deal with p1980 (what does this mean? it can appear in
        # field 008 of MARC records
        p_match = re.match("^p(\d+)", date)
        if p_match:
            date = date[1:]

        # Deal with uncertainty: '1985?'
        uncertainty_match = re.match('([0-9xX]{4})\?', date)
        if uncertainty_match:
            # remove the ?
            date = date[:-1]
            qualifiers.append('Uncertainty')

        # Parse the numbers intelligently
        # do not use std parser function as creates lots of default data
        res = dateutil_parser._parse(date, **kwargs)
        try:
            res = res[0]
        except:
            res = res
        if res is None:
            # Couldn't parse it
            return None
        # Note: Years of less than 3 digits not interpreted by
        #      dateutil correctly
        #      e.g. 87 -> 1987
        #           4  -> day 4 (no year)
        # Both cases are handled in this routine
        if res.year is None and res.day:
            year = res.day
        # If the whole date is simply two digits then dateutil_parser makes
        # it '86' -> '1986'. So strip off the '19'. (If the date specified
        # day/month then a two digit year is more likely to be this century
        # and so allow the '19' prefix to it.)
        elif self._numeric.match(date) and (len(date) == 2 or date.startswith('00')):
            year = res.year % 100
        else:
            year = res.year

        # finally add back in BC stuff
        if pre0AD:
            year = -year

        if not qualifiers:
            qualifier = ''
        else:
            qualifier = ', '.join(qualifiers) + (' : %s' % orig_date)
        return FlexiDate(year, res.month, res.day, res.hour, res.minute, res.second, res.microsecond, qualifier=qualifier)
:param **kwargs: any kwargs accepted by dateutil.parse function.