static void Main(string[] args)
        {
            #if DEBUG
            // Debug mode only: 12-second pause to allow Visual Studio debugger to attach via "Debug | Attach to Process".
            Thread.Sleep(12000);
            #endif
            // Initialize the Log4Net based logger.
            _logger = new SimpleLogger("QvBigDataConn");
            String log_path = Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "QvBigDataConn");
            if (!Directory.Exists(log_path))
            {
                try
                {
                    Directory.CreateDirectory(log_path);
                }
                catch (Exception)
                {
                    log_path = Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
                }
            }
            _logger.EnableFileLogging(log_path, log4net.Core.Level.Debug);
            _logger.LogMsg(log4net.Core.Level.Debug, "Entering Main() function of connector.");

            try
            {
                //_logger.LogMsg(Level.Debug, String.Format("Application config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.None)));
                //_logger.LogMsg(Level.Debug, String.Format("Roaming user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoaming)));
                //_logger.LogMsg(Level.Debug, String.Format("Local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));
                _logger.LogMsg(Level.Debug, String.Format("Initializing local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));

                // Initialize the User settings from saved config file.
                if (Properties.Settings.Default.UpgradeFromPrevious)
                {
                    // If this is the first time the user has run the app and a previous version exists,
                    // copy in the existing user settings.
                    Properties.Settings.Default.Upgrade();
                    Properties.Settings.Default.UpgradeFromPrevious = false;
                    Properties.Settings.Default.Save();
                }
                if (Properties.Settings.Default.Drivers.Count > 0)
                {
                    _driverName = Properties.Settings.Default.Drivers[0];
                    if (Properties.Settings.Default.LastDriver >= 0 && Properties.Settings.Default.LastDriver <= Properties.Settings.Default.Drivers.Count)
                    {
                        _driverName = Properties.Settings.Default.Drivers[Properties.Settings.Default.LastDriver];
                    }
                }
                _userName = Properties.Settings.Default.User;
                _password = Properties.Settings.Default.Password;

                if( Properties.Settings.Default.MessageWaitMilliseconds > 0 && Properties.Settings.Default.MessageWaitMilliseconds < 60000 )
                {
                    _messageWaitMilliseconds = Properties.Settings.Default.MessageWaitMilliseconds;
                }

            }
            catch (Exception ex)
            {
                 _logger.LogMsg(Level.Error, String.Format("Error initializing User settings: {0}", ex.Message ));
            }

            // Flag to force use of direct named pipe handler instead of "QvxLibrary.dll" objects.
            // We force this to true for now. We may want to allow an option from a configuration setting.
            Boolean _usePipeHandler = true;

            // Check command line arguments.
            // If there are 2, assume we are running as a (hidden) named pipe connector. Else run as a Windows GUI application.
            if (args != null && args.Length >= 2)
            {

                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as named pipe connector. Parent window handle = [{0}], QlikView command pipe = [{1}].", args[0].ToString(), args[1].ToString()));

                // Convert window handle (hexadecimal string format) to 32-bit integer.
                int handle = Int32.Parse(args[0].ToString(), System.Globalization.NumberStyles.HexNumber);
                _parentWindowHandle = handle;

                // Full path to command pipe from second argument. This will be formatted as "\\hostname\pipe\mypipename.pip". Hostname ="." if local.
                _commandPipePath = args[1].ToString();

                // For now this flag is always true so we always execute as a raw named pipe handler.
                if (_usePipeHandler)
                {
                    RunNamedPipeHandler(handle, args[1].ToString());
                }
                else
                {
                    // This sets off the QlikView ".NET objects" API.
                    new QvBigDataServer().Run(args[0], args[1]);
                }
            }
            else if (args != null && args.Length == 0)
            {
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as stand-alone."));
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Standalone());
            }

            _logger.LogMsg(Level.Debug, "Exiting program.");
        }
        // Has been hardcoded, should preferably be done programatically.
        public override void Init()
        {
            // Set to true true to get more logging.
            //QvxLog.SetLogLevels(false, false);
            QvxLog.SetLogLevels(true, true);
            QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Init()");

            _logger = new SimpleLogger("QvBigDataConn");
            _logger.EnableFileLogging(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), log4net.Core.Level.Debug);

            _logger.LogMsg(log4net.Core.Level.Info, "Initializing QlikView API connection class.");

            _logger.LogMsg(log4net.Core.Level.Info, String.Format("Command queue path: [{0}].", Program.CommandPipe ) );

            VerifyCredentials();

            var billToCodesFields = new QvxField[]
                {
                    new QvxField("billtocode", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtodesc", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtoeffdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtoexpdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };

            /*
            var applicationsEventLogFields = new QvxField[]
                {
                    new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };

            var systemEventLogFields = new QvxField[]
                {
                    new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };
            */
            MTables = new List<QvxTable> {
                new QvxTable {
                    TableName = "BillToCodes",
                    GetRows = GetBillToCodes,
                    Fields = billToCodesFields
                }

            };

            /*
            MTables = new List<QvxTable> {
                new QvxTable {
                    TableName = "ApplicationsEventLog",
                    GetRows = GetApplicationEvents,
                    Fields = applicationsEventLogFields
                },
                new QvxTable {
                    TableName = "SystemEventLog",
                    GetRows = GetSystemEvents,
                    Fields = systemEventLogFields
                }
            };
             */
        }