/// <summary>
        /// Serialize an ICollection using the enumerator and the Synchronization hints
        /// </summary>
        /// <param name="_collection">The collection to serialize</param>
        /// <param name="_useType">Treat the "_object" parameter as if it were of this type</param>
        /// <param name="_parentNode">The Xml node to receive the elements of the collection</param>
        /// <param name="_serializer">The serializer used to serialize the collection</param>
        /// <returns>TRUE always</returns>
        protected static bool BaseSerialize(object _collection, Type _useType, XmlElement _parentNode, CSerializer _serializer)
        {
            if (!ATreatAsInterface.TreatAsInterface(_serializer))
            {
                return(false);
            }

            var collection         = (TCollectionType)_collection;
            var useSynchronization = collection.IsSynchronized;

            if (useSynchronization)
            {
                Monitor.Enter(collection.SyncRoot);
            }

            try
            {
                SerializeEnumeration(collection, _parentNode, _serializer);
            }
            finally
            {
                if (useSynchronization)
                {
                    Monitor.Exit(collection.SyncRoot);
                }
            }

            return(true);
        }
        /// <summary>
        /// Deserialization helper to deserialize XML nodes into a "special" collection.
        /// </summary>
        /// <remarks>
        /// A "special" collection is one of the "hidden" collections that implement Synchronized or ReadOnly
        /// behavior for the System.Collections collections.
        /// </remarks>
        /// <param name="_object">The working object to receive the deserialized values</param>
        /// <param name="_node">The XmlNode containing the data for the collection</param>
        /// <param name="_deserializer">The deserialization framework performing the overall deserialization</param>
        /// <returns>TRUE always</returns>
        protected bool SpecialDeserialize(CWorkingObject _object, XmlElement _node, CDeserializer _deserializer)
        {
            if (!ATreatAsInterface.TreatAsInterface(_deserializer))
            {
                return(false);
            }

            // First, get an object to deserialize into
            var tmp = new CWorkingObject();

            if (_object.WorkingObject != null)
            {
                tmp.Set(_object.WorkingObject);
            }

            // Deserialize into the temporary WorkingObject
            BasicDeserialize(tmp, _node, _deserializer);

            // At this point, IF there was an object set in _object prior to this routine, its contents
            //  should have been set by the standard collection deserialization and we should be done.
            if (_object.IsSet)
            {
                return(true);
            }

            // Get the collection object populated so far with information from the Xml
            var tmpCollection = tmp.GetWorkingObject <TCollectionType>();

            // Using that object, create a new, syncronized version of that ArrayList.
            var specialCollection = MakeSpecialCollection(tmpCollection);

            // Set this sync'ed version to the _object, and we're done
            _object.Set(specialCollection);
            return(true);
        }
        /// <summary>
        /// Enumerate through the child nodes of the collection and deserialize each one. Use the
        /// method provided to add each element to the collection.
        /// </summary>
        /// <param name="_object">The working object to receive the data about the Stack</param>
        /// <param name="_parentNode">The node containing the elements of the Stack</param>
        /// <param name="_deserializer">The Deserializer controlling this deserializtion</param>
        /// <returns>TRUE always</returns>
        protected bool BasicDeserialize(CWorkingObject _object, XmlElement _parentNode, CDeserializer _deserializer)
        {
            if (!ATreatAsInterface.TreatAsInterface(_deserializer))
            {
                return(false);
            }

            var theCollection = _object.GetExistingOrCreateNew <TCollectionType>();

            foreach (XmlElement element in GetXmlChildren(_parentNode))
            {
                var theElement = (TElementType)_deserializer.FrameworkDeserialize(element, typeof(TElementType));
                AddElement(theCollection, theElement);
            }

            return(true);
        }
        /// <summary>
        /// Deserialize a series of "ChildNode"s from an XmlElement as elements for a generic Dictionary.
        /// </summary>
        /// <param name="_workingObject">The "working" object to receive the dictionary elements</param>
        /// <param name="_parentElement">The "parent" of the XmlElements containing the individual Dictionary elements</param>
        /// <param name="_deserializer">The deserialization framework handing the deserialization</param>
        /// <returns>TRUE unless the collection is not supposed to be treated like an "interface"</returns>
        public bool Deserialize(CWorkingObject _workingObject, XmlElement _parentElement, CDeserializer _deserializer)
        {
            if (!ATreatAsInterface.TreatAsInterface(_deserializer))
            {
                return(false);
            }

            var oType = _workingObject.WorkingType;

            if (oType == null)
            {
                oType = _deserializer.GetExpectedType(_parentElement);
            }
            if (oType == null)
            {
                throw new XDeserializationError(
                          "When deserializing a generic collection, the actual Type of the collection could not be found.");
            }

            var expectedTypes = oType.GetGenericArguments();

            if (expectedTypes.Length != NumberOfExpectedTypes)
            {
                throw new XDeserializationError("The Type '" + oType.FullName + "' has " + expectedTypes.Length +
                                                " generic arguments when it is required to have exactly " + NumberOfExpectedTypes + ".");
            }

            var collection  = _workingObject.GetExistingOrCreateNew(oType);
            var elementName = _deserializer.GetNameForCollectionElement();

            foreach (XmlElement xmlElement in GetXmlChildren(_parentElement))
            {
                if (xmlElement.Name == elementName)
                {
                    AddElementFromXml(collection, xmlElement, expectedTypes, _deserializer);
                }
            }

            return(true);
        }
        /// <summary>
        /// Serialize a generic collection to a parent Xml element
        /// </summary>
        /// <param name="_object">The object (collection) to serialize</param>
        /// <param name="_useType">Treat the "_object" parameter as if it were of this type</param>
        /// <param name="_parentElement">The XML element that is to receive the collection as Xml data</param>
        /// <param name="_serializer">The Serializer framework object in charge of serializing the collection</param>
        /// <returns>TRUE unless the collection is not supposed to be treated like an "interface"</returns>
        public bool Serialize(object _object, Type _useType, XmlElement _parentElement, CSerializer _serializer)
        {
            if (!ATreatAsInterface.TreatAsInterface(_serializer))
            {
                return(false);
            }

            var oType = _useType;

            if (oType == null)
            {
                oType = _object.GetType();
            }

            if (oType == null)
            {
                throw new XSerializationError(
                          "When serializing a generic collection, the actual Type of the collection could not be found.");
            }

            var expectedTypes = oType.GetGenericArguments();

            if (expectedTypes.Length != NumberOfExpectedTypes)
            {
                throw new XSerializationError("The Type '" + oType.FullName + "' has " + expectedTypes.Length +
                                              " generic arguments when it is required to have exactly " + NumberOfExpectedTypes + ".");
            }

            var elementName = _serializer.GetNameForCollectionElement();

            foreach (var element in GetCollectionElements(_object))
            {
                AddElementToXml(elementName, element, _parentElement, expectedTypes, _serializer);
            }

            return(true);
        }