private static IEnumerable<DevicePropertyValueModel> ExtractPropertyValueModels(
            IDynamicMetaObjectProvider deviceProperties)
        {
            DevicePropertyValueModel currentData;
            object currentValue;
            Dictionary<string, DevicePropertyMetadata> devicePropertyIndex;
            int editableOrdering;
            bool isDisplayedRegistered;
            bool isDisplayedUnregistered;
            bool isEditable;
            int nonediableOrdering;
            DevicePropertyMetadata propertyMetadata;
            PropertyType propertyType;

            Debug.Assert(deviceProperties != null, "deviceProperties is a null reference.");

            devicePropertyIndex = GetDevicePropertyConfiguration().ToDictionary(t => t.Name);

            // For now, display r/o properties first.
            editableOrdering = 1;
            nonediableOrdering = int.MinValue;

            foreach (string propertyName in D.Dynamic.GetMemberNames(deviceProperties, true))
            {
                if (devicePropertyIndex.TryGetValue(propertyName, out propertyMetadata))
                {
                    isDisplayedRegistered = propertyMetadata.IsDisplayedForRegisteredDevices;
                    isDisplayedUnregistered = propertyMetadata.IsDisplayedForUnregisteredDevices;
                    isEditable = propertyMetadata.IsEditable;

                    propertyType = propertyMetadata.PropertyType;
                }
                else
                {
                    isDisplayedRegistered = isEditable = true;
                    isDisplayedUnregistered = false;

                    propertyType = PropertyType.String;
                }

                if (!isDisplayedRegistered && !isDisplayedUnregistered)
                {
                    continue;
                }

                currentData = new DevicePropertyValueModel()
                {
                    Name = propertyName,
                    PropertyType = propertyType
                };

                if (isEditable)
                {
                    currentData.IsEditable = true;
                    currentData.DisplayOrder = editableOrdering++;
                }
                else
                {
                    currentData.IsEditable = false;
                    currentData.DisplayOrder = nonediableOrdering++;
                }

                currentData.IsIncludedWithUnregisteredDevices =
                    isDisplayedUnregistered;

                currentValue = D.Dynamic.InvokeGet(deviceProperties, propertyName);
                if (currentValue == null)
                {
                    currentData.Value = string.Empty;
                }
                else
                {
                    currentData.Value = string.Format(CultureInfo.InvariantCulture, "{0}", currentValue);
                }

                yield return currentData;
            }
        }
        private static IEnumerable<DevicePropertyValueModel> ExtractPropertyValueModels(
            object deviceProperties)
        {
            DevicePropertyValueModel currentData;
            object currentValue;
            Dictionary<string, DevicePropertyMetadata> devicePropertyIndex;
            Type devicePropertiesType;
            bool isDisplayedRegistered;
            bool isDisplayedUnregistered;
            bool isEditable;
            int editableOrdering;
            MethodInfo getMethod;
            int nonediableOrdering;
            DevicePropertyMetadata propertyMetadata;

            Debug.Assert(deviceProperties != null, "deviceProperties is a null reference.");

            devicePropertyIndex = GetDevicePropertyConfiguration().ToDictionary(t => t.Name);

            // For now, display r/o properties first.
            editableOrdering = 1;
            nonediableOrdering = int.MinValue;

            devicePropertiesType = deviceProperties.GetType();
            foreach (PropertyInfo prop in devicePropertiesType.GetProperties())
            {
                if (devicePropertyIndex.TryGetValue(
                    prop.Name,
                    out propertyMetadata))
                {
                    isDisplayedRegistered = propertyMetadata.IsDisplayedForRegisteredDevices;
                    isDisplayedUnregistered = propertyMetadata.IsDisplayedForUnregisteredDevices;
                    isEditable = propertyMetadata.IsEditable;
                }
                else
                {
                    isDisplayedRegistered = isEditable = true;
                    isDisplayedUnregistered = false;
                }

                if (!isDisplayedRegistered && !isDisplayedUnregistered)
                {
                    continue;
                }

                if ((getMethod = prop.GetGetMethod()) == null)
                {
                    continue;
                }

                // Mark R/O properties as not-ediable.
                if (!prop.CanWrite)
                {
                    isEditable = false;
                }

                currentData = new DevicePropertyValueModel()
                {
                    Name = prop.Name,
                    PropertyType = propertyMetadata.PropertyType
                };

                if (isEditable)
                {
                    currentData.IsEditable = true;
                    currentData.DisplayOrder = editableOrdering++;
                }
                else
                {
                    currentData.IsEditable = false;
                    currentData.DisplayOrder = nonediableOrdering++;
                }

                currentData.IsIncludedWithUnregisteredDevices = isDisplayedUnregistered;

                currentValue = getMethod.Invoke(deviceProperties, ReflectionHelper.EmptyArray);
                if (currentValue == null)
                {
                    currentData.Value = string.Empty;
                }
                else
                {
                    currentData.Value = string.Format(CultureInfo.InvariantCulture, "{0}", currentValue);
                }

                yield return currentData;
            }
        }