@Test
  public void reusingComponents() throws Exception {
    final Source<Integer, NotUsed> nestedSource =
        Source.single(0) // An atomic source
            .map(i -> i + 1) // an atomic processing stage
            .named("nestedSource"); // wraps up the current Source and gives it a name

    final Flow<Integer, Integer, NotUsed> nestedFlow =
        Flow.of(Integer.class)
            .filter(i -> i != 0) // an atomic processing stage
            .map(i -> i - 2) // another atomic processing stage
            .named("nestedFlow"); // wraps up the Flow, and gives it a name

    final Sink<Integer, NotUsed> nestedSink =
        nestedFlow
            .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow
            .named("nestedSink"); // wrap it up

    // #reuse
    // Create a RunnableGraph from our components
    final RunnableGraph<NotUsed> runnableGraph = nestedSource.to(nestedSink);

    // Usage is uniform, no matter if modules are composite or atomic
    final RunnableGraph<NotUsed> runnableGraph2 =
        Source.single(0).to(Sink.fold(0, (acc, i) -> acc + i));
    // #reuse
  }
  @Test
  public void nonNestedFlow() throws Exception {
    // #non-nested-flow
    Source.single(0)
        .map(i -> i + 1)
        .filter(i -> i != 0)
        .map(i -> i - 2)
        .to(Sink.fold(0, (acc, i) -> acc + i));

    // ... where is the nesting?
    // #non-nested-flow
  }
  @Test
  public void materializedValues() throws Exception {
    // #mat-combine-1
    // Materializes to Promise<BoxedUnit>                                     (red)
    final Source<Integer, CompletableFuture<Optional<Integer>>> source = Source.<Integer>maybe();

    // Materializes to BoxedUnit                                              (black)
    final Flow<Integer, Integer, NotUsed> flow1 = Flow.of(Integer.class).take(100);

    // Materializes to Promise<Option<>>                                     (red)
    final Source<Integer, CompletableFuture<Optional<Integer>>> nestedSource =
        source.viaMat(flow1, Keep.left()).named("nestedSource");
    // #mat-combine-1

    // #mat-combine-2
    // Materializes to BoxedUnit                                              (orange)
    final Flow<Integer, ByteString, NotUsed> flow2 =
        Flow.of(Integer.class).map(i -> ByteString.fromString(i.toString()));

    // Materializes to Future<OutgoingConnection>                             (yellow)
    final Flow<ByteString, ByteString, CompletionStage<OutgoingConnection>> flow3 =
        Tcp.get(system).outgoingConnection("localhost", 8080);

    // Materializes to Future<OutgoingConnection>                             (yellow)
    final Flow<Integer, ByteString, CompletionStage<OutgoingConnection>> nestedFlow =
        flow2.viaMat(flow3, Keep.right()).named("nestedFlow");
    // #mat-combine-2

    // #mat-combine-3
    // Materializes to Future<String>                                         (green)
    final Sink<ByteString, CompletionStage<String>> sink =
        Sink.<String, ByteString>fold("", (acc, i) -> acc + i.utf8String());

    // Materializes to Pair<Future<OutgoingConnection>, Future<String>>       (blue)
    final Sink<Integer, Pair<CompletionStage<OutgoingConnection>, CompletionStage<String>>>
        nestedSink = nestedFlow.toMat(sink, Keep.both());
    // #mat-combine-3

    // #mat-combine-4b
    // Materializes to Future<MyClass>                                        (purple)
    final RunnableGraph<CompletionStage<MyClass>> runnableGraph =
        nestedSource.toMat(nestedSink, Combiner::f);
    // #mat-combine-4b
  }
  @Test
  public void attributes() throws Exception {
    // #attributes-inheritance
    final Source<Integer, NotUsed> nestedSource =
        Source.single(0).map(i -> i + 1).named("nestedSource"); // Wrap, no inputBuffer set

    final Flow<Integer, Integer, NotUsed> nestedFlow =
        Flow.of(Integer.class)
            .filter(i -> i != 0)
            .via(
                Flow.of(Integer.class)
                    .map(i -> i - 2)
                    .withAttributes(Attributes.inputBuffer(4, 4))) // override
            .named("nestedFlow"); // Wrap, no inputBuffer set

    final Sink<Integer, NotUsed> nestedSink =
        nestedFlow
            .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow
            .withAttributes(
                Attributes.name("nestedSink").and(Attributes.inputBuffer(3, 3))); // override
    // #attributes-inheritance
  }
  @Test
  public void nestedFlow() throws Exception {
    // #nested-flow
    final Source<Integer, NotUsed> nestedSource =
        Source.single(0) // An atomic source
            .map(i -> i + 1) // an atomic processing stage
            .named("nestedSource"); // wraps up the current Source and gives it a name

    final Flow<Integer, Integer, NotUsed> nestedFlow =
        Flow.of(Integer.class)
            .filter(i -> i != 0) // an atomic processing stage
            .map(i -> i - 2) // another atomic processing stage
            .named("nestedFlow"); // wraps up the Flow, and gives it a name

    final Sink<Integer, NotUsed> nestedSink =
        nestedFlow
            .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow
            .named("nestedSink"); // wrap it up

    // Create a RunnableGraph
    final RunnableGraph<NotUsed> runnableGraph = nestedSource.to(nestedSink);
    // #nested-flow
  }