docs: def _create_instance(self, cls, args, ref=None):
          """
          Returns an instance of `cls` with `args` passed as arguments.
  
          Recursively inspects `args` to create nested objects and functions as
          necessary.
  
          `cls` will only be considered only if it's an object we track
           (i.e.: troposphere objects).
  
          If `cls` has a `props` attribute, nested properties will be
           instanciated as troposphere Property objects as necessary.
  
          If `cls` is a list and contains a single troposphere type, the
           returned value will be a list of instances of that type.
          """
          if isinstance(cls, Sequence):
              if len(cls) == 1:
                  # a list of 1 type means we must provide a list of such objects
                  if (isinstance(args, basestring) or
                          not isinstance(args, Sequence)):
                      args = [args]
                  return [self._create_instance(cls[0], v) for v in args]
  
          if isinstance(cls, Sequence)\
             or cls not in self.inspect_members.union(self._custom_members):
              # this object doesn't map to any known object. could be a string
              # or int, or a Ref... or a list of types such as
              # [basestring, FindInMap, Ref] or maybe a
              # validator such as `integer` or `port_range`
              return self._convert_definition(args)
  
          elif issubclass(cls, AWSHelperFn):
              # special handling for functions, we want to handle it before
              # entering the other conditions.
              try:
                  if issubclass(cls, Tags):
                      arg_dict = {}
                      for d in args:
                          arg_dict[d['Key']] = d['Value']
                      return cls(arg_dict)
  
                  if (isinstance(args, Sequence) and
                          not isinstance(args, basestring)):
                      return cls(*self._convert_definition(args))
  
                  if issubclass(cls, autoscaling.Metadata):
                      return self._generate_autoscaling_metadata(cls, args)
  
                  if issubclass(cls, Export):
                      return cls(args['Name'])
  
                  args = self._convert_definition(args)
                  if isinstance(args, Ref) and issubclass(cls, Ref):
                      # watch out for double-refs...
                      # this can happen if an object's .props has 'Ref'
                      # as the expected type (which is wrong and should be
                      # changed to basestring!)
                      return args
  
                  return cls(args)
  
              except TypeError as ex:
                  if '__init__() takes exactly' not in ex.message:
                      raise
                  # special AWSHelperFn typically take lowercased parameters,
                  # but templates use uppercase. for this reason we cannot
                  # map to most of them, so we fallback with a generic one.
                  # this might not work for all types if they do extra
                  # processing in their init routine
                  return GenericHelperFn(args)
  
          elif isinstance(args, Mapping):
              # we try to build as many troposphere objects as we can by
              # inspecting its type validation metadata
              kwargs = {}
              kwargs.update(args)
              for prop_name in getattr(cls, 'props', []):
                  if prop_name not in kwargs:
                      continue  # the user did not specify this value; skip it
                  expected_type = cls.props[prop_name][0]
  
                  if (isinstance(expected_type, Sequence) or
                          expected_type in self.inspect_members):
                      kwargs[prop_name] = self._create_instance(
                          expected_type, kwargs[prop_name], prop_name)
                  else:
                      kwargs[prop_name] = self._convert_definition(
                          kwargs[prop_name], prop_name)
  
              args = self._convert_definition(kwargs)
              if isinstance(args, Ref):
                  # use the returned ref instead of creating a new object
                  return args
              if isinstance(args, AWSHelperFn):
                  return self._convert_definition(kwargs)
              assert isinstance(args, Mapping)
              return cls(title=ref, **args)
  
          return cls(self._convert_definition(args))