@Override
 public ProducedType toProducedType(RuntimeModuleManager moduleManager) {
   UnionType ret = new UnionType(moduleManager.getModelLoader().getUnit());
   ArrayList<ProducedType> caseTypes = new ArrayList<ProducedType>(members.length);
   for (TypeDescriptor member : members) caseTypes.add(member.toProducedType(moduleManager));
   ret.setCaseTypes(caseTypes);
   return ret.getType();
 }
 @Test
 public void testUnion() {
   ProducedType type = new TypeParser(MockLoader.instance, mockUnit).decodeType("a|b|c", null);
   Assert.assertNotNull(type);
   TypeDeclaration declaration = type.getDeclaration();
   Assert.assertNotNull(declaration);
   Assert.assertTrue(declaration instanceof UnionType);
   UnionType union = (UnionType) declaration;
   List<ProducedType> types = union.getCaseTypes();
   Assert.assertEquals(3, types.size());
   Assert.assertEquals("a", types.get(0).getDeclaration().getName());
   Assert.assertTrue(types.get(0).getDeclaration() instanceof Class);
   Assert.assertEquals("b", types.get(1).getDeclaration().getName());
   Assert.assertTrue(types.get(1).getDeclaration() instanceof Class);
   Assert.assertEquals("c", types.get(2).getDeclaration().getName());
   Assert.assertTrue(types.get(2).getDeclaration() instanceof Class);
 }
  @Test
  public void testIntersectionAndUnion() {
    ProducedType type = new TypeParser(MockLoader.instance, mockUnit).decodeType("a&b|c", null);
    Assert.assertNotNull(type);
    TypeDeclaration declaration = type.getDeclaration();
    Assert.assertNotNull(declaration);
    Assert.assertTrue(declaration instanceof UnionType);
    UnionType union = (UnionType) declaration;
    List<ProducedType> unionTypes = union.getCaseTypes();
    Assert.assertEquals(2, unionTypes.size());

    Assert.assertTrue(unionTypes.get(0).getDeclaration() instanceof IntersectionType);
    IntersectionType intersection = (IntersectionType) unionTypes.get(0).getDeclaration();

    List<ProducedType> intersectionTypes = intersection.getSatisfiedTypes();
    Assert.assertEquals(2, intersectionTypes.size());
    Assert.assertEquals("a", intersectionTypes.get(0).getDeclaration().getName());
    Assert.assertTrue(intersectionTypes.get(0).getDeclaration() instanceof Class);
    Assert.assertEquals("b", intersectionTypes.get(1).getDeclaration().getName());
    Assert.assertTrue(intersectionTypes.get(1).getDeclaration() instanceof Class);

    Assert.assertEquals("c", unionTypes.get(1).getDeclaration().getName());
    Assert.assertTrue(unionTypes.get(1).getDeclaration() instanceof Class);
  }
  @Test
  public void testUnionParams() {
    ProducedType type =
        new TypeParser(MockLoader.instance, mockUnit).decodeType("a|t2<b|c,t2<d,e|f>>", null);
    Assert.assertNotNull(type);
    TypeDeclaration declaration = type.getDeclaration();
    Assert.assertNotNull(declaration);
    Assert.assertTrue(declaration instanceof UnionType);
    UnionType union = (UnionType) declaration;
    List<ProducedType> caseTypes = union.getCaseTypes();
    Assert.assertEquals(2, caseTypes.size());

    // a
    Assert.assertEquals("a", caseTypes.get(0).getDeclaration().getName());
    Assert.assertTrue(caseTypes.get(0).getDeclaration() instanceof Class);

    // first t2
    ProducedType firstT2 = caseTypes.get(1);
    TypeDeclaration firstT2Declaration = firstT2.getDeclaration();
    Assert.assertNotNull(firstT2Declaration);
    Assert.assertTrue(firstT2Declaration instanceof Class);
    Assert.assertEquals("t2", firstT2Declaration.getName());
    Assert.assertEquals(2, firstT2.getTypeArgumentList().size());

    // b|c
    ProducedType bc = firstT2.getTypeArgumentList().get(0);
    Assert.assertTrue(bc.getDeclaration() instanceof UnionType);
    Assert.assertEquals(2, bc.getDeclaration().getCaseTypes().size());

    // b
    ProducedType b = bc.getDeclaration().getCaseTypes().get(0);
    Assert.assertEquals("b", b.getDeclaration().getName());
    Assert.assertTrue(b.getDeclaration() instanceof Class);

    // c
    ProducedType c = bc.getDeclaration().getCaseTypes().get(1);
    Assert.assertEquals("c", c.getDeclaration().getName());
    Assert.assertTrue(c.getDeclaration() instanceof Class);

    // second t2
    ProducedType secondT2 = firstT2.getTypeArgumentList().get(1);
    TypeDeclaration secondT2Declaration = firstT2.getDeclaration();
    Assert.assertNotNull(secondT2Declaration);
    Assert.assertTrue(secondT2Declaration instanceof Class);
    Assert.assertEquals("t2", secondT2Declaration.getName());
    Assert.assertEquals(2, secondT2.getTypeArgumentList().size());

    // d
    ProducedType d = secondT2.getTypeArgumentList().get(0);
    Assert.assertEquals("d", d.getDeclaration().getName());
    Assert.assertTrue(d.getDeclaration() instanceof Class);

    // e|f
    ProducedType ef = secondT2.getTypeArgumentList().get(1);
    Assert.assertTrue(ef.getDeclaration() instanceof UnionType);
    Assert.assertEquals(2, ef.getDeclaration().getCaseTypes().size());

    // e
    ProducedType e = ef.getDeclaration().getCaseTypes().get(0);
    Assert.assertEquals("e", e.getDeclaration().getName());
    Assert.assertTrue(e.getDeclaration() instanceof Class);

    // f
    ProducedType f = ef.getDeclaration().getCaseTypes().get(1);
    Assert.assertEquals("f", f.getDeclaration().getName());
    Assert.assertTrue(f.getDeclaration() instanceof Class);
  }