def _replace_deferred(self, arg, context):
    """This replaces all deferred nodes (UnboundVariables and _DeferredLayers).

    If arg is a sequence or a dict, then it's deferred values are also replaced.

    Args:
      arg: The argument to replace. If a list or a dict, then all items are also
        replaced.
      context: The context for this replacement.
    Returns:
      The replaced values or arg if it is not a deferred node.
    """
    if isinstance(arg, UnboundVariable):
      return context[arg]
    elif isinstance(arg, _DeferredLayer):
      # pylint: disable=protected-access
      return arg._construct(context)
    elif isinstance(arg, tuple):
      return tuple((self._replace_deferred(x, context) for x in arg))
    elif (isinstance(arg, collections.Sequence) and
          not isinstance(arg, six.string_types)):
      return [self._replace_deferred(x, context) for x in arg]
    elif isinstance(arg, collections.Mapping):
      return {k: self._replace_deferred(v, context)
              for k, v in six.iteritems(arg)}
    else:
      return arg