public async void SolutionEventOpenedAsync()
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (!PLUGIN_READY)
            {
                string solutionDir = await GetSolutionDirectory();

                if (solutionDir == null || solutionDir.Equals(""))
                {
                    Task.Delay(3000).ContinueWith((task) =>
                    {
                        SolutionEventOpenedAsync();
                    });
                    return;
                }
                // init the doc event mgr and inject ObjDte
                docEventMgr            = DocEventManager.Instance;
                DocEventManager.ObjDte = ObjDte;

                // init the session summary mgr
                sessionSummaryMgr = SessionSummaryManager.Instance;
                sessionSummaryMgr.InjectAsyncPackage(this);

                // init the event manager and inject this
                EventManager.Instance.InjectAsyncPackage(this);

                // update the latestPayloadTimestampEndUtc
                NowTime nowTime = SoftwareCoUtil.GetNowTime();
                FileManager.setNumericItem("latestPayloadTimestampEndUtc", nowTime.now);

                // init the wallclock
                WallclockManager wallclockMgr = WallclockManager.Instance;
                wallclockMgr.InjectAsyncPackage(this, ObjDte);

                // setup event handlers
                _textDocKeyEvent.AfterKeyPress += docEventMgr.AfterKeyPressedAsync;
                _docEvents.DocumentOpened      += docEventMgr.DocEventsOnDocumentOpenedAsync;
                _docEvents.DocumentClosing     += docEventMgr.DocEventsOnDocumentClosedAsync;
                _docEvents.DocumentSaved       += docEventMgr.DocEventsOnDocumentSaved;
                _docEvents.DocumentOpening     += docEventMgr.DocEventsOnDocumentOpeningAsync;

                // init the code metrics tree mgr
                CodeMetricsTreeManager.Instance.InjectAsyncPackage(this);

                // initialize the menu commands
                await SoftwareLaunchCommand.InitializeAsync(this);

                await SoftwareDashboardLaunchCommand.InitializeAsync(this);

                await SoftwareTopFortyCommand.InitializeAsync(this);

                await SoftwareLoginCommand.InitializeAsync(this);

                await SoftwareToggleStatusInfoCommand.InitializeAsync(this);

                await SoftwareOpenCodeMetricsTreeCommand.InitializeAsync(this);

                if (_softwareRepoUtil == null)
                {
                    _softwareRepoUtil = new SoftwareRepoManager();
                }

                // Create an AutoResetEvent to signal the timeout threshold in the
                // timer callback has been reached.
                var autoEvent = new AutoResetEvent(false);

                offlineDataTimer = new System.Threading.Timer(
                    SendOfflineData,
                    null,
                    ONE_MINUTE,
                    ONE_MINUTE * 15);

                repoCommitsTimer = new System.Threading.Timer(
                    ProcessRepoJobs,
                    autoEvent,
                    ONE_MINUTE * 5,
                    ONE_MINUTE * 20);

                keystrokeTimer = new System.Threading.Timer(
                    ProcessKeystrokePayload,
                    autoEvent,
                    ONE_MINUTE,
                    ONE_MINUTE);

                // initialize the status bar before we fetch the summary data
                InitializeStatusBar();

                // make sure the last payload is in memory
                FileManager.GetLastSavedKeystrokeStats();

                // check if we've shown the readme or not
                bool initializedVisualStudioPlugin = FileManager.getItemAsBool("visualstudio_CtInit");
                if (!initializedVisualStudioPlugin)
                {
                    DashboardManager.Instance.LaunchReadmeFileAsync();
                    FileManager.setBoolItem("visualstudio_CtInit", true);

                    // launch the tree view
                    CodeMetricsTreeManager.Instance.OpenCodeMetricsPaneAsync();
                }

                Task.Delay(3000).ContinueWith((task) =>
                {
                    EventManager.Instance.CreateCodeTimeEvent("resource", "load", "EditorActivate");
                });

                string PluginVersion = GetVersion();
                Logger.Info(string.Format("Initialized Code Time v{0}", PluginVersion));

                PLUGIN_READY = true;
            }
        }
        public async Task InitializeListenersAsync()
        {
            await JoinableTaskFactory.SwitchToMainThreadAsync(DisposalToken);

            try
            {
                string PluginVersion = GetVersion();
                Logger.Info(string.Format("Initializing Code Time v{0}", PluginVersion));

                // VisualStudio Object
                Events2 events = (Events2)ObjDte.Events;
                _textDocKeyEvent = events.TextDocumentKeyPressEvents;
                _docEvents       = ObjDte.Events.DocumentEvents;

                // setup event handlers
                _textDocKeyEvent.AfterKeyPress += AfterKeyPressedAsync;
                _docEvents.DocumentOpened      += DocEventsOnDocumentOpenedAsync;
                _docEvents.DocumentClosing     += DocEventsOnDocumentClosedAsync;
                _docEvents.DocumentSaved       += DocEventsOnDocumentSaved;
                _docEvents.DocumentOpening     += DocEventsOnDocumentOpeningAsync;

                //initialize the StatusBar
                await InitializeSoftwareStatusAsync();

                if (_sessionSummary == null)
                {
                    _sessionSummary = new SessionSummary();
                }
                // initialize the menu commands
                await SoftwareLaunchCommand.InitializeAsync(this);

                await SoftwareDashboardLaunchCommand.InitializeAsync(this);

                await SoftwareTopFortyCommand.InitializeAsync(this);

                await SoftwareLoginCommand.InitializeAsync(this);

                await SoftwareToggleStatusInfoCommand.InitializeAsync(this);

                if (_softwareRepoUtil == null)
                {
                    _softwareRepoUtil = new SoftwareRepoManager();
                }



                // Create an AutoResetEvent to signal the timeout threshold in the
                // timer callback has been reached.
                var autoEvent = new AutoResetEvent(false);

                // setup timer to process events every 1 minute
                timer = new System.Threading.Timer(
                    ProcessSoftwareDataTimerCallbackAsync,
                    autoEvent,
                    ONE_MINUTE,
                    ONE_MINUTE);

                offlineDataTimer = new System.Threading.Timer(
                    SendOfflineData,
                    null,
                    THIRTY_MINUTES,
                    THIRTY_MINUTES);

                // this.SendOfflineData();

                // start in 5 seconds every 5 min
                //int delay = 1000 * 5;
                //kpmTimer = new System.Threading.Timer(
                //    ProcessFetchDailyKpmTimerCallbackAsync,
                //    autoEvent,
                //    delay,
                //    ONE_MINUTE * 5);

                int delay = 1000 * 45;

                delay            = ONE_MINUTE + (1000 * 10);
                repoCommitsTimer = new System.Threading.Timer(
                    ProcessHourlyJobs,
                    autoEvent,
                    delay,
                    ONE_HOUR);

                musicTimer = new System.Threading.Timer(
                    ProcessMusicTracksAsync,
                    autoEvent,
                    1000 * 5,
                    1000 * 30);

                statusMsgTimer = new System.Threading.Timer(
                    UpdateStatusMsg,
                    autoEvent,
                    1000 * 30,
                    1000 * 10);

                userStatusTimer = new System.Threading.Timer(
                    UpdateUserStatus,
                    autoEvent,
                    ONE_MINUTE,
                    1000 * 120);

                this.InitializeUserInfo();
            }
            catch (Exception ex)
            {
                Logger.Error("Error Initializing SoftwareCo", ex);
            }
        }