mergesort = cluster is create, merge, mergeSort

    % default constructor
    create = proc() returns (cvt)
        return()
        end create

	% merges two subarrays of arr[]
	merge = proc(arr: array[int], l: int, m: int, r: int)
		int: n1 := m - l + 1
		int: n2 := r - m

		
		% create temp arrays
		array[int]: L := array[int]$create(n1)
		array[int]: R := array[int]$create(n2)

		% copy data to temp arrays L[] and R[]
		for x: int in L$indexes() do
			L[x] = arr[l + x]
			end
		for y: int in R$indexes() do
			L[y] = arr[m + 1 + y]
			end

		% merge temp arrays back to arr[l...r]
		int: i := 0 % index first subarray
		int: j := 0 % index second subarray
		int: k := 0 % index merged

		while i < L$size() cand j < R$size() do
			if L[i] < R[j] then
				arr[k] := L[i]
				i := i + 1
			else
				arr[k] := R[j]
				j := j + 1
			end
			
			k := k + 1
		end

		% copy rest of L[]
		while i < L$size() do
			arr[k] := L[i]
			i := i + 1
			k := k + 1
		end

		% copy rest of R[]
		while i < L$size() do
			arr[k] := L[i]
			i := i + 1
			k := k + 1
		end
	end merge

	sort = proc(arr: array[int], l: int, r: int)
		% recursive invocation
		if l < r then
			int: m := l + (r - l) / 2
			sort(arr, l, m)
			sort(arr, m + 1, r)
			merge(arr, l, m, r)
		end
	end sort
	
end mergesort