/**
         * Mergesort algorithm (driver).
         */
        void mergeSort(array a[])
        {
            array tmpArray[a.size()];

            mergeSort( a, tmpArray, 0, a.size( ) - 1 );
        }

        /**
         * Internal method that makes recursive calls.
         * a is an array of items to be sorted.
         * tmpArray is an array to place the merged result.
         * left is the left-most index of the subarray.
         * right is the right-most index of the subarray.
         */
        void mergeSort( array a[], array tmpArray[], int left, int right )
        {
            if( left < right )
            {
                int center = ( left + right ) / 2;
                mergeSort( a, tmpArray, left, center );
                mergeSort( a, tmpArray, center + 1, right );
                merge( a, tmpArray, left, center + 1, right );
            }
        }

        /**
         * Internal method that merges two sorted halves of a subarray.
         * a is an array of items to be sorted
         * tmpArray is an array to place the merged result.
         * leftPos is the left-most index of the subarray.
         * rightPos is the index of the start of the second half.
         * rightEnd is the right-most index of the subarray.
         */
        void merge( array a[], array tmpArray[],
               int leftPos, int rightPos, int rightEnd )
        {
            int leftEnd = rightPos - 1;
            int tmpPos = leftPos;
            int numElements = rightEnd - leftPos + 1;

            // Main loop
            while( leftPos <= leftEnd && rightPos <= rightEnd )
                if( a[ leftPos ] <= a[ rightPos ] )
                    tmpArray[ tmpPos++ ] = a[ leftPos++ ];
                else
                    tmpArray[ tmpPos++ ] = a[ rightPos++ ];

            while( leftPos <= leftEnd )    // Copy rest of first half
                tmpArray[ tmpPos++ ] = a[ leftPos++ ];

            while( rightPos <= rightEnd )  // Copy rest of right half
                tmpArray[ tmpPos++ ] = a[ rightPos++ ];

            // Copy tmpArray back
            for( int i = 0; i < numElements; i++, rightEnd-- )
                a[ rightEnd ] = tmpArray[ rightEnd ];
        }

        /**
         * Quicksort algorithm (driver).
         */
        void quicksort( array a[] )
        {
            quicksort( a, 0, a.size( ) - 1 );
        }

        /**
         * Standard swap
         */
        inline void swap( obj1, obj2 )
        {
            tmp = obj1;
            obj1 = obj2;
            obj2 = tmp;
        }

        /**
         * Return median of left, center, and right.
         * Order these and hide the pivot.
         */
        median3( array a[], int left, int right )
        {
            int center = ( left + right ) / 2;
            if( a[ center ] < a[ left ] )
                swap( a[ left ], a[ center ] );
            if( a[ right ] < a[ left ] )
                swap( a[ left ], a[ right ] );
            if( a[ right ] < a[ center ] )
                swap( a[ center ], a[ right ] );

                // Place pivot at position right - 1
            swap( a[ center ], a[ right - 1 ] );
            return a[ right - 1 ];
        }

        /**
         * Internal quicksort method that makes recursive calls.
         * Uses median-of-three partitioning and a cutoff of 10.
         * a is an array of items to be sorted
         * left is the left-most index of the subarray.
         * right is the right-most index of the subarray.
         */
        void quicksort( array a[], int left, int right )
        {
/* 1*/      if( left + 20 <= right )
            {
/* 2*/          pivot = median3( a, left, right );

                    // Begin partitioning
/* 3*/          int i = left, j = right - 1;
/* 4*/          for( ; ; )
                {
/* 5*/              while( a[ ++i ] < pivot ) { }
/* 6*/              while( pivot < a[ --j ] ) { }
/* 7*/              if( i < j )
/* 8*/                  swap( a[ i ], a[ j ] );
                    else
/* 9*/                  break;
                }

/*10*/          swap( a[ i ], a[ right - 1 ] );  // Restore pivot

/*11*/          quicksort( a, left, i - 1 );     // Sort small elements
/*12*/          quicksort( a, i + 1, right );    // Sort large elements
            }
            else  // Do an insertion sort on the subarray
/*13*/          insertionSort( a, left, right );
        }

        /**
         * Internal insertion sort routine for subarrays
         * that is used by quicksort.
         * a is an array of items to be sorted
         * left is the left-most index of the subarray.
         * right is the right-most index of the subarray.
         */
        void insertionSort( array a[], int left, int right )
        {
            for( int p = left + 1; p <= right; p++ )
            {
                tmp = a[ p ];
                int j;

                for( j = p; j > left && tmp < a[ j - 1 ]; j-- )
                    a[ j ] = a[ j - 1 ];
                a[ j ] = tmp;
            }
        }