diff --git a/Makefile.config b/Makefile.config
index 0d4c90d..be9c42c 100644
--- a/Makefile.config
+++ b/Makefile.config
@@ -1,6 +1,3 @@
-#JUDY_INC=-I/opt/local/include
-#JUDY_LIB=-L/opt/local/lib
-
 PREFIX=/usr/local
 INSTALL_BIN=$(PREFIX)/bin
-INSTALL_DATA=$(PREFIX)/share
\ No newline at end of file
+INSTALL_DATA=$(PREFIX)/share
diff --git a/src/Makefile b/src/Makefile
index 2426051..72f5009 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,8 +1,7 @@
 include ../Makefile.config
 
-CC=gcc
-CFLAGS=-Wall -O3 $(JUDY_INC)
-LIBS=$(JUDY_LIB) -lJudy 
+CC=g++
+CFLAGS=-Wall -O3
 
 OBJS=version.o buzhash.o
 TARGETS=hashgen hashdup onion
diff --git a/src/onion.c b/src/onion.c
index 08dca9a..1dc1327 100644
--- a/src/onion.c
+++ b/src/onion.c
@@ -13,10 +13,18 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <Judy.h>
 #include "buzhash.h"
 #include "version.h"
 
+#if defined __GNUC__ || defined __APPLE__
+#include <ext/hash_map>
+namespace std { using namespace __gnu_cxx; }
+#else
+#include <hash_map>
+#endif
+using namespace std;
+typedef hash_map<uint64_t,bool> ngrhash;
+
 #define BITMASK_HIGH63 0xfffffffffffffffeul
 
 #define NGRAM_SIZE 7
@@ -216,12 +224,7 @@ int main(int argc, char **argv) {
     buzhash_buffer_t bh_buffer;
     buzhash_init_buffer(&bh_buffer, Ngram_size);
 
-    // judy - for global duplicates
-    int judy_rc;
-    Pvoid_t judy = (Pvoid_t) NULL;
-
-    // ljudy - for local (document level) duplicates
-    Pvoid_t ljudy = (Pvoid_t) NULL;
+    ngrhash global, local;
 
     // read hashes of duplicate n-grams if available
     int have_dupl_ngrams = 0;
@@ -244,7 +247,7 @@ int main(int argc, char **argv) {
             hash_t masked_hash = hash & hash_bitmask;
             // store only the 63 most significant bits of the hash;
             // reserve the last bit as a flag (seen / unseen)
-            J1S(judy_rc, judy, masked_hash & BITMASK_HIGH63);
+            global[masked_hash & BITMASK_HIGH63] = true;
 
             // print progress information
             if (!Quiet && bytes_read % (10000000 * sizeof(hash)) == 0) {
@@ -331,7 +334,7 @@ int main(int argc, char **argv) {
         int doc_i;
         for (doc_i=0; doc_i<doc_count-1; doc_i++) {
             buzhash_clear_buffer(&bh_buffer);
-            J1FA(judy_rc, ljudy);
+            local.clear();
             // for all paragraphs in the document
             int par_i;
             for (par_i=docs[doc_i]; par_i<docs[doc_i+1]; par_i++) {
@@ -359,22 +362,22 @@ int main(int argc, char **argv) {
                     hash_t masked_hash = hash & hash_bitmask;
                     if (!buzhash_is_full_buffer(&bh_buffer))
                         continue;
-                    J1T(judy_rc, ljudy, hash);
-                    if (!judy_rc) {
+                    ngrhash::const_iterator it = local.find (hash);
+                    if (it == local.end()) {
                         if (have_dupl_ngrams) {
                             // test with the last bit set to 1
                             // (check against already seen duplicate ngrams)
-                            J1T(judy_rc, judy, masked_hash | 1);
+                            it = global.find (masked_hash | 1);
                         }
                         else {
-                            J1T(judy_rc, judy, masked_hash);
+                            it = global.find (masked_hash);
                         }
                     }
-                    if (judy_rc) {
+                    if (it != global.end()) {
                         bad_tokens+= Ngram_size - prev_bad_tokens;
                         prev_bad_tokens = Ngram_size;
                     } 
-                    J1S(judy_rc, ljudy, hash);
+                    local[hash] = true;
                 }
 
                 // remember the length of the paragraph
@@ -455,13 +458,12 @@ int main(int argc, char **argv) {
                             // stored hash to 1 if we have seen the matching
                             // duplicate n-gram to indicate it has been seen.
                             // Unique n-grams are ignored.
-                            J1U(judy_rc, judy, masked_hash & BITMASK_HIGH63);
-                            if (judy_rc)
-                                J1S(judy_rc, judy, masked_hash | 1); 
+                            if (global.erase (masked_hash & BITMASK_HIGH63))
+                                global[masked_hash | 1] = true;
                         }
                         else {
                             // otherwise we have to store hashes of all n-grams
-                            J1S(judy_rc, judy, masked_hash); 
+                            global[masked_hash] = true;
                         }
                     }
                 }
@@ -502,3 +504,5 @@ int main(int argc, char **argv) {
 
     return 0;
 }
+
+// vim: ts=4 sw=4 sta et sts=4 si cindent tw=80:
