docs: def find_all_matching_parsers(self, strict: bool, desired_type: Type[Any] = JOKER, required_ext: str = JOKER) \
          -> Tuple[Tuple[List[Parser], List[Parser], List[Parser]],
                   List[Parser], List[Parser], List[Parser]]:
          """
          Overrides the parent method to find parsers appropriate to a given extension and type.
          This leverages both the parser registry and the converter registry to propose parsing chains in a relevant order
  
          :param strict:
          :param desired_type: the type of object to match.
          :param required_ext: the required extension.
          :return: match=(matching_parsers_generic, matching_parsers_approx, matching_parsers_exact),
                   no_type_match_but_ext_match, no_ext_match_but_type_match, no_match
          """
          # transform any 'Any' type requirement into the official class for that
          desired_type = get_validated_type(desired_type, 'desired_type', enforce_not_joker=False)
  
          # (1) call the super method to find all parsers
          matching, no_type_match_but_ext_match, no_ext_match_but_type_match, no_match = \
              super(ParserRegistryWithConverters, self).find_all_matching_parsers(strict=self.is_strict,
                                                                                  desired_type=desired_type,
                                                                                  required_ext=required_ext)
          # these are ordered with 'preferred last'
          matching_p_generic, matching_p_approx, matching_p_exact = matching
  
          if desired_type is JOKER:
              # then we want to try to append every possible converter chain, even if we have already found an exact match
              # (exact match will probably contain all parsers in that case?...)
              parsers_to_complete_with_converters = no_type_match_but_ext_match + matching_p_generic + matching_p_approx \
                                                    + matching_p_exact
          else:
              # then we can try to complete all the ones matching the extension (even the generic because combining them
              # with a conversion chain might provide another way to reach the result - different from using the generic
              # alone to reach the to_type)
              parsers_to_complete_with_converters = no_type_match_but_ext_match + matching_p_generic + matching_p_approx
  
          # (2) find all conversion chains that lead to the expected result
          matching_c_generic_to_type, matching_c_approx_to_type, matching_c_exact_to_type = \
              self.get_all_conversion_chains_to_type(to_type=desired_type)
          all_matching_converters = matching_c_generic_to_type + matching_c_approx_to_type + matching_c_exact_to_type
  
          # (3) combine both (parser + conversion chain), and append to the appropriate list depending on the match
          # -- (a) first Parsers matching EXT (not type) + Converters matching their type
          # for all parsers able to parse this extension, and for all the types they support
          #
          # (we have to reverse the list because now we want 'preferred first'. Indeed we wish to prepend to the match
          # lists in order not to hide the parser direct matches)
          matching_p_generic_with_approx_chain, matching_p_approx_with_approx_chain, matching_p_exact_with_approx_chain\
              = [], [], []
          for parser in reversed(parsers_to_complete_with_converters):
              for typ in parser.supported_types:
                  match_results = self._complete_parsers_with_converters(parser, typ, desired_type,
                                                                         matching_c_generic_to_type,
                                                                         matching_c_approx_to_type,
                                                                         matching_c_exact_to_type)
                  # prepend the existing lists with the new match
                  matching_p_generic = match_results[1] + matching_p_generic
                  matching_p_approx = match_results[3] + matching_p_approx
                  matching_p_exact = match_results[5] + matching_p_exact
  
                  # store the approximate matchs in the separate lists
                  matching_p_generic_with_approx_chain = match_results[0] + matching_p_generic_with_approx_chain
                  matching_p_approx_with_approx_chain = match_results[2] + matching_p_approx_with_approx_chain
                  matching_p_exact_with_approx_chain = match_results[4] + matching_p_exact_with_approx_chain
  
          # finally prepend the approximate match lists
          matching_p_generic = matching_p_generic_with_approx_chain + matching_p_generic
          matching_p_approx = matching_p_approx_with_approx_chain + matching_p_approx
          matching_p_exact = matching_p_exact_with_approx_chain + matching_p_exact
  
          # -- (b) then parsers that do not match at all (not the file extension nor the type): we can find parsing chains
          # that make them at least match the type
          #
          # (we have to reverse it because it was 'best last', now it will be 'best first')
          for parser in reversed(no_match):
              for typ in parser.supported_types:
                  for converter in reversed(all_matching_converters):
                      # if converter is able to source from this parser
                      if converter.is_able_to_convert(self.is_strict, from_type=typ, to_type=desired_type):
                          if ParsingChain.are_worth_chaining(parser, typ, converter):
                              # insert it at the beginning since it should have less priority
                              no_ext_match_but_type_match.insert(0, ParsingChain(parser, converter, strict=self.is_strict,
                                                                                 base_parser_chosen_dest_type=typ))
  
          # Finally sort by chain length
          matching_p_generic = sorted(matching_p_generic, key=len, reverse=True)
          matching_p_approx = sorted(matching_p_approx, key=len, reverse=True)
          matching_p_exact = sorted(matching_p_exact, key=len, reverse=True)
  
          # Return
          return (matching_p_generic, matching_p_approx, matching_p_exact), no_type_match_but_ext_match, \
                 no_ext_match_but_type_match, no_match