Объясните (ОЧЕНЬ подробно следующий код о соортировке массива слиянием, написанный на языке программирования C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp4
{
 class Program
 {
 static void Main(string[ ] args)
 {
 int[ ] arr = { 3, 5, 1, 5, 1, 7, 2 };
 foreach (int a in arr)
 Console.Write(a + " "); Console.ReadKey();
 CycleMergeSort(ref arr);
 Console.WriteLine();
 foreach (int a in arr)
 Console.Write(a + " "); Console.ReadKey();
 }
 static void CycleMergeSort(ref int[ ] arr) 
 {
 for (int size = 1; size < arr.Length; size *= 2)
 for (int i = 0; i < arr.Length; i += size * 2)
 MergeSorted(ref arr, i, size);
 }
 static void MergeSorted(ref int[ ] arr, int startIndex, int leftLength) // leftLength - длина объединяемого массива
 {
 int rightLength = arr.Length - startIndex - leftLength;
 if (leftLength < rightLength)
 rightLength = leftLength;
 if (rightLength <= 0)
 return;
 int[ ] result = new int[leftLength + rightLength];
 for (int l = 0, r = 0; l < leftLength || r < rightLength;)
 {
 if (r == rightLength || l != leftLength && arr[startIndex + l] < arr[startIndex + leftLength + r])
 {
 result[l + r] = arr[startIndex + l];
 l++;
 }
 else 
 {
 result[l + r] = arr[startIndex + leftLength + r];
 r++;
 }
 }
 for (int i = 0; i < leftLength + rightLength; i++)
 arr[i + startIndex] = result[i];
 }
 }
}