All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fj.test.Coarbitrary Maven / Gradle / Ivy

package fj.test;

import fj.*;

import static fj.Function.curry;
import static fj.P.p;

import fj.data.*;

import static fj.data.Array.array;
import static fj.data.List.fromString;
import static fj.data.List.nil;

import static fj.test.Variant.variant;

import static java.lang.Double.doubleToRawLongBits;
import static java.lang.Float.floatToRawIntBits;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Properties;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;

/**
 * Transforms a type and a generator to produce a new generator. This function is used to generate
 * {@link Arbitrary arbitrary} functions.
 *
 * @version %build.number%
 */
public abstract class Coarbitrary {
  /**
   * Transforms the given value and generator to a new generator with a high probability of being
   * independent.
   *
   * @param a The value to produce the generator from.
   * @param g The generator to produce the new generator from.
   * @return A new generator with a high probability of being independent.
   */
  public abstract  Gen coarbitrary(A a, Gen g);


  /**
   * A curried version of {@link #coarbitrary(Object, Gen)}.
   *
   * @param a The value to produce the generator from.
   * @return A curried version of {@link #coarbitrary(Object, Gen)}.
   */
  public final  F, Gen> coarbitrary(final A a) {
    return new F, Gen>() {
      public Gen f(final Gen g) {
        return coarbitrary(a, g);
      }
    };
  }

  /**
   * Composes the given function with this coarbitrary to produce a new coarbitrary.
   *
   * @param f The function to compose.
   * @return A new coarbitrary composed with the given function.
   */
  public final  Coarbitrary compose(final F f) {
    return new Coarbitrary() {
      public  Gen coarbitrary(final B b, final Gen g) {
        return Coarbitrary.this.coarbitrary(f.f(b), g);
      }
    };
  }

  /**
   * Contra-maps this coarbitrary using the given function.
   *
   * @param f The function to co-map with.
   * @return A contra-mapped coarbitrary.
   */
  public final  Coarbitrary contramap(final F f) {
    return new Coarbitrary() {
      public  Gen coarbitrary(final B b, final Gen g) {
        return Coarbitrary.this.coarbitrary(f.f(b), g);
      }
    };
  }

