Evaluate the C{modifier} string and following text (passed in
        as C{chunk1} and C{chunk2}) and if they match any known modifiers
        calculate the delta and apply it to C{sourceTime}.

        @type  modifier:   string
        @param modifier:   modifier text to apply to sourceTime
        @type  chunk1:     string
        @param chunk1:     first text chunk that followed modifier (if any)
        @type  chunk2:     string
        @param chunk2:     second text chunk that followed modifier (if any)
        @type  sourceTime: struct_time
        @param sourceTime: C{struct_time} value to use as the base

        @rtype:  tuple
        @return: tuple of: remaining text and the modified sourceTime

def _evalModifier(self, modifier, chunk1, chunk2, sourceTime):
        """
        Evaluate the C{modifier} string and following text (passed in
        as C{chunk1} and C{chunk2}) and if they match any known modifiers
        calculate the delta and apply it to C{sourceTime}.

        @type  modifier:   string
        @param modifier:   modifier text to apply to sourceTime
        @type  chunk1:     string
        @param chunk1:     first text chunk that followed modifier (if any)
        @type  chunk2:     string
        @param chunk2:     second text chunk that followed modifier (if any)
        @type  sourceTime: struct_time
        @param sourceTime: C{struct_time} value to use as the base

        @rtype:  tuple
        @return: tuple of: remaining text and the modified sourceTime
        """
        offset = self.ptc.Modifiers[modifier]

        if sourceTime is not None:
            (yr, mth, dy, hr, mn, sec, wd, yd, isdst) = sourceTime
        else:
            (yr, mth, dy, hr, mn, sec, wd, yd, isdst) = time.localtime()

        # capture the units after the modifier and the remaining
        # string after the unit
        m = self.ptc.CRE_REMAINING.search(chunk2)
        if m is not None:
            index  = m.start() + 1
            unit   = chunk2[:m.start()]
            chunk2 = chunk2[index:]
        else:
            unit   = chunk2
            chunk2 = ''

        flag = False

        if unit == 'month' or \
           unit == 'mth' or \
           unit == 'm':
            if offset == 0:
                dy         = self.ptc.daysInMonth(mth, yr)
                sourceTime = (yr, mth, dy, 9, 0, 0, wd, yd, isdst)
            elif offset == 2:
                # if day is the last day of the month, calculate the last day
                # of the next month
                if dy == self.ptc.daysInMonth(mth, yr):
                    dy = self.ptc.daysInMonth(mth + 1, yr)

                start      = datetime.datetime(yr, mth, dy, 9, 0, 0)
                target     = self.inc(start, month=1)
                sourceTime = target.timetuple()
            else:
                start      = datetime.datetime(yr, mth, 1, 9, 0, 0)
                target     = self.inc(start, month=offset)
                sourceTime = target.timetuple()

            flag = True
            self.dateFlag = 1

        if unit == 'week' or \
             unit == 'wk' or \
             unit == 'w':
            if offset == 0:
                start      = datetime.datetime(yr, mth, dy, 17, 0, 0)
                target     = start + datetime.timedelta(days=(4 - wd))
                sourceTime = target.timetuple()
            elif offset == 2:
                start      = datetime.datetime(yr, mth, dy, 9, 0, 0)
                target     = start + datetime.timedelta(days=7)
                sourceTime = target.timetuple()
            else:
                return self._evalModifier(modifier, chunk1, "monday " + chunk2, sourceTime)

            flag          = True
            self.dateFlag = 1

        if unit == 'day' or \
            unit == 'dy' or \
            unit == 'd':
            if offset == 0:
                sourceTime    = (yr, mth, dy, 17, 0, 0, wd, yd, isdst)
                self.timeFlag = 2
            elif offset == 2:
                start      = datetime.datetime(yr, mth, dy, hr, mn, sec)
                target     = start + datetime.timedelta(days=1)
                sourceTime = target.timetuple()
            else:
                start      = datetime.datetime(yr, mth, dy, 9, 0, 0)
                target     = start + datetime.timedelta(days=offset)
                sourceTime = target.timetuple()

            flag          = True
            self.dateFlag = 1

        if unit == 'hour' or \
           unit == 'hr':
            if offset == 0:
                sourceTime = (yr, mth, dy, hr, 0, 0, wd, yd, isdst)
            else:
                start      = datetime.datetime(yr, mth, dy, hr, 0, 0)
                target     = start + datetime.timedelta(hours=offset)
                sourceTime = target.timetuple()

            flag          = True
            self.timeFlag = 2

        if unit == 'year' or \
             unit == 'yr' or \
             unit == 'y':
            if offset == 0:
                sourceTime = (yr, 12, 31, hr, mn, sec, wd, yd, isdst)
            elif offset == 2:
                sourceTime = (yr + 1, mth, dy, hr, mn, sec, wd, yd, isdst)
            else:
                sourceTime = (yr + offset, 1, 1, 9, 0, 0, wd, yd, isdst)

            flag          = True
            self.dateFlag = 1

        if flag == False:
            m = self.ptc.CRE_WEEKDAY.match(unit)
            if m is not None:
                wkdy          = m.group()
                self.dateFlag = 1

                if modifier == 'eod':
                    # Calculate the  upcoming weekday
                    self.modifierFlag = False
                    (sourceTime, _)   = self.parse(wkdy, sourceTime)
                    sources           = self.ptc.buildSources(sourceTime)
                    self.timeFlag     = 2

                    if modifier in sources:
                        sourceTime = sources[modifier]

                else:
                    wkdy       = self.ptc.WeekdayOffsets[wkdy]
                    diff       = self._CalculateDOWDelta(wd, wkdy, offset,
                                                         self.ptc.DOWParseStyle,
                                                         self.ptc.CurrentDOWParseStyle)
                    start      = datetime.datetime(yr, mth, dy, 9, 0, 0)
                    target     = start + datetime.timedelta(days=diff)
                    sourceTime = target.timetuple()

                flag          = True
                self.dateFlag = 1

        if not flag:
            m = self.ptc.CRE_TIME.match(unit)
            if m is not None:
                self.modifierFlag = False
                (yr, mth, dy, hr, mn, sec, wd, yd, isdst), _ = self.parse(unit)

                start      = datetime.datetime(yr, mth, dy, hr, mn, sec)
                target     = start + datetime.timedelta(days=offset)
                sourceTime = target.timetuple()
                flag       = True
            else:
                self.modifierFlag = False

                # check if the remaining text is parsable and if so,
                # use it as the base time for the modifier source time
                t, flag2 = self.parse('%s %s' % (chunk1, unit), sourceTime)

                if flag2 != 0:
                    sourceTime = t

                sources = self.ptc.buildSources(sourceTime)

                if modifier in sources:
                    sourceTime    = sources[modifier]
                    flag          = True
                    self.timeFlag = 2

        # if the word after next is a number, the string is more than likely
        # to be "next 4 hrs" which we will have to combine the units with the
        # rest of the string
        if not flag:
            if offset < 0:
                # if offset is negative, the unit has to be made negative
                unit = '-%s' % unit

            chunk2 = '%s %s' % (unit, chunk2)

        self.modifierFlag = False

        #return '%s %s' % (chunk1, chunk2), sourceTime
        return '%s' % chunk2, sourceTime