code: def foreach(origin=None, rel=None, target=None, attributes=None):
      '''
      Action function generator to compute a combination of links
      :return: Versa action function to do the actual work
      '''
      def _foreach(ctx):
          '''
          Versa action function utility to compute a list of values from a list of expressions
          :param ctx: Versa context used in processing (e.g. includes the prototype link)
          '''
          _origin = origin(ctx) if callable(origin) else origin
          _rel = rel(ctx) if callable(rel) else rel
          _target = target(ctx) if callable(target) else target
          _attributes = attributes(ctx) if callable(attributes) else attributes
          (o, r, t, a) = ctx.current_link
          o = [o] if _origin is None else (_origin if isinstance(_origin, list) else [_origin])
          r = [r] if _rel is None else (_rel if isinstance(_rel, list) else [_rel])
          t = [t] if _target is None else (_target if isinstance(_target, list) else [_target])
          a = [a] if _attributes is None else (_attributes if isinstance(_attributes, list) else [_attributes])
          return [ ctx.copy(current_link=(curr_o, curr_r, curr_t, curr_a))
                      for (curr_o, curr_r, curr_t, curr_a)
                      in itertools.product(o, r, t, a) ]
      return _foreach