public GameItemViewModel(Game game, IDependencyResolver resolver)
        {
            Game = game;

            _logger = resolver.GetService<ILogger>();
            _vpdbClient = resolver.GetService<IVpdbClient>();
            _gameManager = resolver.GetService<IGameManager>();
            _messageManager = resolver.GetService<IMessageManager>();
            var threadManager = resolver.GetService<IThreadManager>();

            // release identify
            IdentifyRelease = ReactiveCommand.CreateAsyncObservable(_ => _vpdbClient.Api.GetReleasesBySize(Game.FileSize, MatchThreshold).SubscribeOn(threadManager.WorkerScheduler));
            IdentifyRelease.Select(releases => releases
                .Select(release => new {release, release.Versions})
                .SelectMany(x => x.Versions.Select(version => new {x.release, version, version.Files}))
                .SelectMany(x => x.Files.Select(file => new GameResultItemViewModel(game, x.release, x.version, file, CloseResults)))
            ).Subscribe(x => {

                var releases = x as GameResultItemViewModel[] ?? x.ToArray();
                var numMatches = 0;
                _logger.Info("Found {0} releases for game to identify.", releases.Length);
                GameResultItemViewModel match = null;
                foreach (var vm in releases) {
                    if (game.Filename == vm.TableFile.Reference.Name && game.FileSize == vm.TableFile.Reference.Bytes) {
                        numMatches++;
                        match = vm;
                    }
                }
                _logger.Info("Found {0} identical match(es).", numMatches);

                // if file name and file size are identical, directly match.
                if (numMatches == 1 && match != null) {
                    _logger.Info("File name and size are equal to local release, linking.");
                    _gameManager.LinkRelease(match.Game, match.Release, match.TableFile.Reference.Id);
                    _messageManager.LogReleaseLinked(match.Game, match.Release, match.TableFile.Reference.Id);

                } else {
                    _logger.Info("View model updated with identified releases.");
                    IdentifiedReleases = releases;
                    HasExecuted = true;
                }
            }, exception => _vpdbClient.HandleApiError(exception, "identifying a game by file size"));

            //SyncToggled
            //	.Where(_ => Game.IsSynced && Game.HasRelease)
            //	.Subscribe(_ => { GameManager.Sync(Game); });

            // handle errors
            IdentifyRelease.ThrownExceptions.Subscribe(e => { _logger.Error(e, "Error matching game."); });

            // spinner
            IdentifyRelease.IsExecuting.ToProperty(this, vm => vm.IsExecuting, out _isExecuting);

            // result switch
            IdentifyRelease.Select(r => r.Count > 0).Subscribe(hasResults => { HasResults = hasResults; });

            // close button
            CloseResults.Subscribe(_ => { HasExecuted = false; });

            // identify button visibility
            this.WhenAny(
                vm => vm.HasExecuted,
                vm => vm.Game.HasRelease,
                vm => vm.IsExecuting,
                (hasExecuted, hasRelease, isExecuting) => !hasExecuted.Value && !hasRelease.Value && !isExecuting.Value
            ).ToProperty(this, vm => vm.ShowIdentifyButton, out _showIdentifyButton);
        }