/// <summary>
        /// Registers a deserializer for item type-specific data.
        /// </summary>
        /// 
        /// <param name="typeId">
        /// The unique identifier for the item type-specific data as defined
        /// by the HealthVault service.
        /// </param>
        /// 
        /// <param name="itemTypeClass">
        /// The class that implements the item type-specific data. It must
        /// be public, derive from <see cref="Microsoft.Health.HealthRecordItem"/>, and 
        /// have a default constructor.
        /// </param>
        /// 
        /// <param name="overwriteExisting">
        /// <b>true</b> to register the new deserializer even if the type
        /// already has a deserializer registered; <b>false</b> to throw an 
        /// exception because a deserializer is already registered.
        /// </param>
        ///
        /// <exception cref="ArgumentException">
        /// The <paramref name="typeId"/> parameter is <see cref="System.Guid.Empty"/> or
        /// the <paramref name="itemTypeClass"/> parameter does not derive from
        /// <see cref="HealthRecordItem"/>.
        /// </exception>
        /// 
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="itemTypeClass"/> parameter is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="TypeHandlerAlreadyRegisteredException">
        /// The <paramref name="typeId"/> parameter already has a handler 
        /// registered and <paramref name="overwriteExisting"/> is <b>false</b>.
        /// </exception>
        /// 
        public static void RegisterTypeHandler(
            Guid typeId,
            Type itemTypeClass,
            bool overwriteExisting)
        {
            Validator.ThrowArgumentExceptionIf(
                typeId == Guid.Empty,
                "typeId",
                "TypeIdGuidEmpty");

            Validator.ThrowIfArgumentNull(itemTypeClass, "itemTypeClass", "ThingTypeClassNull");

            Validator.ThrowArgumentExceptionIf(
                !itemTypeClass.IsSubclassOf(typeof(HealthRecordItem)),
                "itemTypeClass",
                "ThingTypeClassNotHealthRecordItem");

            if (TypeHandlers.ContainsKey(typeId) && !overwriteExisting)
            {
                throw new TypeHandlerAlreadyRegisteredException(
                    ResourceRetriever.GetResourceString("TypeHandlerAlreadyRegistered"));
            }

            TypeHandlers[typeId] = new HealthRecordItemTypeHandler(typeId, itemTypeClass);
            _typeHandlersByClassName[itemTypeClass.Name] = TypeHandlers[typeId];
        }
        /// <summary>
        /// Registers a class as the handler for the application specific health record
        /// item type with the specific application ID and subtype tag.
        /// </summary>
        /// 
        /// <param name="applicationId">
        /// The application identifier for the application specific data that the
        /// specified type will handle.
        /// </param>
        /// 
        /// <param name="subtypeTag">
        /// The subtype tag for the application specific data that the specified type
        /// will handle.
        /// </param>
        /// 
        /// <param name="applicationSpecificHandlerClass">
        /// The .NET type that handles parsing of the application specific data for
        /// the specified application ID and subtype tag.
        /// </param>
        /// 
        /// <param name="overwriteExisting">
        /// If true and an entry exist for the specified <paramref name="applicationId"/>
        /// and <paramref name="subtypeTag"/> it will be replaced.
        /// </param>
        /// 
        /// <exception cref="ArgumentException">
        /// If <paramref name="applicationId"/> or <paramref name="subtypeTag"/> is 
        /// <b>null</b> or empty, or if <paramref name="applicationSpecificHandlerClass"/> 
        /// does not derive from ApplicationSpecific.
        /// </exception>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="applicationSpecificHandlerClass"/> is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="TypeHandlerAlreadyRegisteredException">
        /// If a type is already registered to handle the application specific data
        /// for the specified <paramref name="applicationId"/> and
        /// <paramref name="subtypeTag"/> and <paramref name="overwriteExisting"/> is false.
        /// </exception>
        /// 
        public static void RegisterApplicationSpecificHandler(
            string applicationId,
            string subtypeTag,
            Type applicationSpecificHandlerClass,
            bool overwriteExisting)
        {
            Validator.ThrowIfStringNullOrEmpty(applicationId, "applicationId");
            Validator.ThrowIfStringNullOrEmpty(subtypeTag, "subtypeTag");
            Validator.ThrowIfArgumentNull(applicationSpecificHandlerClass, "applicationSpecificHandlerClass", "AppDataHandlerClassMandatory");

            Validator.ThrowArgumentExceptionIf(
                applicationSpecificHandlerClass.BaseType.Name != "ApplicationSpecific",
                "applicationSpecificHandlerClass",
                "AppDataHandlerNotApplicationSpecific");

            Dictionary<string, HealthRecordItemTypeHandler> handlerDictionary =
                null;

            if (_appSpecificHandlers.ContainsKey(applicationId))
            {
                handlerDictionary = _appSpecificHandlers[applicationId];

                if (handlerDictionary.ContainsKey(subtypeTag) &&
                    !overwriteExisting)
                {
                    throw new TypeHandlerAlreadyRegisteredException(
                        ResourceRetriever.GetResourceString("AppDataHandlerAlreadyRegistered"));
                }
            }
            else
            {
                handlerDictionary = new Dictionary<string, HealthRecordItemTypeHandler>();
                _appSpecificHandlers.Add(applicationId, handlerDictionary);
            }

            HealthRecordItemTypeHandler handler =
                new HealthRecordItemTypeHandler(applicationSpecificHandlerClass);

            handlerDictionary[subtypeTag] = handler;
        }
        /// <summary>
        /// Registers a deserializer for item extension data.
        /// </summary>
        /// 
        /// <remarks>
        /// Extension data is available to all applications, and since there is no registration
        /// method for the extensionSource identifiers, collisions between applications are possible.
        /// 
        /// Applications should be written to be tolerant of the presence of extension data using the
        /// same extensionSource but a different schema. It is also recommended that extensionSource be
        /// specified the same way .NET namespaces are specified, prefixing the extensionSource with the
        /// company name. 
        /// </remarks>
        /// 
        /// <param name="extensionSource">
        /// The unique identifier for the source of the item extension.
        /// </param>
        /// 
        /// <param name="itemExtensionClass">
        /// The class that implements the item extension. It must
        /// be public, derive from <see cref="Microsoft.Health.HealthRecordItemExtension"/>, 
        /// and have a default constructor.
        /// </param>
        /// 
        /// <param name="overwriteExisting">
        /// <b>true</b> to register the new deserializer even if the type
        /// already has a deserializer registered; <b>false</b> to throw an 
        /// exception because a deserializer is already registered.
        /// </param>
        ///
        /// <exception cref="ArgumentException">
        /// The <paramref name="extensionSource"/> parameter is <b>null</b> or empty or
        /// the <paramref name="itemExtensionClass"/> parameter does not derive from
        /// <see cref="HealthRecordItemExtension"/>.
        /// </exception>
        /// 
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="itemExtensionClass"/> parameter is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="TypeHandlerAlreadyRegisteredException">
        /// The <paramref name="extensionSource"/> already has a handler 
        /// registered and <paramref name="overwriteExisting"/> is <b>false</b>.
        /// </exception>
        /// 
        public static void RegisterExtensionHandler(
            string extensionSource,
            Type itemExtensionClass,
            bool overwriteExisting)
        {
            Validator.ThrowIfStringNullOrEmpty(extensionSource, "extensionSource");
            Validator.ThrowIfArgumentNull(itemExtensionClass, "itemExtensionClass", "ItemExtensionClassNull");

            Validator.ThrowArgumentExceptionIf(
                !itemExtensionClass.IsSubclassOf(typeof(HealthRecordItemExtension)),
                "itemExtensionClass",
                "ThingExtensionClassNotThingExtension");

            if (_extensionHandlers.ContainsKey(extensionSource) &&
                !overwriteExisting)
            {
                throw new TypeHandlerAlreadyRegisteredException(
                    ResourceRetriever.GetResourceString("ExtensionHandlerAlreadyRegistered"));
            }

            _extensionHandlers[extensionSource] =
                new HealthRecordItemTypeHandler(itemExtensionClass);
        }
        /// <summary>
        /// Registers the default type handlers.
        /// </summary>
        /// 
        private static Dictionary<Guid, HealthRecordItemTypeHandler> RegisterDefaultTypeHandlers(
            out Dictionary<string, HealthRecordItemTypeHandler> typeHandlersByClassName)
        {
            Dictionary<Guid, HealthRecordItemTypeHandler> typeHandlers =
                new Dictionary<Guid, HealthRecordItemTypeHandler>();

            typeHandlersByClassName =
                new Dictionary<string, HealthRecordItemTypeHandler>(
                    StringComparer.OrdinalIgnoreCase);

            foreach (DefaultTypeHandler typeHandler in _defaultTypeHandlers)
            {
                HealthRecordItemTypeHandler handler =
                    new HealthRecordItemTypeHandler(typeHandler.TypeId, typeHandler.Type);

                typeHandlers.Add(
                    typeHandler.TypeId,
                    handler);

                typeHandlersByClassName.Add(
                    typeHandler.TypeName,
                    handler);
            }
            return typeHandlers;
        }