public void RetrievingLogs(NewFilterInput filter, BlockRange range, uint attemptNumber)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"Retrieving logs. from: {range.From}, to: {range.To}. Attempt: {attemptNumber}. Filter: {JsonConvert.SerializeObject(filter)}");
     }
 }
 public void RetrievalError(BlockRange range, Exception ex)
 {
     if (IsErrorEnabled)
     {
         Logger.Error($"Exception whilst retrieving logs. from: {range.From}, to: {range.To}.", ex);
     }
 }
示例#3
0
 public void UpdatingBlockProgress(BlockRange range)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"Updating current process progress to: {range.To}");
     }
 }
        public async Task IndexingTransferFunctions()
        {
            using (var azureSearchService = new AzureSearchService(AzureSearchServiceName, _azureSearchApiKey))
            {
                await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);

                using (var azureFunctionMessageIndexer =
                           await azureSearchService.GetOrCreateFunctionIndex <TransferFunction>(indexName: AzureTransferIndexName))
                {
                    var transferHandler =
                        new FunctionIndexTransactionHandler <TransferFunction>(azureFunctionMessageIndexer);

                    var web3            = new Web3.Web3("https://rinkeby.infura.io/v3/25e7b6dfc51040b3bfc0e47317d38f60");
                    var blockchainProxy = new BlockchainProxyService(web3);
                    var handlers        = new HandlerContainer {
                        TransactionHandler = transferHandler
                    };
                    var blockProcessor      = BlockProcessorFactory.Create(blockchainProxy, handlers);
                    var processingStrategy  = new ProcessingStrategy(blockProcessor);
                    var blockchainProcessor = new BlockchainProcessor(processingStrategy);

                    var blockRange = new BlockRange(3146684, 3146694);
                    await blockchainProcessor.ProcessAsync(blockRange);

                    await Task.Delay(TimeSpan.FromSeconds(5));

                    //ensure we have written the expected docs to the index
                    Assert.Equal(3, await azureFunctionMessageIndexer.DocumentCountAsync());
                }

                await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);
            }
        }
 public void NoLogsToProcess(BlockRange range)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"No logs to process. Blocks from: {range.From}, to: {range.To}.");
     }
 }
 public void PausingBeforeRetry(BlockRange range, uint attemptNumber)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"Pausing before retrieval retry. from: {range.From}, to: {range.To}. Attempt: {attemptNumber}");
     }
 }
 public void TooManyRecords(BlockRange range, Exception ex)
 {
     if (IsErrorEnabled)
     {
         Logger.Error($"TooManyRecords exception whilst retrieving logs. from: {range.From}, to: {range.To}.", ex);
     }
 }
