diff --git a/lib/modules/ADT.pmod/heap.pike b/lib/modules/ADT.pmod/heap.pike
new file mode 100644
index 0000000000000000000000000000000000000000..2d1873acfe5f7224ed3925a2c156c1f1b147b0ec
--- /dev/null
+++ b/lib/modules/ADT.pmod/heap.pike
@@ -0,0 +1,110 @@
+#define SWAP(X,Y) do{ mixed tmp=values[X]; values[X]=values[Y]; values[Y]=tmp; }while(0)
+
+static private array values=allocate(10);
+static private int num_values;
+
+#ifdef DEBUG
+void verify_heap()
+{
+  int e;
+  for(e=1;e<num_values;e++)
+  {
+    if(values[(e-1)/2] > values[e])
+    {
+      write(sprintf("FEL in HEAP (%d, %d) num_values=%d\n", (e-1)/2, e, num_values));
+      exit(1);
+    }
+  }
+}
+#else
+#define verify_heap()
+#endif
+
+static void adjust_down(int elem)
+{
+  int steps;
+  while(1)
+  {
+    int child=elem*2+1;
+    if(child >= num_values) break;
+    
+    if(child+1==num_values || values[child] < values[child+1])
+    {
+      if(values[child] < values[elem])
+      {
+	SWAP(child, elem);
+	elem=child;
+	continue;
+      }
+    } else {
+      if(child+1 >= num_values) break;
+      
+      if(values[child+1] < values[elem])
+      {
+	SWAP(elem, child+1);
+	elem=child+1;
+	continue;
+      }
+    }
+    break;
+  }
+}
+
+static int adjust_up(int elem)
+{
+  int parent=(elem-1)/2;
+  
+  if(values[elem] < values[parent])
+  {
+    SWAP(elem, parent);
+    elem=parent;
+    while(values[elem] < values[parent=(elem -1)/2])
+    {
+      SWAP(elem, parent);
+      elem=parent;
+    }
+    adjust_down(elem);
+    return 1;
+  }
+  return 0;
+}
+
+void push(mixed value)
+{
+  if(num_values >= sizeof(values))
+    values+=allocate(10+sizeof(values)/16);
+  
+  values[num_values++]=value;
+  adjust_up(num_values-1);
+  verify_heap();
+}
+
+void adjust(mixed value)
+{
+  int pos=search(values, value);
+  if(pos>=0)
+    if(!adjust_up(pos))
+      adjust_down(pos);
+  verify_heap();
+}
+
+mixed top()
+{
+  mixed ret;
+  if(!num_values)
+    error("Heap underflow!\n");
+  
+  ret=values[0];
+  if(sizeof(values) > 1)
+  {
+    num_values--;
+    values[0]=values[num_values];
+    values[num_values]=0;
+    adjust_down(0);
+    
+    if(num_values * 3 + 10 < sizeof(values))
+      values=values[..num_values+10];
+  }
+  return ret;
+  verify_heap();
+}
diff --git a/lib/modules/ADT.pmod/priority_queue.pike b/lib/modules/ADT.pmod/priority_queue.pike
new file mode 100644
index 0000000000000000000000000000000000000000..4fd0ed115612aab74282df6ad04a51e9c5d6e544
--- /dev/null
+++ b/lib/modules/ADT.pmod/priority_queue.pike
@@ -0,0 +1,29 @@
+inherit "heap";
+
+class elem {
+  int pri;
+  mixed value;
+  
+  void create(int a, mixed b) { pri=a; value=b; }
+  
+  int `<(object o) { return pri<o->pri; }
+  int `>(object o) { return pri>o->pri; }
+  int `==(object o) { return pri==o->pri; }
+};
+
+mixed push(int pri, mixed val)
+{
+  mixed handle;
+  
+  handle=elem(pri, val);
+  ::push(handle);
+  return handle;
+}
+
+void adjust_pri(mixed handle, int new_pri)
+{
+  handle->pri=new_pri;
+  ::adjust(handle);
+}
+
+mixed next() { return top()->value; }
diff --git a/lib/modules/ADT.pmod/stack.pike b/lib/modules/ADT.pmod/stack.pike
new file mode 100644
index 0000000000000000000000000000000000000000..7fd72d8f9417cf5a534aae997d3cd8fd9f39697d
--- /dev/null
+++ b/lib/modules/ADT.pmod/stack.pike
@@ -0,0 +1,45 @@
+#define error(X) throw( ({ (X), backtrace()[0..sizeof(backtrace())-2] }) )
+
+int ptr;
+mixed *arr=allocate(32);
+
+void push(mixed val)
+{
+  if(ptr==sizeof(arr)) arr+=allocate(ptr);
+  arr[ptr++]=val;
+}
+
+mixed pop(void|int val)
+{
+  mixed foo;
+  
+  if (val) {
+    if (ptr <= 0) {
+      error("Stack underflow\n");
+    }
+    
+    if (ptr < val) {
+      val = ptr;
+    }
+    ptr -= val;
+    foo = arr[ptr..ptr + val - 1];
+    
+    for (int i=0; i < val; i++) {
+      arr[ptr + i] = 0;       /* Don't waste references */
+    }
+  } else {
+    if(--ptr < 0)
+      error("Stack underflow\n");
+    
+    foo=arr[ptr];
+    arr[ptr]=0; /* Don't waste references */
+  }
+  return foo;
+}
+
+void reset()
+{
+  arr=allocate(32);
+  ptr=0;
+}
+