 {
   // XXX we should static_assert that SelectedIndices are unique and in the correct range
 
-  cudaStream_t stream = 0;
-
   // create a future to contain the outer argument
   using outer_arg_type = agency::detail::result_of_factory_t<OuterFactory>;
   auto outer_arg_future = agency::cuda::make_ready_future<outer_arg_type>(outer_factory());
 
   // join the events
-  agency::cuda::detail::event when_all_ready = agency::cuda::detail::when_all(stream, outer_arg_future.event(), agency::detail::get<TupleIndices>(tuple_of_futures).event()...);
+  agency::cuda::detail::stream stream;
+  agency::cuda::detail::event when_all_ready = agency::cuda::detail::when_all(stream.native_handle(), outer_arg_future.event(), agency::detail::get<TupleIndices>(tuple_of_futures).event()...);
 
   // get a view of the non-void futures
   auto view_of_non_void_futures = agency::detail::tuple_filter_view<value_type_is_not_void>(tuple_of_futures);

  //     we can't do that because that memory cannot be deallocated by a __device__ function
  // XXX we should implement a better memory allocator that can be used uniformly in __host__ & __device__ code

  return move_construct_result_from_tuple_of_futures(agency::detail::make_tuple_indices(view_of_selected_non_void_futures), when_all_execute_event, view_of_selected_non_void_futures);
}



    >...
  >
>
  move_construct_result(agency::cuda::detail::stream& stream, agency::cuda::detail::event& dependency, Pointer ptr, Pointers... ptrs)
{
  using result_type = agency::detail::when_all_result_t<
    agency::cuda::future<typename std::pointer_traits<Pointer>::element_type>,
