public MetaType Add(Type type, bool applyDefaultBehaviour) { if (type == null) { throw new ArgumentNullException("type"); } MetaType newType = this.FindWithoutAdd(type); if (newType != null) { return(newType); } int opaqueToken = 0; if (type.IsInterface && base.MapType(MetaType.ienumerable).IsAssignableFrom(type) && TypeModel.GetListItemType(this, type) == null) { throw new ArgumentException("IEnumerable[<T>] data cannot be used as a meta-type unless an Add method can be resolved"); } try { newType = this.RecogniseCommonTypes(type); if (newType != null) { if (!applyDefaultBehaviour) { throw new ArgumentException("Default behaviour must be observed for certain types with special handling; " + type.FullName, "applyDefaultBehaviour"); } applyDefaultBehaviour = false; } if (newType == null) { newType = this.Create(type); } newType.Pending = true; this.TakeLock(ref opaqueToken); if (this.FindWithoutAdd(type) != null) { throw new ArgumentException("Duplicate type", "type"); } this.ThrowIfFrozen(); this.types.Add(newType); if (applyDefaultBehaviour) { newType.ApplyDefaultBehaviour(); } newType.Pending = false; } finally { this.ReleaseLock(opaqueToken); } return(newType); }