class RxShamir {

  @Nonnull
  public Observable<Share> createShares(
      @Nonnull final BigInteger secret,
      @Nonnull final CreationScheme creationScheme) {
    
    checkNotNull(secret, "\'secret\' must not be null.");
    checkNotNull(creationScheme, "\'creationScheme\' must not be null.");
    
    final Single<Polynomial> polynomial = Observable
        .range(1, creationScheme.getRequiredShareCount() - 1)
        .flatMapSingle(index -> createRandomCoefficient(creationScheme.getPrime())
            .map(coefficient -> Pair.create(index, coefficient)))
        .startWith(Pair.create(0, secret))
        .collectInto(new HashMap<Integer, BigInteger>(), (map, pair) -> map.put(pair.getKey(), pair.getValue()))
        .map(Polynomial::new);
    
    final Observable<Share> shares = polynomial
        .flatMapObservable(polynomialVal -> Observable
            .range(1, creationScheme.getTotalShareCount())
            .map(index -> Pair.create(
                index,
                polynomialVal
                    .evaluateAt(BigInteger.valueOf(index))
                    .mod(creationScheme.getPrime())))
            .map(pair -> Share
                .builder()
                .setIndex(pair.getKey())
                .setValue(pair.getValue())
                .build()));
    
    return checkCreationInformation(secret, creationScheme).andThen(shares);
  }

  public  RxShamir(@Nonnull final SecureRandom random);

}