docs: def generate(self, dir_pattern, file_pattern, action_ch='g', recursively=False, force=False):
          """
          Main method to generate (source code) files from templates.
  
          See documentation about the directory and file patterns and their possible combinations.
  
          Args:
              dir_pattern: ``glob`` pattern taken from the root directory. **Only** used for directories.
              file_pattern: ``fnmatch`` pattern taken from all matching directories. **Only** used for files.
              action (char): Denote action to be taken. Can be:
                  - g: Generate all files that match both directory and file patterns. This is the default behavior.
                  - d: Same as `g` but with doing anything, i.e. dry run.
                  - c: Same as `g` but erasing the generated files instead, i.e. clean.
              recursively: Do we do the actions in the sub-directories? Note that in this case **only** the file pattern applies as **all**
                  the subdirectories are visited.
              force (boolean): Do we force the generation or not?
  
          """
          # directories to visit
          # using heavy machinery to extract absolute cleaned paths... to avoid any problem...
          directories = [os.path.abspath(directory) for directory in glob.glob(os.path.join(self.__root_directory, dir_pattern)) if os.path.isdir(directory)]
  
          # list of extensions
          extensions = self.__extensions.keys()
  
          for directory in directories:
              for b, f in find_files(directory, file_pattern, recursively=recursively):
                  # test if some template files can be processed
                  file_basename, file_ext = os.path.splitext(f)
  
                  if file_ext in extensions:
                      # try to find corresponding action
                      rel_path = os.path.relpath(os.path.join(b,f), self.__root_directory)
                      rel_basename, rel_filename = os.path.split(rel_path)
                      rel_filename_without_ext, rel_ext = os.path.splitext(rel_filename)
  
                      # template absolute filename
                      in_file_name = os.path.join(b, f)
  
                      generator_action_container = self.__actions.retrieve_element_or_default(rel_basename, None)
                      action = None
  
                      if generator_action_container is not None:
                          action = generator_action_container.get_compatible_generator_action(f)
  
                      # is there a default action if needed?
                      if action is None:
                          action = self.__default_action
  
                      if action:
  
                          if action_ch == 'd':
                              print("Process file '%s' with function '%s':" % (rel_path, action.action_function_name()))
                          for filename_end, context in action.run():
                              # generated absolute file name
                              out_file_name = os.path.join(b, rel_filename_without_ext + filename_end + self.__extensions[file_ext])
                              if action_ch == 'g':
                                  self.__generate_file(template_filename=in_file_name, context=context, generated_filename=out_file_name, force=force)
                              elif action_ch == 'c':
                                  try:
                                      os.remove(out_file_name)
                                      self.log_info("Removed file '%s'" % out_file_name)
                                  except OSError:
                                      pass
                              elif action_ch == 'd':
                                  # we only print relative path
                                  print("   -> %s" % os.path.join(rel_basename, rel_filename_without_ext + filename_end + self.__extensions[file_ext]))