public Timetable(Timetable other) { #region Clone subject/type/stream/class data // copy across all the subject data SubjectList = new List <Subject>(); foreach (var subject in other.SubjectList) { SubjectList.Add(subject.Clone()); } // copy all the type data TypeList = new List <Type>(); foreach (var type in other.TypeList) { TypeList.Add(type.Clone()); } // copy all the stream data StreamList = new List <Stream>(); foreach (var stream in other.StreamList) { StreamList.Add(stream.Clone()); } // copy all the session data ClassList = new List <Session>(); foreach (var session in other.ClassList) { ClassList.Add(session.Clone()); } // update reference to subjects for (var i = 0; i < SubjectList.Count; i++) { foreach (var type in TypeList) { if (type.Subject == other.SubjectList[i]) { type.Subject = SubjectList[i]; } } } // update references to types for (var i = 0; i < TypeList.Count; i++) { // parent references foreach (var stream in StreamList) { if (stream.Type == other.TypeList[i]) { stream.Type = TypeList[i]; } } // child references for (var j = 0; j < TypeList[i].Subject.Types.Count; j++) { if (TypeList[i].Subject.Types[j] == other.TypeList[i]) { TypeList[i].Subject.Types[j] = TypeList[i]; break; } } // unique streams for (var j = 0; j < TypeList[i].UniqueStreams.Count; j++) { if (StreamList[i].Type.Streams[j] == other.StreamList[i]) { StreamList[i].Type.Streams[j] = StreamList[i]; break; } } } // update references to streams for (var i = 0; i < StreamList.Count; i++) { // parent references foreach (var session in ClassList) { if (session.Stream == other.StreamList[i]) { session.Stream = StreamList[i]; } } // child references for (var j = 0; j < StreamList[i].Type.Streams.Count; j++) { if (StreamList[i].Type.Streams[j] == other.StreamList[i]) { StreamList[i].Type.Streams[j] = StreamList[i]; break; } } // find all equivalent streams set to other.StreamList[i] foreach (Stream t in StreamList) { for (var k = 0; k < t.Equivalent.Count; k++) { if (t.Equivalent[k] == other.StreamList[i]) { t.Equivalent[k] = StreamList[i]; break; } } } // find all incompatible streams set to other.StreamList[i] foreach (Stream t in StreamList) { for (var k = 0; k < t.Incompatible.Count; k++) { if (t.Incompatible[k] == other.StreamList[i]) { t.Incompatible[k] = StreamList[i]; break; } } } // find all unique streams set to other.StreamList[i] foreach (var type in TypeList) { for (var j = 0; j < type.UniqueStreams.Count; j++) { if (type.UniqueStreams[j] == other.StreamList[i]) { type.UniqueStreams[j] = StreamList[i]; break; } } } } // update references to the sessions for (var i = 0; i < ClassList.Count; i++) { // child references for (var j = 0; j < ClassList[i].Stream.Classes.Count; j++) { if (ClassList[i].Stream.Classes[j] == other.ClassList[i]) { ClassList[i].Stream.Classes[j] = ClassList[i]; break; } } } #endregion // a shallow copy will do for boolean (value type) // TODO: copies both levels or just first level? _streamClashTable = (bool[][])other._streamClashTable.Clone(); // clone unavailable data UnavailableList = new List <Unavailability>(); foreach (var unavail in other.UnavailableList) { UnavailableList.Add(unavail.Clone()); } // copy status of solution recomputation required RecomputeSolutions = other.RecomputeSolutions; }