IDisposable key_correlator_zipN(DDS.DomainParticipant participant, int N)
    {
        var rx_square_reader =
        DDSObservable.FromKeyedTopic<string, ShapeTypeExtended>(participant, "Square", shape => shape.color);

        // The order of the keys is the same that of the Shapes Demo UI.
        var allkeys = new string[] { "PURPLE", "BLUE", "RED", "GREEN", "YELLOW", "CYAN", "MAGENTA", "ORANGE" };
        var nkeys = allkeys.Take(N);

        Console.Write("Averaging {0}: ", N);
        nkeys.Subscribe(Observer.Create<string>(key => Console.Write("{0} ", key)));
        Console.WriteLine();

        var color_observables =
          nkeys.Select(key => rx_square_reader.Where(sq => sq.Key == key));

        return
        Observable.Zip(color_observables)
              .Subscribe((IList<IGroupedObservable<string, ShapeTypeExtended>> key_list) =>
              {
                Observable.CombineLatest(key_list)
                          .Select((IList<ShapeTypeExtended> shapes) =>
                          {
                            var avg = new ShapeTypeExtended
                            {
                              x = 0,
                              y = 0,
                              color = "RED",
                              shapesize = 30
                            };

                            foreach (var shape in shapes)
                            {
                              avg.x += shape.x;
                              avg.y += shape.y;
                            }
                            avg.x /= shapes.Count;
                            avg.y /= shapes.Count;

                            return avg;
                          })
                          .Subscribe(triangle_writer);
              });
    }
 IDisposable instance_forward(DDS.DomainParticipant participant)
 {
     return DDSObservable.FromKeyedTopic<string, ShapeTypeExtended>
         (participant, "Square", shape => shape.color)
               .Subscribe(dds_instance =>
               {
                 ShapeTypeExtended key = new ShapeTypeExtended { color = dds_instance.Key };
                 DDS.InstanceHandle_t handle = DDS.InstanceHandle_t.HANDLE_NIL;
                 dds_instance.Subscribe(triangle_writer,
                                        () => triangle_writer.dispose(key, ref handle));
               });
 }
    IDisposable key_correlator_dynamic(DDS.DomainParticipant participant, IScheduler scheduler)
    {
        var rx_square_reader =
        DDSObservable.FromKeyedTopic<string, ShapeTypeExtended>(participant, "Square", shape => shape.color, scheduler);
        var triangleColor = "RED";

        return
          rx_square_reader
        .ActiveKeyScan(new { lastSub = Disposable.Empty },
            (seed, stream_list) =>
            {
              seed.lastSub.Dispose();
              if (stream_list.Count == 0)
              {
                var handle = DDS.InstanceHandle_t.HANDLE_NIL;
                triangle_writer.dispose(new ShapeTypeExtended { color = triangleColor }, ref handle);
                return new { lastSub = Disposable.Empty };
              }
              else
                return new
                {
                  lastSub =
                    Observable.CombineLatest(stream_list)
                              .Select((IList<ShapeTypeExtended> shapes) =>
                              {
                                var avg = new ShapeTypeExtended
                                {
                                  x = 0,
                                  y = 0,
                                  color = triangleColor,
                                  shapesize = 30
                                };

                                foreach (var shape in shapes)
                                {
                                  avg.x += shape.x;
                                  avg.y += shape.y;
                                }
                                avg.x /= shapes.Count;
                                avg.y /= shapes.Count;

                                return avg;
                              })
                              .Subscribe(triangle_writer)
                };
            })
        .Subscribe();
    }
    IDisposable collisions_combinelatest(DDS.DomainParticipant participant, IScheduler scheduler)
    {
        var rx_circle_reader =
        DDSObservable.FromTopic<ShapeTypeExtended>(participant, "Circle", Scheduler.Default);
        var rx_square_reader =
        DDSObservable.FromTopic<ShapeTypeExtended>(participant, "Square", Scheduler.Default);

        var dummy = new ShapeTypeExtended { color = "DUMMY" };

        return rx_circle_reader
              .ObserveOn(scheduler)
              .CombineLatest(rx_square_reader,
                             (circle, square) =>
                             {
                               if (distance(circle.x, circle.y, square.x, square.y) <= 30)
                                 return new ShapeTypeExtended
                                 {
                                   x = (square.x + circle.x) / 2,
                                   y = (square.y + circle.y) / 2,
                                   color = "RED",
                                   shapesize = 10
                                 };
                               else
                                 return dummy;
                             })
                 .Where(shape => shape.color != "DUMMY")
                 .Subscribe(triangle_writer);
    }