sysperfana/heapanalyser/Libraries/Engine/HeapLib/Cells/HeapCell.cs
changeset 8 15296fd0af4a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/heapanalyser/Libraries/Engine/HeapLib/Cells/HeapCell.cs	Tue Jun 15 12:47:20 2010 +0300
@@ -0,0 +1,940 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright notice,
+*   this list of conditions and the following disclaimer in the documentation
+*   and/or other materials provided with the distribution.
+* - Neither the name of Nokia Corporation nor the names of its contributors
+*   may be used to endorse or promote products derived from this software
+*   without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+* 
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using SymbianStructuresLib.Debug.Symbols;
+using SymbianUtils.RawItems;
+using SymbianUtils.Utilities;
+using HeapLib.Array;
+using HeapLib.Relationships;
+using HeapLib.Cells.Descriptors;
+
+namespace HeapLib.Cells
+{
+    public class HeapCell : IEnumerable<RawItem>, IEquatable<HeapCell>
+    {
+        #region Enumerations
+        public enum TRegion
+        {
+            EHeader = 0,
+            EPayload,
+            EBeforeCell,
+            EAfterCell
+        }
+
+        public enum TType : byte
+        {
+            EAllocated = 0,
+            EFree
+        }
+
+        public enum TBuildType
+        {
+            ERelease = 0,
+            EDebug = 1
+        }
+
+        public enum TDescriptorType
+        {
+            // These are Symbian's descriptor types
+            EBufC = 0,
+            EPtrC,
+            EPtr,
+            EBuf,
+            EBufCPtr,
+
+            // This are specific to this app
+            ENullTerminatedString,
+            EUnknown,
+        }
+        #endregion
+
+        #region Constructors & destructor
+        public HeapCell()
+        {
+            iRelationshipManager = new RelationshipManager(this);
+        }
+
+        internal HeapCell(HeapCell aCell)
+            : this()
+        {
+            iTag = aCell.Tag;
+            iAddress = aCell.Address;
+            iType = aCell.Type;
+            iFlags = aCell.iFlags;
+            iSymbol[0] = aCell.iSymbol[0];
+            iSymbol[1] = aCell.iSymbol[1];
+            iSymbol[2] = aCell.iSymbol[2];
+            iRawItems = aCell.iRawItems;
+            iDescriptorInfo = aCell.iDescriptorInfo;
+            iHeaderRawItems = aCell.iHeaderRawItems;
+            iLength = aCell.iLength;
+            //
+            iRelationshipManager = aCell.RelationshipManager;
+            iChecksum = new CRC32Checksum(aCell.Checksum);
+        }
+
+        internal HeapCell(uint aAddress, uint aLength, TType aType)
+            : this()
+        {
+            iAddress = aAddress;
+            iType = aType;
+            //
+            iHeaderRawItems.Clear();
+            AddRawItemHeader(new RawItem(aAddress, aLength));
+        }
+        #endregion
+
+        #region Constants
+        public const uint KHeapCellSizeAllocatedUREL = 4;   // Just length
+        public const uint KHeapCellSizeAllocatedUDEB = 12;  // Length + Allocation Number + Nesting Level
+        public const uint KHeapCellSizeFree = 8;            // Length + Pointer to next free cell
+        #endregion
+
+        #region API
+        public void AddRawItem(RawItem aItem)
+        {
+            RawItems.Add(aItem);
+            //
+            byte[] dataArray = aItem.DataArray;
+            iChecksum.Checksum(dataArray);
+        }
+
+        public void AddRawItemHeader(RawItem aItem)
+        {
+            // Not checksummed
+            iHeaderRawItems.Add(aItem);
+            if (iHeaderRawItems.Count == 1)
+            {
+                iLength = iHeaderRawItems[0].Data;
+            }
+        }
+
+        public uint Remainder(uint aAddress)
+        {
+            uint ret = (Address + Length) - aAddress;
+            return ret;
+        }
+
+        public static uint CellHeaderSize(TType aType)
+        {
+            uint ret = AllocatedCellHeaderSize;
+            if (aType == TType.EFree)
+            {
+                ret = FreeCellHeaderSize;
+            }
+            return ret;
+        }
+
+        public static uint AllocatedCellSizeByBuildType(TBuildType aType)
+        {
+            uint size = 0;
+            //
+            switch (aType)
+            {
+                case TBuildType.EDebug:
+                    size = KHeapCellSizeAllocatedUDEB;
+                    break;
+                case TBuildType.ERelease:
+                    size = KHeapCellSizeAllocatedUREL;
+                    break;
+            }
+            //
+            return size;
+        }
+
+        public TRegion RegionForAddress(uint aAddress)
+        {
+            uint address = Address;
+            //
+            TRegion ret = TRegion.EBeforeCell;
+            //
+            if (aAddress < address)
+            {
+                ret = TRegion.EBeforeCell;
+            }
+            else
+            {
+                uint endAddress = EndAddress;
+                //
+                if (aAddress > endAddress)
+                {
+                    ret = TRegion.EAfterCell;
+                }
+                else
+                {
+                    uint startOfPayload = StartOfPayloadAddress;
+                    //
+                    if (aAddress >= startOfPayload)
+                    {
+                        ret = TRegion.EPayload;
+                    }
+                    else
+                    {
+                        ret = TRegion.EHeader;
+                    }
+                }
+            }
+            //
+            return ret;
+        }
+
+        public TRegion RegionForAddress(uint aAddress, out int aRemainingUntilNextBoundary)
+        {
+            TRegion region = RegionForAddress(aAddress);
+            //
+            switch (region)
+            {
+                default:
+                    aRemainingUntilNextBoundary = -1;
+                    break;
+                case TRegion.EHeader:
+                case TRegion.EPayload:
+                    if (region == TRegion.EHeader)
+                    {
+                        uint startOfPayload = StartOfPayloadAddress;
+                        aRemainingUntilNextBoundary = (int)(startOfPayload - aAddress);
+                    }
+                    else
+                    {
+                        uint endAddress = EndAddress;
+                        aRemainingUntilNextBoundary = (int)(endAddress - aAddress + 1);
+                    }
+                    break;
+            }
+            //
+            return region;
+        }
+
+        public bool IsIdentical(HeapCell aCell)
+        {
+            bool identical = false;
+            //
+            if (aCell.Length == this.Length &&
+                 aCell.PossibleVTableAddress == this.PossibleVTableAddress &&
+                 aCell.AllocationNumber == this.AllocationNumber &&
+                 aCell.NestingLevel == this.NestingLevel &&
+                 aCell.RawItems.Count == this.RawItems.Count)
+            {
+                identical = (aCell.Checksum == this.Checksum);
+            }
+            //
+            return identical;
+        }
+
+        internal void ConstructionComplete(Statistics.HeapStatistics aStats)
+        {
+            if (Type == TType.EAllocated)
+            {
+                iDescriptorInfo = Descriptors.DescriptorAlgorithmManager.DescriptorInfo(this, aStats);
+            }
+        }
+        #endregion
+
+        #region Properties
+        public HeapCell.TType Type
+        {
+            get { return iType; }
+            set { iType = value; }
+        }
+
+        public string TypeString
+        {
+            get
+            {
+                string ret = string.Empty;
+                //
+                switch (Type)
+                {
+                    case TType.EAllocated:
+                        ret = "Allocated";
+                        break;
+                    case TType.EFree:
+                        ret = "Free";
+                        break;
+                }
+                //
+                return ret;
+            }
+        }
+
+        // <summary>
+        // The index is the unique number assigned to each cell as it is
+        // added to the heap data for a given heap. This operation is 
+        // performed by the reconstructor during parsing.
+        // </summary>
+        public uint Index
+        {
+            get { return iIndex; }
+            set { iIndex = value; }
+        }
+
+        public uint Address
+        {
+            get { return iAddress; }
+            set { iAddress = value; }
+        }
+
+        public uint StartOfPayloadAddress
+        {
+            get
+            {
+                uint ret = Address;
+                //
+                if (Type == TType.EAllocated)
+                {
+                    ret += HeaderSize;
+                }
+                else if (Type == TType.EFree)
+                {
+                    ret += KHeapCellSizeFree;
+                }
+                else
+                {
+                    System.Diagnostics.Debug.Assert(false);
+                }
+                //
+                return ret;
+            }
+        }
+
+        public uint EndAddress
+        {
+            get { return iAddress + iLength - 1; }
+        }
+
+        public uint Length
+        {
+            // Optimisation: we cache the length when adding the first
+            // header raw item to avoid having to repeatedly access
+            // the raw items array during initial heap preparation.
+            get { return iLength; }
+        }
+
+        public uint NestingLevel
+        {
+            get
+            {
+                // Only applicable to allocated cells in debug builds
+                uint ret = 0;
+                //
+                if (Type == TType.EAllocated && IsDebugAllocator)
+                {
+                    System.Diagnostics.Debug.Assert(HeaderRawItems.Count >= 2);
+                    RawItem item = HeaderRawItems[1]; // Always 2nd raw item in header
+                    ret = item.Data;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public uint AllocationNumber
+        {
+            get
+            {
+                // Only applicable to allocated cells in debug builds
+                uint ret = 0;
+                //
+                if (Type == TType.EAllocated && IsDebugAllocator)
+                {
+                    System.Diagnostics.Debug.Assert(HeaderRawItems.Count >= 3);
+                    RawItem item = HeaderRawItems[2]; // Always 3rd raw item in header
+                    ret = item.Data;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public uint PossibleVTableAddress
+        {
+            get
+            {
+                // This is always the first raw item
+                uint ret = 0;
+                //
+                if (RawItems.Count > 0)
+                {
+                    ret = RawItems[0].Data;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public Symbol Symbol
+        {
+            get { return iSymbol[0]; }
+            set { iSymbol[0] = value; }
+        }
+
+        public Symbol Symbol2
+        {
+            get { return iSymbol[1]; }
+            set { iSymbol[1] = value; }
+        }
+
+        public Symbol Symbol3
+        {
+            get { return iSymbol[2]; }
+            set { iSymbol[2] = value; }
+        }
+
+        public string SymbolString
+        {
+            get
+            {
+                return SymbolStringRef(false);
+            }
+        }
+
+        private string SymbolStringRef(bool reference)
+        {
+            StringBuilder ret = new StringBuilder();
+
+            if (Type == TType.EAllocated)
+            {
+                if (Symbol != null)
+                {
+                    ret.Append(Symbol.NameWithoutVTablePrefix);
+                }
+                else if (IsDescriptor)
+                {
+                    ret.Append("[Descriptor] " + DescriptorTextBeautified);
+                }
+            }
+            else if (Type == TType.EFree)
+            {
+                ret.Append("[Free]");
+                if (Symbol != null)
+                {
+                    ret.Append(" ");
+                    ret.Append(Symbol.NameWithoutVTablePrefix);
+                }
+            }
+
+            // If no text as yet identified, then return [Unknown], if there is not unique referrer.
+            // If the referrer is unique, or if all referrers are of the same known type,
+            // instead of [Unknown], you can see [Part of XXX], where XXX is the type of the referrer. 
+            if (ret.Length == 0)
+            {
+                if (!reference)
+                {
+                    if (iRelationshipManager.ReferencedByUnique != null)
+                    {
+                        string symbolString = iRelationshipManager.ReferencedByUnique.SymbolStringRef(true);
+
+                        if (!symbolString.Equals("[Unknown]"))
+                        {
+                            ret.Append("[Part of ");
+                            ret.Append(symbolString);
+                            ret.Append("]");
+                        }
+                        else
+                        {
+                            ret.Append("[Unknown]");
+                        }
+                    }
+                    else
+                    {
+                        ret.Append("[Unknown]");
+                    }
+                }
+                else
+                {
+                    ret.Append("[Unknown]");
+                }
+            }
+            return ret.ToString();
+        }
+
+        public string SymbolStringWithoutDescriptorPrefix
+        {
+            get
+            {
+                string ret = SymbolString;
+                //
+                if (IsDescriptor)
+                {
+                    ret = "[" + DescriptorLength.ToString("d4") + "] " + DescriptorTextBeautifiedWithoutLength;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public uint HeaderSize
+        {
+            get
+            {
+                uint size = 0;
+                //
+                switch (Type)
+                {
+                    case TType.EAllocated:
+                        size = HeapCell.AllocatedCellHeaderSize;
+                        break;
+                    case TType.EFree:
+                        size = KHeapCellSizeFree;
+                        break;
+                }
+                //
+                return size;
+            }
+        }
+
+        public uint PayloadLength
+        {
+            get { return (EndAddress - StartOfPayloadAddress) + 1; }
+        }
+
+        public RawItem this[uint aAddress]
+        {
+            get
+            {
+                RawItem ret = null;
+                //
+                TRegion region = RegionForAddress(aAddress);
+                if (region == TRegion.EPayload || region == TRegion.EHeader)
+                {
+                    if (region == TRegion.EHeader)
+                    {
+                        uint offset = aAddress - Address;
+                        int index = System.Convert.ToInt32(offset / RawItem.KSizeOfOneRawItemInBytes);
+                        //
+                        if (index < 0 || index >= HeaderRawItems.Count)
+                        {
+                            throw new ArgumentException("Address 0x" + aAddress.ToString("x8") + " is beyond this cell's header");
+                        }
+                        //
+                        ret = HeaderRawItems[index];
+                    }
+                    else
+                    {
+                        // Payload
+                        uint offset = aAddress - StartOfPayloadAddress;
+                        int index = System.Convert.ToInt32(offset / RawItem.KSizeOfOneRawItemInBytes);
+                        //
+                        if (index < 0 || index >= RawItems.Count)
+                        {
+                            throw new ArgumentException("Address 0x" + aAddress.ToString("x8") + " is beyond this cell's payload");
+                        }
+                        //
+                        ret = this[index];
+                    }
+                }
+                else
+                {
+                    throw new ArgumentException("Address 0x" + aAddress.ToString("x8") + " is not within this cell's extent");
+                }
+                return ret;
+            }
+        }
+
+        public RawItem this[int aIndex]
+        {
+            get
+            {
+                return iRawItems[aIndex];
+            }
+        }
+
+        public RawItemCollection RawItems
+        {
+            get { return iRawItems; }
+        }
+
+        public RawItemCollection HeaderRawItems
+        {
+            get { return iHeaderRawItems; }
+        }
+
+        public long CombinedLinkedCellPayloadLengths
+        {
+            get
+            {
+                int depth = 0;
+                long ret = DoGetCombinedLinkedCellPayloadLengths(ref depth);
+                return ret;
+            }
+        }
+
+        public long PayloadLengthIncludingLinkedCells
+        {
+            get
+            {
+                long ret = PayloadLength;
+                ret += RelationshipManager.PayloadLengthOfEmbeddedCells;
+                //
+                return ret;
+            }
+        }
+
+        public object Tag
+        {
+            get { return iTag; }
+            set { iTag = value; }
+        }
+
+        public uint Checksum
+        {
+            get { return iChecksum.Value; }
+        }
+
+        public bool IsUnknown
+        {
+            get { return Symbol == null && Type == TType.EAllocated; }
+        }
+        #endregion
+
+        #region Descriptor related functionality
+        public TDescriptorType DescriptorType
+        {
+            get
+            {
+                TDescriptorType ret = TDescriptorType.EUnknown;
+                //
+                if (IsDescriptor && iDescriptorInfo != null)
+                {
+                    ret = iDescriptorInfo.Type;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public bool IsDescriptorUnicode
+        {
+            get
+            {
+                bool ret = false;
+                //
+                if (IsDescriptor && iDescriptorInfo != null)
+                {
+                    ret = iDescriptorInfo.IsUnicode;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public bool IsDescriptor
+        {
+            get
+            {
+                return (iDescriptorInfo != null);
+            }
+        }
+
+        public int DescriptorLength
+        {
+            get
+            {
+                int length = 0;
+                //
+                if (IsDescriptor && iDescriptorInfo != null)
+                {
+                    length = iDescriptorInfo.Length;
+                }
+                //
+                return length;
+            }
+        }
+
+        public string DescriptorText
+        {
+            get
+            {
+                string ret = string.Empty;
+                //
+                if (IsDescriptor && iDescriptorInfo != null)
+                {
+                    ret = iDescriptorInfo.Text;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public string DescriptorTextBeautifiedWithoutLength
+        {
+            get
+            {
+                StringBuilder ret = new StringBuilder();
+                //
+                string des = DescriptorText;
+                if (des.Length > KMaxSymbolStringDescriptorLength)
+                {
+                    ret.Append(" \"");
+                    ret.Append(des.Substring(0, KMaxSymbolStringDescriptorLength));
+                    ret.Append("...\"");
+                }
+                else
+                {
+                    ret.Append(" \"");
+                    ret.Append(des);
+                    ret.Append("\"");
+                }
+                //
+                return ret.ToString();
+            }
+        }
+
+        public string DescriptorTextBeautified
+        {
+            get
+            {
+                StringBuilder ret = new StringBuilder();
+                //
+                ret.Append("{");
+                ret.Append(DescriptorLength.ToString("d4"));
+                ret.Append("}");
+                //
+                ret.Append(DescriptorTextBeautifiedWithoutLength);
+                //
+                return ret.ToString();
+            }
+        }
+        #endregion
+
+        #region Static properties
+        public static bool IsDebugAllocator
+        {
+            get
+            {
+                return AllocatedCellHeaderSize == AllocatedCellSizeByBuildType(TBuildType.EDebug);
+            }
+        }
+
+        public static uint FreeCellHeaderSize
+        {
+            get { return KFreeCellHeaderSize; }
+        }
+
+        public static uint AllocatedCellHeaderSize
+        {
+            get { return iAllocatedCellHeaderSize; }
+            set { iAllocatedCellHeaderSize = value; }
+        }
+        #endregion
+
+        #region Relationships
+        public RelationshipManager RelationshipManager
+        {
+            get { return iRelationshipManager; }
+        }
+        #endregion
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return new HeapCellRawItemEnumerator(this);
+        }
+
+        IEnumerator<RawItem> IEnumerable<RawItem>.GetEnumerator()
+        {
+            return new HeapCellRawItemEnumerator(this);
+        }
+        #endregion
+
+        #region IEquatable<HeapCell> Members
+        public bool Equals(HeapCell aOther)
+        {
+            bool ret = (aOther.Address == this.Address);
+            return ret;
+        }
+        #endregion
+
+        #region Operators
+        public static bool operator ==(HeapCell aLeft, HeapCell aRight)
+        {
+            bool ret = false;
+
+            // If both are null, or both are same instance, return true.
+            if (System.Object.ReferenceEquals(aLeft, aRight))
+            {
+                ret = true;
+            }
+            else if (((object)aLeft == null) || ((object)aRight == null))
+            {
+                // If one is null, but not both, return false.
+                ret = false;
+            }
+            else
+            {
+                // Return true if the fields match:
+                ret = (aLeft.Address == aRight.Address);
+            }
+            //
+            return ret;
+        }
+
+        public static bool operator !=(HeapCell aLeft, HeapCell aRight)
+        {
+            return !(aLeft == aRight);
+        }
+        #endregion
+
+        #region From System.Object
+        public override int GetHashCode()
+        {
+            return Address.GetHashCode();
+        }
+
+        public override bool Equals(object aObject)
+        {
+            bool ret = false;
+            //
+            if (aObject is HeapCell)
+            {
+                HeapCell otherCell = (HeapCell)aObject;
+                ret = Equals(otherCell);
+            }
+            //
+            return ret;
+        }
+
+        public override string ToString()
+        {
+            string ret = "[0x" + Address.ToString("x8") + " " + TypeString + "]";
+            return ret;
+        }
+
+        public string ToStringExtended()
+        {
+            StringBuilder ret = new StringBuilder();
+
+            // Type
+            if (Type == HeapCell.TType.EAllocated)
+            {
+                if (IsDescriptor)
+                {
+                    ret.Append("[D]");
+                }
+                else
+                {
+                    ret.Append("[A]");
+                }
+            }
+            else
+            {
+                ret.Append("[F]");
+            }
+
+            // Address
+            ret.Append(" 0x" + Address.ToString("x8"));
+
+            // Symbol (if present)
+            if (Symbol != null)
+            {
+                ret.Append(" - " + SymbolString);
+            }
+            else if (IsDescriptor)
+            {
+                ret.Append(" - " + DescriptorTextBeautified);
+            }
+
+            return ret.ToString();
+        }
+        #endregion
+
+        #region Internal flags
+        [Flags]
+        private enum TFlags
+        {
+            EFlagsNone = 0,
+            EFlagsInCombiningCheck = 1
+        }
+        #endregion
+
+        #region Internal constants
+        private const int KMaxRecursiveLinkedCellDepth = 5; // levels
+        private const int KMaxSymbolStringDescriptorLength = 128;
+        private const int KFreeCellHeaderSize = 8; // always
+        #endregion
+
+        #region Internal methods
+        private long DoGetCombinedLinkedCellPayloadLengths(ref int aDepth)
+        {
+            long ret = PayloadLength;
+            //
+            if (aDepth <= KMaxRecursiveLinkedCellDepth)
+            {
+                iFlags |= TFlags.EFlagsInCombiningCheck;
+                //
+                foreach (RelationshipInfo relInfo in RelationshipManager.EmbeddedReferencesTo)
+                {
+                    HeapCell linkedCell = relInfo.ToCell;
+                    bool isInLinkCheck = ((linkedCell.iFlags & TFlags.EFlagsInCombiningCheck) == TFlags.EFlagsInCombiningCheck);
+                    if (isInLinkCheck == false)
+                    {
+                        ++aDepth;
+                        ret += linkedCell.DoGetCombinedLinkedCellPayloadLengths(ref aDepth);
+                    }
+                    else
+                    {
+                    }
+                }
+                //
+                iFlags &= ~TFlags.EFlagsInCombiningCheck;
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region Data members
+        private static uint iAllocatedCellHeaderSize = 0;
+        private object iTag;
+        private uint iIndex;
+        private uint iAddress;
+        private uint iLength;
+        private TType iType = TType.EAllocated;
+        private TFlags iFlags = TFlags.EFlagsNone;
+        private Symbol[] iSymbol = new Symbol[3] { null, null, null };
+        private CRC32Checksum iChecksum = new CRC32Checksum();
+        private DescriptorInfo iDescriptorInfo = null;
+        private RawItemCollection iRawItems = new RawItemCollection();
+        private RawItemCollection iHeaderRawItems = new RawItemCollection();
+        private readonly RelationshipManager iRelationshipManager;
+        #endregion
+    }
+}
\ No newline at end of file