示例#8
0
        private UserMark InsertUserMark(int locationId, int colourIndex, int startToken, int endToken, int verseNumber)
        {
            var userMark = new UserMark
            {
                UserMarkId   = ++_maxUserMarkId,
                LocationId   = locationId,
                UserMarkGuid = Guid.NewGuid().ToString().ToLower(),
                Version      = 1,
                ColorIndex   = colourIndex
            };

            _targetDatabase.AddUserMarkAndUpdateIndex(userMark);

            // now add the block range...
            var blockRange = new BlockRange
            {
                BlockRangeId = ++_maxBlockRangeId,
                BlockType    = 2,
                Identifier   = verseNumber,
                StartToken   = startToken,
                EndToken     = endToken,
                UserMarkId   = userMark.UserMarkId
            };

            _targetDatabase.AddBlockRangeAndUpdateIndex(blockRange);

            return(userMark);
        }
        private async Task <FilterLog[]> RetrieveLogsAsync(
            BlockRange range, NewFilterInput filter, uint retryNumber = 0)
        {
            try
            {
                filter.SetBlockRange(range);

                _logger.RetrievingLogs(filter, range, retryNumber);

                return(await _eventLogProxy.SendRequestAsync(filter).ConfigureAwait(false));
            }
            catch (RpcResponseException rpcResponseEx) when(rpcResponseEx.TooManyRecords())
            {
                _logger.TooManyRecords(range, rpcResponseEx);
                throw rpcResponseEx.TooManyRecordsException();
            }
            catch (Exception ex)
            {
                _logger.RetrievalError(range, ex);

                retryNumber++;
                if (retryNumber < MaxRetries)
                {
                    _logger.PausingBeforeRetry(range, retryNumber);
                    await RetryWaitStrategy.Apply(retryNumber).ConfigureAwait(false);

                    return(await RetrieveLogsAsync(range, filter, retryNumber)
                           .ConfigureAwait(false));
                }

                _logger.MaxRetriesExceededSoThrowing(MaxRetries, ex);

                throw;
            }
        }
        private async Task <FilterLog[]> RetrieveLogsAsync(
            BlockRange range, NewFilterInput filter, uint retryNumber = 0)
        {
            try
            {
                filter.SetBlockRange(range);

                _log.LogInformation($"RetrieveLogsAsync - getting logs. RetryNumber:{retryNumber}, from:{range.From}, to:{range.To}.");

                return(await _eventLogProxy.GetLogs(filter).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                _log.LogError("Get Logs Error", ex);

                retryNumber++;
                if (retryNumber < MaxRetries)
                {
                    _log.LogInformation("Pausing before retry get logs");
                    await RetryWaitStrategy.Apply(retryNumber).ConfigureAwait(false);

                    _log.LogInformation("Retrying get logs");
                    return(await RetrieveLogsAsync(range, filter, retryNumber)
                           .ConfigureAwait(false));
                }

                _log.LogError("MaxRetries exceeded when getting logs, throwing exception.", ex);

                throw;
            }
        }
示例#11
0
 public void ProcessingBlockRange(BlockRange range)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"Processing Block Range.from: { range.From} to { range.To}");
     }
 }
 public void ProcessingRange(BlockRange range)
 {
     if (IsInfoEnabled)
     {
         Logger.Info($"Beginning ProcessAsync. from: {range.From}, to: {range.To}.");
     }
 }
        private ExceptionHandlingBlockCatch CreateCatchHandler(ExceptionHandler handler)
        {
            ILogicalConstruct           theCommonParent;
            BlockRange                  catchBlockRange = GetBlockRangeFromInstructions(handler.HandlerStart, handler.HandlerEnd);
            HashSet <ILogicalConstruct> catchChildren   = GetLogicalConstructsInRange(catchBlockRange, out theCommonParent);

            return(new ExceptionHandlingBlockCatch(catchChildren, context.CFGBlockToLogicalConstructMap[catchBlockRange.Start][0], handler.CatchType));
        }
示例#14
0
        private void InsertBlockRange(BlockRange range, Database destination)
        {
            BlockRange newRange = range.Clone();

            newRange.BlockRangeId = ++_maxBlockRangeId;

            newRange.UserMarkId = _translatedUserMarkIds.GetTranslatedId(range.UserMarkId);
            destination.BlockRanges.Add(newRange);
        }
示例#15
0
 private void HandleBatchProcessed(BlockRange lastRange)
 {
     BlocksProcessed += lastRange.BlockCount;
     LastBlock        = lastRange.To;
     if (lastRange.To >= MaxBlockNumber)
     {
         cancellationTokenSource.Cancel();
     }
 }
        public void Assigns_Specified_Block_Numbers()
        {
            var range = new BlockRange(15, 25);

            var filter = new FilterInputBuilder <TransferEvent>().Build(blockRange: range);

            Assert.Equal(range.From, filter.FromBlock.BlockNumber.Value);
            Assert.Equal(range.To, filter.ToBlock.BlockNumber.Value);
        }
        BlockLogicalConstruct CreateExceptionhandlingBlock(BlockRange cfgBlocks)
        {
            HashSet <ILogicalConstruct> children;
            ILogicalConstruct           theCommonParent;

            children = GetLogicalConstructsInRange(cfgBlocks, out theCommonParent);
            ILogicalConstruct entry = FindChildBlockBelongsTo(theCommonParent, context.CFGBlockToLogicalConstructMap[GetEntryBlockInRange(cfgBlocks)][0]);

            return(new BlockLogicalConstruct(entry, children));
        }
