docs: def _create_all_new_chains(self, converter) -> Tuple[List[Converter], List[Converter],
                                                           List[Converter], List[Converter]]:
          """
          Creates all specific and generic chains that may be built by adding this converter to the existing chains.
  
          :param converter:
          :return: generic_chains, generic_nonstrict_chains, specific_chains, specific_nonstrict_chains
          """
  
          specific_chains, specific_nonstrict_chains, generic_chains, generic_nonstrict_chains = [], [], [], []
  
          if converter.is_generic():
              # the smaller chain : the singleton :)
              generic_chains.append(ConversionChain(initial_converters=[converter], strict_chaining=True))
          else:
              specific_chains.append(ConversionChain(initial_converters=[converter], strict_chaining=True))
  
  
          # 1) create new specific chains by adding this converter at the beginning or end of all *non-generic* ones
          # -- non-strict
          new_c_at_end_ns = []
          new_c_at_beginning_ns = []
          if not self.strict:
              # then there are non-strict chains already. Try to connect to them
              for existing_specific_nonstrict in self._specific_non_strict_conversion_chains:
                  if converter.can_be_appended_to(existing_specific_nonstrict, strict=False):
                      if ConversionChain.are_worth_chaining(existing_specific_nonstrict, converter):
                          new_c_at_end_ns.append(ConversionChain.chain(existing_specific_nonstrict, converter,
                                                                       strict=False))
                  if existing_specific_nonstrict.can_be_appended_to(converter, strict=False):
                      if ConversionChain.are_worth_chaining(converter, existing_specific_nonstrict):
                          new_c_at_beginning_ns.append(ConversionChain.chain(converter, existing_specific_nonstrict,
                                                                             strict=False))
  
          # -- strict
          new_c_at_end = []
          new_c_at_beginning = []
          for existing_specific in self._specific_conversion_chains:
              # first try *strict* mode
              if converter.can_be_appended_to(existing_specific, strict=True):
                  if ConversionChain.are_worth_chaining(existing_specific, converter):
                      new_c_at_end.append(ConversionChain.chain(existing_specific, converter, strict=True))
              elif (not self.strict) and converter.can_be_appended_to(existing_specific, strict=False):
                  if ConversionChain.are_worth_chaining(existing_specific, converter):
                      new_c_at_end_ns.append(ConversionChain.chain(existing_specific, converter, strict=False))
  
              if existing_specific.can_be_appended_to(converter, strict=True):
                  if ConversionChain.are_worth_chaining(converter, existing_specific):
                      # TODO this is where when chaining a generic to a specific, we would actually have to restrict it
                      # note: but maybe we dont care since now this is checked and prevented in the convert() method
                      new_c_at_beginning.append(ConversionChain.chain(converter, existing_specific, strict=True))
              elif (not self.strict) and existing_specific.can_be_appended_to(converter, strict=False):
                  if ConversionChain.are_worth_chaining(converter, existing_specific):
                      # TODO this is where when chaining a generic to a specific, we would actually have to restrict it
                      # note: but maybe we dont care since now this is checked and prevented in the convert() method
                      new_c_at_beginning_ns.append(ConversionChain.chain(converter, existing_specific, strict=False))
  
          # append to the right list depending on the nature of this converter
          if converter.is_generic():
              generic_chains += new_c_at_end
              generic_nonstrict_chains += new_c_at_end_ns
          else:
              specific_chains += new_c_at_end
              specific_nonstrict_chains += new_c_at_end_ns
          # common for both types
          specific_chains += new_c_at_beginning
          specific_nonstrict_chains += new_c_at_beginning_ns
  
          # by combining all created chains into a big one
          for a in new_c_at_end:
              for b in new_c_at_beginning:
                  b_ = b.remove_first()
                  if b_.can_be_appended_to(a, strict=True):
                      if ConversionChain.are_worth_chaining(a, b_):
                          specific_chains.append(ConversionChain.chain(a, b_, strict=True))
              for b in new_c_at_beginning_ns:
                  b_ = b.remove_first()
                  if b_.can_be_appended_to(a, strict=False):
                      if ConversionChain.are_worth_chaining(a, b_):
                          specific_nonstrict_chains.append(ConversionChain.chain(a, b_, strict=False))
          for a in new_c_at_end_ns:
              for b in (new_c_at_beginning_ns + new_c_at_beginning):
                  b_ = b.remove_first()
                  if b_.can_be_appended_to(a, strict=False):
                      if ConversionChain.are_worth_chaining(a, b_):
                          specific_nonstrict_chains.append(ConversionChain.chain(a, b_, strict=False))
  
          # by inserting this converter at the beginning of an existing *generic*
          if converter.is_generic():
              # we want to avoid chaining generic converters together
              pass
          else:
              new_c_at_beginning_generic = []
              new_c_at_beginning_generic_ns = []
              for existing_specific in self._generic_conversion_chains:
                  # start with strict
                  if existing_specific.can_be_appended_to(converter, strict=True):
                      if ConversionChain.are_worth_chaining(converter, existing_specific):
                          new_c_at_beginning_generic.append(ConversionChain.chain(converter, existing_specific,
                                                                                  strict=True))
                  elif (not self.strict) and existing_specific.can_be_appended_to(converter, strict=False):
                      if ConversionChain.are_worth_chaining(converter, existing_specific):
                          new_c_at_beginning_generic_ns.append(ConversionChain.chain(converter, existing_specific,
                                                                                     strict=False))
  
              for existing_specific_ns in self._generic_nonstrict_conversion_chains:
                  if existing_specific_ns.can_be_appended_to(converter, strict=False):
                      if ConversionChain.are_worth_chaining(converter, existing_specific_ns):
                          new_c_at_beginning_generic_ns.append(ConversionChain.chain(converter, existing_specific_ns,
                                                                                 strict=False))
              generic_chains += new_c_at_beginning_generic
              generic_nonstrict_chains += new_c_at_beginning_generic_ns
  
              # by combining specific and generic created chains into a big one
              for a in new_c_at_end:
                  for b in new_c_at_beginning_generic:
                      b_ = b.remove_first()
                      if b_.can_be_appended_to(a, strict=True):
                          if ConversionChain.are_worth_chaining(a, b_):
                              generic_chains.append(ConversionChain.chain(a, b_, strict=True))
                  for b in new_c_at_beginning_generic_ns:
                      b_ = b.remove_first()
                      if b_.can_be_appended_to(a, strict=False):
                          if ConversionChain.are_worth_chaining(a, b_):
                              generic_nonstrict_chains.append(ConversionChain.chain(a, b_, strict=False))
              for a in new_c_at_end_ns:
                  for b in (new_c_at_beginning_generic_ns + new_c_at_beginning_generic):
                      b_ = b.remove_first()
                      if b_.can_be_appended_to(a, strict=False):
                          if ConversionChain.are_worth_chaining(a, b_):
                              generic_nonstrict_chains.append(ConversionChain.chain(a, b_, strict=False))
  
          return generic_chains, generic_nonstrict_chains, specific_chains, specific_nonstrict_chains