/// <summary>
        /// Performs additional checks on the arguements that were passed to the application.
        /// </summary>
        /// <param name="Args">The arguements that were passed to the application.</param>
        /// <returns><c>true</c> if there were no validation errors and <c>false</c> if there were validation errors.</returns>
        private static bool PassesAdditionalValidation(ApplicationArguments Args)
        {
            try
            {
                // validate we can connect to the database (i.e. clanbanner_sql_Content).
                using (var sqConn = new SQLiteConnection(string.Format("Data Source={0};Version=3;", Args.Database)))
                {
                    sqConn.Open();
                    sqConn.Close();
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to create a connection to the SQLite database {0}.", Args.Database);
                return(false);
            }

            try
            {
                uint.Parse(Args.DecalId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.DecalId);
                return(false);
            }

            try
            {
                uint.Parse(Args.DecalColorId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.DecalColorId);
                return(false);
            }

            try
            {
                uint.Parse(Args.DecalBackgroundColorId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.DecalBackgroundColorId);
                return(false);
            }

            try
            {
                uint.Parse(Args.GonfalonId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.GonfalonId);
                return(false);
            }

            try
            {
                uint.Parse(Args.GonfalonColorId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.GonfalonColorId);
                return(false);
            }

            try
            {
                uint.Parse(Args.GonfalonDetailId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.GonfalonDetailId);
                return(false);
            }

            try
            {
                uint.Parse(Args.GonfalonDetailColorId);
            }
            catch (Exception)
            {
                Console.WriteLine("Unable to cast {0} to an unsigned integer.", Args.GonfalonDetailColorId);
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// This is the main method that is used for creating the cln banner image.
        /// </summary>
        /// <param name="Args">The arguements that were passed to the application.</param>
        private static void BuildClanBanner(ApplicationArguments Args)
        {
            // get the managed GDI+ png image codec.  This is what the managed GDI+ will use to encode the image
            // when the codec is passed to the Save function.
            ImageCodecInfo codec = GetEncoderInfo("image/png");

            if (codec == null)
            {
                throw new NullReferenceException("Unable to get the ImageCodecInfo for image/png");
            }

            // The Quality parameter specifies the level of compression for an image which is from 0 to 100.
            // The lower the number specified, the higher the compression and therefore the lower the quality of
            // the image. Zero would give you the lowest quality image and 100 the highest.
            Encoder           encorderQuality         = Encoder.Quality;
            EncoderParameter  encoderParameterQuality = new EncoderParameter(encorderQuality, 90L);
            EncoderParameters codecParams             = new EncoderParameters(1);

            codecParams.Param[0] = encoderParameterQuality;

            // go ahead and parse the hashes to unsigned integers.  There is no need to use uint.TryParse because
            // we tested the arguements earlier in our additional validation.
            uint decalId                = uint.Parse(Args.DecalId);
            uint decalColorId           = uint.Parse(Args.DecalColorId);
            uint decalBackgroundColorId = uint.Parse(Args.DecalBackgroundColorId);
            uint gonfalonId             = uint.Parse(Args.GonfalonId);
            uint gonfalonColorId        = uint.Parse(Args.GonfalonColorId);
            uint gonfalonDetailId       = uint.Parse(Args.GonfalonDetailId);
            uint gonfalonDetailColorId  = uint.Parse(Args.GonfalonDetailColorId);

            dynamic gonfalonJson = ExecuteQuery(Args.Database, string.Format("SELECT json FROM Gonfalons WHERE CASE WHEN (id < 0) THEN (id + 4294967296) ELSE id END = {0}", gonfalonId));

            byte[] gonfalonImageData = new System.Net.WebClient().DownloadData(string.Format("{0}{1}", BASE_ADDRESS, gonfalonJson.foregroundImagePath));
            Bitmap gonfalonImage;

            using (var ms = new MemoryStream(gonfalonImageData))
            {
                gonfalonImage = new Bitmap(ms);
            }

            byte[] flagStaffImageData = new System.Net.WebClient().DownloadData(string.Format("{0}{1}", BASE_ADDRESS, FLAG_STAFF));
            Bitmap flagStaffImage;

            using (var ms = new MemoryStream(flagStaffImageData))
            {
                flagStaffImage = new Bitmap(ms);
            }

            int masterWidth  = flagStaffImage.Width;
            int masterHeight = flagStaffImage.Height;

            flagStaffImage = ScaleImage(flagStaffImage, 422, 616);

            byte[] flagOverlayImageData = new System.Net.WebClient().DownloadData(string.Format("{0}{1}", BASE_ADDRESS, FLAG_OVERLAY));
            Bitmap flagOverlayImage;

            using (var ms = new MemoryStream(flagOverlayImageData))
            {
                flagOverlayImage = new Bitmap(ms);
            }

            // We need to shift the overlay image so that it lines up properly with the gonfalon for clipping.
            Bitmap b = new Bitmap(flagOverlayImage.Width, flagOverlayImage.Height);

            b.SetResolution(flagOverlayImage.HorizontalResolution, flagOverlayImage.VerticalResolution);
            Graphics  g    = Graphics.FromImage(b);
            Rectangle rect = new Rectangle(35, 0, gonfalonImage.Width, gonfalonImage.Height);

            g.DrawImage(gonfalonImage, rect, 0, 0, gonfalonImage.Width, gonfalonImage.Height, GraphicsUnit.Pixel);

            ClipBitmapBasedOnGonfalon(b, ref flagOverlayImage, false);

            Bitmap decal = BuildDecalImage(Args.Database, gonfalonImage, decalId, decalColorId, decalBackgroundColorId);

            Bitmap gonfalon = BuildGonfalonImage(Args.Database, gonfalonImage, gonfalonColorId, gonfalonDetailId, gonfalonDetailColorId);

            Stack <ImageSettings> images = new Stack <ImageSettings>();

            images.Push(new ImageSettings(flagStaffImage, 38, 0));
            images.Push(new ImageSettings(flagOverlayImage, 12, 42));
            images.Push(new ImageSettings(decal, 48, 42));
            images.Push(new ImageSettings(gonfalon, 48, 42));

            Bitmap clanBanner = Merge(images, masterWidth, masterHeight, flagStaffImage.HorizontalResolution, flagStaffImage.VerticalResolution);

            clanBanner.Save(Args.SaveAs, codec, codecParams);
        }