private static <T> Arbitrary<List<T>> withDuplicates(
        final int maxDuplicates,
        final ListArbitrary<T> arbitrary)
    {
        return Combinators.combine(
            Arbitraries.integers().list().ofMaxSize(2 * maxDuplicates),
            arbitrary
        ).as((positions, originalItems) ->
        {
            if (originalItems.isEmpty())
            {
                return originalItems;
            }

            final List<T> items = new ArrayList<>(originalItems);
            T itemToDupe = null;
            int j = 0;

            for (final int position : positions)
            {
                j += position;
                j %= items.size();
                j = Math.abs(j);
                if (itemToDupe == null)
                {
                    itemToDupe = items.get(j);
                }
                else
                {
                    items.add(j, itemToDupe);
                    itemToDupe = null;
                }
            }

            return items;
        });
    }
This combinator adds duplicates to an arbitrary list. We prefer this to JQwik's built-in functionality,
as that is inefficient and dominates test runs.
<p>
This method works by generating a list of integers, which represent, in an alternating manner,
the number of items to skip before <i>selecting</i> an item to duplicate
and the number of items to skip before <i>inserting</i> the duplicate.

@param maxDuplicates the maximum number of duplicates to add
@param arbitrary     the arbitrary list to duplicate items in
@param <T>           the type of the list
@return an arbitrary list with duplicates
sbe-tool/src/propertyTest/java/uk/co/real_logic/sbe/properties/arbitraries/SbeArbitraries.java