return h->num;
 }
 
-void* dict_lookup(dict_t*h, const void*key)
+void dict_do_lookup(dict_t*h, const void*key, void***match)
 {
-    if(!h->num)
-        return 0;
+    if(!h->num) {
+        *match = 0;
+        return;
+    }
     
     unsigned int ohash = h->key_type->hash(key);
     unsigned int hash = ohash % h->hashsize;
     /* check first entry for match */
     dictentry_t*e = h->slots[hash];
     if(e && h->key_type->equals(e->key, key)) {
-        return e->data;
+        *match = &e->data;
+        return;
     } else if(e) {
         e = e->next;
     }
     /* check subsequent entries for a match */
     while(e) {
         if(h->key_type->equals(e->key, key)) {
-            return e->data;
+            *match = &e->data;
+            return;
         }
         e = e->next;
     }
+    *match = 0;
+}
+void* dict_lookup(dict_t*h, const void*key)
+{
+    void**data = 0;
+    dict_do_lookup(h, key, &data);
+    if(data)
+        return *data;
     return 0;
 }
+char dict_contains(dict_t*h, const void*key)
+{
+    void**data = 0;
+    dict_do_lookup(h, key, &data);
+    return !!data;
+}
+
 char dict_del(dict_t*h, const void*key)
 {
     if(!h->num)
 
 int dict_count(dict_t*h);
 void dict_dump(dict_t*h, FILE*fi, const char*prefix);
 dictentry_t* dict_get_slot(dict_t*h, const void*key);
+char dict_contains(dict_t*h, const void*s);
 void* dict_lookup(dict_t*h, const void*s);
 char dict_del(dict_t*h, const void*s);
 dict_t*dict_clone(dict_t*);