`Streams.concat` functions as expected when its arguments are finite streams.
If we concat two streams: the first is finite and the second is infinite, then obviously we get an infinite stream. But we can iterate over a limited number of elements. This is the scenario where the program hangs.

```java
import com.google.common.collect.Streams;

import java.util.PrimitiveIterator;
import java.util.stream.IntStream;

public class MyMain {
    public static void main(String[] args) {

        IntStream stream123 = IntStream.of(1, 2, 3);
        IntStream stream4567 = IntStream.of(4, 5, 6, 7);
        IntStream stream1234567 = Streams.concat(stream123, stream4567);
        printFirstElements(stream1234567, 5);
        // output:
        // 1
        // 2
        // 3
        // 4
        // 5



        IntStream streamInfinite99 = IntStream.generate(() -> 99);
        printFirstElements(streamInfinite99, 3);
        // output:
        // 99
        // 99
        // 99

        IntStream stream123AndThenInfinite77 = Streams.concat(IntStream.of(1, 2, 3), IntStream.generate(() -> 77));
        printFirstElements(stream123AndThenInfinite77, 5);
        // output:
        // 1
        // 2
        // 3
        // and then program hangs
    }

    static void printFirstElements(IntStream stream, int count) {
        int counter = 0;
        for (PrimitiveIterator.OfInt iterator = stream.iterator(); iterator.hasNext(); ) {
            Integer next = iterator.next();
            System.out.println(next);
            counter++;
            if (counter == count) {
                break;
            }
        }
    }
}
```
package com.google.common.base;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
 * Useful suppliers.
 *
 * <p>All methods return serializable suppliers as long as they're given serializable parameters.
 *
 * @author Laurence Gonsalves
 * @author Harry Heymann
 * @since 2.0
 */
@GwtCompatible
public final class Suppliers {
  private Suppliers() {}
  /**
   * Returns a new supplier which is the composition of the provided function and supplier. In other
   * words, the new supplier's value will be computed by retrieving the value from {@code supplier},
   * and then applying {@code function} to that value. Note that the resulting supplier will not
   * call {@code supplier} or invoke {@code function} until it is called.
   */
  public static <F, T> Supplier<T> compose(Function<? super F, T> function, Supplier<F> supplier) {
    return new SupplierComposition<>(function, supplier);
  }
  private static class SupplierComposition<F, T> implements Supplier<T>, Serializable {