function X = mergesort(List, descending)
% List:       list of numbers to sort
% descending: if 0 then sort in 'ascending' order, 
%             else in 'descending' order

if nargin < 1
	error('Too few parameters.');
end

if nargin < 2
	descending = 0;
end

n = length(List);
if n <= 1
	X = List;
	return
end

% median
med = floor(n/2);   % rounds the input X to the nearest integers towards minus infinity

% sort left and right sub list 'ascending'
X1 = mergesort(List(1:med), 0);
X2 = mergesort(List(med+1:end), 0);

% allocate memory
X  = List;

i1 = 1;
i2 = 1;
for i = 1:n
    if i1 > length(X1)
        % all elements of X1 were processed
        X(i:end) = X2(i2:end);
        break
    end
	if i2 > length(X2)
        % all elements of X2 were processed
        X(i:end) = X1(i1:end);
        break
	end
	if X1(i1) <= X2(i2)
        % current element of X1 is smaller than (or equal to) current 
        % element of X2
        X(i) = X1(i1);
        i1   = i1 + 1;
    else
        % current element of X2 is smaller than current object in X2
        X(i) = X2(i2);
        i2   = i2 + 1;
	end
end

if descending
	X = X(end:-1:1);
end
