private XElement WriteValue(string elementName, SerializeAttribute serializeAttribute, object value, params object[] content)
		{
			if (value == null) throw new ArgumentNullException("value");

			XElement element;

			Type type = value.GetType();
			int refID = _visitedObjects.FindRefID(value);
			if (refID >= 0)
			{
				element = new XElement(elementName, content, new XAttribute(XmlConstants.REF, refID.ToString(CultureInfo.InvariantCulture)));
				if (serializeAttribute != null && serializeAttribute.ConstructorArgumentIndex >= 0)
					element.Add(new XAttribute(XmlConstants.ARG, serializeAttribute.ConstructorArgumentIndex));
				return element;
			}

			element = CreateElement(elementName, value, serializeAttribute, content);
			if (serializeAttribute != null && serializeAttribute.Formatter != null)
			{
				element.Add(GetFormattedValue(serializeAttribute.Formatter, value));
			}
			else if (type.IsPrimitive)
			{
				element.Add(new XAttribute(XmlConstants.VALUE, Convert.ToString(value, CultureInfo.InvariantCulture)));
			}
			else if (type.IsEnum)
			{
				element.Add(new XAttribute(XmlConstants.VALUE, value.ToString()));
			}
			else if (value is string)
			{
				element.Add(new XAttribute(XmlConstants.VALUE, XmlHelper.EscapeInvalidCharacters((string)value)));
			}
			else if (typeof(IDictionary).IsAssignableFrom(type))
			{
				WriteDictionaryElements(element, (IDictionary)value);
			}
			else if (typeof(IList).IsAssignableFrom(type) || typeof(ICollection).IsAssignableFrom(type))
			{
				WriteListElements(element, (IEnumerable)value);
			}
			else if (type == typeof(Color))
			{
				element.Add(new XAttribute(XmlConstants.VALUE, ColorTranslator.ToHtml((Color)value)));
			}
            else if (type == typeof(PointF))
            {
                PointF p = (PointF)value;
                element.Add(new XAttribute(XmlConstants.VALUE, XmlHelper.EscapeInvalidCharacters(p.X + "|" + p.Y)));
            }
			else
			{
				var map = SerializationMap.FromType(value.GetType());
				WriteMembers(element, map.Members, value);
			}

			return element;
		}
		/// <summary>
		/// Creates a new SerializationMapEntry instance.
		/// </summary>
		/// <param name="memberInfo">Info about the field or property to serialize.</param>
		/// <param name="attribute">Details about how to serialize this member.</param>
		public SerializationMapEntry(MemberInfo memberInfo, SerializeAttribute attribute)
		{
			Member = memberInfo;
			Attribute = attribute;
		}
		private XElement CreateElement(string elementName, object value, SerializeAttribute attribute, params object[] content)
		{
			Type type = value.GetType();

			var result = new XElement(elementName, content);
			result.Add(new XAttribute(XmlConstants.TYPE_ID, GetTypeID(type).ToString()));

			if (attribute != null && attribute.ConstructorArgumentIndex >= 0)
				result.Add(new XAttribute(XmlConstants.ARG, attribute.ConstructorArgumentIndex));

			if (!type.IsValueType && !type.Equals(typeof(string))) // Don't cache value types or strings
				_visitedObjects.Add(value, result);

			return result;
		}