/// <summary>
        /// This method is called to handle the construction of an Item
        /// instance from the supplied request entity. It is called
        /// whenever an Item start tag is detected.
        /// An instance of an Item is created and initialized to default
        /// values. These values are then overridden from values supplied
        /// as attributes to the Item element.
        /// This item is then stored in the XmlInventoryCollection and
        /// will be verified by Validate.
        /// All context is reset whenever the effective folder changes
        /// or an item is successfully validated.
        /// </summary>
        private void CollectItem(XmlInventoryCollection ic)
        {
            Rest.Log.DebugFormat("{0} Interpret item element", MsgId);

            InventoryItemBase result = new InventoryItemBase();

            result.Name        = String.Empty;
            result.Description = String.Empty;
            result.ID          = UUID.Zero;
            result.Folder      = UUID.Zero;
            result.Owner       = ic.UserID;
            result.CreatorId   = ic.UserID.ToString();
            result.AssetID     = UUID.Zero;
            result.GroupID     = UUID.Zero;
            result.GroupOwned  = false;
            result.InvType     = (int) InventoryType.Unknown;
            result.AssetType   = (int) AssetType.Unknown;

            if (ic.xml.HasAttributes)
            {
                for (int i = 0; i < ic.xml.AttributeCount; i++)
                {
                    ic.xml.MoveToAttribute(i);

                    switch (ic.xml.Name)
                    {
                        case "name":
                            result.Name         =     ic.xml.Value;
                            break;
                        case "desc":
                            result.Description  =     ic.xml.Value;
                            break;
                        case "uuid":
                            result.ID           = new UUID(ic.xml.Value);
                            break;
                        case "folder":
                            result.Folder       = new UUID(ic.xml.Value);
                            break;
                        case "owner":
                            result.Owner        = new UUID(ic.xml.Value);
                            break;
                        case "invtype":
                            result.InvType      =     Int32.Parse(ic.xml.Value);
                            break;
                        case "creator":
                            result.CreatorId    =     ic.xml.Value;
                            break;
                        case "assettype":
                            result.AssetType    =     Int32.Parse(ic.xml.Value);
                            break;
                        case "groupowned":
                            result.GroupOwned   =     Boolean.Parse(ic.xml.Value);
                            break;
                        case "groupid":
                            result.GroupID      = new UUID(ic.xml.Value);
                            break;
                        case "flags":
                            result.Flags        =     UInt32.Parse(ic.xml.Value);
                            break;
                        case "creationdate":
                            result.CreationDate =     Int32.Parse(ic.xml.Value);
                            break;
                        case "saletype":
                            result.SaleType     =     Byte.Parse(ic.xml.Value);
                            break;
                        case "saleprice":
                            result.SalePrice    =     Int32.Parse(ic.xml.Value);
                            break;

                        default:
                            Rest.Log.DebugFormat("{0} Item: Unrecognized attribute: {1}:{2}",
                                                 MsgId, ic.xml.Name, ic.xml.Value);
                            ic.Fail(Rest.HttpStatusCodeBadRequest, String.Format("unrecognized attribute",
                                ic.xml.Name));
                            break;
                    }
                }
            }

            ic.xml.MoveToElement();

            ic.Push(result);
        }
        /// <summary>
        /// This method assembles an asset instance from the
        /// information supplied in the request's entity. It is
        /// called as a result of detecting a start tag for a
        /// type of Asset.
        /// The information is collected locally, and an asset
        /// instance is created only if the basic XML parsing
        /// completes successfully.
        /// Default values for all parts of the asset are
        /// established before overriding them from the supplied
        /// XML.
        /// If an asset has inline=true as an attribute, then
        /// the element contains the data representing the
        /// asset. This is saved as the data component.
        /// inline=false means that the element's payload is
        /// simply the UUID of the asset referenced by the
        /// item being constructed.
        /// An asset, if created is stored in the
        /// XmlInventoryCollection
        /// </summary>
        private void CollectAsset(XmlInventoryCollection ic)
        {
            Rest.Log.DebugFormat("{0} Interpret asset element", MsgId);

            string    name  = String.Empty;
            string    desc  = String.Empty;
            sbyte     type  = (sbyte) AssetType.Unknown;
            bool      temp  = false;
            bool     local  = false;

            // This is not a persistent attribute
            bool    inline  = false;

            UUID    uuid  = UUID.Zero;

            // Attribute is optional
            if (ic.xml.HasAttributes)
            {
                for (int i = 0; i < ic.xml.AttributeCount; i++)
                {
                    ic.xml.MoveToAttribute(i);
                    switch (ic.xml.Name)
                    {
                        case "name" :
                            name = ic.xml.Value;
                            break;

                        case "type" :
                            type = SByte.Parse(ic.xml.Value);
                            break;

                        case "description" :
                            desc = ic.xml.Value;
                            break;

                        case "temporary" :
                            temp = Boolean.Parse(ic.xml.Value);
                            break;

                        case "uuid" :
                            uuid = new UUID(ic.xml.Value);
                            break;

                        case "inline" :
                            inline = Boolean.Parse(ic.xml.Value);
                            break;

                        case "local" :
                            local = Boolean.Parse(ic.xml.Value);
                            break;

                        default :
                            Rest.Log.DebugFormat("{0} Asset: Unrecognized attribute: {1}:{2}",
                                                 MsgId, ic.xml.Name, ic.xml.Value);
                            ic.Fail(Rest.HttpStatusCodeBadRequest,
                                    String.Format("unrecognized attribute <{0}>", ic.xml.Name));
                            break;
                    }
                }
            }

            ic.xml.MoveToElement();

            // If this is a reference to an existing asset, just store the
            // asset ID into the item.

            if (!inline)
            {
                if (ic.Item != null)
                {
                    ic.Item.AssetID = new UUID(ic.xml.ReadElementContentAsString());
                    Rest.Log.DebugFormat("{0} Asset ID supplied: {1}", MsgId, ic.Item.AssetID);
                }
                else
                {
                    Rest.Log.DebugFormat("{0} LLUID unimbedded asset must be inline", MsgId);
                    ic.Fail(Rest.HttpStatusCodeBadRequest, "no context for asset");
                }
            }

            // Otherwise, generate an asset ID, store that into the item, and
            // create an entry in the asset list for the inlined asset. But
            // only if the size is non-zero.

            else
            {
                AssetBase asset = null;
                string b64string = null;

                // Generate a UUID if none were given, and generally none should
                // be. Ever.

                if (uuid == UUID.Zero)
                {
                    uuid = UUID.Random();
                }

                // Create AssetBase entity to hold the inlined asset

                asset = new AssetBase(uuid, name, type, UUID.Zero.ToString());

                asset.Description = desc;
                asset.Local       = local;
                asset.Temporary   = temp;

                b64string         = ic.xml.ReadElementContentAsString();

                Rest.Log.DebugFormat("{0} Data length is {1}", MsgId, b64string.Length);
                Rest.Log.DebugFormat("{0} Data content starts with: \n\t<{1}>", MsgId,
                                     b64string.Substring(0, b64string.Length > 132 ? 132 : b64string.Length));

                asset.Data        = Convert.FromBase64String(b64string);

                // Ensure the asset always has some kind of data component

                if (asset.Data == null)
                {
                    asset.Data = new byte[1];
                }

                // If this is in the context of an item, establish
                // a link with the item in context.

                if (ic.Item != null && ic.Item.AssetID == UUID.Zero)
                {
                    ic.Item.AssetID = uuid;
                }

                ic.Push(asset);
            }
        }
        /// <summary>
        /// This method creates an inventory Folder from the
        /// information supplied in the request's entity.
        /// A folder instance is created and initialized to reflect
        /// default values. These values are then overridden
        /// by information supplied in the entity.
        /// If context was not explicitly provided, then the
        /// appropriate ID values are determined.
        /// </summary>

        private void CollectFolder(XmlInventoryCollection ic)
        {
            Rest.Log.DebugFormat("{0} Interpret folder element", MsgId);

            InventoryFolderBase result = new InventoryFolderBase();

            // Default values

            result.Name     = String.Empty;
            result.ID       = UUID.Zero;
            result.Owner    = ic.UserID;
            result.ParentID = UUID.Zero; // Context
            result.Type     = (short) AssetType.Folder;
            result.Version  = 1;

            if (ic.xml.HasAttributes)
            {
                for (int i = 0; i < ic.xml.AttributeCount; i++)
                {
                    ic.xml.MoveToAttribute(i);
                    switch (ic.xml.Name)
                    {
                    case "name":
                        result.Name     =     ic.xml.Value;
                        break;
                    case "uuid":
                        result.ID       = new UUID(ic.xml.Value);
                        break;
                    case "parent":
                        result.ParentID = new UUID(ic.xml.Value);
                        break;
                    case "owner":
                        result.Owner    = new UUID(ic.xml.Value);
                        break;
                    case "type":
                        result.Type     =     Int16.Parse(ic.xml.Value);
                        break;
                    case "version":
                        result.Version  =     UInt16.Parse(ic.xml.Value);
                        break;
                    default:
                        Rest.Log.DebugFormat("{0} Folder: unrecognized attribute: {1}:{2}",
                                             MsgId, ic.xml.Name, ic.xml.Value);
                        ic.Fail(Rest.HttpStatusCodeBadRequest, String.Format("unrecognized attribute <{0}>",
                                 ic.xml.Name));
                        break;
                    }
                }
            }

            ic.xml.MoveToElement();

            // The client is relying upon the reconstitution process
            // to determine the parent's UUID based upon context. This
            // is necessary where a new folder may have been
            // introduced.

            if (result.ParentID == UUID.Zero)
            {
                result.ParentID = ic.Parent();
            }
            else
            {
                bool found = false;

                foreach (InventoryFolderBase parent in ic.rdata.folders)
                {
                    if (parent.ID == result.ParentID)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Rest.Log.ErrorFormat("{0} Invalid parent ID ({1}) in folder {2}",
                                         MsgId, ic.Item.Folder, result.ID);
                    ic.Fail(Rest.HttpStatusCodeBadRequest, "invalid parent");
                }
            }

            // This is a new folder, so no existing UUID is available
            // or appropriate

            if (result.ID == UUID.Zero)
            {
                result.ID = UUID.Random();
            }

            // Treat this as a new context. Any other information is
            // obsolete as a consequence.

            ic.Push(result);
        }