text: # various utility functions
  
  
  # from https://stackoverflow.com/questions/2277352/split-a-string-at-uppercase-letters
  def split_on_uppercase(s, keep_contiguous=True):
      """
  
      Args:
          s (str): string
          keep_contiguous (bool): flag to indicate we want to
                                  keep contiguous uppercase chars together
  
      Returns:
  
      """
  
      string_length = len(s)
      is_lower_around = (lambda: s[i - 1].islower() or 
                         string_length > (i + 1) and s[i + 1].islower())
  
      start = 0
      parts = []
      for i in range(1, string_length):
          if s[i].isupper() and (not keep_contiguous or is_lower_around()):
              parts.append(s[start: i])
              start = i
      parts.append(s[start:])
  
      return parts
  
  
  # from https://stackoverflow.com/questions/9835762/how-do-i-find-the-duplicates-in-a-list-and-create-another-list-with-them
  def list_duplicates(seq):
    seen = set()
    seen_add = seen.add
    # adds all elements it doesn't know yet to seen and all other to seen_twice
    seen_twice = set( x for x in seq if x in seen or seen_add(x) )
    # turn the set into a list (as requested)
    return list( seen_twice )