    def parse_content(self, content):
        self.data = []
        self.environment = {}
        self.invalid_lines = []
        # Crontabs can use 'nicknames' for common event frequencies:
        nicknames = {
            '@yearly': '0 0 1 1 *',
            '@annually': '0 0 1 1 *',
            '@monthly': '0 0 1 * *',
            '@weekly': '0 0 * * 0',
            '@daily': '0 0 * * *',
            '@hourly': '0 * * * *',
        }
        cron_re = re.compile(_make_cron_re(), flags=re.IGNORECASE)
        env_re = re.compile(r'^\s*(?P<key>\w+)\s*=\s*(?P<value>\S.*)$')
        for line in get_active_lines(content):
            if line.startswith('@'):
                # Reboot is 'special':
                if line.startswith('@reboot'):
                    parts = line.split(None, 2)
                    self.data.append({'time': '@reboot', 'command': parts[1]})
                    continue
                else:
                    parts = line.split(None, 2)
                    if parts[0] not in nicknames:
                        raise ParseException(
                            "{n} not recognised as a time specification 'nickname'".format(n=parts[0])
                        )
                    # Otherwise, put the time spec nickname translation into
                    # the line
                    line = line.replace(parts[0], nicknames[parts[0]])
                    # And then we fall through to the rest of the parsing.
            cron_match = cron_re.match(line)
            env_match = env_re.match(line)
            if cron_match:
                self.data.append(cron_match.groupdict())
            elif env_match:
                # Environment variable - capture in dictionary
                self.environment[env_match.group('key')] = env_match.group('value')
            else:
                self.invalid_lines.append(line)