text: # pylint: disable=C0114
  
  import regex as re
  import Persistence.log as log
  from .candidate import Candidate
  from .result import Result
  log_ = log.getLogger(__name__)
  follog_ = log.getLogger(__name__ + '.following', '{name} {message}')
  
  def process_tweet(tweet, api, magic_tags, modus=None, default_magic_tag='DS100'):
      textlist = list(tweet.text)
      for key in ['media', 'urls']:
          if key in tweet.original.entities:
              for ent in tweet.original.entities[key]:
                  start = ent['indices'][0]
                  end = ent['indices'][1]
                  length = end - start
                  textlist[start:end] = '_'*length
      tweet.text = "".join(textlist)
      reply = compose_answer(tweet.text,
                             api.database,
                             tweet.hashtags(magic_tags),
                             modus,
                             default_magic_tag)
      if len(reply.strip()) == 0:
          log_.info("No expandable content found")
          return
      api.twitter.tweet(reply,
          in_reply_to_status_id=tweet.id,
          auto_populate_reply_metadata=True
      )
  
  def process_commands(tweet, twapi):
      author = tweet.author()
      if tweet.has_hashtag(['folgenbitte'], case_sensitive=False):
          is_followed = twapi.is_followed(author)
          if is_followed:
              follog_.log(45, "folgenbitte from @%s: already following", author.screen_name)
          else:
              follog_.log(45, "folgenbitte from @%s: not yet following", author.screen_name)
          if not is_followed:
              twapi.follow(author)
      if tweet.has_hashtag(['entfolgen'], case_sensitive=False):
          is_followed = twapi.is_followed(author)
          if is_followed:
              follog_.log(45, "entfolgen from @%s: still following so far", author.screen_name)
          else:
              follog_.log(45, "entfolgen from @%s: not even following yet", author.screen_name)
          if is_followed:
              twapi.defollow(author)
  
  def find_tokens(tweet, modus, magic_tag):
      finder = re.compile(r"""
          (?p)                # find longest match
          (?:^|\W)            # either at the beginning of the text or after a non-alphanumeric character, but don't find this
          (?:                 # Select source
              (\$|\#|\%|\&amp;|\/)# Special character to find something: #,$,%,&,/
              (?:(\p{Lu}+):)? # Optional prefix, e.g. "DS:" or "FFM:"
          )
          (                   # Payload
              [\p{L}\p{N}_]+  # All  letters plus all kinds of numbers plus _
          )
          (?:$|\W)            # either end of string or non-\w character
          """, re.X)
      tokens = finder.findall(tweet, overlapped=True)
      candidates = [Candidate(t, magic_tag) for t in tokens]
      # if modus isn't 'all', then that's all already.
      # if modus *is* 'all', and we have more than one result: great, too!
      if modus != 'all' or len(tokens) > 1:
          return candidates
      # if modus is 'all' and we have only one token and it's not the magic_tag, fine!
      if len(tokens) == 1 and str.join('', tokens[0][-1]) != magic_tag:
          return candidates
      # now: If modus is all and we have at found nothing but maybe the magic_tag,
      # we'll look for more. This can only be uppercase.
      finder2 = re.compile(r"""
          (?p)            # find longest match
          (?:^|\W)        # either at the beginning of the text or after a non-alphanumeric character, but don't find this
          ()
          ()
          (
              \p{Lu}[\p{Lu}\p{N}_]*)
                          # All uppercase letters plus all kinds of numbers plus _
          (?:$|\W)        # either end of string or non-\w character
          """, re.X)
      tokens = finder2.findall(tweet, overlapped=True)
      return [Candidate(t, magic_tag) for t in tokens]
  
  def find_source(sql, tag):
      sql.cursor.execute("""
          SELECT
              abbr
          FROM
              sourceflags
          WHERE
              magictag = :magic
          LIMIT 1
          """,
          ({'magic': tag,})
      )
      row = sql.cursor.fetchone()
      if row is None:
          return tag
      return row['abbr']
  
  def process_magic(magic_tags, length, default='DS100'):
      if len(magic_tags) == 0:
          # no magic tag: Only magic is in DS100.
          magic_tags = [[default, [0, 0]]]
      else:
          # the first magic tag is valid from the beginning, no matter
          # where it is!
          magic_tags[0][1] = [0, 0]
      magic_tags.append(['__', [length, length]])
      return magic_tags
  
  def compose_answer(tweet, sql, magic_tags, modus, default_magic_tag='DS100'):
      short_list = []
      # generate answer
      generated_content = ""
      magic_tags = process_magic(magic_tags, len(tweet), default_magic_tag)
      for mt, nextmt in zip(magic_tags[:-1], magic_tags[1:]):
          tweetpart = tweet[mt[1][1]:nextmt[1][0]]
          tag = mt[0]
          log_.debug("Part: '%s' mt '%s'", tweetpart, tag)
          for match in find_tokens(tweetpart, modus, tag):
              result = Result(match, sql)
              norm = result.normalized()
              if norm and norm in short_list:
                  continue
              if norm:
                  short_list.append(norm)
              if result.loggable(magic_tags):
                  sql.log_request(result)
              if result.status != 'found':
                  continue
              generated_content += result.answered()
      return generated_content
  