  /**
   * A coarbitrary for a function.
   *
   * @param a An arbitrary for the domain of the function.
   * @param c A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function.
   */
  public static  Coarbitrary> coarbF(final Arbitrary a, final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F f, final Gen g) {
        return a.gen.bind(new F>() {
          public Gen f(final A a) {
            return c.coarbitrary(f.f(a), g);
          }
        });
      }
    };
  }

  /**
   * A coarbitrary for a function-2.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-2.
   */
  public static  Coarbitrary> coarbF2(final Arbitrary aa, final Arbitrary ab,
                                                           final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F2 f, final Gen g) {
        return coarbF(aa, coarbF(ab, c)).coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-3.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-3.
   */
  public static  Coarbitrary> coarbF3(final Arbitrary aa, final Arbitrary ab,
                                                                 final Arbitrary ac, final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F3 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, c))).coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-4.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param ad An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-4.
   */
  public static  Coarbitrary> coarbF4(final Arbitrary aa, final Arbitrary ab,
                                                                       final Arbitrary ac, final Arbitrary ad,
                                                                       final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F4 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, coarbF(ad, c)))).coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-5.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param ad An arbitrary for part of the domain of the function.
   * @param ae An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-5.
   */
  public static  Coarbitrary> coarbF5(final Arbitrary aa,
                                                                               final Arbitrary ab,
                                                                               final Arbitrary ac,
                                                                               final Arbitrary ad,
                                                                               final Arbitrary ae,
                                                                               final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F5 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, coarbF(ad, coarbF(ae, c))))).coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-6.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param ad An arbitrary for part of the domain of the function.
   * @param ae An arbitrary for part of the domain of the function.
   * @param af An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-6.
   */
  public static  Coarbitrary> coarbF6(final Arbitrary aa,
                                                                                     final Arbitrary ab,
                                                                                     final Arbitrary ac,
                                                                                     final Arbitrary ad,
                                                                                     final Arbitrary ae,
                                                                                     final Arbitrary af,
                                                                                     final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F6 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, coarbF(ad, coarbF(ae, coarbF(af, c)))))).coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-7.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param ad An arbitrary for part of the domain of the function.
   * @param ae An arbitrary for part of the domain of the function.
   * @param af An arbitrary for part of the domain of the function.
   * @param ag An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-7.
   */
  public static  Coarbitrary> coarbF7(final Arbitrary aa,
                                                                                           final Arbitrary ab,
                                                                                           final Arbitrary ac,
                                                                                           final Arbitrary ad,
                                                                                           final Arbitrary ae,
                                                                                           final Arbitrary af,
                                                                                           final Arbitrary ag,
                                                                                           final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F7 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, coarbF(ad, coarbF(ae, coarbF(af, coarbF(ag, c)))))))
            .coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for a function-8.
   *
   * @param aa An arbitrary for part of the domain of the function.
   * @param ab An arbitrary for part of the domain of the function.
   * @param ac An arbitrary for part of the domain of the function.
   * @param ad An arbitrary for part of the domain of the function.
   * @param ae An arbitrary for part of the domain of the function.
   * @param af An arbitrary for part of the domain of the function.
   * @param ag An arbitrary for part of the domain of the function.
   * @param ah An arbitrary for part of the domain of the function.
   * @param c  A coarbitrary for the codomain of the function.
   * @return A coarbitrary for a function-8.
   */
  public static  Coarbitrary> coarbF8(final Arbitrary aa,
                                                                                                 final Arbitrary ab,
                                                                                                 final Arbitrary ac,
                                                                                                 final Arbitrary ad,
                                                                                                 final Arbitrary ae,
                                                                                                 final Arbitrary af,
                                                                                                 final Arbitrary ag,
                                                                                                 final Arbitrary ah,
                                                                                                 final Coarbitrary c) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final F8 f, final Gen g) {
        return coarbF(aa, coarbF(ab, coarbF(ac, coarbF(ad, coarbF(ae, coarbF(af, coarbF(ag, coarbF(ah, c))))))))
            .coarbitrary(curry(f), g);
      }
    };
  }

  /**
   * A coarbitrary for booleans.
   */
  public static final Coarbitrary coarbBoolean = new Coarbitrary() {
    public  Gen coarbitrary(final Boolean b, final Gen g) {
      return variant(b ? 0 : 1, g);
    }
  };

  /**
   * A coarbitrary for integers.
   */
  public static final Coarbitrary coarbInteger = new Coarbitrary() {
    public  Gen coarbitrary(final Integer i, final Gen g) {
      return variant(i >= 0 ? 2 * i : -2 * i + 1, g);
    }
  };

  /**
   * A coarbitrary for bytes.
   */
  public static final Coarbitrary coarbByte = new Coarbitrary() {
    public  Gen coarbitrary(final Byte b, final Gen g) {
      return variant(b >= 0 ? 2 * b : -2 * b + 1, g);
    }
  };

  /**
   * A coarbitrary for shorts.
   */
  public static final Coarbitrary coarbShort = new Coarbitrary() {
    public  Gen coarbitrary(final Short s, final Gen g) {
      return variant(s >= 0 ? 2 * s : -2 * s + 1, g);
    }
  };

  /**
   * A coarbitrary for longs.
   */
  public static final Coarbitrary coarbLong = new Coarbitrary() {
    public  Gen coarbitrary(final Long l, final Gen g) {
      return variant(l >= 0L ? 2L * l : -2L * l + 1L, g);
    }
  };

  /**
   * A coarbitrary for characters.
   */
  public static final Coarbitrary coarbCharacter = new Coarbitrary() {
    public  Gen coarbitrary(final Character c, final Gen g) {
      return variant(c << 1, g);
    }
  };

  /**
   * A coarbitrary for floats.
   */
  public static final Coarbitrary coarbFloat = new Coarbitrary() {
    public  Gen coarbitrary(final Float f, final Gen g) {
      return coarbInteger.coarbitrary(floatToRawIntBits(f), g);
    }
  };

  /**
   * A coarbitrary for doubles.
   */
  public static final Coarbitrary coarbDouble = new Coarbitrary() {
    public  Gen coarbitrary(final Double d, final Gen g) {
      return coarbLong.coarbitrary(doubleToRawLongBits(d), g);
    }
  };

  /**
   * A coarbitrary for the optional value.
   *
   * @param ca A coarbitrary for the type of the optional value.
   * @return A coarbitrary for the optional value.
   */
  public static  Coarbitrary> coarbOption(final Coarbitrary ca) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final Option o, final Gen g) {
        return o.isNone() ? variant(0, g) : variant(1, ca.coarbitrary(o.some(), g));
      }
    };
  }

  /**
   * A coarbitrary for the disjoint union.
   *
   * @param ca A coarbitrary for one side of the disjoint union.
   * @param cb A coarbitrary for one side of the disjoint union.
   * @return A coarbitrary for the disjoint union.
   */
  public static  Coarbitrary> coarbEither(final Coarbitrary ca, final Coarbitrary cb) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final Either e, final Gen g) {
        return e.isLeft() ?
            variant(0, ca.coarbitrary(e.left().value(), g)) :
            variant(1, cb.coarbitrary(e.right().value(), g));
      }
    };
  }

  /**
   * A coarbitrary for lists.
   *
   * @param ca A coarbitrary for the elements of the list.
   * @return A coarbitrary for lists.
   */
  public static  Coarbitrary> coarbList(final Coarbitrary ca) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final List as, final Gen g) {
        return as.isEmpty() ?
            variant(0, g) :
            variant(1, ca.coarbitrary(as.head(), coarbitrary(as.tail(), g)));
      }
    };
  }

  /**
   * A coarbitrary for strings.
   */
  public static final Coarbitrary coarbString = new Coarbitrary() {
    public  Gen coarbitrary(final String s, final Gen g) {
      return coarbList(coarbCharacter).coarbitrary(fromString(s), g);
    }
  };

  /**
   * A coarbitrary for string buffers.
   */
  public static final Coarbitrary coarbStringBuffer = new Coarbitrary() {
    public  Gen coarbitrary(final StringBuffer s, final Gen g) {
      return coarbString.coarbitrary(s.toString(), g);
    }
  };

  /**
   * A coarbitrary for string builders.
   */
  public static final Coarbitrary coarbStringBuilder = new Coarbitrary() {
    public  Gen coarbitrary(final StringBuilder s, final Gen g) {
      return coarbString.coarbitrary(s.toString(), g);
    }
  };

  /**
   * A coarbitrary for streams.
   *
   * @param ca A coarbitrary for the elements of the stream.
   * @return A coarbitrary for streams.
   */
  public static  Coarbitrary> coarbStream(final Coarbitrary ca) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final Stream as, final Gen g) {
        return as.isEmpty() ?
            variant(0, g) :
            variant(1, ca.coarbitrary(as.head(), coarbitrary(as.tail()._1(), g)));
      }
    };
  }

  /**
   * A coarbitrary for the provided LcgRng
   * @return A coarbitrary for the provided LcgRng.
   */
  public static Coarbitrary coarbLcgRng() {
    return new Coarbitrary() {
      @Override
      public  Gen coarbitrary(LcgRng rng, Gen g) {
        long i = rng.getSeed();
        return variant(i >= 0 ? 2 * i : -2 * i + 1, g);
      }
    };
  }

  /**
   * A coarbitrary for state.
   */
  public static  Coarbitrary> coarbState(Arbitrary as, F2 f) {
    return new Coarbitrary>() {
      @Override
      public  Gen coarbitrary(State s1, Gen g) {
        return as.gen.bind(r -> {
          P2 p = s1.run(r);
          return variant(f.f(p._1(), p._2()), g);
        });
      }
    };
  }

  /**
   * A coarbitrary for arrays.
   *
   * @param ca A coarbitrary for the elements of the array.
   * @return A coarbitrary for arrays.
   */
  public static  Coarbitrary> coarbArray(final Coarbitrary ca) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final Array as, final Gen g) {
        return coarbList(ca).coarbitrary(as.toList(), g);
      }
    };
  }

  /**
   * A coarbitrary for throwables.
   *
   * @param cs A coarbitrary for the throwable message.
   * @return A coarbitrary for throwables.
   */
  public static Coarbitrary coarbThrowable(final Coarbitrary cs) {
    return cs.contramap(new F() {
      public String f(final Throwable t) {
        return t.getMessage();
      }
    });
  }

  /**
   * A coarbitrary for throwables.
   */
  public static final Coarbitrary coarbThrowable =
      coarbThrowable(coarbString);

  // BEGIN java.util

  /**
   * A coarbitrary for array lists.
   *
   * @param ca A coarbitrary for the elements of the array list.
   * @return A coarbitrary for array lists.
   */
  public static  Coarbitrary> coarbArrayList(final Coarbitrary ca) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final ArrayList as, final Gen g) {
        return coarbArray(ca).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for bit sets.
   */
  public static final Coarbitrary coarbBitSet = new Coarbitrary() {
    public  Gen coarbitrary(final BitSet s, final Gen g) {
      List x = nil();

      for (int i = 0; i < s.size(); i++) {
        x = x.snoc(s.get(i));
      }

      return coarbList(coarbBoolean).coarbitrary(x, g);
    }
  };

  /**
   * A coarbitrary for calendars.
   */
  public static final Coarbitrary coarbCalendar = new Coarbitrary() {
    public  Gen coarbitrary(final Calendar c, final Gen g) {
      return coarbLong.coarbitrary(c.getTime().getTime(), g);
    }
  };

  /**
   * A coarbitrary for dates.
   */
  public static final Coarbitrary coarbDate = new Coarbitrary() {
    public  Gen coarbitrary(final Date d, final Gen g) {
      return coarbLong.coarbitrary(d.getTime(), g);
    }
  };

  /**
   * A coarbitrary for enum maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for enum maps.
   */
  public static , V> Coarbitrary> coarbEnumMap(final Coarbitrary ck,
                                                                               final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final EnumMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for enum sets.
   *
   * @param c A coarbitrary for the elements of the enum set.
   * @return A coarbitrary for enum sets.
   */
  public static > Coarbitrary> coarbEnumSet(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final EnumSet as, final Gen g) {
        return coarbHashSet(c).coarbitrary(new HashSet(as), g);
      }
    };
  }

  /**
   * A coarbitrary for gregorian calendars.
   */
  public static final Coarbitrary coarbGregorianCalendar = new Coarbitrary() {
    public  Gen coarbitrary(final GregorianCalendar c, final Gen g) {
      return coarbLong.coarbitrary(c.getTime().getTime(), g);
    }
  };

  /**
   * A coarbitrary for hash maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for hash maps.
   */
  public static  Coarbitrary> coarbHashMap(final Coarbitrary ck, final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final HashMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for hash sets.
   *
   * @param c A coarbitrary for the elements of the hash set.
   * @return A coarbitrary for hash sets.
   */
  public static  Coarbitrary> coarbHashSet(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final HashSet as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for hash tables.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for hash tables.
   */
  public static  Coarbitrary> coarbHashtable(final Coarbitrary ck, final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final Hashtable h, final Gen g) {
        List> x = nil();

        for (final K k : h.keySet()) {
          x = x.snoc(p(k, h.get(k)));
        }

        return coarbList(coarbP2(ck, cv)).coarbitrary(x, g);
      }
    };
  }

  /**
   * A coarbitrary for identity hash maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for identity hash maps.
   */
  public static  Coarbitrary> coarbIdentityHashMap(final Coarbitrary ck,
                                                                               final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final IdentityHashMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for linked hash maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for linked hash maps.
   */
  public static  Coarbitrary> coarbLinkedHashMap(final Coarbitrary ck,
                                                                           final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final LinkedHashMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for linked hash sets.
   *
   * @param c A coarbitrary for the elements of the linked hash set.
   * @return A coarbitrary for linked hash sets.
   */
  public static  Coarbitrary> coarbLinkedHashSet(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final LinkedHashSet as, final Gen g) {
        return coarbHashSet(c).coarbitrary(new HashSet(as), g);
      }
    };
  }

  /**
   * A coarbitrary for linked lists.
   *
   * @param c A coarbitrary for the elements of the linked list.
   * @return A coarbitrary for linked lists.
   */
  public static  Coarbitrary> coarbLinkedList(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final LinkedList as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for priority queues.
   *
   * @param c A coarbitrary for the elements of the priority queue.
   * @return A coarbitrary for priority queues.
   */
  public static  Coarbitrary> coarbPriorityQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final PriorityQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for properties.
   */
  public static final Coarbitrary coarbProperties = new Coarbitrary() {
    @SuppressWarnings({"UseOfObsoleteCollectionType"})
    public  Gen coarbitrary(final Properties p, final Gen g) {
      final Hashtable t = new Hashtable();

      for (final Object s : p.keySet()) {
        t.put((String) s, p.getProperty((String) s));
      }

      return coarbHashtable(coarbString, coarbString).coarbitrary(t, g);
    }
  };

  /**
   * A coarbitrary for stacks.
   *
   * @param c A coarbitrary for the elements of the stack.
   * @return A coarbitrary for stacks.
   */
  public static  Coarbitrary> coarbStack(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final Stack as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for tree maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for tree maps.
   */
  public static  Coarbitrary> coarbTreeMap(final Coarbitrary ck, final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final TreeMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for tree sets.
   *
   * @param c A coarbitrary for the elements of the tree set.
   * @return A coarbitrary for tree sets.
   */
  public static  Coarbitrary> coarbTreeSet(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final TreeSet as, final Gen g) {
        return coarbHashSet(c).coarbitrary(new HashSet(as), g);
      }
    };
  }

  /**
   * A coarbitrary for vectors.
   *
   * @param c A coarbitrary for the elements of the vector.
   * @return A coarbitrary for vectors.
   */
  public static  Coarbitrary> coarbVector(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked", "UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final Vector as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for weak hash maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for weak hash maps.
   */
  public static  Coarbitrary> coarbWeakHashMap(final Coarbitrary ck,
                                                                       final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final WeakHashMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  // END java.util

  // BEGIN java.util.concurrent

  /**
   * A coarbitrary for array blocking queues.
   *
   * @param c A coarbitrary for the elements of the array blocking queue.
   * @return A coarbitrary for array blocking queues.
   */
  public static  Coarbitrary> coarbArrayBlockingQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final ArrayBlockingQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for concurrent hash maps.
   *
   * @param ck A coarbitrary for the map keys.
   * @param cv A coarbitrary for the map values.
   * @return A coarbitrary for concurrent hash maps.
   */
  public static  Coarbitrary> coarbConcurrentHashMap(final Coarbitrary ck,
                                                                                   final Coarbitrary cv) {
    return new Coarbitrary>() {
      @SuppressWarnings({"UseOfObsoleteCollectionType"})
      public  Gen coarbitrary(final ConcurrentHashMap m, final Gen g) {
        return coarbHashtable(ck, cv).coarbitrary(new Hashtable(m), g);
      }
    };
  }

  /**
   * A coarbitrary for concurrent linked queues.
   *
   * @param c A coarbitrary for the elements of the concurrent linked queue.
   * @return A coarbitrary for concurrent linked queues.
   */
  public static  Coarbitrary> coarbConcurrentLinkedQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final ConcurrentLinkedQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for copy-on-write array lists.
   *
   * @param c A coarbitrary for the elements of the copy-on-write array list.
   * @return A coarbitrary for copy-on-write array lists.
   */
  public static  Coarbitrary> coarbCopyOnWriteArrayList(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final CopyOnWriteArrayList as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for copy-on-write array sets.
   *
   * @param c A coarbitrary for the elements of the copy-on-write array set.
   * @return A coarbitrary for copy-on-write array sets.
   */
  public static  Coarbitrary> coarbCopyOnWriteArraySet(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final CopyOnWriteArraySet as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for delay queues.
   *
   * @param c A coarbitrary for the elements of the delay queue.
   * @return A coarbitrary for delay queues.
   */
  public static  Coarbitrary> coarbDelayQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final DelayQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for linked blocking queues.
   *
   * @param c A coarbitrary for the elements of the linked blocking queue.
   * @return A coarbitrary for linked blocking queues.
   */
  public static  Coarbitrary> coarbLinkedBlockingQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final LinkedBlockingQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for priority blocking queues.
   *
   * @param c A coarbitrary for the elements of the priority blocking queue.
   * @return A coarbitrary for priority blocking queues.
   */
  public static  Coarbitrary> coarbPriorityBlockingQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final PriorityBlockingQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  /**
   * A coarbitrary for synchronous queues.
   *
   * @param c A coarbitrary for the elements of the synchronous queue.
   * @return A coarbitrary for synchronous queues.
   */
  public static  Coarbitrary> coarbSynchronousQueue(final Coarbitrary c) {
    return new Coarbitrary>() {
      @SuppressWarnings({"unchecked"})
      public  Gen coarbitrary(final SynchronousQueue as, final Gen g) {
        return coarbArray(c).coarbitrary(array(as.toArray((A[]) new Object[as.size()])), g);
      }
    };
  }

  // END java.util.concurrent

  // BEGIN java.sql

  public static final Coarbitrary coarbSQLDate = new Coarbitrary() {
    public  Gen coarbitrary(final java.sql.Date d, final Gen g) {
      return coarbLong.coarbitrary(d.getTime(), g);
    }
  };

  public static final Coarbitrary coarbTimestamp = new Coarbitrary() {
    public  Gen coarbitrary(final Timestamp t, final Gen g) {
      return coarbLong.coarbitrary(t.getTime(), g);
    }
  };

  public static final Coarbitrary Coarbitrary> coarbP1(final Coarbitrary ca) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P1 p, final Gen g) {
        return ca.coarbitrary(p._1(), g);
      }
    };
  }

  /**
   * A coarbitrary for product-2 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-2 is defined.
   * @param cb A coarbitrary for one of the types over which the product-2 is defined.
   * @return A coarbitrary for product-2 values.
   */
  public static  Coarbitrary> coarbP2(final Coarbitrary ca, final Coarbitrary cb) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P2 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(), g));
      }
    };
  }

  /**
   * A coarbitrary for product-3 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-3 is defined.
   * @param cb A coarbitrary for one of the types over which the product-3 is defined.
   * @param cc A coarbitrary for one of the types over which the product-3 is defined.
   * @return A coarbitrary for product-3 values.
   */
  public static  Coarbitrary> coarbP3(final Coarbitrary ca, final Coarbitrary cb,
                                                           final Coarbitrary cc) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P3 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(), cc.coarbitrary(p._3(), g)));
      }
    };
  }

  /**
   * A coarbitrary for product-4 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-4 is defined.
   * @param cb A coarbitrary for one of the types over which the product-4 is defined.
   * @param cc A coarbitrary for one of the types over which the product-4 is defined.
   * @param cd A coarbitrary for one of the types over which the product-4 is defined.
   * @return A coarbitrary for product-4 values.
   */
  public static  Coarbitrary> coarbP4(final Coarbitrary ca, final Coarbitrary cb,
                                                                 final Coarbitrary cc, final Coarbitrary cd) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P4 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(), cc.coarbitrary(p._3(), cd.coarbitrary(p._4(), g))));
      }
    };
  }

  /**
   * A coarbitrary for product-5 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-5 is defined.
   * @param cb A coarbitrary for one of the types over which the product-5 is defined.
   * @param cc A coarbitrary for one of the types over which the product-5 is defined.
   * @param cd A coarbitrary for one of the types over which the product-5 is defined.
   * @param ce A coarbitrary for one of the types over which the product-5 is defined.
   * @return A coarbitrary for product-5 values.
   */
  public static  Coarbitrary> coarbP5(final Coarbitrary ca, final Coarbitrary cb,
                                                                       final Coarbitrary cc, final Coarbitrary cd,
                                                                       final Coarbitrary ce) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P5 p, final Gen g) {
        return ca.coarbitrary(p._1(),
            cb.coarbitrary(p._2(), cc.coarbitrary(p._3(), cd.coarbitrary(p._4(), ce.coarbitrary(p._5(), g)))));
      }
    };
  }

  /**
   * A coarbitrary for product-6 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-6 is defined.
   * @param cb A coarbitrary for one of the types over which the product-6 is defined.
   * @param cc A coarbitrary for one of the types over which the product-6 is defined.
   * @param cd A coarbitrary for one of the types over which the product-6 is defined.
   * @param ce A coarbitrary for one of the types over which the product-6 is defined.
   * @param cf A coarbitrary for one of the types over which the product-6 is defined.
   * @return A coarbitrary for product-6 values.
   */
  public static  Coarbitrary> coarbP6(final Coarbitrary ca,
                                                                               final Coarbitrary cb,
                                                                               final Coarbitrary cc,
                                                                               final Coarbitrary cd,
                                                                               final Coarbitrary ce,
                                                                               final Coarbitrary cf) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P6 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(),
            cc.coarbitrary(p._3(), cd.coarbitrary(p._4(), ce.coarbitrary(p._5(), cf.coarbitrary(p._6(), g))))));
      }
    };
  }

  /**
   * A coarbitrary for product-7 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-7 is defined.
   * @param cb A coarbitrary for one of the types over which the product-7 is defined.
   * @param cc A coarbitrary for one of the types over which the product-7 is defined.
   * @param cd A coarbitrary for one of the types over which the product-7 is defined.
   * @param ce A coarbitrary for one of the types over which the product-7 is defined.
   * @param cf A coarbitrary for one of the types over which the product-7 is defined.
   * @param cg A coarbitrary for one of the types over which the product-7 is defined.
   * @return A coarbitrary for product-7 values.
   */
  public static  Coarbitrary> coarbP7(final Coarbitrary ca,
                                                                                     final Coarbitrary cb,
                                                                                     final Coarbitrary cc,
                                                                                     final Coarbitrary cd,
                                                                                     final Coarbitrary ce,
                                                                                     final Coarbitrary cf,
                                                                                     final Coarbitrary cg) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P7 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(), cc.coarbitrary(p._3(),
            cd.coarbitrary(p._4(), ce.coarbitrary(p._5(), cf.coarbitrary(p._6(), cg.coarbitrary(p._7(), g)))))));
      }
    };
  }

  /**
   * A coarbitrary for product-8 values.
   *
   * @param ca A coarbitrary for one of the types over which the product-8 is defined.
   * @param cb A coarbitrary for one of the types over which the product-8 is defined.
   * @param cc A coarbitrary for one of the types over which the product-8 is defined.
   * @param cd A coarbitrary for one of the types over which the product-8 is defined.
   * @param ce A coarbitrary for one of the types over which the product-8 is defined.
   * @param cf A coarbitrary for one of the types over which the product-8 is defined.
   * @param cg A coarbitrary for one of the types over which the product-8 is defined.
   * @param ch A coarbitrary for one of the types over which the product-8 is defined.
   * @return A coarbitrary for product-8 values.
   */
  public static  Coarbitrary> coarbP8(final Coarbitrary ca,
                                                                                           final Coarbitrary cb,
                                                                                           final Coarbitrary cc,
                                                                                           final Coarbitrary cd,
                                                                                           final Coarbitrary ce,
                                                                                           final Coarbitrary cf,
                                                                                           final Coarbitrary cg,
                                                                                           final Coarbitrary ch) {
    return new Coarbitrary>() {
      public  Gen coarbitrary(final P8 p, final Gen g) {
        return ca.coarbitrary(p._1(), cb.coarbitrary(p._2(), cc.coarbitrary(p._3(), cd.coarbitrary(p._4(),
            ce.coarbitrary(p._5(), cf.coarbitrary(p._6(), cg.coarbitrary(p._7(), ch.coarbitrary(p._8(), g))))))));
      }
    };
  }
}