private void button1_Click(object sender, EventArgs e)
        {
            var bgcolor = source.GetPixel(0, 0);
            var record  = BrutalDeluxeClassifier.Decompose(source, bgcolor);

            var classified = new Bitmap(source.Width, source.Height);

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < (source.Width / 2); x++)
                {
                    // A mask value of 255 (0xFF) is a tansparent pair of pixels, use the background color
                    var color = BrutalDeluxeClassifier.ToRGB(record.Classes[x, y]);
                    classified.SetPixel(2 * x, y, color);
                    classified.SetPixel(2 * x + 1, y, color);
                }
            }

            pictureBox3.Image    = Expand(classified, pictureBox3.ClientSize.Width, pictureBox3.ClientSize.Height);;
            pictureBox3.SizeMode = PictureBoxSizeMode.Zoom;


            var rb_record = BrutalDeluxeClassifier.DecomposeIntoRedBlueImageMap(source, bgcolor);

            var rb_classified = new Bitmap(source.Width, source.Height);

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < (source.Width / 2); x++)
                {
                    // A mask value of 255 (0xFF) is a tansparent pair of pixels, use the background color
                    var color = BrutalDeluxeClassifier.ToRGB(rb_record.Classes[x, y]);
                    rb_classified.SetPixel(2 * x, y, color);
                    rb_classified.SetPixel(2 * x + 1, y, color);
                }
            }

            pictureBox2.Image    = Expand(rb_classified, pictureBox2.ClientSize.Width, pictureBox2.ClientSize.Height);;
            pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;

            var histogram = BrutalDeluxeClassifier.GenerateStatistics(rb_record);

            textBox1.Clear();

            textBox1.AppendText("Most Common Values\n");
            textBox1.AppendText("------------------\n");
            foreach (var stat in histogram.OrderByDescending(x => x.Value).Take(10))
            {
                textBox1.AppendText(String.Format("0x{0:X} : {1}\n", stat.Key, stat.Value));
            }

            // Initialize the search
            var maxCycles = 5 + source.Height * (3 + (source.Width / 4 * 31) - 1 + 41) - 1;

            problem      = SpriteGeneratorSearchProblem.CreateSearchProblem();
            initialState = SpriteGeneratorState.Init(rb_record.SpriteData);

            var expander = new SpriteGeneratorNodeExpander();

            strategy = new InspectableTreeSearch(expander);

            strategy.Initialize(problem, initialState);
        }
        static void Main(string[] args)
        {
            var   data      = new List <byte>();
            var   mask      = new List <byte>();
            var   filename  = (string)null;
            Color?maskColor = null;
            int?  maxCycles = null;
            var   sprite    = new List <SpriteByte>();
            bool  verbose   = false;

            var p = new FluentCommandLineParser();

            p.Setup <List <string> >('d', "data")
            .Callback(_ => data = _.Select(s => Convert.ToByte(s, 16)).ToList());

            p.Setup <List <string> >('m', "mask")
            .Callback(_ => mask = _.Select(s => Convert.ToByte(s, 16)).ToList());

            p.Setup <string>('i', "image")
            .Callback(_ => filename = _);

            p.Setup <string>('l', "limit")
            .Callback(_ => maxCycles = int.Parse(_));

            p.Setup <string>('v', "verbose")
            .Callback(_ => verbose = true);

            p.Setup <string>("bg-color")
            .Callback(_ => maskColor = Color.FromArgb(0xFF, Color.FromArgb(Convert.ToInt32(_, 16))));

            p.Parse(args);

            Console.WriteLine("Manual data has " + data.Count + " bytes");
            Console.WriteLine("Manual mask has " + mask.Count + " bytes");
            Console.WriteLine("Input filename is " + filename);
            Console.WriteLine("Image mask color is " + (maskColor.HasValue ? maskColor.ToString() : "(none)"));

            // Set the global state
            var problem = SpriteGeneratorSearchProblem.CreateSearchProblem();
            var search  = maxCycles.HasValue ?
                          SpriteGeneratorSearchProblem.Create(maxCycles.Value) :
                          SpriteGeneratorSearchProblem.Create();

            SpriteGeneratorState initialState = null;

            // Handle the difference command line cases
            if (!String.IsNullOrEmpty(filename))
            {
                var bitmap = new Bitmap(filename);
                var record = BrutalDeluxeClassifier.Decompose(bitmap, maskColor);

                record.Data.Dump();
                Console.WriteLine();
                record.Mask.Dump();
                Console.WriteLine();
                record.Classes.Dump();

                //initialState = SpriteGeneratorState.Init(sprite);
            }
            else if (data.Count == mask.Count)
            {
                initialState = SpriteGeneratorState.Init(data, mask);
            }
            else
            {
                initialState = SpriteGeneratorState.Init(data);
            }

            //var solution = search.Search(problem, initialState);
            //WriteOutSolution(solution);
        }