public static void ParseTextForDevices(List<string> text, List<Device> devices)
        {
            bool inDevices = false;
            int relativeIndex = 0;
            
            foreach (string line in text)
            {
                if (Regex.Match(line, DevicesFooterPattern).Success)
                {
                    inDevices = false;
                }

                if (inDevices)
                {
                    Match match = Regex.Match(line, DeviceFullPattern);
                    if (match.Success)
                    {
                        Device device = new Device();

                        device.Name = match.Groups[1].Value.Trim();

                        string value = match.Groups[2].Value.TrimEnd();
                        Dictionary<string, string> details =
                            value.Split(';')
                                .Select(x => x.Split('='))
                                .ToDictionary(y => y[0].Trim(), y => y[1].Trim());

                        device.Driver = details["driver"];
                        device.ProcessorCount = int.Parse(details["procs"]);
                        if (details.ContainsKey("path"))
                            device.Path = details["path"];
                        if (details.ContainsKey("serial"))
                            device.Serial = details["serial"];

                        device.Kind = device.Driver.Equals("opencl") ? DeviceKind.GPU :
                            device.Driver.Equals("cpu") ? DeviceKind.CPU : DeviceKind.USB;

                        if ((devices.Count > 0) && (devices.Last()).Kind != device.Kind)
                            //relativeIndex is relative to device Kind
                            relativeIndex = 0;

                        device.RelativeIndex = relativeIndex;

                        devices.Add(device);

                        relativeIndex++;
                    }
                }

                if (Regex.Match(line, DevicesHeaderPattern).Success)
                {
                    inDevices = true;
                }
            }
        }
        private static void ParseTextForUsbDevices(List<string> text, List<Device> devices)
        {
            bool inUsbList = false;

            string currentUsbManufacturer = string.Empty;
            string currentUsbProduct = string.Empty;

            foreach (string line in text)
            {
                if (Regex.Match(line, UsbDevicesFooterPattern).Success)
                {
                    inUsbList = false;
                }

                if (inUsbList)
                {
                    Match match = Regex.Match(line, UsbManufacturerPattern);
                    if (match.Success)
                        currentUsbManufacturer = match.Groups[1].Value.TrimEnd();

                    match = Regex.Match(line, UsbProductPattern);
                    if (match.Success)
                    {
                        currentUsbProduct = match.Groups[1].Value.TrimEnd();

                        Device device = new Device();
                        device.Platform.Name = string.Empty;
                        device.Platform.Vendor = currentUsbManufacturer;
                        device.Platform.Version = string.Empty;
                        device.Name = currentUsbProduct;
                        device.Kind = DeviceKind.USB;

                        devices.Add(device);
                    }
                }

                if (Regex.Match(line, UsbDevicesHeaderPattern).Success)
                {
                    inUsbList = true;
                }
            }
        }
        private Coin CoinConfigurationForDevice(Device device)
        {
            //get the actual device configuration, text in the ListViewItem may be unsaved
            Engine.Data.Configuration.Device deviceConfiguration;
            if (MiningEngine.Mining &&
                // if the timing is right, we may be .Mining but not yet have data in miningDeviceConfigurations
                (miningDeviceConfigurations != null))
                deviceConfiguration = miningDeviceConfigurations.SingleOrDefault(dc => dc.Equals(device));
            else
                deviceConfiguration = EngineConfiguration.DeviceConfigurations.SingleOrDefault(dc => dc.Equals(device));

            if (deviceConfiguration == null)
                return null;

            string itemCoinSymbol = deviceConfiguration.CoinSymbol;

            List<Coin> configurations;
            if (MiningEngine.Mining &&
                // if the timing is right, we may be .Mining but not yet have data in miningCoinConfigurations
                (miningCoinConfigurations != null))
                configurations = miningCoinConfigurations;
            else
                configurations = EngineConfiguration.CoinConfigurations;

            Coin coinConfiguration = configurations.SingleOrDefault(c => c.PoolGroup.Id.Equals(itemCoinSymbol, StringComparison.OrdinalIgnoreCase));
            return coinConfiguration;
        }
        private string GetFriendlyDeviceName(Device device)
        {
            string result = device.Name;

            DeviceViewModel deviceViewModel = LocalViewModel.Devices.SingleOrDefault(d => d.Equals(device));
            if ((deviceViewModel != null) && !String.IsNullOrEmpty(deviceViewModel.FriendlyName))
                result = deviceViewModel.FriendlyName;

            return result;
        }
        private static void ParseTextForGpuDevices(List<string> text, List<Device> devices)
        {
            bool inPlatform = false;

            string currentPlatformVendor = string.Empty;
            string currentPlatformName = string.Empty;
            string currentPlatformVersion = string.Empty;
            string currentDeviceName = string.Empty;
            string currentDeviceDescription = string.Empty;

            List<string> names = new List<string>();
            List<string> descriptions = new List<string>();

            foreach (string line in text)
            {
                Match match = Regex.Match(line, PlatformVendorPattern);
                if (match.Success)
                    currentPlatformVendor = match.Groups[1].Value.TrimEnd();

                match = Regex.Match(line, PlatformNamePattern);
                if (match.Success)
                    currentPlatformName = match.Groups[1].Value.TrimEnd();

                match = Regex.Match(line, PlatformVersionPattern);
                if (match.Success)
                    currentPlatformVersion = match.Groups[1].Value.TrimEnd();
                
                if (Regex.Match(line, PlatformDevicesFooterPattern).Success)
                {
                    for (int i = 0; i < names.Count; i++)
                    {
                        Device device = new Device();
                        device.Platform.Name = currentPlatformName;
                        device.Platform.Vendor = currentPlatformVendor;
                        device.Platform.Version = currentPlatformVersion;

                        device.Name = names[i];

                        device.Kind = DeviceKind.GPU;

                        devices.Add(device);
                    }

                    inPlatform = false;
                    names.Clear();
                    descriptions.Clear();
                }

                if (inPlatform)
                {
                    match = Regex.Match(line, DeviceNamePattern);
                    if (match.Success)
                    {
                        currentDeviceName = match.Groups[1].Value.TrimEnd();
                        names.Add(currentDeviceName);
                    }

                    match = Regex.Match(line, DeviceDescriptionPattern);
                    if (match.Success)
                    {
                        currentDeviceDescription = match.Groups[1].Value.TrimEnd();
                        descriptions.Add(currentDeviceDescription);
                    }

                }

                if (Regex.Match(line, PlatformDevicesHeaderPattern).Success)
                {
                    inPlatform = true;
                    names.Clear();
                    descriptions.Clear();
                }
            }
        }