protected bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger,
                                              string name, string type, string blockName,
                                              MemoryReader.Converter <double> elementConverter,
                                              MemoryBlockPredicate memoryBlockPredicate)
            {
                if (elementConverter == null)
                {
                    return(false);
                }
                int size           = LoadSize(debugger, name);
                var blockConverter = new MemoryReader.ArrayConverter <double>(elementConverter, size);

                ulong address = ExpressionParser.GetValueAddress(debugger, blockName);

                if (address == 0)
                {
                    return(false);
                }

                double[] values = new double[blockConverter.ValueCount()];
                if (!mreader.Read(address, values, blockConverter))
                {
                    return(false);
                }
                return(memoryBlockPredicate(values));
            }
            public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger,
                                                    string name, string type,
                                                    MemoryReader.Converter <double> elementConverter,
                                                    MemoryBlockPredicate memoryBlockPredicate)
            {
                if (elementConverter == null)
                {
                    return(false);
                }

                int size1, size2;

                LoadSizes(debugger, name, out size1, out size2);
                if (size1 <= 0)
                {
                    return(false);
                }

                {
                    ulong firstAddress = ExpressionParser.GetValueAddress(debugger, "(*(" + name + ".m_first))");
                    if (firstAddress == 0)
                    {
                        return(false);
                    }
                    var      blockConverter = new MemoryReader.ArrayConverter <double>(elementConverter, size1);
                    double[] values         = new double[blockConverter.ValueCount()];
                    if (!mreader.Read(firstAddress, values, blockConverter))
                    {
                        return(false);
                    }
                    if (!memoryBlockPredicate(values))
                    {
                        return(false);
                    }
                }

                if (size2 > 0)
                {
                    ulong buffAddress = ExpressionParser.GetValueAddress(debugger, "(*(" + name + ".m_buff))");
                    if (buffAddress == 0)
                    {
                        return(false);
                    }
                    var      blockConverter = new MemoryReader.ArrayConverter <double>(elementConverter, size2);
                    double[] values         = new double[blockConverter.ValueCount()];
                    if (!mreader.Read(buffAddress, values, blockConverter))
                    {
                        return(false);
                    }
                    if (!memoryBlockPredicate(values))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger,
                                                    string name, string type,
                                                    MemoryReader.Converter <double> elementConverter,
                                                    MemoryBlockPredicate memoryBlockPredicate)
            {
                int size = LoadSize(debugger, name);

                if (size == 0)
                {
                    return(true);
                }

                // Map size
                int mapSize = 0;

                if (!ExpressionParser.TryLoadInt(debugger, MapSizeStr(name), out mapSize))
                {
                    return(false);
                }

                VariableInfo mapInfo = new VariableInfo(debugger, MapStr(name) + "[0]");

                if (!mapInfo.IsValid)
                {
                    return(false);
                }

                // Map - array of pointers
                ulong[] pointers = new ulong[mapSize];
                if (!mreader.ReadPointerArray(mapInfo.Address, mapInfo.Type, mapInfo.Size, pointers))
                {
                    return(false);
                }

                // Block size
                int dequeSize = 0;

                if (!ExpressionParser.TryLoadInt(debugger, "((int)" + name + "._EEN_DS)", out dequeSize))
                {
                    return(false);
                }

                // Offset
                int offset = 0;

                if (!ExpressionParser.TryLoadInt(debugger, OffsetStr(name), out offset))
                {
                    return(false);
                }

                // Initial indexes
                int firstBlock   = ((0 + offset) / dequeSize) % mapSize;
                int firstElement = (0 + offset) % dequeSize;
                int backBlock    = (((size - 1) + offset) / dequeSize) % mapSize;
                int backElement  = ((size - 1) + offset) % dequeSize;
                int blocksCount  = firstBlock <= backBlock
                                ? backBlock - firstBlock + 1
                                : mapSize - firstBlock + backBlock + 1;

                int globalIndex = 0;

                for (int i = 0; i < blocksCount; ++i)
                {
                    int   blockIndex = (firstBlock + i) % mapSize;
                    ulong address    = pointers[blockIndex];
                    if (address != 0) // just in case
                    {
                        int elemIndex = (i == 0)
                                        ? firstElement
                                        : 0;
                        int blockSize = dequeSize - elemIndex;
                        if (i == blocksCount - 1) // last block
                        {
                            blockSize -= dequeSize - (backElement + 1);
                        }

                        if (blockSize > 0) // just in case
                        {
                            MemoryReader.ArrayConverter <double>
                            arrayConverter = new MemoryReader.ArrayConverter <double>(elementConverter, blockSize);
                            if (arrayConverter == null)
                            {
                                return(false);
                            }

                            int   valuesCount  = elementConverter.ValueCount() * blockSize;
                            ulong firstAddress = address + (ulong)(elemIndex * elementConverter.ByteSize());

                            double[] values = new double[valuesCount];
                            if (!mreader.Read(firstAddress, values, arrayConverter))
                            {
                                return(false);
                            }

                            if (!memoryBlockPredicate(values))
                            {
                                return(false);
                            }

                            globalIndex += blockSize;
                        }
                    }
                }

                return(true);
            }