示例#18
0
            public async Task When_Nothing_Has_Been_Processed_Returns_Specified_Starting_Block()
            {
                Web3Mock.BlockNumberMock.Setup(r => r.SendRequestAsync(null)).ReturnsAsync(20.ToHexBigInteger());
                ProgressRepo.Setup(r => r.GetLastBlockNumberProcessedAsync()).ReturnsAsync((ulong?)null);

                var range = await Service.GetNextBlockRangeToProcessAsync(100);

                var expectedBlockRange = new BlockRange(10, 20);

                Assert.Equal(expectedBlockRange, range.Value);
            }
示例#19
0
        private void ScopifyRangeAndMarkEnd()
        {
            Block      jumpTarget = ctx.cfg.GetJumpBlockTargetByJIndex(bci.bciIndexInPrototype + 1);
            BlockRange br         = new BlockRange(ctx.cfg, ctx.currentBlock.blockIndex, jumpTarget.blockIndex);

            br.IncrementBlockRangeScope();
            if (br.Range != null)
            {
                br.Range[br.Range.Length - 1].neededEnds++;
            }
        }
示例#20
0
            public async Task Returns_Next_Unprocessed_Block()
            {
                Web3Mock.BlockNumberMock.Setup(r => r.SendRequestAsync(null)).ReturnsAsync(50.ToHexBigInteger());
                ProgressRepo.Setup(r => r.GetLastBlockNumberProcessedAsync()).ReturnsAsync(5);

                var range = await Service.GetNextBlockRangeToProcessAsync(100);

                var expectedBlockRange = new BlockRange(6, 50);

                Assert.Equal(expectedBlockRange, range.Value);
            }
        public void FindExceptionHandlingConstructs()
        {
            //The CLR searchese top to bottom through the EH table at the end of the method declaration looking for a CATCH or FILTER handlers
            //which guarded(try) block encompasses the spot where the exception occurred (FAULT and FINALLY handlers are compeltely ignored at this pass,
            //no matter whether the exception falls in their guarded(try) blocks). Assuming that CATCH/FILTER handler was found at row N of the EH table
            // the CLR marks it (but it does NOT execute it at this point) and does a second pass through the EH table searching ONLY rows 1 to N this time.
            //On hte second pass only FAULT/FINALLY handlers are considered. Any FAULT/FILTER handler found which guarded block encompasses the instruction causing
            //the exception gets executed at this pass. Only then the CATCH/FILTER handler at row N gets executed.
            //That means that the order in which handlers appear in the EH table has precedence over their hierarchical structure in the IL (i.e. which try block is inside another try block) when determineing
            //their order of execution. Hence given a FAULT/FINALLY handler that completely contains a CATCH/FILTER handler in the IL but whose EH table entry occurs before
            // the CATCH/FILTER  handler EH table entry in the LogicalConstruct tree the CATCH/FILTER handler will be parent of the FAULT/FINALLY handler (complete reverse of theri relationship in the IL)
            //since the FAULT/FINALLY handler will be executed before the CATCH/FILTER one.


            foreach (ExceptionHandler handler in context.CFG.RawExceptionHandlers)
            {
                BlockRange tryBlockRange = GetBlockRangeFromInstructions(handler.TryStart, handler.TryEnd);

                ExceptionHandlingLogicalConstruct tryBlockExistingHandler = null;
                if (tryBlocksFound.TryGetValue(tryBlockRange, out tryBlockExistingHandler))
                {
                    AddHandlerToTryBlock(tryBlockExistingHandler, handler);
                }
                else
                {
                    BlockLogicalConstruct             theTryBlock  = CreateExceptionhandlingBlock(tryBlockRange);
                    ExceptionHandlingLogicalConstruct guardedBlock = null;

                    switch (handler.HandlerType)
                    {
                    case ExceptionHandlerType.Catch:
                        guardedBlock = new TryCatchFilterLogicalConstruct(theTryBlock, CreateCatchHandler(handler));
                        break;

                    case ExceptionHandlerType.Filter:
                        guardedBlock = new TryCatchFilterLogicalConstruct(theTryBlock, CreateFilterHandler(handler));
                        break;

                    case ExceptionHandlerType.Fault:
                        BlockRange faultBlockRange = GetBlockRangeFromInstructions(handler.HandlerStart, handler.HandlerEnd);
                        guardedBlock = new TryFaultLogicalConstruct(theTryBlock, CreateExceptionhandlingBlock(faultBlockRange));
                        break;

                    case ExceptionHandlerType.Finally:
                        BlockRange finallyBlockRange = GetBlockRangeFromInstructions(handler.HandlerStart, handler.HandlerEnd);
                        guardedBlock = new TryFinallyLogicalConstruct(theTryBlock, CreateExceptionhandlingBlock(finallyBlockRange));
                        break;
                    }

                    tryBlocksFound.Add(tryBlockRange, guardedBlock);
                }
            }
        }
        private HashSet <ILogicalConstruct> GetLogicalConstructsInRange(BlockRange blockRange, out ILogicalConstruct theCommonParent)
        {
            HashSet <ILogicalConstruct>    children      = new HashSet <ILogicalConstruct>();
            HashSet <ISingleEntrySubGraph> blocksParents = new HashSet <ISingleEntrySubGraph>();

            int rangeBegin = blockRange.Start.First.Offset;
            int rangeEnd   = blockRange.End.First.Offset;

            for (int i = 0; i < context.CFG.Blocks.Length; i++)
            {
                InstructionBlock currentBlock = context.CFG.Blocks[i];
                if (currentBlock.First.Offset >= rangeBegin && currentBlock.First.Offset <= rangeEnd)
                {
                    CFGBlockLogicalConstruct[] cfgConstructs = context.CFGBlockToLogicalConstructMap[currentBlock];

                    for (int j = 0; j < cfgConstructs.Length; j++)
                    {
                        blocksParents.Add((ILogicalConstruct)cfgConstructs[j].Parent);
                        children.Add(cfgConstructs[j]);
                    }
                }
            }

            if (blocksParents.Count == 1)
            {
                theCommonParent = (ILogicalConstruct)blocksParents.ToArray <ISingleEntrySubGraph>()[0];

                return(children);
            }
            //TODO: CCheck whether the parent logical construct of of each CFGBlockLogicalConstruct that belongs to the exception handling block,
            //(i.e. each member of blocksParents) contains as children ONLY blocks that belong to the exception handling block (i.e. blocks that are in blockRange).

            theCommonParent = (ILogicalConstruct)LogicalFlowUtilities.FindFirstCommonParent(blocksParents);

            HashSet <ILogicalConstruct> result = new HashSet <ILogicalConstruct>();

            foreach (ILogicalConstruct child in children)
            {
                ILogicalConstruct desiredNode;
                LogicalFlowUtilities.TryGetParentConstructWithGivenParent(child, theCommonParent, out desiredNode);
                result.Add(desiredNode);
            }

            if (theCommonParent is ExceptionHandlingLogicalConstruct)
            {
                result.Clear();
                result.Add(theCommonParent);
                theCommonParent = theCommonParent.Parent as ILogicalConstruct;
            }

            return(result);
        }
        private void Output(BlockRange lastRange)
        {
            BlocksProcessed += lastRange.BlockCount; LastBlock = lastRange.To;
            if (lastRange.To >= MaxBlockNumber)
            {
                cancellationTokenSource.Cancel();
            }

            var elapsed = stopWatch.Elapsed;

            _log.LogInformation($"** ELAPSED: Hours: {elapsed.Hours}, Minutes: {elapsed.Minutes}, Seconds: {elapsed.Seconds}");
            _log.LogInformation($"** PROGRESS: Blocks: {BlocksProcessed}, Last Block: {LastBlock}, Blocks With Transfers: {BlocksContainingTransfers.Count}, Transfers: {EventsHandled}");
        }
