1    type Multiset<T> @abstract =
2        let multiset = StdMultiset<T>.new
3        let mut is_invoking_callbacks = false
4        let on_added_callbacks = StdList<T -> Unit>.new
5        let on_removed_callbacks = StdList<T -> Unit>.new
6        let tokens = StdList<Token>.new
7    
8        let invoke_callbacks (callbacks : StdList<T -> Unit>) (x : T) =
9            assert not is_invoking_callbacks
10           is_invoking_callbacks = true
11   
12           for f in callbacks do
13               f x
14   
15           is_invoking_callbacks = false
16   
17       def is_empty = multiset.is_empty
18       def is_not_empty = multiset.is_not_empty
19   
20       def contains (x : T) = multiset.contains x
21       def get_iterator = multiset.get_iterator
22   
23       def subscribe (f : T -> Unit) (g : T -> Unit) =
24           assert not is_invoking_callbacks
25   
26           on_added_callbacks.add f
27           on_removed_callbacks.add g
28   
29           Token { assert not is_invoking_callbacks
30                   on_added_callbacks.remove f
31                   on_removed_callbacks.remove g }
32   
33       def push_token (token : Token) =
34           tokens.add token
35   
36       fun destruct =
37           for i = tokens.size - 1 downto 0 do
38               tokens[i].discard
39   
40   type MutMultiset<T> @[mut_of Multiset] =
41       inherit Multiset<T>
42   
43       def add (x : T) =
44           assert not is_invoking_callbacks
45   
46           multiset.add x
47   
48           if multiset.multiplicity x == 1 then
49               invoke_callbacks on_added_callbacks x
50   
51       def remove (x : T) =
52           assert not is_invoking_callbacks
53   
54           multiset.remove x
55           if not multiset.contains x then
56               invoke_callbacks on_removed_callbacks x
57   
58       def as_readonly = self as Multiset<T>
59