// Given two arrows with the same source, check we can multiply them
  // and get an arrow to the product of their targets
  @Test
  public void testProductOf2() {
    ARROW p = fixtures.arrowFooToBar();
    ARROW q = fixtures.arrowFooToBaz();

    DOT a = p.getSource();
    DOT b = p.getTarget();
    DOT c = q.getTarget();
    assertTrue(a == q.getSource());

    ProductDiagram<DOT, ARROW> diagram = _topos.product(b, c);
    List<ARROW> arrowComponents = new ArrayList<ARROW>();
    arrowComponents.add(p);
    arrowComponents.add(q);
    ARROW pxq = diagram.multiplyArrows(a, arrowComponents);
    List<ARROW> projections = diagram.getProjections();
    assertTrue(p.equals(projections.get(0).compose(pxq)));
    assertTrue(q.equals(projections.get(1).compose(pxq)));
  }
  @Test
  public void testCanonicalProductIso() {
    DOT dot1 = fixtures.dotBar();
    DOT dot2 = fixtures.dotFoo();
    ProductDiagram<DOT, ARROW> productA = _topos.product(dot1, dot2);
    ProductDiagram<DOT, ARROW> productB = _topos.product(dot1, dot2);

    ARROW isoAB = _topos.canonicalIso(productA, productB);
    ARROW isoBA = _topos.canonicalIso(productB, productA);

    DOT dotA = productA.getProduct();
    DOT dotB = productB.getProduct();

    assertSame(isoAB.getSource(), dotA);
    assertSame(isoAB.getTarget(), dotB);
    assertSame(isoBA.getSource(), dotB);
    assertSame(isoBA.getTarget(), dotA);

    assertEquals(dotA.getIdentity(), isoBA.compose(isoAB));
    assertEquals(dotB.getIdentity(), isoAB.compose(isoBA));
  }