public GameOutcome GetGameOutcomeByGameIdAndHomeTeam(int gameId, bool homeTeam, bool fullDetail = true)
    {
      var results = new GameOutcome();

      using (var context = new LO30Context())
      {
        results = context.GameOutcomes
                          .Where(x => x.GameId == gameId && x.HomeTeam == homeTeam)
                          .IncludeAll()
                          .FirstOrDefault();
      }
      return results;
    }
    public ProcessingResult ProcessScoreSheetEntriesIntoGameResults(int startingGameId, int endingGameId)
    {
      var result = new ProcessingResult();

      DateTime last = DateTime.Now;
      TimeSpan diffFromLast = new TimeSpan();

      try
      {
        // get list of game entries for these games (use game just in case there was no score sheet entries...0-0 game with no penalty minutes)
        var games = _context.Games.Where(s => s.GameId >= startingGameId && s.GameId <= endingGameId).ToList();

        result.toProcess = games.Count;

        // get a list of periods
        var periods = new int[] { 1, 2, 3, 4 };

        var modifiedCount = 0;

        // loop through each game
        for (var g = 0; g < games.Count; g++)
        {
          var gameId = games[g].GameId;
          int scoreHomeTeamTotal = 0;
          int scoreAwayTeamTotal = 0;
          int penaltyHomeTeamTotal = 0;
          int penaltyAwayTeamTotal = 0;

          // look up the home and away team id
          var homeGameTeam = _context.GameTeams.Where(x => x.GameId == gameId && x.HomeTeam == true).FirstOrDefault();
          var awayGameTeam = _context.GameTeams.Where(x => x.GameId == gameId && x.HomeTeam == false).FirstOrDefault();
          
          if (homeGameTeam == null || awayGameTeam == null)
          {
            throw new ArgumentNullException("homeGameTeam and/or awayGameTeam cannot be null");
          }

          #region loop through each period
          for (var p = 0; p < periods.Length; p++)
          {
            var period = periods[p];
            var scoreHomeTeamPeriod = 0;
            var scoreAwayTeamPeriod = 0;

            #region process all score sheet entries for this specific game/period
            var scoreSheetEntries = _context.ScoreSheetEntryProcessedGoals.Where(s => s.GameId == gameId && s.Period == period).ToList();

            for (var s = 0; s < scoreSheetEntries.Count; s++)
            {
              var scoreSheetEntry = scoreSheetEntries[s];

              if (scoreSheetEntry.HomeTeam)
              {
                scoreHomeTeamPeriod++;
                scoreHomeTeamTotal++;
              }
              else
              {
                scoreAwayTeamPeriod++;
                scoreAwayTeamTotal++;
              }
            }
            #endregion

            #region create and save (or update) the home and away teams GameScore by period
            var homeGameScore = new GameScore(sid: homeGameTeam.SeasonId, tid: homeGameTeam.TeamId, gid: gameId, per: period, score: scoreHomeTeamPeriod);
            _context.GameScores.Add(homeGameScore);

            var awayGameScore = new GameScore(sid: awayGameTeam.SeasonId, tid: awayGameTeam.TeamId, gid: gameId, per: period, score: scoreAwayTeamPeriod);
            _context.GameScores.Add(awayGameScore);
            #endregion

            #region process all score sheet entry penalties for this specific game/period
            var scoreSheetEntryPenalties = _context.ScoreSheetEntryPenalties.Where(s => s.GameId == gameId && s.Period == period).ToList();

            for (var s = 0; s < scoreSheetEntryPenalties.Count; s++)
            {
              var scoreSheetEntryPenalty = scoreSheetEntryPenalties[s];

              if (scoreSheetEntryPenalty.HomeTeam)
              {
                penaltyHomeTeamTotal = penaltyHomeTeamTotal + scoreSheetEntryPenalty.PenaltyMinutes;
              }
              else
              {
                penaltyAwayTeamTotal = penaltyAwayTeamTotal + scoreSheetEntryPenalty.PenaltyMinutes;
              }
            }
            #endregion
          }
          #endregion

          #region create and save (or update) the home and away teams GameScore for game
          var finalPeriod = 0;
          var homeFinalGameScore = new GameScore(sid: homeGameTeam.SeasonId, tid: homeGameTeam.TeamId, gid: gameId, per: finalPeriod, score: scoreHomeTeamTotal);
          _context.GameScores.Add(homeFinalGameScore);

          var awayFinalGameScore = new GameScore(sid: awayGameTeam.SeasonId, tid: awayGameTeam.TeamId, gid: gameId, per: finalPeriod, score: scoreAwayTeamTotal);
          _context.GameScores.Add(awayFinalGameScore);
          #endregion

          #region create and save (or update) the home and away teams GameOutcome for game
          // save game results for the game
          string homeResult = "T";
          string awayResult = "T";
          if (scoreHomeTeamTotal > scoreAwayTeamTotal)
          {
            homeResult = "W";
            awayResult = "L";
          }
          else if (scoreHomeTeamTotal < scoreAwayTeamTotal)
          {
            homeResult = "L";
            awayResult = "W";
          }

          var gameRosters = _context.GameRosters.Where(x=>x.GameId == gameId).ToList();

          if (gameRosters == null)
          {
            throw new ArgumentNullException("gameRosters");
          }

          var gameSubCounts = gameRosters
              .GroupBy(x => new { x.TeamId })
              .Select(grp => new
              {
                TeamId = grp.Key.TeamId,

                Subs = grp.Sum(x => Convert.ToInt32(x.Sub))
              })
              .ToList();

          var homeSubCount = gameSubCounts.Where(x => x.TeamId == homeGameTeam.TeamId).FirstOrDefault().Subs;
          var awaySubCount = gameSubCounts.Where(x => x.TeamId == awayGameTeam.TeamId).FirstOrDefault().Subs;

          var homeGameOutcome = new GameOutcome(
                                        sid: homeGameTeam.SeasonId,
                                        tid: homeGameTeam.TeamId,
                                        gid: gameId,
                                        res: homeResult,
                                        gf: scoreHomeTeamTotal,
                                        ga: scoreAwayTeamTotal,
                                        pim: penaltyHomeTeamTotal,
                                        over: false,
                                        otid: awayGameTeam.TeamId,
                                        subs: homeSubCount
                                        );

          var awayGameOutcome = new GameOutcome(
                                        sid: awayGameTeam.SeasonId,
                                        tid: awayGameTeam.TeamId,
                                        gid: gameId,
                                        res: awayResult,
                                        gf: scoreAwayTeamTotal,
                                        ga: scoreHomeTeamTotal,
                                        pim: penaltyAwayTeamTotal,
                                        over: false,
                                        otid: homeGameTeam.TeamId,
                                        subs: awaySubCount
                                        );

          _context.GameOutcomes.Add(homeGameOutcome);
          _context.GameOutcomes.Add(awayGameOutcome);
          modifiedCount += _context.SaveChanges();
          #endregion
        }

        //_logger.Write("ProcessScoreSheetEntriesIntoGameResults: savedGameOutcomes:" + modifiedCount);

        result.modified = modifiedCount;
      }
      catch (Exception ex)
      {
        result.modified = -2;
        result.error = ex.Message;

        //_logger.Write(ex);
      }

      diffFromLast = DateTime.Now - last;
      result.time = diffFromLast.ToString();
      return result;
    }