<#@ template language="C#v3.5" debug="True"       #>
<#@ output extension="generated.cs"               #>
<#@ assembly name="System.Core"                   #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
//---------------------------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated by BLToolkit template for T4.
//    Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------------------------------------------
using System;
using System.Data.Linq;
using System.Data.SqlTypes;
using System.Globalization;
using System.IO;
using System.Xml;
#if !SILVERLIGHT
using System.Xml.Linq;
#endif

namespace BLToolkit.Common
{
	using Properties;

	public partial class Convert
	{ 
<#
		GenerationEnvironment.Remove(GenerationEnvironment.Length - 2, 2);

		_types =
			Set(_ => { _.Group = "Simple"; _.Method = "To" + _.Name; }, new[]
				{
					new ToType { Name = "Boolean",        NullValue = "Configuration.NullableValues.Boolean", Froms = { { "Char", null } } },
					new ToType { Name = "Byte",           NullValue = "Configuration.NullableValues.Byte"     },
					new ToType { Name = "Char",           NullValue = "Configuration.NullableValues.Char"     },
					new ToType { Name = "DateTime",       NullValue = "Configuration.NullableValues.DateTime" },
					new ToType { Name = "DateTimeOffset", NullValue = "DateTimeOffset.MinValue"               },
					new ToType { Name = "Decimal",        NullValue = "Configuration.NullableValues.Decimal", Froms = { { "Byte[]", null }, { "Binary", null } } },
					new ToType { Name = "Double",         NullValue = "Configuration.NullableValues.Double"   },
					new ToType { Name = "Guid",           NullValue = "Configuration.NullableValues.Guid"     },
					new ToType { Name = "Int16",          NullValue = "Configuration.NullableValues.Int16"    },
					new ToType { Name = "Int32",          NullValue = "Configuration.NullableValues.Int32"    },
					new ToType { Name = "Int64",          NullValue = "Configuration.NullableValues.Int64"    },
					new ToType { Name = "Single",         NullValue = "Configuration.NullableValues.Single"   },
					new ToType { Name = "String",         NullValue = "Configuration.NullableValues.String",  FromObjectReturn = "return p.ToString();" },
					new ToType { Name = "TimeSpan",       NullValue = "Configuration.NullableValues.TimeSpan" },
				}.Concat(Set(_ => _.NonCompliant = true, new[]
				{
					new ToType { Name = "SByte",          NullValue = "Configuration.NullableValues.SByte"    },
					new ToType { Name = "UInt16",         NullValue = "Configuration.NullableValues.UInt16"   },
					new ToType { Name = "UInt32",         NullValue = "Configuration.NullableValues.UInt32"   },
					new ToType { Name = "UInt64",         NullValue = "Configuration.NullableValues.UInt64"   },
				})))
			.Concat(Set(_ => { _.Group = "Nullable"; _.Method = "ToNullable" + _.Name; _.Name += "?"; }, new[]
				{
					new ToType { Name = "Boolean"        },
					new ToType { Name = "Byte"           },
					new ToType { Name = "Char"           },
					new ToType { Name = "DateTime"       },
					new ToType { Name = "DateTimeOffset" },
					new ToType { Name = "Decimal"        },
					new ToType { Name = "Double"         },
					new ToType { Name = "Guid"           },
					new ToType { Name = "Int16"          },
					new ToType { Name = "Int32"          },
					new ToType { Name = "Int64"          },
					new ToType { Name = "Single"         },
					new ToType { Name = "TimeSpan"       },
				}.Concat(Set(_ => _.NonCompliant = true, new[]
				{
					new ToType { Name = "SByte"  },
					new ToType { Name = "UInt16" },
					new ToType { Name = "UInt32" },
					new ToType { Name = "UInt64" },
				}))))
			.Concat(Set(_ => { _.Group = "Sql"; _.Method = "To" + _.Name; _.NonSilverlightable = true; _.NullValue = _.Name + ".Null"; }, new[]
				{
					new ToType { Name = "SqlString"   },
					new ToType { Name = "SqlByte"     },
					new ToType { Name = "SqlInt16"    },
					new ToType { Name = "SqlInt32"    },
					new ToType { Name = "SqlInt64"    },
					new ToType { Name = "SqlSingle"   },
					new ToType { Name = "SqlDouble"   },
					new ToType { Name = "SqlBoolean"  },
					new ToType { Name = "SqlDecimal"  },
					new ToType { Name = "SqlMoney"    },
					new ToType { Name = "SqlDateTime" },
					new ToType { Name = "SqlGuid"     },
					new ToType { Name = "SqlBinary"   },
					new ToType { Name = "SqlBytes"    },
					new ToType { Name = "SqlChars"    },
					new ToType { Name = "SqlXml"      },
				}))
			.Concat(Set(_ => { _.Group = "Other"; }, new[]
				{
					new ToType { Name = "Type",        Method = "ToType",        NonSLMethods = { "Guid", "Guid?", "Binary", "Byte[]" } },
					new ToType { Name = "Stream",      Method = "ToStream",      NullValue = "Stream.Null" },
					new ToType { Name = "Byte[]",      Method = "ToByteArray",   NonSLMethods = { "DateTime", "DateTime?", "DateTimeOffset", "DateTimeOffset?" }, Froms = { { "Decimal", null }, { "Stream", null }, { "Char[]", null } } },
					new ToType { Name = "Char[]",      Method = "ToCharArray",                             },
					new ToType { Name = "Binary",      Method = "ToLinqBinary",                            },
					new ToType { Name = "XmlReader",   Method = "ToXmlReader",   NonSilverlightable = true },
					new ToType { Name = "XmlDocument", Method = "ToXmlDocument", NonSilverlightable = true },
					new ToType { Name = "XElement",    Method = "ToXElement",    NonSilverlightable = true },
				}))
			.ToDictionary(_ => _.Name);


