public void AddEvidence()
        {
            var pairResult        = TestHelpers.GetPairResult(10);
            var pairResultFarAway = TestHelpers.GetPairResult(750);
            ConcurrentDictionary <int, uint> probableTrueSnvRegionsLookup = new ConcurrentDictionary <int, uint>();
            ConcurrentDictionary <int, uint> allHits = new ConcurrentDictionary <int, uint>();

            // TODO: yuck. this stuff should be moved over to binevidence or at least somehow consolidated
            for (var i = 0; i < 1000; i++)
            {
                allHits[i] = 0;
                probableTrueSnvRegionsLookup[i] = 0;
            }
            BinEvidenceHelpers.AddEvidence(pairResult, 500, 0, allHits, probableTrueSnvRegionsLookup, true, 1000, 1);
            Assert.Equal(2f, allHits[0]);
            Assert.Equal(2f, probableTrueSnvRegionsLookup[0]);

            // Same bin, not mismatch
            BinEvidenceHelpers.AddEvidence(pairResult, 500, 0, allHits, probableTrueSnvRegionsLookup, false, 1000, 1);
            Assert.Equal(4f, allHits[0]);
            Assert.Equal(2f, probableTrueSnvRegionsLookup[0]);

            BinEvidenceHelpers.AddEvidence(pairResultFarAway, 500, 0, allHits, probableTrueSnvRegionsLookup, false, 1000, 1);
            Assert.Equal(4f, allHits[0]);
            Assert.Equal(2f, probableTrueSnvRegionsLookup[0]);
            Assert.Equal(2f, allHits[1]);
            Assert.Equal(0f, probableTrueSnvRegionsLookup[1]);
        }
        public ActionBlock <PairResult[]> GetEarlyFlushBlock(PairClassification classification, bool isSingleMismatch)
        {
            var actBlock = new ActionBlock <PairResult[]>((p) =>
            {
                if (_lightDebug)
                {
                    Logger.WriteToLog(
                        $"Started handling {classification} block for region {_chrom}:{_startPosition}-{_endPosition}.");
                }

                var toRemove2 = _allToWaitFor.Keys.Where(x => x.IsCompleted);
                foreach (var task in toRemove2)
                {
                    _allToWaitFor.TryRemove(task, out _);
                }

                if (_debug)
                {
                    Console.WriteLine($"{p.Length} pairs in category {classification} in {_startPosition}-{_endPosition}");
                }

                var idNum        = Thread.CurrentThread.ManagedThreadId;
                var writerHandle = _writerSource.BamWriterHandle(_chrom, classification, _startPosition);

                _categoryLookup.AddOrUpdate(classification, p.Sum(x => x.ReadPair.NumPrimaryReads),
                                            (c, n) => { return(n + p.Sum(x => x.ReadPair.NumPrimaryReads)); });

                if (_filterForProperPairs && _improperTypes.Contains(classification))
                {
                    _progressTracker.AddOrUpdate("Skipped", p.Sum(x => x.ReadPair.NumPrimaryReads),
                                                 (c, n) => { return(n + p.Sum(x => x.ReadPair.NumPrimaryReads)); });
                }
                else
                {
                    var numAlignmentsWritten = 0;

                    var classificationString = classification.ToString();
                    foreach (var pair in p)
                    {
                        if (classification != PairClassification.Duplicate)
                        {
                            // Don't add bin evidence for duplicates, may wash the signal out
                            BinEvidenceHelpers.AddEvidence(pair, _messySiteWidth, _adjustedStartPosition,
                                                           _totalBinCounts,
                                                           _singleMismatchBinCounts, isSingleMismatch, _numBins, _refId);
                        }

                        foreach (var alignment in pair.Alignments)
                        {
                            if (alignment == null)
                            {
                                continue;
                            }

                            alignment.ReplaceOrAddStringTag("XP", classificationString);
                            numAlignmentsWritten++;

                            if (writerHandle == null)
                            {
                                throw new Exception("This is odd, why is the handle null");
                            }

                            writerHandle.WriteAlignment(alignment);
                        }
                    }

                    _progressTracker.AddOrUpdate("Early Flushed", p.Sum(x => x.ReadPair.NumPrimaryReads),
                                                 (s, n) => { return(n + p.Sum(x => x.ReadPair.NumPrimaryReads)); });
                    _progressTracker.AddOrUpdate("Simple Alignments Written", numAlignmentsWritten,
                                                 (s, n) => { return(n + numAlignmentsWritten); });


                    Array.Clear(p, 0, p.Length);
                    _writerSource.DoneWithWriter(_chrom, classification, idNum, numAlignmentsWritten, writerHandle);
                    if (_lightDebug)
                    {
                        Logger.WriteToLog(
                            $"Done handling {classification} block for region {_chrom}:{_startPosition}-{_endPosition}.");
                    }
                }
            }, new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = _maxDegreeOfParallelism, EnsureOrdered = true
            });

            return(actBlock);
        }