/// <summary>
        /// Adds information about the value of capability in specified usage mode to the string builder.
        /// </summary>
        /// <param name="capUsageMode"></param>
        /// <param name="capValue"></param>
        /// <param name="capsInfo"></param>
        private void AddCapInfoToCapsInfo(DeviceCapabilityUsageMode capUsageMode, TwainValueContainerBase capValue, StringBuilder capsInfo)
        {
            capsInfo.Append(string.Format("  Usage mode: {0}{1}", capUsageMode, Environment.NewLine));
            capsInfo.Append(string.Format("    Value container type: {0}{1}", capValue.ContainerType, Environment.NewLine));

            switch (capValue.ContainerType)
            {
            case TwainValueContainerType.OneValue:
                TwainOneValueContainer oneDeviceCapabilityValue = (TwainOneValueContainer)capValue;
                AddCapOneCurrentValueInfoToCapsInfo(oneDeviceCapabilityValue, capsInfo);
                break;

            case TwainValueContainerType.Range:
                TwainRangeValueContainer rangeDeviceCapabilityValue = (TwainRangeValueContainer)capValue;
                AddCapRangeCurrentValueInfoToCapsInfo(rangeDeviceCapabilityValue, capsInfo);
                AddCapRangeDefaultValueInfoToCapsInfo(rangeDeviceCapabilityValue, capsInfo);
                AddCapMinValueInfoToCapsInfo(rangeDeviceCapabilityValue, capsInfo);
                AddCapMaxValueInfoToCapsInfo(rangeDeviceCapabilityValue, capsInfo);
                AddCapStepSizeInfoToCapsInfo(rangeDeviceCapabilityValue, capsInfo);
                break;

            case TwainValueContainerType.Enum:
                TwainEnumValueContainer enumDeviceCapabilityValue = (TwainEnumValueContainer)capValue;
                AddCapEnumCurrentValueInfoToCapsInfo(enumDeviceCapabilityValue, capsInfo);
                AddCapEnumDefaultValueInfoToCapsInfo(enumDeviceCapabilityValue, capsInfo);
                AddCapValuesInfoToCapsInfo(enumDeviceCapabilityValue, capsInfo);
                break;

            case TwainValueContainerType.Array:
                TwainArrayValueContainer arrayDeviceCapabilityValue = (TwainArrayValueContainer)capValue;
                AddCapValuesInfoToCapsInfo(arrayDeviceCapabilityValue, capsInfo);
                break;
            }
        }
        private void getMethodComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Cursor = Cursors.Wait;

            DeviceCapabilityInfo deviceCapabilityInfo = (DeviceCapabilityInfo)supportedCapabilitiesListBox.SelectedItem;
            DeviceCapability     cap = deviceCapabilityInfo.DeviceCapability;

            DeviceCapabilityUsageMode usageMode = DeviceCapabilityUsageMode.Get;

            if (getMethodComboBox.SelectedItem != null)
            {
                usageMode = (DeviceCapabilityUsageMode)getMethodComboBox.SelectedItem;
            }

            GetCapValue(cap, usageMode);

            Cursor = Cursors.Arrow;
        }
        /// <summary>
        /// Copies information about all capabilities to the clipboard.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void copyToClipboardButton_Click(object sender, RoutedEventArgs e)
        {
            if (_device.State == DeviceState.Closed)
            {
                MessageBox.Show("Device is not open.");
                return;
            }

            Cursor = Cursors.Wait;

            StringBuilder capsInfo = new StringBuilder();

            capsInfo.Append(string.Format("Manufacturer: {0}{1}", _device.Info.Manufacturer, Environment.NewLine));
            capsInfo.Append(string.Format("Product family: {0}{1}", _device.Info.ProductFamily, Environment.NewLine));
            capsInfo.Append(string.Format("Product name: {0}{1}", _device.Info.ProductName, Environment.NewLine));
            capsInfo.Append(string.Format("Driver version: {0}{1}", _device.Info.DriverVersion, Environment.NewLine));
            capsInfo.Append(string.Format("TWAIN version: {0}{1}", _device.Info.TwainVersion, Environment.NewLine));
            capsInfo.Append(string.Format("TWAIN 2.0 compatible: {0}{1}", _device.Info.IsTwain2Compatible, Environment.NewLine));
            capsInfo.Append(string.Format("Flatbed present: {0}{1}", _device.HasFlatbed, Environment.NewLine));
            capsInfo.Append(string.Format("Feeder present: {0}{1}{1}", _device.HasFeeder, Environment.NewLine));

            DeviceCapability deviceCapability;

            for (int i = 0; i < _device.Capabilities.Count; i++)
            {
                try
                {
                    deviceCapability = _device.Capabilities[i];

                    capsInfo.Append(string.Format("Capability: {0}{1}", deviceCapability, Environment.NewLine));

                    TwainValueContainerBase capValue = deviceCapability.GetValue();

                    DeviceCapabilityUsageMode capUsageMode = deviceCapability.UsageMode;
                    capsInfo.Append(string.Format("  Supported usage modes: {0}{1}", capUsageMode, Environment.NewLine));

                    if (capValue != null)
                    {
                        if ((capUsageMode & DeviceCapabilityUsageMode.Get) != 0)
                        {
                            AddCapInfoToCapsInfo(DeviceCapabilityUsageMode.Get, capValue, capsInfo);
                        }
                        if ((capUsageMode & DeviceCapabilityUsageMode.GetCurrent) != 0)
                        {
                            AddCapInfoToCapsInfo(DeviceCapabilityUsageMode.GetCurrent, deviceCapability.GetCurrentValue(), capsInfo);
                        }
                        if ((capUsageMode & DeviceCapabilityUsageMode.GetDefault) != 0)
                        {
                            AddCapInfoToCapsInfo(DeviceCapabilityUsageMode.GetDefault, deviceCapability.GetDefaultValue(), capsInfo);
                        }
                    }
                    else
                    {
                        capsInfo.Append(string.Format("  Value: NULL{0}", Environment.NewLine));
                    }
                }
                catch (TwainDeviceException)
                {
                }
                catch (TwainDeviceCapabilityException)
                {
                }
                capsInfo.Append(Environment.NewLine);
            }
            capsInfo.Append(Environment.NewLine);

            // get information about image layout
            try
            {
                capsInfo.Append(string.Format("Default image layout: {0}{1}", _device.ImageLayout.GetDefault(), Environment.NewLine));
                capsInfo.Append(Environment.NewLine);
            }
            catch (TwainDeviceException)
            {
            }

            // get information about cameras of device
            DeviceCamera[] deviceCameras = _device.Cameras.GetCameras();
            if (deviceCameras.Length > 0)
            {
                for (int i = 0; i < deviceCameras.Length; i++)
                {
                    capsInfo.Append(string.Format("Camera{0}: {1}{2}", i, deviceCameras[i], Environment.NewLine));
                }
                capsInfo.Append(Environment.NewLine);
            }

            //
            Clipboard.SetText(capsInfo.ToString());

            Cursor = Cursors.Arrow;

            MessageBox.Show("Information about device capabilities is copied to clipboard.");
        }
        /// <summary>
        /// Gets information about value of specified capability in specified usage mode.
        /// </summary>
        /// <param name="deviceCapability"></param>
        /// <param name="usageMode"></param>
        private void GetCapValue(DeviceCapability deviceCapability, DeviceCapabilityUsageMode usageMode)
        {
            usageModeTextBox.Text     = "";
            containerTypeTextBox.Text = "";
            valueTypeTextBox.Text     = "";
            currentValueTextBox.Text  = "";
            minValueTextBox.Text      = "";
            maxValueTextBox.Text      = "";
            defaultValueTextBox.Text  = "";
            stepSizeTextBox.Text      = "";
            supportedValuesListBox.Items.Clear();

            try
            {
                TwainValueContainerBase deviceCapabilityValue = null;
                if (usageMode == DeviceCapabilityUsageMode.GetCurrent)
                {
                    deviceCapabilityValue = deviceCapability.GetCurrentValue();
                }
                else if (usageMode == DeviceCapabilityUsageMode.GetDefault)
                {
                    deviceCapabilityValue = deviceCapability.GetDefaultValue();
                }
                else
                {
                    deviceCapabilityValue = deviceCapability.GetValue();
                }

                if (getMethodComboBox.Items.Count == 0)
                {
                    //
                    usageModeTextBox.Text = deviceCapability.UsageMode.ToString();
                    //
                    if ((deviceCapability.UsageMode & DeviceCapabilityUsageMode.Get) != 0)
                    {
                        getMethodComboBox.Items.Add(DeviceCapabilityUsageMode.Get);
                    }
                    if ((deviceCapability.UsageMode & DeviceCapabilityUsageMode.GetCurrent) != 0)
                    {
                        getMethodComboBox.Items.Add(DeviceCapabilityUsageMode.GetCurrent);
                    }
                    if ((deviceCapability.UsageMode & DeviceCapabilityUsageMode.GetDefault) != 0)
                    {
                        getMethodComboBox.Items.Add(DeviceCapabilityUsageMode.GetDefault);
                    }
                }

                if (deviceCapabilityValue != null)
                {
                    //
                    containerTypeTextBox.Text = deviceCapabilityValue.ContainerType.ToString();
                    valueTypeTextBox.Text     = deviceCapability.ValueType.ToString();

                    //
                    switch (deviceCapabilityValue.ContainerType)
                    {
                    case TwainValueContainerType.OneValue:
                        TwainOneValueContainer oneDeviceCapabilityValue = (TwainOneValueContainer)deviceCapabilityValue;
                        AddCapOneCurrentValueToForm(oneDeviceCapabilityValue);
                        break;

                    case TwainValueContainerType.Range:
                        TwainRangeValueContainer rangeDeviceCapabilityValue = (TwainRangeValueContainer)deviceCapabilityValue;
                        AddCapRangeCurrentValueToForm(rangeDeviceCapabilityValue);
                        AddCapRangeDefaultValueToForm(rangeDeviceCapabilityValue);
                        AddCapMinValueToForm(rangeDeviceCapabilityValue);
                        AddCapMaxValueToForm(rangeDeviceCapabilityValue);
                        AddCapStepSizeToForm(rangeDeviceCapabilityValue);
                        break;

                    case TwainValueContainerType.Enum:
                        TwainEnumValueContainer enumDeviceCapabilityValue = (TwainEnumValueContainer)deviceCapabilityValue;
                        AddCapEnumCurrentValueToForm(enumDeviceCapabilityValue);
                        AddCapEnumDefaultValueToForm(enumDeviceCapabilityValue);
                        AddCapValuesToForm(enumDeviceCapabilityValue);
                        break;

                    case TwainValueContainerType.Array:
                        TwainArrayValueContainer arrayDeviceCapabilityValue = (TwainArrayValueContainer)deviceCapabilityValue;
                        AddCapValuesToForm(arrayDeviceCapabilityValue);
                        break;
                    }
                }
            }
            catch (TwainDeviceCapabilityException ex)
            {
                currentValueTextBox.Text = ex.Message;
            }
        }