/// <summary>
        /// </summary>
        /// <returns>Docking station event</returns>
        public DockingStationEvent Execute()
        {
            UploadDatabaseEvent uploadEvent = new UploadDatabaseEvent(this);

            CompressDatabase(uploadEvent);
#if DEBUG
            // UncompressDatabase( uploadEvent );  // unit test.  Temporarily uncomment it to run it.
#endif

            return(uploadEvent);
        }
        /// <summary>
        ///
        /// </summary>
        /// <remarks>
        /// System.IO.Packaging.ZipPackage can handle .zip files, but it is not supported in Compact Framework.
        /// We therefore use the freeware SharpZipLib to do our uncompression.
        /// </remarks>
        /// <param name="uploadEvent"></param>
        private void CompressDatabase(UploadDatabaseEvent uploadEvent)
        {
            string dbFilePath = Controller.FLASHCARD_PATH + Controller.INET_DB_NAME;

            FileInfo finfo       = new FileInfo(dbFilePath);
            long     totalLength = finfo.Length;

            using (FileStream dbFileStream = new FileStream(dbFilePath, FileMode.Open))
            {
                MemoryStream    outputMemStream = new MemoryStream();
                ZipOutputStream zipStream       = new ZipOutputStream(outputMemStream);

                // We just use default compression leve, which I think is actually 6.
                zipStream.SetLevel(Deflater.DEFAULT_COMPRESSION);   // 0-9, 9 being the highest compression, 0 being no compression

                ZipEntry newEntry = new ZipEntry(Controller.INET_DB_NAME);
                newEntry.DateTime = DateTime.UtcNow;

                zipStream.PutNextEntry(newEntry);

                // Assign the entry's size to what the file size is expected to be when
                // uncompressed.  This is necessary to get Window's built-in extractor to work,
                // according to SharpZipLib sample code.
                newEntry.Size = finfo.Length;

                DateTime startTime = DateTime.UtcNow;

                // Copy the file into the zip stream.  The ZipStream
                // compresses the data as it's fed into it.
                const int bufferSize   = 8196;
                long      logThreshold = bufferSize * 50;
                byte[]    buffer       = new byte[bufferSize];
                int       bytesRead;
                long      totalBytesRead = 0;
                while ((bytesRead = dbFileStream.Read(buffer, 0, bufferSize)) > 0)
                {
                    zipStream.Write(buffer, 0, bytesRead);

                    totalBytesRead += bytesRead;

                    if ((totalBytesRead % logThreshold) == 0)
                    {
                        LogCompression(totalBytesRead, totalLength, outputMemStream.Length);
                    }
                }

                zipStream.CloseEntry();

                zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
                zipStream.Close();               // Must finish the ZipOutputStream before using outputMemStream.

                outputMemStream.Position = 0;

                DateTime endTime = DateTime.UtcNow;
                TimeSpan elapsed = endTime - startTime;
                LogCompression(totalBytesRead, totalLength, outputMemStream.Length);
                Log.Debug(string.Format("Compression finished. Elapsed time: {0} seconds.", (int)elapsed.TotalSeconds));

                // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
                uploadEvent.File = outputMemStream.ToArray();
                // Alternative:  GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
                //byte[] byteArrayOut = outputMemStream.GetBuffer();
                //long len = outputMemStream.Length;

                uploadEvent.FileName = newEntry.Name + ".zip";
            }
        }