void AddDevice(devType parentInnerDevice, Device parentDevice, DeviceConfiguration deviceConfiguration, Firesec.Models.CoreConfiguration.config coreConfig)
		{
			if (parentInnerDevice.dev == null)
				return;

			parentDevice.Children = new List<Device>();
			foreach (var innerDevice in parentInnerDevice.dev)
			{
                var device = SetInnerDevice(innerDevice, parentDevice, deviceConfiguration, coreConfig);
				if (device != null)
				{
					parentDevice.Children.Add(device);
					deviceConfiguration.Devices.Add(device);
                    AddDevice(innerDevice, device, deviceConfiguration, coreConfig);
				}
			}
		}
        Device SetInnerDevice(devType innerDevice, Device parentDevice, DeviceConfiguration deviceConfiguration, Firesec.Models.CoreConfiguration.config coreConfig)
		{
			var device = new Device()
			{
				Parent = parentDevice
			};
            var drvType = coreConfig.drv.FirstOrDefault(x => x.idx == innerDevice.drv);
            if(drvType == null)
            {
                Logger.Error("ConfigurationConverter.SetInnerDevice drvType = null " + innerDevice.drv.ToString());
                LoadingErrorManager.Add("Ошибка сопоставления при конвертации конфигурации");
                return null;
            }
			var driverUID = new Guid(drvType.id);
			device.DriverUID = driverUID;
			device.Driver = ConfigurationCash.DriversConfiguration.Drivers.FirstOrDefault(x => x.UID == driverUID);
			if (device.Driver == null)
			{
				Logger.Error("ConvertDevices.SetInnerDevice driver = null " + driverUID.ToString());
                LoadingErrorManager.Add("Неизвестный драйвер устройства " + driverUID.ToString());
				return null;
			}

			device.IntAddress = int.Parse(innerDevice.addr);
			if ((device.Parent != null) && (device.Parent.Driver.IsChildAddressReservedRange))
				device.IntAddress += device.Parent.IntAddress;

			if ((innerDevice.disabled != null) && (innerDevice.disabled == "1"))
				device.IsMonitoringDisabled = true;

			if (innerDevice.param != null)
			{
				var DatabaseIdParam = innerDevice.param.FirstOrDefault(x => x.name == "DB$IDDevices");
				if (DatabaseIdParam != null)
					device.DatabaseId = DatabaseIdParam.value;

				var UIDParam = innerDevice.param.FirstOrDefault(x => x.name == "INT$DEV_GUID");
				if (UIDParam != null)
					device.UID = GuidHelper.ToGuid(UIDParam.value);
				else
					device.UID = Guid.NewGuid();
			}

			if (innerDevice.dev_param != null)
			{
				var AltInterfaceParam = innerDevice.dev_param.FirstOrDefault(x => x.name == "SYS$Alt_Interface");
				if (AltInterfaceParam != null)
					device.IsAltInterface = true;
				else
					device.IsAltInterface = false;
			}

			device.Properties = new List<Property>();
			if (innerDevice.prop != null)
			{
				foreach (var innerProperty in innerDevice.prop)
				{
					if (innerProperty.name == "IsAlarmDevice")
					{
						device.IsRmAlarmDevice = true;
						continue;
					}
					if (innerProperty.name == "NotUsed")
					{
						device.IsNotUsed = true;
						continue;
					}
					device.Properties.Add(new Property()
					{
						Name = innerProperty.name,
						Value = innerProperty.value
					});
				}
			}

			var description = innerDevice.name;
			if (description != null)
				description = description.Replace('¹', '№');
			device.Description = description;
            SetZone(device, innerDevice, deviceConfiguration, coreConfig);

			device.ShapeIds = new List<string>();
			if (innerDevice.shape != null)
			{
				foreach (var shape in innerDevice.shape)
				{
					device.ShapeIds.Add(shape.id);
				}
			}

			device.PlaceInTree = device.GetPlaceInTree();
			return device;
		}
        void AddInnerDevice(Device parentDevice, devType parentInnerDevice, DeviceConfiguration deviceConfiguration, Firesec.Models.CoreConfiguration.config coreConfig)
		{
			var childInnerDevices = new List<devType>();
			foreach (var device in parentDevice.Children)
			{
				var childInnerDevice = DeviceToInnerDevice(device, deviceConfiguration, coreConfig);
				childInnerDevices.Add(childInnerDevice);
                AddInnerDevice(device, childInnerDevice, deviceConfiguration, coreConfig);
			}
			parentInnerDevice.dev = childInnerDevices.ToArray();
		}
        devType DeviceToInnerDevice(Device device, DeviceConfiguration deviceConfiguration, Firesec.Models.CoreConfiguration.config coreConfig)
		{
			var innerDevice = new devType();
			innerDevice.name = device.Description;
			if (innerDevice.name != null)
				innerDevice.name = innerDevice.name.Replace('№', 'N');

			innerDevice.drv = coreConfig.drv.FirstOrDefault(x => x.id.ToUpper() == device.Driver.StringUID).idx;

			var intAddress = device.IntAddress;
			if ((device.Parent != null) && (device.Parent.Driver.IsChildAddressReservedRange))
				intAddress -= device.Parent.IntAddress;

			if (device.Driver.HasAddress)
				innerDevice.addr = intAddress.ToString();
			else
				innerDevice.addr = "0";

			if (device.IsMonitoringDisabled == true)
				innerDevice.disabled = "1";
			else
				innerDevice.disabled = null;

			if (device.ZoneUID != Guid.Empty)
			{
                var zone = deviceConfiguration.Zones.FirstOrDefault(x => x.UID == device.ZoneUID);
                if (zone != null)
                {
                    var zones = new List<inZType>();
                    zones.Add(new inZType() { idz = zone.No.ToString() });
                    innerDevice.inZ = zones.ToArray();
                }
			}

			innerDevice.prop = AddProperties(device).ToArray();
			innerDevice.param = AddParameters(device).ToArray();
			innerDevice.dev_param = AddDevParameters(device).ToArray();
			innerDevice.shape = AddShapes(device).ToArray();

			return innerDevice;
		}
        void SetZone(Device device, devType innerDevice, DeviceConfiguration deviceConfiguration, Firesec.Models.CoreConfiguration.config coreConfig)
		{
            if (innerDevice.inZ != null && innerDevice.inZ.Count() > 0)
			{
				string zoneIdx = innerDevice.inZ[0].idz;
				string zoneNo = coreConfig.zone.FirstOrDefault(x => x.idx == zoneIdx).no;
                int intZoneNo = int.Parse(zoneNo);
                var zone = deviceConfiguration.Zones.FirstOrDefault(x => x.No == intZoneNo);
                if (zone != null)
                {
                    device.ZoneUID = zone.UID;
                }
			}
			if (innerDevice.prop != null)
			{
				var zoneLogicProperty = innerDevice.prop.FirstOrDefault(x => x.name == "ExtendedZoneLogic");
				if (zoneLogicProperty != null)
				{
					string zoneLogicstring = zoneLogicProperty.value;
					if (string.IsNullOrEmpty(zoneLogicstring) == false)
                        device.ZoneLogic = ZoneLogicConverter.Convert(deviceConfiguration, SerializerHelper.GetZoneLogic(zoneLogicstring));
				}

				var indicatorLogicProperty = innerDevice.prop.FirstOrDefault(x => x.name == "C4D7C1BE-02A3-4849-9717-7A3C01C23A24");
				if (indicatorLogicProperty != null)
				{
					string indicatorLogicString = indicatorLogicProperty.value;
					if (string.IsNullOrEmpty(indicatorLogicString) == false)
					{
						var indicatorLogic = SerializerHelper.GetIndicatorLogic(indicatorLogicString);
						if (indicatorLogic != null)
						{
							device.IndicatorLogic = IndicatorLogicConverter.Convert(deviceConfiguration, indicatorLogic);
						}
					}
				}

				var pDUGroupLogicProperty = innerDevice.prop.FirstOrDefault(x => x.name == "E98669E4-F602-4E15-8A64-DF9B6203AFC5");
				if (pDUGroupLogicProperty != null)
				{
					string pDUGroupLogicPropertyString = pDUGroupLogicProperty.value;
					if (string.IsNullOrEmpty(pDUGroupLogicPropertyString) == false)
						device.PDUGroupLogic = PDUGroupLogicConverter.Convert(SerializerHelper.GetGroupProperties(pDUGroupLogicPropertyString));
				}
			}
		}