upperUntil :: (Ord a, Ord b, Ord c, Show a) =>
              (a -> b -> Bool) -- ^ cut-off predicate
           -> DepGraph a b c -- ^ dependency graph to be traversed
           -> Set.Set a -- ^ compare entries to these elements
           -> Set.Set (c, b)
upperUntil cop gr es
    | Set.null es = Set.empty
    | otherwise =
        let s = upperLevel gr es
            cop' x = not . cop x
            s' = setFilterLookup (getKey gr) cop' gr s
            s'' = upperUntil cop gr $ Set.map (getKey gr . fst) s'
        in Set.union s' s''
upperUntil :: (Ord a, Ord b, Ord c, Show a) =>
              (a -> b -> Bool) -- ^ cut-off predicate
           -> DepGraph a b c -- ^ dependency graph to be traversed
           -> Set.Set a -- ^ compare entries to these elements
           -> Set.Set (c, b)
upperUntil cop gr es
    | Set.null es = Set.empty
    | otherwise =
        let s = upperLevel gr es
            cop' x = not . cop x
            s' = setFilterLookup (getKey gr) cop' gr s
            s'' = upperUntil cop gr $ Set.map (getKey gr . fst) s'
        in Set.union s' s''
upperUntil cop gr es
    | Set.null es = Set.empty
    | otherwise =
        let s = upperLevel gr es
            cop' x = not . cop x
            s' = setFilterLookup (getKey gr) cop' gr s
            s'' = upperUntil cop gr $ Set.map (getKey gr . fst) s'
        in Set.union s' s''