public class Foo : Object {
  public int id { get; construct; }
  
  public Foo (int id) {
    Object (id : id);
  }
}
  
public static int main (string[] args) {
  
  HashFunc keyfunc = (a) => { return ((uint)a & 0xffff); };
  EqualFunc eqfunc = (as1, as2) => { return (as1 == as2); };
  
  var foos = new Gee.HashMap<int, Foo> (keyfunc, eqfunc);
  
  for (int i = 1; i < 4; i++) {
    var f = new Foo (i);
    stdout.printf ("set %p:%d\n", f, f.id);
    foos.set (i, f);
  }
  
  stdout.printf ("foos %p, size %d\n", foos, foos.size);
  stdout.printf ("foos has: \n");
  
  stdout.printf ("(using foos.values)\n");
  foreach (Foo f in foos.values) {
    stdout.printf ("%p:%d\n", f, (f != null) ? f.id : 0);
  }
  
  // According to the Gee 0.7 documentation, and my local 0.6.1-3.fc16
  // VAPI, and the Vala tutorial, iterating with foreach over the bare
  // object should use the method from the iterable interface. For 0.6.1
  // the AbstractMap VAPI declares it as:
  //
  // Gee.Iterable<Gee.Map.Entry<K,V>>
  //
  // and so the returned type for should be Gee.Map.Entry<int,Foo>.
  //
  // However valac 0.14.0 gives the following error trying to compile this:
  //
  // hashset-test.vala:31.3-31.44: error: Assignment: Cannot convert from `Foo' to `Gee.Map.Entry<int,Foo>'
  //   foreach (Gee.Map.Entry<int,Foo> e in foos) {
  //   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  //stdout.printf ("(iterate over foos)\n");
  //foreach (Gee.Map.Entry<int,Foo> e in foos) {
  //  Foo f = e.value;
  //  stdout.printf ("%d: %p:%d\n", e.key, f, (f != null) ? f.id : 0);
  //}

  // Given the VAPI definition, this shouldn't compile, and it shouldn't
  // work. However, given the error produced by the above, then this should
  // compile - and it does, without any warning.
  // However it doesn't work, as it prints out:
  //
  // set 0x1a78230:1
  // set 0x1a78290:2
  // set 0x1a782f0:3
  // foos 0x1a7c820, size 3
  // foos has: 
  // (using foos.values)
  // 0x1a78230:1
  // 0x1a78290:2
  // 0x1a782f0:3
  // (iterate over foos, wrong way)
  // (nil)
  // 0x1a78230
  // 0x1a78290
  //
  // -----
  // Note the 'nil' and the missing entry.
  stdout.printf ("(iterate over foos, wrong way)\n");
  foreach (Foo f in foos) {
    stdout.printf ("%p\n", f);
  }
  
  return 0;
}