示例#24
0
            public async Task When_Nothing_Has_Been_Processed_And_Default_Starting_Block_Is_Null_Returns_Current_Block_On_The_Chain_Less_Min_Confirmations()
            {
                Service = new BlockProgressService(Web3Mock.Web3, null, ProgressRepo.Object, minimumBlockConfirmations: 6);

                Web3Mock.BlockNumberMock.Setup(r => r.SendRequestAsync(null)).ReturnsAsync(20.ToHexBigInteger());
                ProgressRepo.Setup(r => r.GetLastBlockNumberProcessedAsync()).ReturnsAsync((BigInteger?)null);

                var range = await Service.GetNextBlockRangeToProcessAsync(100);

                var expectedBlockRange = new BlockRange(14, 14);

                Assert.Equal(expectedBlockRange, range.Value);
            }
示例#25
0
        public void Test_blockRange_1()
        {
            // 准备好一个芯片内容
            byte[] data = Element.FromHexString(
                @"91 00 05 1c
be 99 1a 14
02 01 d0 14
02 04 b3 46
07 44 1c b6
e2 e3 35 d6
83 02 07 ac
c0 9e ba a0
6f 6b 00 00"
                );

            // 测试 BlockRange.GetBlockRanges()
            List <BlockRange> ranges = BlockRange.GetBlockRanges(
                4,
                data,
                "ll....lll",
                'l');

            Assert.IsTrue(ranges[0].BlockCount == 2);
            Assert.IsTrue(ranges[0].Locked == true);
            Assert.IsTrue(ranges[0].Bytes.SequenceEqual(
                              Element.FromHexString(
                                  @"91 00 05 1c
                be 99 1a 14"
                                  )
                              ));

            Assert.IsTrue(ranges[1].BlockCount == 4);
            Assert.IsTrue(ranges[1].Locked == false);
            Assert.IsTrue(ranges[1].Bytes.SequenceEqual(
                              Element.FromHexString(
                                  @"02 01 d0 14
                02 04 b3 46
                07 44 1c b6
                e2 e3 35 d6"
                                  )
                              ));
            Assert.IsTrue(ranges[2].BlockCount == 3);
            Assert.IsTrue(ranges[2].Locked == true);
            Assert.IsTrue(ranges[2].Bytes.SequenceEqual(
                              Element.FromHexString(
                                  @"83 02 07 ac
                c0 9e ba a0
                6f 6b 00 00"
                                  )
                              ));
        }
 private HashSet <ILogicalConstruct> GetLogicalConstructsInRange(BlockRange blockRange, out ILogicalConstruct theCommonParent)
 {
     V_0 = new HashSet <ILogicalConstruct>();
     V_1 = new HashSet <ISingleEntrySubGraph>();
     V_2 = blockRange.Start.get_First().get_Offset();
     V_3 = blockRange.End.get_First().get_Offset();
     V_5 = 0;
     while (V_5 < (int)this.context.get_CFG().get_Blocks().Length)
     {
         V_6 = this.context.get_CFG().get_Blocks()[V_5];
         if (V_6.get_First().get_Offset() >= V_2 && V_6.get_First().get_Offset() <= V_3)
         {
             V_7 = this.context.get_CFGBlockToLogicalConstructMap().get_Item(V_6);
             V_8 = 0;
             while (V_8 < (int)V_7.Length)
             {
                 dummyVar0 = V_1.Add((ILogicalConstruct)V_7[V_8].get_Parent());
                 dummyVar1 = V_0.Add(V_7[V_8]);
                 V_8       = V_8 + 1;
             }
         }
         V_5 = V_5 + 1;
     }
     if (V_1.get_Count() == 1)
     {
         theCommonParent = (ILogicalConstruct)V_1.ToArray <ISingleEntrySubGraph>()[0];
         return(V_0);
     }
     theCommonParent = (ILogicalConstruct)LogicalFlowUtilities.FindFirstCommonParent(V_1);
     V_4             = new HashSet <ILogicalConstruct>();
     V_9             = V_0.GetEnumerator();
     try
     {
         while (V_9.MoveNext())
         {
             dummyVar2 = LogicalFlowUtilities.TryGetParentConstructWithGivenParent(V_9.get_Current(), theCommonParent, out V_10);
             dummyVar3 = V_4.Add(V_10);
         }
     }
     finally
     {
         ((IDisposable)V_9).Dispose();
     }
     if (theCommonParent as ExceptionHandlingLogicalConstruct != null)
     {
         V_4.Clear();
         dummyVar4       = V_4.Add(theCommonParent);
         theCommonParent = theCommonParent.get_Parent() as ILogicalConstruct;
     }
     return(V_4);
 }
        private InstructionBlock GetEntryBlockInRange(BlockRange blockRange)
        {
            int rangeBegin = blockRange.Start.First.Offset;
            int rangeEnd   = blockRange.End.First.Offset;

            for (int i = 0; i < context.CFG.Blocks.Length; i++)
            {
                InstructionBlock currentBlock = context.CFG.Blocks[i];
                if (currentBlock.First.Offset >= rangeBegin && currentBlock.First.Offset <= rangeEnd)
                {
                    return(currentBlock);
                }
            }

            throw new Exception("Invalid range");
        }
 private InstructionBlock GetEntryBlockInRange(BlockRange blockRange)
 {
     V_0 = blockRange.Start.get_First().get_Offset();
     V_1 = blockRange.End.get_First().get_Offset();
     V_2 = 0;
     while (V_2 < (int)this.context.get_CFG().get_Blocks().Length)
     {
         V_3 = this.context.get_CFG().get_Blocks()[V_2];
         if (V_3.get_First().get_Offset() >= V_0 && V_3.get_First().get_Offset() <= V_1)
         {
             return(V_3);
         }
         V_2 = V_2 + 1;
     }
     throw new Exception("Invalid range");
 }
