code: def get_all_tags(self):
          
          
          if self._all_tags_cache != None:
              return self._all_tags_cache
      
          tag_list_common = set()
          tag_list_misconception = set()
          tag_list_org = set()
  
          tasks = self.get_tasks()
          for id, task in tasks.items():
              for tag in task.get_tags()[0]:
                  tag_list_common.add(tag)
              for tag in task.get_tags()[1]:
                  tag_list_misconception.add(tag)
              for tag in task.get_tags()[2]:
                  tag_list_org.add(tag)
          
          tag_list_common = natsorted(tag_list_common, key=lambda y: y.get_name().lower())
          tag_list_misconception = natsorted(tag_list_misconception, key=lambda y: y.get_name().lower())
          tag_list_org = natsorted(tag_list_org, key=lambda y: y.get_name().lower())
               
          self._all_tags_cache = (list(tag_list_common), list(tag_list_misconception), list(tag_list_org))
          return self._all_tags_cache
docs: Return a tuple of lists ([common_tags], [anti_tags], [organisational_tags]) all tags of all tasks of this course 
          Since this is an heavy procedure, we use a cache to cache results. Cache should be updated when a task is modified.