static void SWAPK(int k, int k_max, BigInteger [][] b, BigInteger [][] H,
              boolean []f, BigInteger [] d, BigInteger [][] lambda)
   // the SWAPK procedure of algorithm 2.7.2
   {
//      System.out.println("SWAPK:");
     // exchange H[k] and H[k-1]
     // This can be done efficiently by swapping pointers (not entries).
     BigInteger [] aswap=H[k];
     H[k]=H[k-1];
     H[k-1]=aswap;

     // exchange b[k] and b[k-1] by the same method
     aswap=b[k];
     b[k]=b[k-1];
     b[k-1]=aswap;

     if(k>1) {
       for(int j=0;j<=k-2;j++)
       {
         // exchange lambda[k][j] and lambda[k-1][j]
         BigInteger swap=lambda[k][j];
//         System.out.println("Swapping ["+k+"]["+j+"]="+lambda[k][j]+" with ["+(k-1)+"]["+j+"]="+lambda[k-1][j]);
         lambda[k][j]=lambda[k-1][j];
         lambda[k-1][j]=swap;
       }
     }

     BigInteger _lambda=lambda[k][k-1];
//     System.out.println("lambda["+k+"]["+(k-1)+"]="+_lambda);

     if(_lambda.compareTo(ZERO)==0)
     {
       d[k]=d[k-1];
       f[k-1]=false;
//       System.out.println("SWAPK: f["+(k-1)+"] is false");
       f[k]=true;
//       System.out.println("SWAPK: f["+k+"] is true");
       lambda[k][k-1] = ZERO;
       for(int i=k+1;i<=k_max;i++)
       {
         lambda[i][k]=lambda[i][k-1];
         lambda[i][k-1] = ZERO;
       }
     }
     else
       // lambda!=0
     {
       for(int i=k+1;i<=k_max;i++) {
         //lambda[i][k-1]=(_lambda*lambda[i][k-1])/d[k];
          BigInteger lnum = _lambda.multiply(lambda[i][k-1]);
         lambda[i][k-1] = floorDivide(lnum,d[k]);
       }

       // Multiplie lambda[i][k-1] by _lambda/d[k].
       // One could also write
       //   lambda[i][k-1]*=(lambda/d[k]);   (*)
       // Without a BigInt class, this can prevent overflows when computing
       // _lambda*lambda[i][k-1].
       // But examples show that lambda/d[k] is in general not an integer.
       // So (*) could lead to problems due to the inexact floating point
       // arithmetic...
       // Therefore, we chose the secure evaluation order in all such cases.

       BigInteger t=d[k+1];
       //d[k]=(_lambda*_lambda)/d[k];
       BigInteger num = _lambda.multiply(_lambda);
       d[k]=floorDivide(num,d[k]);
       d[k+1]=d[k];

       for(int j=k+1;j<=k_max-1;j++) {
         for(int i=j+1;i<=k_max;i++) {
           //lambda[i][j]=(lambda[i][j]*d[k])/t;
            num = lambda[i][j].multiply(d[k]);
           lambda[i][j]=floorDivide(num,t);
         }
       }

       for(int j=k+1;j<=k_max;j++) {
         //d[j+1]=(d[j+1]*d[k])/t;
          num = d[j+1].multiply(d[k]); 
         d[j+1]=floorDivide(num,t);
       }
     }

   }