/// <summary>
        /// Selects a guessed background of the input image
        /// </summary>
        /// <param name="input">The input image</param>
        /// <param name="token">The cancellation token</param>
        /// <remarks>Performs a BFS</remarks>
        /// <returns>Returns the list of pixels having the same color as the color of the guessed background, null when cancellation was requested</returns>
        private List <int> SelectBackground(PPImage input, CancellationToken token = default)
        {
            SKColor bgColor = SKColors.Transparent;

            Dictionary <SKColor, List <int> > components = new Dictionary <SKColor, List <int> >();

            int[] cornerIndices = new int[] { 0,                                              //top-left
                                              input.Bitmap.Width - 1,                         //top-right
                                              (input.Bitmap.Height - 1) * input.Bitmap.Width, //bottom-left
                                              input.Bitmap.Width *input.Bitmap.Height - 1 };  //bottom-right};

            var pixels = input.Bitmap.Pixels;

            SKColor[] cornerColors = new SKColor[4]
            {
                pixels[cornerIndices[0]],
                pixels[cornerIndices[1]],
                pixels[cornerIndices[2]],
                pixels[cornerIndices[3]]
            };

            bool[] visited = new bool[input.Bitmap.Width * input.Bitmap.Height];
            Dictionary <SKColor, float> colorCounts = new Dictionary <SKColor, float>();

            Queue <int> toVisit = new Queue <int>();

            foreach (var corner in cornerIndices)
            {
                if (token.IsCancellationRequested)
                {
                    return(null);
                }
                toVisit.Enqueue(corner);
                visited[corner] = true;
            }

            if (cornerColors.All(x => x == cornerColors[0]))
            {
                colorCounts.Add(cornerColors[0], 0.0f);
                components.Add(cornerColors[0], new List <int>());
                int totalVisited = 0;
                while (toVisit.Count > 0)
                {
                    if (token.IsCancellationRequested)
                    {
                        return(null);
                    }
                    var curr = toVisit.Dequeue();
                    totalVisited++;
                    foreach (var neigh in GetNeighborhood(curr, input).Where(x => x != curr && x >= 0 && x < input.Bitmap.Width * input.Bitmap.Height))
                    {
                        if (visited[neigh] || pixels[neigh] != cornerColors[0])
                        {
                            continue;
                        }
                        toVisit.Enqueue(neigh);
                        visited[neigh] = true;
                    }
                    if (pixels[curr] == cornerColors[0])
                    {
                        components[cornerColors[0]].Add(curr);
                        colorCounts[cornerColors[0]] += 1.0f;
                    }
                }

                return(components[cornerColors[0]]);
            }
            else
            {
                var uniqueColors = cornerColors.Distinct();
                foreach (var x in uniqueColors)
                {
                    components.Add(x, new List <int>());
                    colorCounts.Add(x, 0.0f);
                }

                while (toVisit.Count > 0)
                {
                    if (token.IsCancellationRequested)
                    {
                        return(null);
                    }
                    var curr = toVisit.Dequeue();
                    foreach (var neigh in GetNeighborhood(curr, input).Where(z => z != curr && z >= 0 && z < input.Bitmap.Width * input.Bitmap.Height))
                    {
                        if (visited[neigh] || !cornerColors.Contains(pixels[neigh]))
                        {
                            continue;
                        }
                        toVisit.Enqueue(neigh);
                        visited[neigh] = true;
                    }
                    //if (uniqueColors.Contains(input.Pixels[curr]))
                    //{
                    components[pixels[curr]].Add(curr);
                    float x       = curr % input.Bitmap.Width;
                    float y       = curr / input.Bitmap.Width;
                    float middleX = input.Bitmap.Width / 2.0f;
                    float middleY = input.Bitmap.Height / 2.0f;
                    colorCounts[pixels[curr]] += Max(Abs(middleX - x), Abs(middleY - y));
                    //colorCounts[input.Pixels[curr]] += 1.0f;
                    //}
                    visited[curr] = true;
                }

                bgColor = colorCounts.OrderByDescending(x => x.Value).First().Key;
                return(components[bgColor]);
            }

            //return bgColor;
        }