use hash for name lookup
diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c
index 948c627..e54eaa7 100644
--- a/libasn1fix/asn1fix_cws.c
+++ b/libasn1fix/asn1fix_cws.c
@@ -389,7 +389,6 @@
 	char *mivr; /* Most Immediate Value Representation */
 	int new_ref = 1;
 	asn1p_t *asn;
-	asn1p_module_t *mod;
 	asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
 	int i, ret = 0, psize;
 	char *pp;
@@ -458,9 +457,13 @@
 		free(mivr);
 		return -1;
 	} else {
-		mod = TQ_FIRST(&(asn->modules));
-		assert(mod);
-		expr = TQ_REMOVE(&(mod->members), next);
+        asn1p_module_t *mod = TQ_FIRST(&(asn->modules));
+        assert(mod);
+
+        /* This member removal is safe with respect to members hash since the
+         * entire asn module will be deleted down below.
+         */
+        expr = TQ_REMOVE(&(mod->members), next);
 		assert(expr);
 
         expr->parent_expr = NULL;
diff --git a/libasn1fix/asn1fix_internal.h b/libasn1fix/asn1fix_internal.h
index 5fd7e76..c429730 100644
--- a/libasn1fix/asn1fix_internal.h
+++ b/libasn1fix/asn1fix_internal.h
@@ -22,6 +22,7 @@
 
 #include <asn1parser.h>		/* Our lovely ASN.1 parser module */
 #include <asn1_namespace.h>
+#include <genhash.h>
 #include "asn1fix.h"
 
 #ifdef	_WIN32
diff --git a/libasn1fix/asn1fix_retrieve.c b/libasn1fix/asn1fix_retrieve.c
index 536f502..40acbe5 100644
--- a/libasn1fix/asn1fix_retrieve.c
+++ b/libasn1fix/asn1fix_retrieve.c
@@ -28,35 +28,44 @@
 	return NULL;
 }
 
+static asn1p_expr_t *
+asn1f_lookup_in_module(asn1p_module_t *mod, const char *name) {
+    asn1p_expr_t *expr = genhash_get(mod->members_hash, name);
+    if(!expr) {
+        asn1p_expr_t *memb;
+        TQ_FOR(memb, &mod->members, next) {
+            if(memb->expr_type == ASN_BASIC_ENUMERATED) {
+                asn1p_expr_t *v = asn1f_lookup_child(memb, name);
+                if(v) return v;
+            }
+        }
+    }
+
+    return expr;
+}
+
 asn1p_module_t *
 asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) {
 	asn1p_xports_t *xp;
-	asn1p_module_t *fromModule;
-	asn1p_expr_t *tc = (asn1p_expr_t *)0;
-	asn1p_expr_t *memb = (asn1p_expr_t *)0;
-	asn1p_expr_t *v = (asn1p_expr_t *)0;
 
 	/*
 	 * Search in which exactly module this name is defined.
 	 */
 	TQ_FOR(xp, &(mod->imports), xp_next) {
-		fromModule = asn1f_lookup_module(arg, xp->fromModuleName, NULL);
-		TQ_FOR(tc, &(xp->members), next) {
-			if(strcmp(name, tc->Identifier) == 0)
+        asn1p_module_t *fromModule =
+            asn1f_lookup_module(arg, xp->fromModuleName, NULL);
+        asn1p_expr_t *tc = (asn1p_expr_t *)0;
+
+        TQ_FOR(tc, &(xp->xp_members), next) {
+            if(strcmp(name, tc->Identifier) == 0)
 				break;
 
 			if(!fromModule)
 				continue;
 
-			TQ_FOR(memb, &(fromModule->members), next) {
-				if((memb->expr_type != ASN_BASIC_ENUMERATED) ||
-					(strcmp(memb->Identifier, tc->Identifier) != 0))
-					continue;
-
-				v = asn1f_lookup_child(memb, name);
-				if (v) break;
-			}
-			if(v) break;
+            asn1p_expr_t *v = v =
+                asn1f_lookup_in_module(fromModule, tc->Identifier);
+            if(v) break;
 		}
 		if(tc) break;
 	}
@@ -291,8 +300,6 @@
         ns_item--) {
         struct asn1_namespace_element_s *ns_el =
             &my_namespace->elements[ns_item];
-        asn1p_expr_t *ref_tc; /* Referenced tc */
-        asn1p_expr_t *v = (asn1p_expr_t *)0;
 
         switch(ns_el->selector) {
         case NAM_SYMBOL:
@@ -312,22 +319,12 @@
                 DISPOSE_OF_MY_NAMESPACE();
                 return ns_el->u.symbol.resolution;
             }
-        case NAM_SPACE:
+        case NAM_SPACE: {
+            asn1p_expr_t *ref_tc; /* Referenced tc */
             /*
              * Do a direct symbol search in the given module.
              */
-            TQ_FOR(ref_tc, &(ns_el->u.space.module->members), next) {
-                if(ref_tc->Identifier)
-                    if(strcmp(ref_tc->Identifier, identifier) == 0) break;
-
-                if(ref_tc->expr_type == ASN_BASIC_ENUMERATED) {
-                    v = asn1f_lookup_child(ref_tc, identifier);
-                    if(v) {
-                        ref_tc = v;
-                        break;
-                    }
-                }
-            }
+            ref_tc = asn1f_lookup_in_module(ns_el->u.space.module, identifier);
             if(ref_tc) {
                 /* It is acceptable that we don't use input parameters */
                 if(rhs_pspecs && !ref_tc->lhs_params) {
@@ -355,6 +352,7 @@
                 DISPOSE_OF_MY_NAMESPACE();
                 return ref_tc;
             }
+        }
 
     /*
             if(!expr && !(arg->expr->_mark & TM_BROKEN)
@@ -479,6 +477,11 @@
         ref = expr->reference;
         break;
     case FTT_VALUE:
+
+	DEBUG("%s(%s->%s) meta %d for line %d",
+		"VALUE", expr->Identifier, asn1f_printable_reference(ref),
+		expr->meta_type, expr->_lineno);
+
         assert(expr->meta_type == AMT_VALUE);
         assert(expr->value);
         /* Expression may be a terminal type itself */
@@ -574,7 +577,7 @@
 		return 0;
 	}
 
-	TQ_FOR(item, &(exports->members), next) {
+	TQ_FOR(item, &(exports->xp_members), next) {
 		if(strcmp(item->Identifier, name) == 0)
 			return 0;
 	}
diff --git a/libasn1fix/check_fixer.c b/libasn1fix/check_fixer.c
index 6f5f25e..b71a8c9 100644
--- a/libasn1fix/check_fixer.c
+++ b/libasn1fix/check_fixer.c
@@ -12,6 +12,7 @@
 #include <errno.h>
 #include <libgen.h>
 
+#include "genhash.h"
 #include "asn1fix.h"
 #include "asn1_buffer.h"
 #include "asn1_namespace.h"
@@ -340,11 +341,7 @@
 	/*
 	 * Scan in search for the original.
 	 */
-	TQ_FOR(expr, &(mod->members), next) {
-		if(strcmp(expr->Identifier, name) == 0)
-			break;
-	}
-
+    expr = genhash_get(mod->members_hash, name);
 	if(expr == NULL) {
 		fprintf(stderr,
 			"CHECKER: Value \"%s\" requested by "