protected override void OnWriteStartObject()
        {
            var      tmp      = object_states.Pop();
            XamlType xamlType = tmp.Type;

            var nodeType = xamlType.IsMarkupExtension && !xamlType.ConstructionRequiresArguments ? XamlNodeType.Value : XamlNodeType.StartObject;

            WritePendingStartMember(nodeType);
            WritePendingValue(nodeType);

            string ns     = xamlType.PreferredXamlNamespace;
            string prefix = GetPrefix(ns);              // null prefix is not rejected...

            if (w.WriteState == WriteState.Attribute)
            {
                // MarkupExtension
                w.WriteString("{");
                if (!String.IsNullOrEmpty(prefix))
                {
                    w.WriteString(prefix);
                    w.WriteString(":");
                }
                string name = ns == XamlLanguage.Xaml2006Namespace ? xamlType.GetInternalXmlName() : xamlType.Name;
                w.WriteString(name);
                // space between type and first member (if any).
                if (xamlType.IsMarkupExtension && xamlType.GetSortedConstructorArguments().GetEnumerator().MoveNext())
                {
                    w.WriteString(" ");
                }
            }
            else
            {
                WritePendingNamespaces();
                w.WriteStartElement(prefix, xamlType.GetInternalXmlName(), xamlType.PreferredXamlNamespace);
                var l = xamlType.TypeArguments;
                if (l != null)
                {
                    w.WriteStartAttribute("x", "TypeArguments", XamlLanguage.Xaml2006Namespace);
                    for (int i = 0; i < l.Count; i++)
                    {
                        if (i > 0)
                        {
                            w.WriteString(", ");
                        }
                        w.WriteString(new XamlTypeName(l [i]).ToString(prefix_lookup));
                    }
                    w.WriteEndAttribute();
                }
            }

            object_states.Push(tmp);
        }
        void OnWriteStartMemberElement(XamlType xt, XamlMember xm)
        {
            CurrentMemberState.OccuredAs = AllowedMemberLocations.MemberElement;
            string prefix = GetPrefix(xm.PreferredXamlNamespace);
            string name   = xm.IsDirective ? xm.Name : String.Concat(xt.GetInternalXmlName(), ".", xm.Name);

            WritePendingNamespaces();
            w.WriteStartElement(prefix, name, xm.PreferredXamlNamespace);
        }
		// member element, implicit member, children via content property, or value
		IEnumerable<XamlXmlNodeInfo> ReadMemberElement (XamlType parentType, XamlType xt)
		{
			XamlMember xm = null;
			var name = r.LocalName;
			int idx = name.IndexOf ('.');
			string typeName = null;
			if (idx >= 0) {
				typeName = name.Substring (0, idx);
				name = name.Substring (idx + 1);
				// check if it is an attachable member first, either of this type or another type
				// Should this also check the namespace to find the correct type?
				if (typeName == xt.GetInternalXmlName())
					xm = xt.GetMember (name);
				else
					xm = FindAttachableMember (r.Prefix, typeName, name);
			} else {
				xm = (XamlMember)FindStandardDirective (name, AllowedMemberLocations.MemberElement);
				if (xm == null) {
					// still not? could it be omitted as content property or items ?
					if ((xm = GetExtraMember (xt)) != null) {
						// Note that this does not involve r.Read()
						foreach (var ni in ReadMember (xt, xm))
							yield return ni;
						yield break;
					}
				}
			}
			if (xm == null) {
				// Current element could be for another member in the parent type (if exists)
				if (parentType != null 
					&& typeName != null
					&& typeName == parentType.GetInternalXmlName ()
					&& parentType.GetMember (name) != null) {
					// stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
					yield return Node (XamlNodeType.None, null);
					yield break;
				}

				// ok, then create unknown member.
				xm = new XamlMember (name, xt, false); // FIXME: not sure if isAttachable is always false.
			}

			if (!r.IsEmptyElement) {
				r.Read ();
				foreach (var ni in ReadMember (xt, xm))
					yield return ni;
				r.MoveToContent ();
				r.ReadEndElement ();
			}
			else
				r.Read ();
		}