private static string GetCannotDuplicateKnownTypeCodeErrorMessage( PolymorphismTarget target, string typeCode, string memberName, int tupleItemNumber )
			{
				switch ( target )
				{
					case PolymorphismTarget.CollectionItem:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify multiple types for ext-type code '{0}' for collection items of member '{1}'.",
								StringEscape.ForDisplay( typeCode ),
								memberName
							);
					}
					case PolymorphismTarget.DictionaryKey:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify multiple types for ext-type code '{0}' for dictionary keys of member '{1}'.",
								StringEscape.ForDisplay( typeCode ),
								memberName
							);
					}
					case PolymorphismTarget.TupleItem:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify multiple types for ext-type code '{0}' for #{1} item of tuple type member '{2}'.",
								StringEscape.ForDisplay( typeCode ),
								tupleItemNumber,
								memberName
							);
					}
					default:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify multiple types for ext-type code '{0}' for member '{1}'.",
								StringEscape.ForDisplay( typeCode ),
								memberName
							);
					}
				}
			}
			private static string GetCannotSpecifyKnownTypeAndRuntimeTypeErrorMessage( PolymorphismTarget target, string memberName, int? tupleItemNumber )
			{
				switch ( target )
				{
					case PolymorphismTarget.CollectionItem:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify '{0}' and '{1}' simultaneously to collection items of member '{2}' itself.",
								typeof( MessagePackRuntimeCollectionItemTypeAttribute ),
								typeof( MessagePackKnownCollectionItemTypeAttribute ),
								memberName
							);
					}
					case PolymorphismTarget.DictionaryKey:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify '{0}' and '{1}' simultaneously to dictionary keys of member '{2}' itself.",
								typeof( MessagePackRuntimeDictionaryKeyTypeAttribute ),
								typeof( MessagePackKnownDictionaryKeyTypeAttribute ),
								memberName
							);
					}
					case PolymorphismTarget.TupleItem:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify '{0}' and '{1}' simultaneously to #{2} item of tuple type member '{3}' itself.",
								typeof( MessagePackRuntimeTupleItemTypeAttribute ),
								typeof( MessagePackKnownTupleItemTypeAttribute ),
								tupleItemNumber,
								memberName
							);
					}
					default:
					{
						return
							String.Format(
								CultureInfo.CurrentCulture,
								"Cannot specify '{0}' and '{1}' simultaneously to member '{2}' itself.",
								typeof( MessagePackRuntimeTypeAttribute ),
								typeof( MessagePackKnownTypeAttribute ),
								memberName
							);
					}
				}
			}
			private void SetRuntimeType( PolymorphismTarget target, string memberName, int tupleItemNumber, Func<PolymorphicTypeVerificationContext, bool> typeVerifier )
			{
				if ( this._knownTypeMapping.Count > 0 )
				{
					throw new SerializationException(
						GetCannotSpecifyKnownTypeAndRuntimeTypeErrorMessage( target, memberName, tupleItemNumber )
					);
				}

				this.TypeVerifier = typeVerifier;
				this._useTypeEmbedding = true;
			}
			private void SetKnownType( PolymorphismTarget target, string memberName, int tupleItemNumber, string typeCode, Type bindingType )
			{
				if ( this._useTypeEmbedding )
				{
					throw new SerializationException(
						GetCannotSpecifyKnownTypeAndRuntimeTypeErrorMessage( target, memberName, tupleItemNumber )
					);
				}

				try
				{
					this._knownTypeMapping.Add( typeCode, bindingType );
					this.TypeVerifier = DefaultTypeVerfiier;
				}
				catch ( ArgumentException )
				{
					throw new SerializationException(
						GetCannotDuplicateKnownTypeCodeErrorMessage( target, typeCode, memberName, tupleItemNumber )
					);
				}
			}
			private void SetDefault( PolymorphismTarget target, string memberName, int tupleItemNumber, PolymorphismSchema defaultSchema )
			{
				if ( this._useTypeEmbedding || this._knownTypeMapping.Count > 0 )
				{
					// Default is not required.
					return;
				}

				switch ( defaultSchema.PolymorphismType )
				{
					case PolymorphismType.KnownTypes:
					{
						foreach ( var typeMapping in defaultSchema.CodeTypeMapping )
						{
							this.SetKnownType( target, memberName, tupleItemNumber, typeMapping.Key, typeMapping.Value );
						}

						break;
					}
					case PolymorphismType.RuntimeType:
					{
						this.SetRuntimeType( target, memberName, tupleItemNumber, defaultSchema.TypeVerifier );
						break;
					}
				}
			}
			public static TypeTableEntry Create( MemberInfo member, PolymorphismTarget targetType, PolymorphismSchema defaultSchema )
			{
				var result = new TypeTableEntry();
				var memberName = member.ToString();
				foreach (
					var attribute in
						member.GetCustomAttributes( false )
							.OfType<IPolymorphicHelperAttribute>()
							.Where( a => a.Target == targetType )
				)
				{
					// TupleItem schema should never come here, so passing -1 as tupleItemNumber is OK.
					result.Interpret( attribute, memberName, -1 );
				}

				if ( defaultSchema != null )
				{
					// TupleItem schema should never come here, so passing -1 as tupleItemNumber is OK.
					result.SetDefault( targetType, memberName, -1, defaultSchema );
				}

				return result;
			}