public void demonstratePNCounter() {
   // #pncounter
   final Cluster node = Cluster.get(system);
   final PNCounter c0 = PNCounter.create();
   final PNCounter c1 = c0.increment(node, 1);
   final PNCounter c2 = c1.increment(node, 7);
   final PNCounter c3 = c2.decrement(node, 2);
   System.out.println(c3.value()); // 6
   // #pncounter
 }
  @Test
  public void demonstrateUpdateWithRequestContext() {
    probe = new JavaTestKit(system);

    // #update-request-context
    final Cluster node = Cluster.get(system);
    final ActorRef replicator = DistributedData.get(system).replicator();

    final WriteConsistency writeTwo = new WriteTo(2, Duration.create(3, SECONDS));
    final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");

    receive(
        ReceiveBuilder.match(
                String.class,
                a -> a.equals("increment"),
                a -> {
                  // incoming command to increase the counter
                  Optional<Object> reqContext = Optional.of(sender());
                  Replicator.Update<PNCounter> upd =
                      new Replicator.Update<PNCounter>(
                          counter1Key,
                          PNCounter.create(),
                          writeTwo,
                          reqContext,
                          curr -> curr.increment(node, 1));
                  replicator.tell(upd, self());
                })
            .match(
                UpdateSuccess.class,
                a -> a.key().equals(counter1Key),
                a -> {
                  ActorRef replyTo = (ActorRef) a.getRequest().get();
                  replyTo.tell("ack", self());
                })
            .match(
                UpdateTimeout.class,
                a -> a.key().equals(counter1Key),
                a -> {
                  ActorRef replyTo = (ActorRef) a.getRequest().get();
                  replyTo.tell("nack", self());
                })
            .build());

    // #update-request-context
  }
  @Test
  public void demonstrateUpdate() {
    probe = new JavaTestKit(system);

    // #update
    final Cluster node = Cluster.get(system);
    final ActorRef replicator = DistributedData.get(system).replicator();

    final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
    final Key<GSet<String>> set1Key = GSetKey.create("set1");
    final Key<ORSet<String>> set2Key = ORSetKey.create("set2");
    final Key<Flag> activeFlagKey = FlagKey.create("active");

    replicator.tell(
        new Replicator.Update<PNCounter>(
            counter1Key,
            PNCounter.create(),
            Replicator.writeLocal(),
            curr -> curr.increment(node, 1)),
        self());

    final WriteConsistency writeTo3 = new WriteTo(3, Duration.create(1, SECONDS));
    replicator.tell(
        new Replicator.Update<GSet<String>>(
            set1Key, GSet.create(), writeTo3, curr -> curr.add("hello")),
        self());

    final WriteConsistency writeMajority = new WriteMajority(Duration.create(5, SECONDS));
    replicator.tell(
        new Replicator.Update<ORSet<String>>(
            set2Key, ORSet.create(), writeMajority, curr -> curr.add(node, "hello")),
        self());

    final WriteConsistency writeAll = new WriteAll(Duration.create(5, SECONDS));
    replicator.tell(
        new Replicator.Update<Flag>(
            activeFlagKey, Flag.create(), writeAll, curr -> curr.switchOn()),
        self());
    // #update

    probe.expectMsgClass(UpdateSuccess.class);
    // #update-response1
    receive(
        ReceiveBuilder.match(
                UpdateSuccess.class,
                a -> a.key().equals(counter1Key),
                a -> {
                  // ok
                })
            .build());
    // #update-response1

    // #update-response2
    receive(
        ReceiveBuilder.match(
                UpdateSuccess.class,
                a -> a.key().equals(set1Key),
                a -> {
                  // ok
                })
            .match(
                UpdateTimeout.class,
                a -> a.key().equals(set1Key),
                a -> {
                  // write to 3 nodes failed within 1.second
                })
            .build());
    // #update-response2
  }