/// <summary>
        /// Adds a new object to the DataObjects dictionary using the Namespace property as the key.
        /// It also reassigns the parent data object if it has not been assigned.
        /// </summary>
        /// <param name="childDataObject">The child data object to add.</param>
        public void Add(TC childDataObject)
        {
            if (childDataObject == null)
            {
                throw new Exception("The child data object should never be null.");
            }

            if (!childDataObject.CanBeAssignedParentMetaObject(ParentDataObject))
            {
                throw new Exception(string.Format(InvalidParentTypeErrorMessage,
                                                  childDataObject.Description, childDataObject.Namespace, ParentDataObject.Description, ParentDataObject.Namespace));
            }

            var tempParentDataObject = childDataObject.ParentMetaObject;

            childDataObject.ParentMetaObject = ParentDataObject;
            if (ChildDataObjects.ContainsKey(childDataObject.Namespace))
            {
                var errorMessage = string.Format(ObjectAlreadyExistsErrorMessage,
                                                 ParentDataObject.Description, ParentDataObject.Namespace, childDataObject.Description, childDataObject.Namespace);
                childDataObject.ParentMetaObject = tempParentDataObject;
                throw new Exception(errorMessage);
            }

            if (!ChildDataObjects.TryAdd(childDataObject.Namespace, childDataObject))
            {
                throw new Exception(string.Format(ObjectAlreadyExistsErrorMessage,
                                                  ParentDataObject.Description, ParentDataObject.Namespace, childDataObject.Description, childDataObject.Namespace));
            }
        }
        /// <summary>
        /// Calls ContainsKey on underlying dictionary.
        /// </summary>
        /// <param name="key">The key to find.</param>
        /// <returns>true if the dictionary has the key, false if not.</returns>
        public bool ContainsKey(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new Exception("Key parameter should never be null.");
            }

            return(ChildDataObjects.ContainsKey(key));
        }
        /// <summary>
        /// Removes a data object from the internal dictionary by key.
        /// </summary>
        /// <param name="key">The key for the data object to remove.</param>
        public void Remove(string key)
        {
            if (!ChildDataObjects.ContainsKey(key))
            {
                return;
            }

            if (Constants.StringComparer.Compare(_lastUsedDataObject.Namespace, key) == 0)
            {
                _lastUsedDataObject = null;
            }

            TC childDataObject;

            ChildDataObjects.TryRemove(key, out childDataObject);
            childDataObject.ParentMetaObject = null;
        }
        /// <summary>
        /// Removes a data object from the internal dictionary by value.
        /// </summary>
        /// <param name="childDataObject">The child data object to remove.</param>
        public void Remove(TC childDataObject)
        {
            if (!ChildDataObjects.ContainsKey(childDataObject.Namespace))
            {
                return;
            }

            if (Constants.StringComparer.Compare(_lastUsedDataObject.Namespace, childDataObject.Namespace) == 0 ||
                _lastUsedDataObject.Equals(childDataObject))
            {
                _lastUsedDataObject = null;
            }

            TC childDataObjectToRemove;

            ChildDataObjects.TryRemove(childDataObject.Namespace, out childDataObjectToRemove);
            childDataObject.ParentMetaObject = null;
        }