/// <summary>
        ///     Builds a preference entry for the provided parent based on the provided XElement node
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="foundEntry">The found entry.</param>
        /// <returns></returns>
        private TPreferenceEntry BuildPreferenceEntry <TPreferenceEntry>(IPreference parent, XElement foundEntry)
            where TPreferenceEntry : class, IPreferenceEntry
        {
            // Rather ugly way of reading shared properties + returning the newly created entry
            // Several unplesant compromises here
            Func <IPreferenceEntry, TPreferenceEntry> readSharedProperties = entry =>
            {
                entry.FriendlyName = XElementHelper.ReadStringValue(foundEntry, "friendlyName");
                entry.Description  = XElementHelper.ReadStringValue(foundEntry, "description", false);
                entry.IsSelected   = XElementHelper.ReadBoolValue(foundEntry, "isDefault", false);

                return(entry as TPreferenceEntry);
            };

            if (parent is INumericPreference)
            {
                var entry = new NumericPreferenceEntry
                {
                    Parent = (INumericPreference)parent,
                    Name   = XElementHelper.ReadDoubleValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            if (parent is IDatePreference)
            {
                var dateFormat = ((IDatePreference)parent).DateFormat;

                var entry = new DatePreferenceEntry
                {
                    Parent = (IDatePreference)parent,
                    Name   = XElementHelper.ReadDateValue(foundEntry, "name", dateFormat)
                };

                return(readSharedProperties(entry));
            }
            if (parent is IStringListPreference)
            {
                var entry = new StringListPreferenceEntry
                {
                    Parent = (IStringListPreference)parent,
                    Name   = XElementHelper.ReadStringValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            if (parent is IStringPreference)
            {
                var entry = new StringPreferenceEntry
                {
                    Parent = (IStringPreference)parent,
                    Name   = XElementHelper.ReadStringValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            throw new NotSupportedException("Invalid parent object");
        }
        /// <summary>
        ///     Builds a preference entry for the provided parent based on the provided XElement node
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="foundEntry">The found entry.</param>
        /// <returns></returns>
        private TPreferenceEntry BuildPreferenceEntry <TPreferenceEntry>(IPreference parent, XElement foundEntry)
            where TPreferenceEntry : class, IPreferenceEntry
        {
            // Rather ugly way of reading shared properties + returning the newly created entry
            // Several unplesant compromises here
            Func <IPreferenceEntry, TPreferenceEntry> readSharedProperties = entry =>
            {
                entry.FriendlyName = XElementHelper.ReadStringValue(foundEntry, "friendlyName");
                entry.Description  = XElementHelper.ReadStringValue(foundEntry, "description", false);
                entry.IsSelected   = XElementHelper.ReadBoolValue(foundEntry, "isDefault", false);

                //if (isSelectedByDefault && parent.HasDirectlyEditableValue)
                //{
                //    /*
                //     * This preference has both a list of pre-defined entries - one of which are selected by default -
                //     * and a default value specified in the config file. There is really no obvious way to know which
                //     * the user actually wanted to be the default value, so log this as a warning, and let the
                //     * pre-defined option override the directly specified default value.
                //     */

                //    parent.Value = name;
                //}

                return(entry as TPreferenceEntry);
            };

            if (parent is INumericPreference)
            {
                var entry = new NumericPreferenceEntry
                {
                    Parent = (INumericPreference)parent,
                    Name   = XElementHelper.ReadDoubleValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            if (parent is IDatePreference)
            {
                var dateFormat = ((IDatePreference)parent).DateFormat;

                var entry = new DatePreferenceEntry
                {
                    Parent = (IDatePreference)parent,
                    Name   = XElementHelper.ReadDateValue(foundEntry, "name", dateFormat)
                };

                return(readSharedProperties(entry));
            }
            if (parent is IStringListPreference)
            {
                var entry = new StringListPreferenceEntry
                {
                    Parent = (IStringListPreference)parent,
                    Name   = XElementHelper.ReadStringValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            if (parent is IStringPreference)
            {
                var entry = new StringPreferenceEntry
                {
                    Parent = (IStringPreference)parent,
                    Name   = XElementHelper.ReadStringValue(foundEntry, "name")
                };

                return(readSharedProperties(entry));
            }
            throw new NotSupportedException("Invalid parent object");
        }