public void Dispose()
        {
            try
            {
                if (_itemScoringTimer != null)
                {
                    _itemScoringTimer.Dispose();
                }

                if (ScoreRequestSender != null)
                {
                    ScoreRequestSender.Dispose();
                }
            }
            catch (Exception ex)
            {
                // Nothing we can do here
            }
        }
        /// <summary>
        /// Submit responses that need scores to the remote item scoring engine
        /// </summary>
        /// <param name="pendingResponses"></param>
        /// <returns></returns>
        private int ProcessPendingResponses(IEnumerable <ScorableResponse> pendingResponses)
        {
            int failures = 0;

            if (ItemScoringConf == null)
            {
                return(pendingResponses.Count());
            }

            foreach (ScorableResponse scorableResponse in pendingResponses)
            {
                ItemScoringRule rule = ItemScoringConf.GetItemScoringRule(scorableResponse.Format, scorableResponse.TestId);

                if (rule == null || (rule.Enabled && (rule.ServerUrl == null || rule.StudentAppUrl == null)))
                {
                    failures++;
                    continue;
                }

                if (!rule.Enabled || scorableResponse.Response == null)
                {
                    // This item is NOT supposed to be machine scored.
                    ScoredResponse scoredResponse = new ScoredResponse
                    {
                        ItemKey         = scorableResponse.ItemKey,
                        OppKey          = scorableResponse.OppKey,
                        Position        = scorableResponse.Position,
                        Score           = -1,
                        ScoreDimensions = null,
                        ScoreMark       = scorableResponse.ScoreMark,
                        ScoreRationale  = !rule.Enabled ? "Item configured not to be scored" : "Item Response is NULL",
                        ScoreStatus     = "NotScored",
                        Sequence        = scorableResponse.ResponseSequence
                    };
                    try
                    {
                        UpdateItemScore(scoredResponse);
                    }
                    catch (Exception e)
                    {
                        failures++;
                    }
                }
                else if (String.IsNullOrEmpty(scorableResponse.ItemFile))   // Sometimes, we get responses that have no item file specified. We cannot do anything with these.
                {
                    // This item is NOT supposed to be machine scored.
                    ScoredResponse scoredResponse = new ScoredResponse
                    {
                        ItemKey         = scorableResponse.ItemKey,
                        OppKey          = scorableResponse.OppKey,
                        Position        = scorableResponse.Position,
                        Score           = -1,
                        ScoreDimensions = null,
                        ScoreMark       = scorableResponse.ScoreMark,
                        ScoreRationale  = "Item file path is null",
                        ScoreStatus     = "ScoringError",
                        Sequence        = scorableResponse.ResponseSequence
                    };
                    try
                    {
                        UpdateItemScore(scoredResponse);
                    }
                    catch (Exception e)
                    {
                        failures++;
                    }
                }
                else
                {
                    // Send this item off to scoring
                    string           itemScoringServerUrl = ScoringDaemonSettings.ItemScoringServerUrlOverride ?? rule.ServerUrl;
                    ItemScoreRequest itemScoreRequest     = ServiceLocator.Resolve <ItemScoreRequestFactory>().MakeItemScoreRequest(this, scorableResponse, rule, itemScoringServerUrl);

                    if (itemScoreRequest == null)
                    {
                        failures++;
                        continue;
                    }

                    ScoreRequestSender.SendRequestAsync(itemScoringServerUrl, itemScoreRequest, null);
                }
            }

            return(failures);
        }