public virtual object Clone() { Type t = this.GetType(); // make a copy, attached to broker SEntity clone = (SEntity)Activator.CreateInstance(t); // reference all registered fields IList <FieldInfo> fields = SEntity.GetFieldsOrdered(t); foreach (FieldInfo field in fields) { if (field.FieldType.IsValueType || field.FieldType == typeof(string)) { // copy over value types object val = field.GetValue(this); field.SetValue(clone, val); } else if (field.FieldType.IsInterface || typeof(SEntity).IsAssignableFrom(field.FieldType)) { // make unique copy of referenced type except for owner history!!! object val = field.GetValue(this); if (val is SEntity) { SEntity sentity = (SEntity)val; SEntity valclone = (SEntity)sentity.Clone(); field.SetValue(clone, valclone); } else { field.SetValue(clone, val); } } else if (typeof(IList).IsAssignableFrom(field.FieldType)) { IList listSource = (IList)field.GetValue(this); if (listSource != null) { // don't copy collections, but initialize new collection System.Collections.IList listClone = (System.Collections.IList)Activator.CreateInstance(field.FieldType); field.SetValue(clone, listClone); Type[] genericargs = field.FieldType.GetGenericArguments(); if (genericargs.Length == 1) { foreach (object element in listSource) { object elemClone = null; // clone resources -- don't carry over rooted objects if (element is ICloneable) { // clone resources, list of list, e.g. IfcBSplineSurface elemClone = ((ICloneable)element).Clone(); } else { // i.e. length coordinate elemClone = element; } // now add to list, INCLUDING IF NULL such as blank entries of table listClone.Add(elemClone); } } } } } return(clone); }