示例#29
0
        void InvokeRead(BlockRange range, Exception error = null)
        {
            var completion = new ReadCompletion(range, error);

            try
            {
                this.ReadAction?.Invoke(this.streamHandle, completion);
            }
            catch (Exception exception)
            {
                Log.Warn($"{nameof(Pipeline)} Exception whilst invoking read callback.", exception);
            }
            finally
            {
                completion.Dispose();
            }
        }
示例#30
0
        private static bool OverlappingBlockRanges(BlockRange blockRange1, BlockRange blockRange2)
        {
            if (blockRange1.StartToken == blockRange2.StartToken &&
                blockRange1.EndToken == blockRange2.EndToken)
            {
                return(true);
            }

            if (blockRange1.StartToken == null ||
                blockRange1.EndToken == null ||
                blockRange2.StartToken == null ||
                blockRange2.EndToken == null)
            {
                return(false);
            }

            return(blockRange2.StartToken < blockRange1.EndToken &&
                   blockRange2.EndToken > blockRange1.StartToken);
        }
示例#31
0
		void MoveStatementsToBlock (BlockRange range, BlockStatement block)
		{
			MoveStatementsToBlock (range.Start, range.End, block);
		}
示例#32
0
 /// <summary>
 /// Check equal of current <see cref="BlockRange"/> and other <see cref="BlockRange"/>.
 /// </summary>
 /// <param name="other">Other <see cref="BlockRange"/> to check.</param>
 /// <returns>If <see cref="BlockRange"/>s are the same in all data members
 /// (<see cref="CommonStartIndex"/>, <see cref="Count"/> and <see cref="Subindex"/>) return true, otherwise return false.</returns>
 public bool Equals(BlockRange other)
 {
     return (CommonStartIndex == other.CommonStartIndex
             && Count == other.Count
             && Subindex == other.Subindex);
 }
		private HashSet<ILogicalConstruct> GetLogicalConstructsInRange(BlockRange blockRange, out ILogicalConstruct theCommonParent)
		{
			HashSet<ILogicalConstruct> children = new HashSet<ILogicalConstruct>();
			HashSet<ISingleEntrySubGraph> blocksParents = new HashSet<ISingleEntrySubGraph>();

            int rangeBegin = blockRange.Start.First.Offset;
            int rangeEnd = blockRange.End.First.Offset;
            for (int i = 0; i < context.CFG.Blocks.Length; i++)
            {
                InstructionBlock currentBlock = context.CFG.Blocks[i];
                if(currentBlock.First.Offset >= rangeBegin && currentBlock.First.Offset <= rangeEnd)
                {
                    CFGBlockLogicalConstruct[] cfgConstructs = context.CFGBlockToLogicalConstructMap[currentBlock];

                    for (int j = 0; j < cfgConstructs.Length; j++)
                    {
                        blocksParents.Add((ILogicalConstruct)cfgConstructs[j].Parent);
                        children.Add(cfgConstructs[j]);
                    }
                }
            }

			if (blocksParents.Count == 1)
			{
				theCommonParent = (ILogicalConstruct)blocksParents.ToArray<ISingleEntrySubGraph>()[0];

				return children;
			}
				//TODO: CCheck whether the parent logical construct of of each CFGBlockLogicalConstruct that belongs to the exception handling block,
				//(i.e. each member of blocksParents) contains as children ONLY blocks that belong to the exception handling block (i.e. blocks that are in blockRange).

			theCommonParent = (ILogicalConstruct)LogicalFlowUtilities.FindFirstCommonParent(blocksParents);

			HashSet<ILogicalConstruct> result = new HashSet<ILogicalConstruct>();
            foreach (ILogicalConstruct child in children)
            {
                ILogicalConstruct desiredNode;
                LogicalFlowUtilities.TryGetParentConstructWithGivenParent(child, theCommonParent, out desiredNode);
                result.Add(desiredNode);
            }

            if (theCommonParent is ExceptionHandlingLogicalConstruct)
            {
                result.Clear();
                result.Add(theCommonParent);
                theCommonParent = theCommonParent.Parent as ILogicalConstruct;
            }

			return result;
		}
		BlockLogicalConstruct CreateExceptionhandlingBlock(BlockRange cfgBlocks)
		{
			HashSet<ILogicalConstruct> children;
			ILogicalConstruct theCommonParent;

			children = GetLogicalConstructsInRange(cfgBlocks, out theCommonParent);
			ILogicalConstruct entry = FindChildBlockBelongsTo(theCommonParent, context.CFGBlockToLogicalConstructMap[GetEntryBlockInRange(cfgBlocks)][0]);
			return new BlockLogicalConstruct(entry, children);
		}
        private InstructionBlock GetEntryBlockInRange(BlockRange blockRange)
        {
            int rangeBegin = blockRange.Start.First.Offset;
            int rangeEnd = blockRange.End.First.Offset;

            for (int i = 0; i < context.CFG.Blocks.Length; i++)
            {
                InstructionBlock currentBlock = context.CFG.Blocks[i];
                if (currentBlock.First.Offset >= rangeBegin && currentBlock.First.Offset <= rangeEnd)
                {
                    return currentBlock;
                }
            }

            throw new Exception("Invalid range");
        }