		// To Boolean
		//
		ConvertFrom("String", "p == null? {2} : p.Length == 1 ? ToBoolean(p[0]) : Boolean.Parse(p)",       "Boolean", "Boolean?", "SqlBoolean");
		ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : BitConverter.ToBoolean(p, 0)",           "Boolean", "Boolean?", "SqlBoolean");
		ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : BitConverter.ToBoolean(p.ToArray(), 0)", "Boolean", "Boolean?", "SqlBoolean");

		ConvertTo    ("Boolean", "p.HasValue && p.Value",                "Boolean?");
		ConvertToNull("Boolean", "p != 0", "p.HasValue && p.Value != 0", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal");
		ConvertTo    ("Boolean", "p.HasValue && ToBoolean(p.Value)",     "Char?");
		ConvertTo    ("Boolean", "!p.IsNull && p.Value",                 "SqlBoolean");
		ConvertTo    ("Boolean", "!p.IsNull && ToBoolean(p.Value)",      Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money"));

		ConvertFrom("Boolean", "p",                                "Boolean?", "SqlBoolean");
		ConvertFrom("Char",    "ToBoolean(p)",                     "Boolean?", "SqlBoolean");
		ConvertFrom("Char?",   "p.HasValue && ToBoolean(p.Value)", "Boolean?", "SqlBoolean");

		// To Boolean?
		//		
		ConvertToNull("Boolean?", "p != 0", "p.HasValue ? p.Value != 0 : {2}", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal");
		ConvertTo    ("Boolean?", "p.IsNull ? {2} : p.Value",                  "SqlBoolean");
		ConvertTo    ("Boolean?", "p.IsNull ? {2} : ToBoolean(p.Value)",       Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money"));

		// SqlBoolean
		//
		ConvertTo    ("SqlBoolean", "p.HasValue ? p.Value : {2}",                "Boolean?");
		ConvertToNull("SqlBoolean", "p != 0", "p.HasValue ? p.Value != 0 : {2}", "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal");
		ConvertTo    ("SqlBoolean", "p.IsNull ? {2} : ToBoolean(p.Value)",       Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money"));

		// To Byte
		//
		ConvertNumber("Byte",
			new string[] { "Byte" },
			new string[] { "SByte", "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" },
			new string[] { "Byte" },
			new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : p[0]",           "Byte", "Byte?", "SqlByte");
		ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : p.ToArray()[0]", "Byte", "Byte?", "SqlByte");

		// To Char
		//
		ConvertNumber("Char",
			new string[] { "Char" },
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal" },
			new string[] { },
			new string[] { "String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		ConvertFrom("String", "string.IsNullOrEmpty(p)? ({0})0 : p[0]", "Char", "Char?");

		// To DateTime
		//
		ConvertTo(new[] { "DateTime",  "SqlDateTime" }, "p.HasValue ? p.Value : {2}", "DateTime?");
		ConvertTo(new[] { "DateTime?", "SqlDateTime" }, "p",                          "DateTime");
		ConvertTo(new[] { "DateTime",  "DateTime?"   }, "p.IsNull ? {2} : p.Value",   "SqlDateTime");
		
		ConvertFrom("String",          "p == null ? {2} : {3}.Parse(p, null, DateTimeStyles.NoCurrentDateDefault)", "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("TimeSpan",        "{3}.MinValue + p",                                                          "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Int64",           "{3}.MinValue + TimeSpan.FromTicks(p)",                                      "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Double",          "{3}.MinValue + TimeSpan.FromDays (p)",                                      "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("DateTimeOffset",  "p.LocalDateTime",                                                           "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("DateTimeOffset?", "p.HasValue ?                     p.Value.LocalDateTime : {2}",              "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("TimeSpan?",       "p.HasValue ? {3}.MinValue +                    p.Value : {2}",              "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Int64?",          "p.HasValue ? {3}.MinValue + TimeSpan.FromTicks(p.Value): {2}",              "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Double?",         "p.HasValue ? {3}.MinValue + TimeSpan.FromDays (p.Value): {2}",              "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("SqlDateTime",     "p.IsNull   ? {2} :                                   p.Value",              "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("SqlString",       "p.IsNull   ? {2} :                             To{3}(p.Value)",             "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("SqlInt64",        "p.IsNull   ? {2} : {3}.MinValue + TimeSpan.FromTicks(p.Value)",             "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("SqlDouble",       "p.IsNull   ? {2} : {3}.MinValue + TimeSpan.FromDays (p.Value)",             "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Byte[]",          "p == null || p.Length == 0 ? {2} : {3}.FromBinary(ToInt64(p))",             "DateTime", "DateTime?", "SqlDateTime");
		ConvertFrom("Binary",          "p == null || p.Length == 0 ? {2} : {3}.FromBinary(ToInt64(p.ToArray()))",   "DateTime", "DateTime?", "SqlDateTime");

		// To DateTimeOffset
		//
		ConvertTo("DateTimeOffset",  "p.HasValue ? p.Value : {2}", "DateTimeOffset?");
		ConvertTo("DateTimeOffset?", "p",                          "DateTimeOffset");

		ConvertFrom("TimeSpan",    "{3}.MinValue + p",                                                    "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Int64",       "{3}.MinValue + TimeSpan.FromTicks(p)",                                "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Double",      "{3}.MinValue + TimeSpan.FromDays (p)",                                "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("DateTime",    "p",                                                                   "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("DateTime?",   "p.HasValue ?                                   p.Value : {2}",        "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("TimeSpan?",   "p.HasValue ? {3}.MinValue +                    p.Value : {2}",        "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Int64?",      "p.HasValue ? {3}.MinValue + TimeSpan.FromTicks(p.Value): {2}",        "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Double?",     "p.HasValue ? {3}.MinValue + TimeSpan.FromDays (p.Value): {2}",        "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("SqlDateTime", "p.IsNull   ? {2} :                                   p.Value",        "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("SqlString",   "p.IsNull   ? {2} :                  ToDateTimeOffset(p.Value)",       "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("SqlInt64",    "p.IsNull   ? {2} : {3}.MinValue + TimeSpan.FromTicks(p.Value)",       "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("SqlDouble",   "p.IsNull   ? {2} : {3}.MinValue + TimeSpan.FromDays (p.Value)",       "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Byte[]",      "p == null || p.Length == 0 ? {2} : new {0}(ToDateTime(p))",           "DateTimeOffset", "DateTimeOffset?");
		ConvertFrom("Binary",      "p == null || p.Length == 0 ? {2} : new {0}(ToDateTime(p.ToArray()))", "DateTimeOffset", "DateTimeOffset?");

		// To Decimal
		//
		ConvertNumber("Decimal",
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Decimal" },
			new string[] { "Single", "Double" },
			new string[] { "Byte", "Int16", "Int32", "Int64", "Decimal", "Money" },
			new string[] { "String", "Single", "Double", "Boolean" });

		ConvertNumber("Money",
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Decimal" },
			new string[] { "Single", "Double" },
			new string[] { "Byte", "Int16", "Int32", "Int64", "Decimal", "Money" },
			new string[] { "String", "Single", "Double", "Boolean" });

		ConvertTo(new[] { "Decimal?", "SqlDecimal", "SqlMoney" }, "p == null || p.Length == 0 ? {2} : ToDecimal(p)", "Byte[]", "Binary");

		// To Double
		//
		ConvertTo(new[] { "Double", "Double?", "SqlDouble" }, "(p - {1}.MinValue).TotalDays",          "DateTime", "DateTimeOffset");
		ConvertTo("SqlDouble",                                "p.IsNull? {0}.Null: ToDouble(p.Value)", "SqlDateTime");

		ConvertNumber("Double",
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Single", "Double" },
			new string[] { "Decimal" },
			new string[] { "Byte", "Int16", "Int32", "Int64", "Single", "Double" },
			new string[] { "String", "Decimal", "Money", "Boolean", "DateTime" });

		ConvertTo(new[] { "Double", "Double?", "SqlDouble" }, "p.HasValue ? (p.Value - {4}.MinValue).TotalDays : {2}", "DateTime?", "DateTimeOffset?");

		ConvertFrom("TimeSpan",  "p.TotalDays",                          "Double", "Double?", "SqlDouble");
		ConvertFrom("TimeSpan?", "p.HasValue ? p.Value.TotalDays : {2}", "Double", "Double?", "SqlDouble");

		// To Guid
		//
		ConvertTo(new[] { "Guid",  "SqlGuid" }, "p.HasValue ? p.Value : {2}", "Guid?");
		ConvertTo(new[] { "Guid?", "SqlGuid" }, "p",                          "Guid");
		ConvertTo(new[] { "Guid",  "Guid?"   }, "p.IsNull ? {2} : p.Value",   "SqlGuid");

		ConvertTo(new[] { "Guid", "Guid?", "SqlGuid" },  "p == null ? {2} : new Guid(p)", "String", "Byte[]");
		
		ConvertFrom("SqlGuid",   "p.IsNull  ? {2} : p.Value",               "Guid", "Guid?", "SqlGuid");
		ConvertFrom("SqlString", "p.IsNull  ? {2} : new Guid(p.Value)",     "Guid", "Guid?", "SqlGuid");
		ConvertFrom("SqlBinary", "p.IsNull  ? {2} : p.ToSqlGuid().Value",   "Guid", "Guid?", "SqlGuid");
		ConvertFrom("Binary",    "p == null ? {2} : new Guid(p.ToArray())", "Guid", "Guid?", "SqlGuid");
		ConvertFrom("Type",      "p == null ? {2} : p.GUID",                "Guid", "Guid?", "SqlGuid");

		// To Int16
		//
		ConvertNumber("Int16",
			new string[] { "SByte", "Int16", "Byte" },
			new string[] { "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" },
			new string[] { "Byte", "Int16" },
			new string[] { "String", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		// To Int32
		//
		ConvertNumber("Int32",
			new string[] { "SByte", "Int16", "Int32", "Byte", "UInt16", "Char" },
			new string[] { "Int64", "UInt32", "UInt64", "Single", "Double", "Decimal" },
			new string[] { "Byte", "Int16", "Int32" },
			new string[] { "String", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		// To Int64
		//
		ConvertTo("Int64",    "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset");
		ConvertTo("Int64?",   "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset");
		ConvertTo("SqlInt64", "(p - DateTime.MinValue).Ticks", "DateTime", "DateTimeOffset");
		ConvertTo("SqlInt64", "p.IsNull? {0}.Null: ToInt64(p.Value)",      "SqlDateTime");

		ConvertNumber("Int64",
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char" },
			new string[] { "UInt64", "Single", "Double", "Decimal" },
			new string[] { "Byte", "Int16", "Int32", "Int64" },
			new string[] { "String", "Single", "Double", "Decimal", "Money", "Boolean", "DateTime" });

		ConvertTo("Int64",  "  p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?");
		ConvertTo("Int64?",   "p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?");
		ConvertTo("SqlInt64", "p.HasValue ? (p.Value - DateTime.MinValue).Ticks : 0", "DateTime?", "DateTimeOffset?");

		ConvertFrom("TimeSpan",  "p.Ticks",                        "Int64", "Int64?", "SqlInt64");
		ConvertFrom("TimeSpan?", "p.HasValue ? p.Value.Ticks : 0", "Int64", "Int64?", "SqlInt64");

		// To SByte
		//
		ConvertNumber("SByte",
			new string[] { "SByte" },
			new string[] { "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" },
			new string[] { },
			new string[] { "String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : checked(({0})p[0])",           "SByte", "SByte?");
		ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : checked(({0})p.ToArray()[0])", "SByte", "SByte?");

		// To Single
		//
		ConvertNumber("Single",
			new string[] { "SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "Char", "UInt64", "Single" },
			new string[] { "Double", "Decimal" },
			new string[] { "Byte", "Int16", "Int32", "Int64", "Single" },
			new string[] { "String", "Double", "Decimal", "Money", "Boolean" });

		// To String
		//
		ConvertToNull(new[] { "String", "SqlString" },
			"p.To{3}()",
			"p.HasValue ? p.Value.To{3}() : {2}",
				"SByte", "Int16", "Int32", "Int64", "Byte", "UInt16", "UInt32", "UInt64",
				"Single", "Double", "Boolean", "Decimal", "Char", "TimeSpan", "DateTime", "DateTimeOffset", "Guid");

		ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.FullName",                                          "Type");
		ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : System.Text.Encoding.UTF8.GetString(p, 0, p.Length)", "Byte[]");
		ConvertTo(new[] { "String", "SqlString" }, "To{0}(p.ToArray())",                                                    "Binary");

		ConvertTo(new[] { "String", "SqlString" }, "p.To{0}()",
			Sql("String", "Byte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean", "Guid"));

		ConvertTo(        "String",                "p.IsNull ? {2} : p.ToSqlString().Value", "SqlChars");
		ConvertTo(new[] { "String", "SqlString" }, "p.IsNull ? {2} : p.Value",               "SqlXml");
		ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.InnerXml",           "XmlDocument");
		ConvertTo(new[] { "String", "SqlString" }, "p == null ? {2} : p.ToString()",         "XElement");

		ConvertTo("SqlString", "p ?? {2}",  "String");
		ConvertTo("SqlString", "p.To{0}()", "SqlChars");

		// To TimeSpan
		// 
		ConvertTo("TimeSpan",  "p.HasValue ? p.Value : {2}", "TimeSpan?");
		ConvertTo("TimeSpan?", "p",                          "TimeSpan");

		ConvertFrom("DateTime",        "p - DateTime.MinValue",                                                 "TimeSpan", "TimeSpan?");
		ConvertFrom("DateTimeOffset",  "p - DateTimeOffset.MinValue",                                           "TimeSpan", "TimeSpan?");
		ConvertFrom("Int64",           "TimeSpan.FromTicks(p)",                                                 "TimeSpan", "TimeSpan?");
		ConvertFrom("Double",          "TimeSpan.FromDays (p)",                                                 "TimeSpan", "TimeSpan?");
		ConvertFrom("DateTime?",       "p.HasValue ? p.Value - DateTime.MinValue       : {2}",                  "TimeSpan", "TimeSpan?");
		ConvertFrom("DateTimeOffset?", "p.HasValue ? p.Value - DateTimeOffset.MinValue : {2}",                  "TimeSpan", "TimeSpan?");
		ConvertFrom("Int64?",          "p.HasValue ? {3}.FromTicks(p.Value)            : {2}",                  "TimeSpan", "TimeSpan?");
		ConvertFrom("Double?",         "p.HasValue ? {3}.FromDays (p.Value)            : {2}",                  "TimeSpan", "TimeSpan?");
		ConvertFrom("SqlString",       "p.IsNull   ? {2} : {3}.Parse(p.Value)",                                 "TimeSpan", "TimeSpan?");
		ConvertFrom("SqlDateTime",     "p.IsNull   ? {2} : p.Value - DateTime.MinValue",                        "TimeSpan", "TimeSpan?");
		ConvertFrom("SqlInt64",        "p.IsNull   ? {2} : {3}.FromTicks(p.Value)",                             "TimeSpan", "TimeSpan?");
		ConvertFrom("SqlDouble",       "p.IsNull   ? {2} : {3}.FromDays(p.Value)",                              "TimeSpan", "TimeSpan?");
		ConvertFrom("Byte[]",          "p == null || p.Length == 0? {2} : {3}.FromTicks(ToInt64(p))",           "TimeSpan", "TimeSpan?");
		ConvertFrom("Binary",          "p == null || p.Length == 0? {2} : {3}.FromTicks(ToInt64(p.ToArray()))", "TimeSpan", "TimeSpan?");

		// To UInt16
		//
		ConvertNumber("UInt16",
			new string[] { "UInt16", "Byte" },
			new string[] { "SByte", "Int16", "Int32", "Int64", "UInt32", "UInt64", "Single", "Double", "Decimal", "Char" },
			new string[] { "Byte" },
			new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		// To UInt32
		//
		ConvertNumber("UInt32",
			new string[] { "Byte", "UInt16", "UInt32" },
			new string[] { "SByte", "Int16", "Int32", "Int64", "UInt64", "Single", "Double", "Decimal", "Char" },
			new string[] { "Byte" },
			new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		// To UInt64
		//
		ConvertNumber("UInt64",
			new string[] { "Byte", "UInt16", "UInt32", "UInt64" },
			new string[] { "SByte", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Char" },
			new string[] { "Byte" },
			new string[] { "String", "Int16", "Int32", "Int64", "Single", "Double", "Decimal", "Money", "Boolean" });

		// To SqlBinary
		//
		ConvertTo("SqlBinary", "p", "Byte[]");
		ConvertTo("SqlBinary", "p == null ?      {2} : p.ToArray()",                   "Binary");
		ConvertTo("SqlBinary", "p == Guid.Empty? {2} : new SqlGuid(p).To{0}()",        "Guid");
		ConvertTo("SqlBinary", "p.HasValue ? new SqlGuid(p.Value).ToSqlBinary(): {2}", "Guid?");
		ConvertTo("SqlBinary", "p.To{0}()",                                            "SqlBytes" , "SqlGuid");

		// To SqlXml
		//
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p)))",                    "String");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(p)",                                                         "Stream", "XmlReader");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p.InnerXml)))",           "XmlDocument");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(p.ToString())))",         "XElement");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new XmlTextReader(new StringReader(new string(p))))",        "Char[]");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new MemoryStream(p))",                                       "Byte[]");
		ConvertTo("SqlXml", "p == null ? {2} : new {0}(new MemoryStream(p.ToArray()))",                             "Binary");
		ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new XmlTextReader(new StringReader(p.Value)))",               "SqlString");
		ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new XmlTextReader(new StringReader(p.ToSqlString().Value)))", "SqlChars");
		ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(new MemoryStream(p.Value))",                                  "SqlBinary");
		ConvertTo("SqlXml", "p.IsNull ? {2} : new {0}(p.Stream)",                                                   "SqlBytes");

		// To Stream
		// 
		ConvertTo("Stream", "p == Guid.Empty ? {2} : new MemoryStream(p.ToByteArray())",  "Guid");
		ConvertTo("Stream", "p == null ? {2} : new MemoryStream(p)",                      "Byte[]");
		ConvertTo("Stream", "p == null ? {2} : new MemoryStream(p.ToArray())",            "Binary");
		ConvertTo("Stream", "p.HasValue ? new MemoryStream(p.Value.ToByteArray()) : {2}", "Guid?");
		ConvertTo("Stream", "p.IsNull ? {2} : p.Stream",                                  "SqlBytes");
		ConvertTo("Stream", "p.IsNull ? {2} : new MemoryStream(p.Value)",                 "SqlBinary");
		ConvertTo("Stream", "p.IsNull ? {2} : new MemoryStream(p.Value.ToByteArray())",   "SqlGuid");

		// To Type
		//
		ConvertTo("Type", "p == null ? {2} : Type.GetType(p)",                            "String");
		ConvertTo("Type", "p == null ? {2} : Type.GetType(new string(p))",                "Char[]");
		ConvertTo("Type", "p == null ? {2} : Type.GetTypeFromCLSID(ToGuid(p))",           "Byte[]");
		ConvertTo("Type", "p == null ? {2} : Type.GetTypeFromCLSID(ToGuid(p.ToArray()))", "Binary");
		ConvertTo("Type", "p == Guid.Empty ? {2} : Type.GetTypeFromCLSID(p)",             "Guid");
		ConvertTo("Type", "p.HasValue ? Type.GetTypeFromCLSID(p.Value) : {2}",            "Guid?");
		ConvertTo("Type", "p.IsNull ? {2} : Type.GetType(p.Value)",                       "SqlString");
		ConvertTo("Type", "p.IsNull ? {2} : Type.GetType(new string(p.Value))",           "SqlChars");
		ConvertTo("Type", "p.IsNull ? {2} : Type.GetTypeFromCLSID(p.Value)",              "SqlGuid");

		// To Byte[]
		//
		ConvertTo("Byte[]", "p == null ? {2} : System.Text.Encoding.UTF8.GetBytes(p)", "String");
		ConvertTo("Byte[]", "new[] {{ p }}",                                           "Byte");
		ConvertTo("Byte[]", "new[] {{ checked((Byte)p) }}",                            "SByte");
		ConvertTo("Byte[]", "ToByteArray(p.ToBinary())",                               "DateTime");
		ConvertTo("Byte[]", "ToByteArray(p.LocalDateTime.ToBinary())",                 "DateTimeOffset");
		ConvertTo("Byte[]", "p == null ? {2} : p.ToArray()",                           "Binary");
		ConvertTo("Byte[]", "ToByteArray(p.Ticks)",                                    "TimeSpan");
		ConvertTo("Byte[]", "p == Guid.Empty ? {2} : p.ToByteArray()",                 "Guid");

		ConvertTo("Byte[]", "BitConverter.GetBytes(p)",
			"Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Boolean", "Char");
		ConvertTo("Byte[]", "p.HasValue ? ToByteArray(p.Value) : {2}",
			"SByte?", "Int16?", "Int32?", "Int64?", "Byte?", "UInt16?", "UInt32?", "UInt64?", "Single?", "Double?", "Boolean?", "Decimal?", "Char?", "DateTime?", "DateTimeOffset?", "TimeSpan?", "Guid?");

		ConvertTo("Byte[]", "p.IsNull ? {2} : p.Value",         "SqlBinary", "SqlBytes");
		ConvertTo("Byte[]", "p.IsNull ? {2} : p.ToByteArray()", "SqlGuid");
		ConvertTo("Byte[]", "p.IsNull ? {2} : ToByteArray(p.Value)",
			"SqlString", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney", "SqlBoolean");

		// To SqlBytes
		//
		ConvertTo("SqlBytes", "p == null ? {2} : new {0}(p)",                      "Byte[]", "Stream");
		ConvertTo("SqlBytes", "p == null ? {2} : new {0}(p.ToArray())",            "Binary");
		ConvertTo("SqlBytes", "p == Guid.Empty ? {2}: new {0}(p.ToByteArray())",   "Guid");
		ConvertTo("SqlBytes", "p.HasValue ? new {0}(p.Value.ToByteArray()) : {2}", "Guid?");
		ConvertTo("SqlBytes", "p.IsNull ? {2} : new {0}(p)",                       "SqlBinary");
		ConvertTo("SqlBytes", "p.IsNull ? {2} : new {0}(p.ToByteArray())",         "SqlGuid");

		ConvertTo("SqlBytes", "p == null ? {2} : new {0}(ToByteArray(p))",         "String");
		
		ConvertTo("SqlBytes", "new {0}(ToByteArray(p))",
			"Byte", "SByte", "DateTime", "DateTimeOffset", "TimeSpan", "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Single", "Double", "Boolean", "Char");
		ConvertTo("SqlBytes", "p.HasValue ? ToSqlBytes(p.Value) : {2}",
			"SByte?", "Int16?", "Int32?", "Int64?", "Byte?", "UInt16?", "UInt32?", "UInt64?", "Single?", "Double?", "Boolean?", "Decimal?", "Char?", "DateTime?", "DateTimeOffset?", "TimeSpan?", "Guid?");

		ConvertTo("Byte[]", "p.IsNull ? {2} : ToSqlBytes(p.Value)",
			"SqlString", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney", "SqlBoolean");



		string[] numberTypes1  = new string[] { "Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Char", "Single", "Double", "SqlByte", "SqlInt16", "SqlInt32", "SqlInt64", "SqlSingle", "SqlDouble", "SqlDecimal", "SqlMoney" };
		string[] numberTypes2  = Add(numberTypes1, "SByte", "Byte");
		string[] numberTypes1n = numberTypes1.Where(_ => !_.StartsWith("Sql")).Select(_ => _ + "?").ToArray();
		string[] numberTypes2n = numberTypes2.Where(_ => !_.StartsWith("Sql")).Select(_ => _ + "?").ToArray();

		// From String
		//
		ConvertFrom("String", "p == null? {2} : {3}.Parse(p)",
			Add(Add(numberTypes2, numberTypes2n), "Decimal", "DateTimeOffset", "TimeSpan", "Decimal?", "DateTimeOffset?", "TimeSpan?"));

		// From Boolean
		//
		ConvertFrom("Boolean", "p ? ({0})1 : ({0})0",                     Add(Add(numberTypes2, numberTypes2n), "Decimal", "Decimal?"));

		// From Boolean?
		//
		ConvertFrom("Boolean?", "p.HasValue && p.Value ? ({0})1: ({0})0", Add(Add(numberTypes2, numberTypes2n), "Decimal", "Decimal?"));

		// From Byte[]
		//
		ConvertFrom("Byte[]", "p == null || p.Length == 0 ? {2} : BitConverter.To{3}(p, 0)",           Add(numberTypes1, numberTypes1n));

		// From Binary
		//
		ConvertFrom("Binary", "p == null || p.Length == 0 ? {2} : BitConverter.To{3}(p.ToArray(), 0)", Add(numberTypes1, numberTypes1n));

		Generate();
#>
	}
}
<#+
class ToType
{
	public string Group;
	public string Name;
	public string Method;
	public bool   NonCompliant;
	public bool   NonSilverlightable; // :)
	public string NullValue;
	public string FromObjectReturn;

	public Dictionary<string,string> Froms        = new Dictionary<string,string>();
	public HashSet<string>           NonSLMethods = new HashSet<string>();
}

Dictionary<string,ToType> _types;

void ConvertTo(string toType, string convertText, params string[] fromTypes)
{
	foreach (string fromType in fromTypes)
	{
		if (toType == fromType)
			continue;

		if (!_types.ContainsKey(fromType))
			throw new InvalidOperationException(fromType);

		if (!_types[toType].Froms.ContainsKey(fromType))
			_types[toType].Froms.Add(fromType, string.Format(
				convertText,
				toType,
				fromType,
				_types[toType].NullValue ?? "(" + toType + ")null",
				toType.  TrimEnd('?').Replace("Sql", "").Replace("Money", "Decimal"),
				fromType.TrimEnd('?').Replace("Sql", "").Replace("Money", "Decimal")));
	}
}

void ConvertTo(string[] toTypes, string convertText, params string[] fromTypes)
{
	foreach (var t in toTypes)
		ConvertTo(t, convertText, fromTypes);
}

void ConvertFrom(string fromType, string convertText, params string[] toTypes)
{
	foreach (string toType in toTypes)
		ConvertTo(toType, convertText, fromType);
}

void ConvertToNull(string toType, string convertText, string convertTextNull, params string[] fromTypes)
{
	ConvertTo(toType, convertText,     fromTypes);
	ConvertTo(toType, convertTextNull, fromTypes.Select(_ => _ + "?").ToArray());
}

void ConvertToNull(string[] toTypes, string convertText, string convertTextNull, params string[] fromTypes)
{
	foreach (var t in toTypes)
		ConvertToNull(t, convertText, convertTextNull, fromTypes);
}

void ConvertNumber(string toType, string[] types1, string[] types2, string[] types3, string[] types4)
{
	if (toType != "Money")
	{
		ConvertToNull(toType,
			"p",
			"p.HasValue ? p.Value : {2}",
			types1);
		ConvertToNull(toType,
			"checked(({0})p)",
			"p.HasValue ? checked(({0})p.Value) : {2}",
			types2);
		ConvertTo(toType, "p.IsNull ? {2} : p.Value",        Sql(types3));
		ConvertTo(toType, "p.IsNull ? {2} : To{0}(p.Value)", Sql(types4));

		ConvertToNull(toType + "?",
			"p",
			"p.HasValue ? p.Value : {2}",
			types1);
		ConvertToNull(toType + "?",
			"checked(({0})p)",
			"p.HasValue ? checked(({0})p.Value) : {2}",
			types2);
		ConvertTo(toType + "?", "p.IsNull ? {2} : p.Value",        Sql(types3));
		ConvertTo(toType + "?", "p.IsNull ? {2} : To{3}(p.Value)", Sql(types4));
	}

	if (_types.ContainsKey("Sql" + toType))
	{
		ConvertToNull("Sql" + toType,
			"p",
			"p.HasValue ? p.Value : {2}",
			types1);
		ConvertToNull("Sql" + toType,
			"checked(({3})p)",
			"p.HasValue ? checked(({3})p.Value) : {2}",
			types2);
		ConvertTo("Sql" + toType, "p.To{0}()", Sql(types3));
		ConvertTo("Sql" + toType, "p.To{0}()", Sql(types4));
	}
}

string[] Sql(params string[] types)
{
	return types.Select(_ => "Sql" + _).ToArray();
}

string[] Add(string[] str1, params string[] str2)
{
	return str1.Concat(str2).ToArray();
}

IEnumerable<ToType> Set(Action<ToType> action, IEnumerable<ToType> types)
{
	foreach (var t in types)
	{
		action(t);
		yield return t;
	}
}

string LenDiff(int max, string str)
{
	var s = "";

	while (max-- > str.Length)
		s += " ";

	return s;
}

Dictionary<string,int> _groupOrder = new Dictionary<string,int>
{
	{ "Simple",   1 },
	{ "Nullable", 2 },
	{ "Sql",      3 },
	{ "Other",    4 },
};

HashSet<string> _codedTypes = new HashSet<string>
{
	"Boolean", "Char", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64", "Single", "Double", "Decimal", "DateTime", "String",
};

void Generate()
{
	PushIndent("\t\t");

	foreach (var gr in _types.Values.Select(_ => _.Group).Distinct())
	{
		WriteLine("");
		WriteLine("#region {0} Types", gr);

		foreach (var to in
			from t in _types.Values
			where t.Group == gr
			orderby t.Name
			select t)
		{
			WriteLine("");
			WriteLine("#region {0}", to.Name);
			
			var froms = from f in to.Froms.Keys select f;

			if (to.NonSilverlightable)
			{
				ClearIndent();
				WriteLine("");
				WriteLine("#if !SILVERLIGHT");
				PushIndent("\t\t");

				froms =
					from f in froms
					orderby _groupOrder[_types[f].Group], _types[f].Name
					select f;
			}
			else
			{
				froms =
					from f in froms
					orderby _types[f].NonSilverlightable, _groupOrder[_types[f].Group], _types[f].Name
					select f;
			}

			var group = "";
			var sl    = false;
			var len   = froms.Concat(new[] { "" }).Select(_ => _.Length).Max();
			var lcode = to.Froms.Values.Concat(new[] { "" }).Select(_ => (_ ?? "").Length).Max();

			foreach (var f in froms)
			{
				var code = to.Froms[f];

				if (code == null)
					continue;

				var fr = _types[f];

				if (!to.NonSilverlightable && sl != fr.NonSilverlightable)
				{
					sl = fr.NonSilverlightable;

					ClearIndent();
					WriteLine("");
					WriteLine("#if !SILVERLIGHT");
					PushIndent("\t\t");
				}

				if (fr.Group != group)
				{
					group = fr.Group;

					WriteLine("");
					WriteLine("// {0} Types", group);
					WriteLine("//");
				}

				if (to.NonSLMethods.Contains(fr.Name))
				{
					ClearIndent();
					WriteLine("#if !SILVERLIGHT");
					PushIndent("\t\t");
				}

				WriteLine("/// <summary>Converts the value from <c>{0}</c> to an equivalent <c>{1}</c> value.</summary>", fr.Name, to.Name);

				if (to.NonCompliant || fr.NonCompliant)
					WriteLine("[CLSCompliant(false)]");

				WriteLine("public static {0} {1}({2}{3} p) {{ return {4};{5} }}",
					to.Name, to.Method, fr.Name, LenDiff(len, fr.Name), code, LenDiff(lcode, code));

				if (to.NonSLMethods.Contains(fr.Name))
				{
					ClearIndent();
					WriteLine("#endif");
					PushIndent("\t\t");
				}
			}

			if (sl)
			{
				ClearIndent();
				WriteLine("");
				WriteLine("#endif");
				PushIndent("\t\t");
			}

			// From Object
			//
			if (to.Froms.Count > 0)
			{
				WriteLine("");
				WriteLine("// From Object");
				WriteLine("//");

				WriteLine("/// <summary>Converts the value from <c>Object</c> to an equivalent <c>{0}</c> value.</summary>", to.Name);

				if (to.NonCompliant)
					WriteLine("[CLSCompliant(false)]");

				WriteLine("public static {0} {1}(object p)", to.Name, to.Method);
				WriteLine("{");

				PushIndent("\t");

				var defType = false;

				var tc =
					from f in to.Froms.Keys
					where _codedTypes.Contains(f)
					select f;

				if (tc.Any())
				{
					WriteLine("if (p == null) return {0};", to.NullValue ?? "null");
					WriteLine("");

					if (!_codedTypes.Contains(to.Name))
					{
						WriteLine("if (p is {0}) return ({0})p;", to.Name);
						WriteLine("");
					}

					defType = true;

					WriteLine("var type = p.GetType();");
					WriteLine("");
					WriteLine("// Primitive types");
					WriteLine("//");
					WriteLine("switch (Type.GetTypeCode(type))");
					WriteLine("{");
					PushIndent("\t");

					len = new[] { to.Name, "DBNull" }.Concat(tc).Select(_ => _.Length).Max();

					WriteLine("case TypeCode.DBNull{0} : return {1};", LenDiff(len, "DBNull"), to.NullValue ?? "null");

					if (_codedTypes.Contains(to.Name))
						WriteLine("case TypeCode.{0}{1} : return ({0})p;", to.Name, LenDiff(len, to.Name));

					foreach (var t in tc)
					{
						if (to.NonSLMethods.Contains(t))
						{
							ClearIndent();
							WriteLine("#if !SILVERLIGHT");
							PushIndent("\t\t");
							PushIndent("\t");
							PushIndent("\t");
						}

						WriteLine("case TypeCode.{0}{1} : return {2}(({0}){1}p);", t, LenDiff(len, t), to.Method);

						if (to.NonSLMethods.Contains(t))
						{
							ClearIndent();
							WriteLine("#endif");
							PushIndent("\t\t");
							PushIndent("\t");
							PushIndent("\t");
						}
					}

					PopIndent();
					WriteLine("}");
				}
				else
				{
					WriteLine("if (p == null || p is DBNull) return {0};", to.NullValue ?? "null");
					WriteLine("");
					WriteLine("if (p is {0}) return ({0})p;", to.Name);
				}

				tc =
					from f in to.Froms.Keys
					where !_codedTypes.Contains(f)
					select f;

				if (to.NonSilverlightable)
				{
					tc =
						from f in tc
						orderby _groupOrder[_types[f].Group], _types[f].Name
						select f;
				}
				else
				{
					tc =
						from f in tc
						orderby _types[f].NonSilverlightable, _groupOrder[_types[f].Group], _types[f].Name
						select f;
				}

				var openGroupBlock = false;

				group = "";
				sl    = false;
				len   = new[] { "" }.Concat(tc).Select(_ => _.Length).Max();

				foreach (var f in tc)
				{
					var fr = _types[f];

					if (!to.NonSilverlightable && sl != fr.NonSilverlightable)
					{
						sl = fr.NonSilverlightable;

						ClearIndent();
						WriteLine("");
						WriteLine("#if !SILVERLIGHT");
						PushIndent("\t\t");
						PushIndent("\t");
					}

					if (fr.Group != group)
					{
						group = fr.Group;

						if (openGroupBlock)
						{
							openGroupBlock = false;
							PopIndent();
							WriteLine("}");
						}

						WriteLine("");
						WriteLine("// {0} Types", group);
						WriteLine("//");

						if (group == "Nullable")
						{
							openGroupBlock = true;

							if (!defType)
							{
								defType = true;
								WriteLine("var type = p.GetType();");
								WriteLine("");
							}

							WriteLine("if (type.IsGenericType)");
							WriteLine("{");
							
							PushIndent("\t");
						}
						else if (group == "Sql")
						{
							openGroupBlock = true;

							WriteLine("if (p is INullable)");
							WriteLine("{");
							
							PushIndent("\t");
						}
					}

					if (to.NonSLMethods.Contains(fr.Name))
					{
						ClearIndent();
						WriteLine("#if !SILVERLIGHT");
						PushIndent("\t\t");
						PushIndent("\t");
						if (openGroupBlock)
							PushIndent("\t");
					}

					WriteLine("if (p is {0}){1} return {2}(({0}){1}p);", fr.Name, LenDiff(len, fr.Name), to.Method);

					if (to.NonSLMethods.Contains(fr.Name))
					{
						ClearIndent();
						WriteLine("#endif");
						PushIndent("\t\t");
						PushIndent("\t");
						if (openGroupBlock)
							PushIndent("\t");
					}
				}

				if (openGroupBlock)
				{
					PopIndent();
					WriteLine("}");
				}

				if (sl)
				{
					ClearIndent();
					WriteLine("");
					WriteLine("#endif");
					PushIndent("\t\t");
					PushIndent("\t");
				}

				if (_codedTypes.Contains(to.Name))
				{
					WriteLine("");
					WriteLine("if (p is IConvertible) return ((IConvertible)p).To{0}(null);", to.Name);
				}

				WriteLine("");

				if (to.FromObjectReturn != null)
					WriteLine(to.FromObjectReturn);
				else
					WriteLine("throw CreateInvalidCastException(p.GetType(), typeof({0}));", to.Name);

				PopIndent();

				WriteLine("}");
			}

			if (to.NonSilverlightable)
			{
				ClearIndent();
				WriteLine("");
				WriteLine("#endif");
				PushIndent("\t\t");
			}

			WriteLine("");
			WriteLine("#endregion");
		}

		WriteLine("");
		WriteLine("#endregion");
	}

	ClearIndent();
}
#>
