public override id _DecodeDictionaryOfObjectsForElement(GSXibElement element)
        {
            NSDictionary elements = element.Elements;
            NSEnumerator en;
            NSString key;
            NSMutableDictionary dict;

            dict = (NSMutableDictionary)NSMutableDictionary.Alloc().Init();
            en = elements.KeyEnumerator();
            while ((key = (NSString)en.NextObject()) != null)
            {
                id obj = this.ObjectForXib((GSXibElement)elements.ObjectForKey(key));
                if (obj == null)
                    System.Diagnostics.Trace.WriteLine(string.Format("No object for {0} at key {1}", elements.ObjectForKey(key).ToString(), key.Value));
                else
                    dict.SetObjectForKey(obj, key);
            }

            return dict;
        }
 public virtual void AddElement(GSXibElement element)
 {
     _values.AddObject(element);
 }
        public override id _DecodeArrayOfObjectsForElement(GSXibElement element)
        {
            NSArray values = element.Values;
            int max = values.Count;
            id[] list = new id[max];
            int i;

            for (i = 0; i < max; i++)
            {
                list[i] = this.ObjectForXib((GSXibElement)values.ObjectAtIndex(i));
                if (list[i] == null)
                    System.Diagnostics.Trace.WriteLine(string.Format("No object for {0} at index {1}", values.ObjectAtIndex(i).ToString(), i));
            }

            return NSArray.ArrayWithObjects(list);
        }
        public virtual id ObjectForXib(GSXibElement element)
        {
            NSString elementName;
            NSString objID;

            if (element == null)
                return null;

            objID = element.AttributeForKey(@"id");
            if (objID != null)
            {
                id newObj = Decoded.ObjectForKey(objID);
                if (newObj != null)
                {
                    // The object was already decoded as a reference
                    return newObj;
                }
            }

            elementName = element.Type;
            if (@"object".IsEqualToString(elementName))
            {
                NSString classname = element.AttributeForKey(@"class");
                return DecodeObjectForXib(element, classname, objID);
            }
            else if (@"string".IsEqualToString(elementName))
            {
                NSString type = element.AttributeForKey(@"type");
                id newObj = element.Value;

                if (type != null && type.IsEqualToString(@"base64-UTF8"))
                {
                     NSData d = ((NSString)newObj).DataUsingEncoding(NSStringEncoding.NSASCIIStringEncoding, false);
                     d = GSMimeDocument.DecodeBase64((NSData)d);
                     newObj = NSString.Alloc().InitWithData(d, NSStringEncoding.NSUTF8StringEncoding);
                }

                // empty strings are not nil!
                if (newObj == null)
                    newObj = (NSString)@"";

                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"int".IsEqualToString(elementName))
            {
                id newObj = NSNumber.NumberWithInt(element.Value.IntValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"double".IsEqualToString(elementName))
            {
                id newObj = NSNumber.NumberWithDouble(element.Value.DoubleValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"bool".IsEqualToString(elementName))
            {
                //Fixme
                id newObj = NSNumber.NumberWithBool(element.Value.BoolValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"integer".IsEqualToString(elementName))
            {
                NSString value = element.AttributeForKey(@"value");
                id newObj = NSNumber.NumberWithInteger(value.IntegerValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"real".IsEqualToString(elementName))
            {
                NSString value = element.AttributeForKey(@"value");
                id newObj = NSNumber.NumberWithFloat(value.FloatValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"bool".IsEqualToString(elementName))
            {
                NSString value = element.AttributeForKey(@"value");
                id newObj = NSNumber.NumberWithBool(value.BoolValue);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"reference".IsEqualToString(elementName))
            {
                NSString refId = element.AttributeForKey(@"ref");

                if (refId == null)
                {
                    return null;
                }
                else
                {
                    id newObj = Decoded.ObjectForKey(refId);
                     // FIXME: We need a marker for nil
                    if (newObj == null)
                    {
                        //NSLog(@"Decoding reference %@", ref);
                        element = (GSXibElement)Objects.ObjectForKey(refId);
                        if (element != null)
                        {
                            // Decode the real object
                            newObj = ObjectForXib(element);
                        }
                    }
                    return newObj;
                }
            }
            else if (@"nil".IsEqualToString(elementName))
            {
                return null;
            }
            else if (@"characters".IsEqualToString(elementName))
            {
                id newObj = element.Value;
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"bytes".IsEqualToString(elementName))
            {
                id newObj = element.Value.DataUsingEncoding(NSStringEncoding.NSASCIIStringEncoding, false);
                newObj = GSMimeDocument.DecodeBase64((NSData)newObj);

                //string encodedData = Encoding.ASCII.GetString(((NSData)newObj).Bytes);
                //byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
                //objID = new NSString(System.Text.Encoding.ASCII.GetString(encodedDataAsBytes));

                //newObj = GSMimeDocument.DecodeBase64(newObj);
                if (objID != null)
                    Decoded.SetObjectForKey(newObj, objID);

                return newObj;
            }
            else if (@"array".IsEqualToString(elementName))
            {
                NSString classname = element.AttributeForKey(@"class");
                if (classname == null)
                {
                    classname = @"NSArray";
                }
                return DecodeObjectForXib(element, classname, objID);
            }
            else if (@"dictionary".IsEqualToString(elementName))
            {
                NSString classname = element.AttributeForKey(@"class");
                if (classname == null)
                {
                    classname = @"NSDictionary";
                }
                return DecodeDictionaryForXib(element, classname, objID);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Unknown element type {0}", elementName);
            }

            return null;
        }
        //- (id) decodeObjectForXib: (GSXibElement*)element forClassName: (NSString*)classname withID: (NSString*)objID
        public virtual id DecodeObjectForXib(GSXibElement element, NSString classname, NSString objID)
        {
            GSXibElement last;
            id o, r;
            id dlgate = this.Delegate;

            o = AllocObjectForClassName(classname);
            if (objID != null)
                Decoded.SetObjectForKey(o, objID);

            // push
            last = CurrentElement;
            CurrentElement = element;

            r = (id)Objc.MsgSend(o, "InitWithCoder", this);
            //r = ((NSCoding)o).InitWithCoder(this);

            // pop
            CurrentElement = last;

            if (r != o)
            {
                Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                //((INSKeyedUnarchiverDelegate)dlgate).UnarchiverWillReplaceObject(this, o, r);
                o = r;
                if (objID != null)
                    Decoded.SetObjectForKey(o, objID);

            }

            //r = [o awakeAfterUsingCoder: self];
            r = (id)Objc.MsgSend(o, "AwakeAfterUsingCoder", this);
            if (r != o)
            {
                Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                //((INSKeyedUnarchiverDelegate)dlgate).UnarchiverWillReplaceObject(this, o, r);
                o = r;
                if (objID != null)
                    Decoded.SetObjectForKey(o, objID);

            }

            if (dlgate != null)
            {
                //r = ((INSKeyedUnarchiverDelegate)dlgate).UnarchiverDidDecodeObject(this, o);
                r = (id)Objc.MsgSend(dlgate, "UnarchiverDidDecodeObject", this, o);
                if (r != o)
                {
                    Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                    o = r;
                    if (objID != null)
                        Decoded.SetObjectForKey(o, objID);
                }
            }

            if (objID != null)
            {
                System.Diagnostics.Debug.WriteLine("XIB decoded object {0} for id {1}", o.ToString(), (string)objID);
            }

            return o;
        }
        public virtual id DecodeDictionaryForXib(GSXibElement element, NSString classname, NSString objID)
        {
            id o, r;
            id dlgate = this.Delegate;

            o = AllocObjectForClassName(classname);
            if (objID != null)
                Decoded.SetObjectForKey(o, objID);

             //r = [o initWithDictionary: [self _decodeDictionaryOfObjectsForElement: element]];
            r = ((NSDictionary)o).InitWithDictionary((NSDictionary)_DecodeDictionaryOfObjectsForElement(element));
            if (r != o)
            {
                Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                //((INSKeyedUnarchiverDelegate)dlgate).UnarchiverWillReplaceObject(this, o, r);
                o = r;
                if (objID != null)
                    Decoded.SetObjectForKey(o, objID);
            }

            //r = [o awakeAfterUsingCoder: self];
            r = (id)Objc.MsgSend(o, "AwakeAfterUsingCoder", this);
            if (r != o)
            {
                Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                o = r;
                if (objID != null)
                    Decoded.SetObjectForKey(o, objID);

            }

            if (dlgate != null)
            {
                //r = ((INSKeyedUnarchiverDelegate)dlgate).UnarchiverDidDecodeObject(this, o);
                r = (id)Objc.MsgSend(dlgate, "UnarchiverDidDecodeObject", this, o);
                if (r != o)
                {
                    Objc.MsgSend(dlgate, "UnarchiverWillReplaceObject", this, o, r);
                    o = r;
                    if (objID != null)
                        Decoded.SetObjectForKey(o, objID);
                }
            }

            if (objID != null)
            {
                System.Diagnostics.Debug.WriteLine("XIB decoded object {0} for id {1}", o.ToString(), (string)objID);
            }

            return o;
        }
 public virtual void SetElementForKey(GSXibElement element, NSString key)
 {
     _elements.SetObjectForKey(element, key);
 }