docs: def chain(first_converter, second_converter, strict: bool):
          """
          Utility method to chain two converters. If any of them is already a ConversionChain, this method "unpacks" it
          first. Note: the created conversion chain is created with the provided 'strict' flag, that may be different
          from the ones of the converters (if compliant). For example you may chain a 'strict' chain with a 'non-strict'
          chain, to produce a 'non-strict' chain.
  
          :param first_converter:
          :param second_converter:
          :param strict:
          :return:
          """
          if isinstance(first_converter, ConversionChain):
              if isinstance(second_converter, ConversionChain):
                  # BOTH are chains
                  if (first_converter.strict == strict) and (second_converter.strict == strict):
                      return first_converter.add_conversion_steps(second_converter._converters_list)
                  else:
                      if not strict:
                          # create a non-strict chain
                          return ConversionChain(initial_converters=first_converter._converters_list,
                                                 strict_chaining=False) \
                              .add_conversion_steps(second_converter._converters_list)
                      else:
                          raise ValueError('Trying to chain conversion chains with different strict modes than expected')
  
              else:
                  # FIRST is a chain
                  if strict == first_converter.strict:
                      return first_converter.add_conversion_step(second_converter)
                  else:
                      if not strict:
                          # create a non-strict chain
                          return ConversionChain(initial_converters=[second_converter], strict_chaining=False) \
                              .insert_conversion_steps_at_beginning(first_converter._converters_list)
                      else:
                          raise ValueError('Trying to chain after a conversion chain that has different strict mode than '
                                           'expected')
  
          else:
              if isinstance(second_converter, ConversionChain):
                  # SECOND is a chain
                  if strict == second_converter.strict:
                      return second_converter.insert_conversion_step_at_beginning(first_converter)
                  else:
                      if not strict:
                          # create a non-strict chain
                          return ConversionChain(initial_converters=[first_converter], strict_chaining=False) \
                              .add_conversion_steps(second_converter._converters_list)
                      else:
                          raise ValueError(
                              'Trying to chain before a conversion chain that has different strict mode than '
                              'expected')
              else:
                  # Neither is a chain
                  return ConversionChain([first_converter, second_converter], strict)