// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static void addToIntersection(List<Type> list, 
//         Type type, Unit unit) {
//     if (type==null || 
//             !list.isEmpty() && 
//             type.isAnything()) {
//         return;
//     }
//     else if (type.isExactlyNothing()) {
//         list.clear();
//         list.add(type);
//     }
//     else if (type.isIntersection()) {
//         List<Type> satisfiedTypes = 
//                 type.getSatisfiedTypes();
//         for (int i=0, 
//                 size=satisfiedTypes.size(); 
//                 i<size; i++) {
//             Type t = satisfiedTypes.get(i);
//             addToIntersection(list, t, unit);
//         }
//     }
//     else {
//         if (type.isWellDefined()) {
//             TypeDeclaration dec = type.getDeclaration();
//             for (int i=0; i<list.size(); i++) {
//                 Type t = list.get(i);
//                 if (t.isSubtypeOf(type)) {
//                     return;
//                 }
//                 else if (type.isSubtypeOf(t)) {
//                     list.remove(i);
//                     i--; // redo this index
//                 }
//                 else if (disjoint(type, t, unit)) {
//                     list.clear();
//                     list.add(unit.getNothingType());
//                     return;
//                 } 
//                 else {
//                     if (type.isClassOrInterface() && 
//                         t.isClassOrInterface() && 
//                         t.getDeclaration().equals(dec) &&
//                             !type.containsUnknowns() &&
//                             !t.containsUnknowns()) {
//                         //canonicalize a type of form
//                         //T<InX,OutX>&T<InY,OutY> to 
//                         //T<InX|InY,OutX&OutY>
//                         Type pi = 
//                                 principalInstantiation(
//                                         dec, type, t, 
//                                         unit);
//                         if (!pi.containsUnknowns()) {
//                             list.remove(i);
//                             list.add(pi);
//                             return;
//                         }
//                     }
//                 }
//             }
//             if (list.size()>1) {
//                 //it is possible to have a type that is
//                 //a supertype of the intersection, even 
//                 //though it is not a supertype of any of  
//                 //the intersected types!
//                 Type t = canonicalIntersection(list, unit);
//                 if (type.isSupertypeOf(t)) {
//                     return;
//                 }
//             }
//             list.add(type);
//         }
//     }
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static void addToUnion(List<Type> list, 
//         Type pt) {
//     if (pt==null || 
//             !list.isEmpty() && 
//             pt.isExactlyNothing()) {
//         return;
//     }
//     else if (pt.isAnything()) {
//         list.clear();
//         list.add(pt);
//     }
//     else if (pt.isUnion()) {
//         List<Type> caseTypes = 
//                 pt.getCaseTypes();
//         for ( int i=0, size=caseTypes.size(); 
//                 i<size; i++ ) {
//             Type t = caseTypes.get(i);
//             addToUnion(list, t.substitute(pt));
//         }
//     }
//     else if (pt.isWellDefined()) {
//         boolean add=true;
//         for (int i=0; i<list.size(); i++) {
//             Type t = list.get(i);
//             if (pt.isSubtypeOf(t)) {
//                 add=false;
//                 break;
//             }
//             else if (pt.isSupertypeOf(t)) {
//                 list.remove(i);
//                 i--; // redo this index
//             }
//         }
//         if (add) {
//             list.add(pt);
//         }
//     }
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static Type canonicalIntersection(
//         List<Type> types, Unit unit) {
//     if (types.size()==1) {
//         return types.get(0);
//     }
//     IntersectionType it = new IntersectionType(unit);
//     it.setSatisfiedTypes(types);
//     return it.canonicalize().getType();
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static Type intersection(
//         List<Type> types, Unit unit) {
//     if (types.size()==1) {
//         return types.get(0);
//     }
//     IntersectionType it = new IntersectionType(unit);
//     it.setSatisfiedTypes(types);
//     return it.getType();
// }


import static com.redhat.ceylon.model.typechecker.model.ModelUtil.addToIntersection;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.addToUnion;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.canonicalIntersection;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.intersection;
import java.util.ArrayList;
import java.util.List;
    @Override
    public String getName() {
        return getType().asString();
    }
    
    @Override
    public String getName(Unit unit) {
    	return getType().asString(unit);
    }
    
    @Override
    public String getQualifiedNameString() {
        return getType().asQualifiedString();
    }
    
    @Override
    public String toString() {
        return getName();
    }

    @Override
    public boolean isEmptyType() {
        for (Type st: getSatisfiedTypes()) {
            if (st.getDeclaration().isEmptyType()) {
                return true;
            }
        }
        return false;
    }
    
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static void addToIntersection(List<Type> list, 
//         Type type, Unit unit) {
//     if (type==null || 
//             !list.isEmpty() && 
//             type.isAnything()) {
//         return;
//     }
//     else if (type.isExactlyNothing()) {
//         list.clear();
//         list.add(type);
//     }
//     else if (type.isIntersection()) {
//         List<Type> satisfiedTypes = 
//                 type.getSatisfiedTypes();
//         for (int i=0, 
//                 size=satisfiedTypes.size(); 
//                 i<size; i++) {
//             Type t = satisfiedTypes.get(i);
//             addToIntersection(list, t, unit);
//         }
//     }
//     else {
//         if (type.isWellDefined()) {
//             TypeDeclaration dec = type.getDeclaration();
//             for (int i=0; i<list.size(); i++) {
//                 Type t = list.get(i);
//                 if (t.isSubtypeOf(type)) {
//                     return;
//                 }
//                 else if (type.isSubtypeOf(t)) {
//                     list.remove(i);
//                     i--; // redo this index
//                 }
//                 else if (disjoint(type, t, unit)) {
//                     list.clear();
//                     list.add(unit.getNothingType());
//                     return;
//                 } 
//                 else {
//                     if (type.isClassOrInterface() && 
//                         t.isClassOrInterface() && 
//                         t.getDeclaration().equals(dec) &&
//                             !type.containsUnknowns() &&
//                             !t.containsUnknowns()) {
//                         //canonicalize a type of form
//                         //T<InX,OutX>&T<InY,OutY> to 
//                         //T<InX|InY,OutX&OutY>
//                         Type pi = 
//                                 principalInstantiation(
//                                         dec, type, t, 
//                                         unit);
//                         if (!pi.containsUnknowns()) {
//                             list.remove(i);
//                             list.add(pi);
//                             return;
//                         }
//                     }
//                 }
//             }
//             if (list.size()>1) {
//                 //it is possible to have a type that is
//                 //a supertype of the intersection, even 
//                 //though it is not a supertype of any of  
//                 //the intersected types!
//                 Type t = canonicalIntersection(list, unit);
//                 if (type.isSupertypeOf(t)) {
//                     return;
//                 }
//             }
//             list.add(type);
//         }
//     }
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static void addToUnion(List<Type> list, 
//         Type pt) {
//     if (pt==null || 
//             !list.isEmpty() && 
//             pt.isExactlyNothing()) {
//         return;
//     }
//     else if (pt.isAnything()) {
//         list.clear();
//         list.add(pt);
//     }
//     else if (pt.isUnion()) {
//         List<Type> caseTypes = 
//                 pt.getCaseTypes();
//         for ( int i=0, size=caseTypes.size(); 
//                 i<size; i++ ) {
//             Type t = caseTypes.get(i);
//             addToUnion(list, t.substitute(pt));
//         }
//     }
//     else if (pt.isWellDefined()) {
//         boolean add=true;
//         for (int i=0; i<list.size(); i++) {
//             Type t = list.get(i);
//             if (pt.isSubtypeOf(t)) {
//                 add=false;
//                 break;
//             }
//             else if (pt.isSupertypeOf(t)) {
//                 list.remove(i);
//                 i--; // redo this index
//             }
//         }
//         if (add) {
//             list.add(pt);
//         }
//     }
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static Type canonicalIntersection(
//         List<Type> types, Unit unit) {
//     if (types.size()==1) {
//         return types.get(0);
//     }
//     IntersectionType it = new IntersectionType(unit);
//     it.setSatisfiedTypes(types);
//     return it.canonicalize().getType();
// }
// 
// Path: src/com/redhat/ceylon/model/typechecker/model/ModelUtil.java
// public static Type intersection(
//         List<Type> types, Unit unit) {
//     if (types.size()==1) {
//         return types.get(0);
//     }
//     IntersectionType it = new IntersectionType(unit);
//     it.setSatisfiedTypes(types);
//     return it.getType();
// }


// Path: src/com/redhat/ceylon/model/typechecker/model/IntersectionType.java
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.addToIntersection;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.addToUnion;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.canonicalIntersection;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.intersection;
import java.util.ArrayList;
import java.util.List;

    @Override
    public String getName() {
        return getType().asString();
    }
    
    @Override
    public String getName(Unit unit) {
    	return getType().asString(unit);
    }
    
    @Override
    public String getQualifiedNameString() {
        return getType().asQualifiedString();
    }
    
    @Override
    public String toString() {
        return getName();
    }

    @Override
    public boolean isEmptyType() {
        for (Type st: getSatisfiedTypes()) {
            if (st.getDeclaration().isEmptyType()) {
                return true;
            }
        }
        return false;
    }
    
    @Override