private Type glbFlattened(List<Type> flatBounds, Type errT) {
        List<Type> bounds = closureMin(flatBounds);

        if (bounds.isEmpty()) {             // length == 0
            return syms.objectType;
        } else if (bounds.tail.isEmpty()) { // length == 1
            return bounds.head;
        } else {                            // length > 1
            int classCount = 0;
            List<Type> cvars = List.nil();
            List<Type> lowers = List.nil();
            for (Type bound : bounds) {
                if (!bound.isInterface()) {
                    classCount++;
                    Type lower = cvarLowerBound(bound);
                    if (bound != lower && !lower.hasTag(BOT)) {
                        cvars = cvars.append(bound);
                        lowers = lowers.append(lower);
                    }
                }
            }
            if (classCount > 1) {
                if (lowers.isEmpty()) {
                    return createErrorType(errT);
                } else {
                    // try again with lower bounds included instead of capture variables
                    List<Type> newBounds = bounds.diff(cvars).appendList(lowers);
                    return glb(newBounds);
                }
            }
        }
        return makeIntersectionType(bounds);
    }
private Type glbFlattened ( List < Type > flatBounds , Type errT ) { List < Type > bounds = closureMin ( flatBounds ) ; if ( bounds . isEmpty ( ) ) { return syms . objectType ; } else if ( bounds . tail . isEmpty ( ) ) { return bounds . head ; } else { int classCount = 0 ; List < Type > cvars = List . nil ( ) ; List < Type > lowers = List . nil ( ) ; for ( Type bound : bounds ) { if ( ! bound . isInterface ( ) ) { classCount ++ ; Type lower = cvarLowerBound ( bound ) ; if ( bound != lower && ! lower . hasTag ( BOT ) ) { cvars = cvars . append ( bound ) ; lowers = lowers . append ( lower ) ; } } } if ( classCount > 1 ) { if ( lowers . isEmpty ( ) ) { return createErrorType ( errT ) ; } else { List < Type > newBounds = bounds . diff ( cvars ) . appendList ( lowers ) ; return glb ( newBounds ) ; } } } return makeIntersectionType ( bounds ) ; }
Perform glb for a list of non-primitive, non-error, non-compound types;
redundant elements are removed.  Bounds should be ordered according to
{@link Symbol#precedes(TypeSymbol,Types)}.

@param flatBounds List of type to glb
@param errT Original type to use if the result is an error type