@Nonnull
    public static <T> AggregateOperation1<T, LongDoubleAccumulator, Double> averagingDouble(
            @Nonnull ToDoubleFunctionEx<? super T> getDoubleValueFn
    ) {
        checkSerializable(getDoubleValueFn, "getDoubleValueFn");
        // count == accumulator.value1
        // sum == accumulator.value2
        return AggregateOperation
                .withCreate(LongDoubleAccumulator::new)
                .andAccumulate((LongDoubleAccumulator a, T item) -> {
                    // a bit faster check than in addExact, specialized for increment
                    if (a.getLong() == Long.MAX_VALUE) {
                        throw new ArithmeticException("Counter overflow");
                    }
                    a.setLong(a.getLong() + 1);
                    a.setDouble(a.getDouble() + getDoubleValueFn.applyAsDouble(item));
                })
                .andCombine((a1, a2) -> {
                    a1.setLong(Math.addExact(a1.getLong(), a2.getLong()));
                    a1.setDouble(a1.getDouble() + a2.getDouble());
                })
                .andDeduct((a1, a2) -> {
                    a1.setLong(Math.subtractExact(a1.getLong(), a2.getLong()));
                    a1.setDouble(a1.getDouble() - a2.getDouble());
                })
                .andExportFinish(a -> a.getDouble() / a.getLong());
    }
@Test
    public void when_averagingDouble_tooManyItems_then_exception() {
        // Given
        AggregateOperation1<Double, LongDoubleAccumulator, Double> aggrOp = averagingDouble(Double::doubleValue);
        LongDoubleAccumulator acc = new LongDoubleAccumulator(Long.MAX_VALUE, 0.0d);


        // When
        BiConsumerEx<? super LongDoubleAccumulator, ? super Double> biConsumerEx = aggrOp.accumulateFn();
        assertThrows(ArithmeticException.class, () -> biConsumerEx.accept(acc, 0.0d));
    }