namespace Felines {
  
  delegate string SpeakFunc ();
  
  class Meow : Object
  {
    public SpeakFunc speak_func;
    
    public Meow (int speak_mode)
    {       
      /* This assignment causes a ref on self, both for lamdas and
       * instance methods */
      if (speak_mode == 0)
        speak_func = static_speak_func;
      else if (speak_mode == 1)
        speak_func = () => { return "Lamda meow!"; };
      else
        speak_func = default_speak_func;
      
      /* By the end of the constructor we should have ref count 1 */
      assert (this.ref_count == 1);
    }
    
    /* Using this as speak_func causes a self ref which we are leaking */
    private string default_speak_func ()
    {
      return "Default meooouw!";
    }
    
    /* Expectedly - Static methods do not cause a self ref */
    private static string static_speak_func ()
    {
      return "Static meeew!";
    }
  }
  
  public static int main (string[] args)
  {
    var meow = new Meow (0);
    print ("Static Kitty says: %s\n", meow.speak_func ());
    
    meow = new Meow (1);
    print ("Lambda Kitty says: %s\n", meow.speak_func ());
    
    meow = new Meow (2);    
    print ("Instance Kitty says: %s\n", meow.speak_func ());
    
    return 0;
  }
}
