static void Main() 
  {
    { 
      Person person = new Person();
      check(person, "Person");
      person.Dispose();
    }
    { 
      Person person = new Child();
      check(person, "Child");
      person.Dispose();
    }
    { 
      Person person = new GrandChild();
      check(person, "GrandChild"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangPerson();
      check(person, "TargetLangPerson"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangChild();
      check(person, "TargetLangChild"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangGrandChild();
      check(person, "TargetLangGrandChild"); 
      person.Dispose();
    }

    // Semis - don't override id() in target language
    { 
      Person person = new TargetLangSemiPerson();
      check(person, "Person"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangSemiChild();
      check(person, "Child"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangSemiGrandChild();
      check(person, "GrandChild"); 
      person.Dispose();
    }

    // Orphans - don't override id() in C++
    { 
      Person person = new OrphanPerson();
      check(person, "Person"); 
      person.Dispose();
    }
    { 
      Person person = new OrphanChild();
      check(person, "Child"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangOrphanPerson();
      check(person, "TargetLangOrphanPerson"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangOrphanChild();
      check(person, "TargetLangOrphanChild"); 
      person.Dispose();
    }

    // Duals - id() makes an upcall to the base id()
    { 
      Person person = new TargetLangDualPerson();
      check(person, "TargetLangDualPerson + Person"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangDualChild();
      check(person, "TargetLangDualChild + Child"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangDualGrandChild();
      check(person, "TargetLangDualGrandChild + GrandChild"); 
      person.Dispose();
    }

    // Mix Orphans and Duals
    { 
      Person person = new TargetLangDualOrphanPerson();
      check(person, "TargetLangDualOrphanPerson + Person"); 
      person.Dispose();
    }
    { 
      Person person = new TargetLangDualOrphanChild();
      check(person, "TargetLangDualOrphanChild + Child"); 
      person.Dispose();
    }
  }