//  this function implements efficient counting of intersections
    //  with logarithmic running time in the worst case;
    //  for implementation details of this method see documentation;
    int  CountIntersections
        (
            Interval const &        interval_x  ,
            MultiSetInt const &     mset_a      ,
            MultiSetInt const &     mset_b
        )
    {
        assert ( mset_a.size()==mset_b.size() ) ;

        int     n     = mset_a . size ( ) ;
        int     n_a   = mset_b . upper_bound ( interval_x.A() ) -
                        mset_b . begin ( ) ;
        int     n_b   = mset_a . end ( ) -
                        mset_a . lower_bound ( interval_x.B() ) ;
        int     count = n - n_a - n_b ;
        return  count ;
    }
 //  this function detects intersection of two intervals,
 //  it returns true in the following cases:
 //  - both intervals are non-empty and their intersection
 //    is a non-empty interval ;
 //  - an empty interval is in the interior of the other
 //    non-empty interval ;
 //  in all other cases this functions returns false ;
 bool Intersect ( Interval const &  x , Interval const &  y )
 {
     return ( x.A() < y.B()  ) && ( y.A() < x.B() ) ;
 }