private static unsafe void _Dump(NtfsAttributeListAttribute *from, DumpCallbackDelegate callback)
        {
            if (null == from)
            {
                throw new ArgumentNullException();
            }
            if (NtfsAttributeType.AttributeAttributeList != from->Header.AttributeType)
            {
                throw new ArgumentException();
            }
            IPartitionClusterData disposableData = null;
            ListEntry *           listBase       = null;
            uint listLength;

            try {
                if (from->Header.IsResident)
                {
                    NtfsResidentAttribute *listAttribute = (NtfsResidentAttribute *)from;
                    listBase   = (ListEntry *)((byte *)from + listAttribute->ValueOffset);
                    listLength = listAttribute->ValueLength;
                }
                else
                {
                    NtfsNonResidentAttribute *listAttribute = (NtfsNonResidentAttribute *)from;
                    disposableData = listAttribute->GetData();
                    if (null == disposableData)
                    {
                        throw new ApplicationException();
                    }
                    listBase = (ListEntry *)disposableData.Data;
                    ulong candidateLength = listAttribute->DataSize;
                    if (uint.MaxValue < candidateLength)
                    {
                        throw new ApplicationException();
                    }
                    listLength = (uint)candidateLength;
                }
                if (null == listBase)
                {
                    throw new ApplicationException();
                }
                uint offset = 0;
                while (offset < listLength)
                {
                    ListEntry *entry = (ListEntry *)((byte *)listBase + offset);
                    callback(entry);
                    offset += entry->EntryLength;
                }
            }
            finally {
                if (null != disposableData)
                {
                    disposableData.Dispose();
                }
            }
        }
        /// <summary>Enumerate attributes bound to this <see cref="NtfsFileRecord"/>, optionally filtering
        /// on attribute name.</summary>
        /// <param name="header">The file record.</param>
        /// <param name="callback"></param>
        /// <param name="searchedAttributeType"></param>
        /// <param name="nameFilter">An optional name filter that will be provided with the basic attribute
        /// properties (including name) in order to decide if data should be retrieved. This is especially
        /// usefull for <see cref="NtfsAttributeListAttribute"/> attributes that may reference lengthy
        /// attributes data which are expensive to retrieve.</param>
        internal static unsafe void EnumerateRecordAttributes(NtfsFileRecord *header,
                                                              RecordAttributeEnumeratorCallbackDelegate callback, NtfsAttributeType searchedAttributeType,
                                                              AttributeNameFilterDelegate nameFilter)
        {
            // Walk attributes, seeking for the searched one.
            NtfsAttribute *currentAttribute = (NtfsAttribute *)((byte *)header + header->AttributesOffset);
            NtfsAttributeListAttribute *pendingAttributeList = null;

            NtfsAttribute *[] candidates = new NtfsAttribute *[MaxAttributeCount];
            int candidatesCount          = 0;

            for (int attributeIndex = 0; attributeIndex < header->NextAttributeNumber; attributeIndex++)
            {
                if (currentAttribute->IsLast)
                {
                    break;
                }
                if (header->BytesInUse < ((byte *)currentAttribute - (byte *)header))
                {
                    break;
                }
                if (NtfsAttributeType.EndOfListMarker == currentAttribute->AttributeType)
                {
                    break;
                }
                // If we found an AttributeListAttribute, we must go one level deeper to
                // complete the enumeration.
                if (NtfsAttributeType.AttributeAttributeList == currentAttribute->AttributeType)
                {
                    if (null != pendingAttributeList)
                    {
                        // No more than one attribute of this kind per file record.
                        throw new ApplicationException();
                    }
                    if (NtfsAttributeType.AttributeAttributeList == searchedAttributeType)
                    {
                        if (!callback(currentAttribute, null))
                        {
                            return;
                        }
                    }
                    // Defer handling
                    pendingAttributeList = (NtfsAttributeListAttribute *)currentAttribute;
                    break;
                }
                if (candidatesCount >= MaxAttributeCount)
                {
                    throw new ApplicationException();
                }
                if ((NtfsAttributeType.Any == searchedAttributeType) ||
                    (currentAttribute->AttributeType == searchedAttributeType))
                {
                    candidates[candidatesCount++] = currentAttribute;
                }
                currentAttribute = (NtfsAttribute *)((byte *)currentAttribute + currentAttribute->Length);
            }
            if (NtfsAttributeType.AttributeAttributeList == searchedAttributeType)
            {
                // Either we already found one such attribute and invoked the callback or found none and
                // we can return immediately. Should we have found several such attributes we would have
                // risen an exception.
                return;
            }
            if (null == pendingAttributeList)
            {
                // We already walked every attributes and captured those that matched the type filter if
                // any. Invoke callbak on each such attribute.
                for (int candidateIndex = 0; candidateIndex < candidatesCount; candidateIndex++)
                {
                    if (!callback(candidates[candidateIndex], null))
                    {
                        return;
                    }
                }
                // We are done.
                return;
            }
            NtfsAttributeListAttribute.Dump(pendingAttributeList);
            // HandleAttributeListAttributeEntry
            // We have an attribute list attribute. Delegate him the enumeration.
            NtfsPartition currentPartition = NtfsPartition.Current;

            NtfsAttributeListAttribute.EnumerateEntries((NtfsAttribute *)pendingAttributeList, searchedAttributeType,
                                                        new ListEntryHandler(searchedAttributeType, nameFilter, callback).HandleListEntry);
            return;
        }
 internal static unsafe void Dump(NtfsAttributeListAttribute *from)
 {
     _Dump(from, delegate(ListEntry * entry) { entry->Dump(); });
 }