@Override
    public ICardinality merge(ICardinality... estimators) throws CardinalityMergeException {
        if (estimators == null) {
            return mergeEstimators(this);
        }

        CountThenEstimate[] all = Arrays.copyOf(estimators, estimators.length + 1, CountThenEstimate[].class);
        all[all.length - 1] = this;
        return mergeEstimators(all);
    }
@Test
    public void testMerge() throws CardinalityMergeException {
        int numToMerge = 10;
        int tippingPoint = 100;
        int cardinality = 1000;

        CountThenEstimate[] ctes = new CountThenEstimate[numToMerge];

        for (int i = 0; i < numToMerge; i++) {
            ctes[i] = new CountThenEstimate(tippingPoint, AdaptiveCounting.Builder.obyCount(100000));
            for (int j = 0; j < tippingPoint - 1; j++) {
                ctes[i].offer(Math.random());
            }
        }

        int expectedCardinality = numToMerge * (tippingPoint - 1);
        long mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
        double error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
        assertEquals(0.01, error, 0.01);

        for (int i = 0; i < numToMerge / 2; i++) {
            for (int j = tippingPoint - 1; j < cardinality; j++) {
                ctes[i].offer(Math.random());
            }
        }

        expectedCardinality = (numToMerge / 2) * (cardinality + tippingPoint - 1);
        mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
        error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
        assertEquals(0.01, error, 0.01);


        for (int i = numToMerge / 2; i < numToMerge; i++) {
            for (int j = tippingPoint - 1; j < cardinality; j++) {
                ctes[i].offer(Math.random());
            }
        }

        expectedCardinality = numToMerge * cardinality;
        mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
        error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
        assertEquals(0.01, error, 0.01);


    }