1    type Multimap<K, V> @abstract =
2        let multimap = StdMultimap<K, V>.new
3        let mut is_invoking_callbacks = false
4        let on_added_callbacks = StdList<K * V -> Unit>.new
5        let on_removed_callbacks = StdList<K * V -> Unit>.new
6        let tokens = List<Token>.new
7    
8        def subscribe (f : K * V -> Unit
9                       g : K * V -> Unit) =
10           assert not is_invoking_callbacks
11   
12           on_added_callbacks.add f
13           on_removed_callbacks.add g
14   
15           Token { assert not is_invoking_callbacks
16                   on_added_callbacks.remove f
17                   on_removed_callbacks.remove g }
18   
19       def bind (f : K * V -> Unit) (g : K * V -> Unit) =
20           assert not is_invoking_callbacks
21   
22           on_added_callbacks.add f
23           on_removed_callbacks.add g
24   
25           for k, v in multimap do
26               f k v
27   
28           Token { assert not is_invoking_callbacks
29                   on_added_callbacks.remove f
30                   on_removed_callbacks.remove g
31   
32                   for k, v in multimap do
33                       g k v }
34   
35       def contains (k : K) = multimap.contains k
36       fun get (k : K) = multimap[k]
37   
38       def push_token (token : Token) =
39           tokens.add token
40   
41   type MutMultimap<K, V> @[mut_of Multimap] =
42       inherit Multimap<K, V>
43   
44       let invoke_callbacks (callbacks : StdList<K * V -> Unit>
45                             k : K
46                             v : V) =
47           assert not is_invoking_callbacks
48           is_invoking_callbacks = true
49   
50           for f in callbacks do
51               f k v
52   
53           is_invoking_callbacks = false
54   
55       def add (k : K) (v : V)  =
56           multimap.add k v
57           invoke_callbacks on_added_callbacks k v
58   
59       def remove (k : K) (v : V) =
60           multimap.remove k v
61           invoke_callbacks on_removed_callbacks k v
62   
63       def as_readonly = self as Multimap<K, V>
64