diff --git a/src/fsort_template.h b/src/fsort_template.h
index 375bbfe3b47369574390ccf75acb92ce8016b59a..c00ac378f694d84ec93213379dca185ed4b1d76b 100644
--- a/src/fsort_template.h
+++ b/src/fsort_template.h
@@ -1,5 +1,5 @@
 /*
- * $Id: fsort_template.h,v 1.4 1998/04/27 22:33:17 hubbe Exp $
+ * $Id: fsort_template.h,v 1.5 1999/04/30 07:25:42 hubbe Exp $
  */
 
 #ifndef SWAP
@@ -16,6 +16,9 @@
 #define DEC(X) X=STEP(X,-1)
 #define SIZE ((long)(char *)STEP((TYPE *)0,1))
 
+#define PARENT(X) (((X)-1)>>1)
+#define CHILD1(X) (((X)<<1)+1)
+
 static void ID(register TYPE *bas,
 	       register TYPE *last
 #ifdef EXTRA_ARGS
@@ -26,67 +29,56 @@ static void ID(register TYPE *bas,
 #endif
   )
 {
-  register TYPE *a,*b, tmp;
-  if(bas >= last) return;
-  a = STEP(bas,1);
-  if(a == last)
+  register TYPE tmp;
+  long howmany,x,y,z;
+#ifdef PIKE_DEBUG
+  extern int d_flag;
+#endif
+
+  howmany=((((char *)last)-((char *)bas))/SIZE)+1;
+  if(howmany<2) return;
+
+  for(x=PARENT(howmany-1);x>=0;x--)
   {
-    if( CMP(bas,last) > 0) SWAP(bas,last); 
-  }else{
-    b=STEP(bas,((((char *)last)-((char *)bas))/SIZE)>>1);
-    SWAP(bas,b);
-    b=last;
-    while(a < b)
+    y=x;
+    while(1)
     {
-#if 1
-      while(a<b)
-      {
-	while(1)
-	{
-	  if(a<=b && CMP(a,bas) <= 0)
-	    INC(a);
-	  else
-	  {
-	    while(a< b && CMP(bas,b) <= 0) DEC(b);
-	    break;
-	  }
-	  if(a< b && CMP(bas,b) <= 0)
-	    DEC(b);
-	  else
-	  {
-	    while(a<=b && CMP(a,bas) <= 0) INC(a);
-	    break;
-	  }
-	}
+      z=CHILD1(y);
+      if(z>=howmany) break;
+      if(z+1 < howmany && CMP(STEP(bas,z),STEP(bas,z+1))<=0) z++;
+      if(CMP( STEP(bas, y), STEP(bas, z)) >0) break;
+      SWAP( STEP(bas, y), STEP(bas, z));
+      y=z;
+    }
+  }
 
-	if(a<b)
-	{
-	  SWAP(a,b);
-	  INC(a);
-	  if(b > STEP(a,1)) DEC(b);
-	}
-      }
-#else
-      while(a<=b && CMP(a,bas) < 0) INC(a);
-      while(a< b && CMP(bas,b) < 0) DEC(b);
-      if(a<b)
-      {
-        SWAP(a,b);
-	INC(a);
-	if(b > STEP(a,1)) DEC(b);
-      }
-#endif
+  for(x=howmany-1;x;x--)
+  {
+    SWAP( STEP(bas,x), bas);
+    y=0;
+    while(1)
+    {
+      z=CHILD1(y);
+      if(z>=x) break;
+      if(z+1 < x && CMP(STEP(bas,z),STEP(bas,z+1))<=0) z++;
+      if(CMP( STEP(bas, y), STEP(bas, z)) >0) break;
+      SWAP( STEP(bas, y), STEP(bas, z));
+      y=z;
     }
-    DEC(a);
-    SWAP(a,bas);
-    DEC(a);
-    ID(bas,a XARGS);
-    ID(b,last XARGS);
   }
+
+#ifdef PIKE_DEBUG
+  if(d_flag>1)
+    for(x=howmany-1;x;x--)
+      if( CMP( STEP(bas,x-1), STEP(bas,x)  ) > 0)
+	fatal("Sorting failed!\n");
+#endif
 }
 
 #undef INC
 #undef DEC
+#undef PARENT
+#undef CHILD1
 
 #ifdef UNDEF_XARGS
 #undef XARGS