@Override
	public List<? extends ExtendedSet<T>> powerSet(int min, int max) {
		if (min < 1 || max < min)
			throw new IllegalArgumentException();

		// special cases
		List<ExtendedSet<T>> res = new ArrayList<ExtendedSet<T>>();
		if (size() < min)
			return res;
		if (size() == min) {
			res.add(this.clone());
			return res;
		}
		if (size() == min + 1) {
			for (T item : this.descending()) {
				ExtendedSet<T> set = this.clone();
				set.remove(item);
				res.add(set);
			}
			if (max > min)
				res.add(this.clone());
			return res;
		}

		// the first level contains only one prefix made up of all 1-subsets
		List<List<ExtendedSet<T>>> level = new ArrayList<List<ExtendedSet<T>>>();
		level.add(new ArrayList<ExtendedSet<T>>());
		for (T item : this) {
			ExtendedSet<T> single = this.empty();
			single.add(item);
			level.get(0).add(single);
		}
		if (min == 1)
			res.addAll(level.get(0));

		// all combinations
		int l = 2;
		while (!level.isEmpty() && l <= max) {
			List<List<ExtendedSet<T>>> newLevel = new ArrayList<List<ExtendedSet<T>>>();
			for (List<ExtendedSet<T>> prefix : level) {
				for (int i = 0; i < prefix.size() - 1; i++) {
					List<ExtendedSet<T>> newPrefix = new ArrayList<ExtendedSet<T>>();
					for (int j = i + 1; j < prefix.size(); j++) {
						ExtendedSet<T> x = prefix.get(i).clone();
						x.add(prefix.get(j).last());
						newPrefix.add(x);
						if (l >= min)
							res.add(x);
					}
					if (newPrefix.size() > 1)
						newLevel.add(newPrefix);
				}
			}
			level = newLevel;
			l++;
		}

		return res;
	}
@ Override public List < ? extends ExtendedSet < T > > powerSet ( int min , int max ) { if ( min < 1 || max < min ) throw new IllegalArgumentException ( ) ; List < ExtendedSet < T > > res = new ArrayList < ExtendedSet < T > > ( ) ; if ( size ( ) < min ) return res ; if ( size ( ) == min ) { res . add ( this . clone ( ) ) ; return res ; } if ( size ( ) == min + 1 ) { for ( T item : this . descending ( ) ) { ExtendedSet < T > set = this . clone ( ) ; set . remove ( item ) ; res . add ( set ) ; } if ( max > min ) res . add ( this . clone ( ) ) ; return res ; } List < List < ExtendedSet < T > > > level = new ArrayList < List < ExtendedSet < T > > > ( ) ; level . add ( new ArrayList < ExtendedSet < T > > ( ) ) ; for ( T item : this ) { ExtendedSet < T > single = this . empty ( ) ; single . add ( item ) ; level . get ( 0 ) . add ( single ) ; } if ( min == 1 ) res . addAll ( level . get ( 0 ) ) ; int l = 2 ; while ( ! level . isEmpty ( ) && l <= max ) { List < List < ExtendedSet < T > > > newLevel = new ArrayList < List < ExtendedSet < T > > > ( ) ; for ( List < ExtendedSet < T > > prefix : level ) { for ( int i = 0 ; i < prefix . size ( ) - 1 ; i ++ ) { List < ExtendedSet < T > > newPrefix = new ArrayList < ExtendedSet < T > > ( ) ; for ( int j = i + 1 ; j < prefix . size ( ) ; j ++ ) { ExtendedSet < T > x = prefix . get ( i ) . clone ( ) ; x . add ( prefix . get ( j ) . last ( ) ) ; newPrefix . add ( x ) ; if ( l >= min ) res . add ( x ) ; } if ( newPrefix . size ( ) > 1 ) newLevel . add ( newPrefix ) ; } } level = newLevel ; l ++ ; } return res ; }
{@inheritDoc}