public async Task <(Guid RevisionId, Dictionary <ClientFileId, Guid> ClientFileIdMap, Dictionary <string, Guid> ByName)> FindOrCreateRevision(ReviewIdentifier reviewId, PublishReview.RevisionCommits commits, FeatureToggle features)
        {
            var existingRevision = await _sessionAdapter.GetRevision(reviewId, commits);

            if (existingRevision != null)
            {
                var fileHistory = _sessionAdapter.GetFileHistoryEntries(existingRevision);

                var idMap = fileHistory.ToDictionary(x => ClientFileId.Persistent(x.FileId), x => x.FileId);

                var nameMap = fileHistory.GroupBy(x => x.FileName).ToDictionary(x => x.Key, x => x.First().FileId);

                return(existingRevision.Id, idMap, nameMap);
            }

            // create revision
            var nextNumber = _sessionAdapter.GetNextRevisionNumber(reviewId);

            await CreateRef(reviewId, nextNumber, commits.Base, "base", _api);

            try
            {
                await CreateRef(reviewId, nextNumber, commits.Head, "head", _api);
            }
            catch (ExistingRefConflictException unexpectedException)
            {
                // The base ref is already created, we must add the record to database no matter what
                Console.WriteLine("Failed to create ref for head commit - ignoring");
                Console.WriteLine(unexpectedException.ToString());
            }

            var revision = await _factory.Create(reviewId, nextNumber, commits.Base, commits.Head);

            await _sessionAdapter.Save(revision);

            var clientFileIdMap = await new FillFileHistory(_sessionAdapter, _api, revision, features).Fill();

            var byClientId = clientFileIdMap.ToDictionary(x => x.Key, x => x.Value.Item2);

            var byName = clientFileIdMap.GroupBy(x => x.Value.Item1).ToDictionary(x => x.Key, x => x.First().Value.Item2);

            return(RevisionId : revision.Id, ClientFileIdMap : byClientId, byName);
        }