/// <summary>
        /// Creates a new <see cref="Controller"/> instance.
        /// </summary>
        /// <param name="tagController">The tag controller used by the created controller.</param>
        /// <param name="controllerTag">The tag, the new controller is dependend on.</param>
        /// <param name="userDefinedInterfaces">User defined interfaces</param>
        /// <param name="tagListener">A tag listener instance</param>
        /// <returns>A new <see cref="Controller"/> instance.</returns>
        public Controller Create(
            ITagController tagController,
            IControllerTag controllerTag,
            IList <string> userDefinedInterfaces,
            ITagListener tagListener)
        {
            var controller = Create(tagController, controllerTag, tagListener);

            if (userDefinedInterfaces != null)
            {
                tagListener.AddUdtHandler <Command>(CmdList.PlcArrayDataType());

                foreach (var userDefinedInterface in userDefinedInterfaces.Where(value => !string.IsNullOrWhiteSpace(value)))
                {
                    var path = TagName.SpecificInterface(parent: null).AppendTagName(userDefinedInterface);

                    var userDefinedInterfaceTags = ChildTagsFromPath(controllerTag, path);
                    controller.AddUserDefinedInterface(path, userDefinedInterfaceTags);

                    // create the commands
                    foreach (var userDefinedInterfaceTag in userDefinedInterfaceTags)
                    {
                        var commands = CreateCommands(controllerTag, controller, userDefinedInterfaceTag, tagListener);
                        controller.UpdateUserDefinedCommands(userDefinedInterfaceTag.NestedName, commands.ToList());
                    }
                }
            }

            return(controller);
        }
        /// <summary>
        /// Creates a new <see cref="Controller"/> instance.
        /// </summary>
        /// <param name="tagController">The tag controller used by the created controller.</param>
        /// <param name="controllerTag">The tag, the new controller is dependend on.</param>
        /// <param name="tagListener">A tag listener instance.</param>
        /// <returns>A new <see cref="Controller"/> instance.</returns>
        public Controller Create(ITagController tagController, IControllerTag controllerTag, ITagListener tagListener)
        {
            Controller controller = CreateControllerInstance(tagController, controllerTag);
            IEnumerable <Impl.Command> commands = CreateCommands(controllerTag, controller);

            controller.UpdateCommands(commands);
            controller.AddCommonInterfaceTags(CommonInterfaceTagsFrom(controllerTag));
            controller.AddParameters(ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).Parameters()));
            controller.AddActualValues(ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).ActualValues()));
            controller.AddConfigurations(ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).Configurations()));
            controller.AddOutputs(ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).Outputs()));
            controller.AddInputs(ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).Inputs()));
            controller.AddPossibleAlarms(ReadPossibleAlarms(controllerTag, tagListener));

            return(controller);
        }
        private IEnumerable <PossibleAlarm> ReadPossibleAlarms(IControllerTag controllerTag, ITagListener tagListener)
        {
            // TODO: we assume that the order is right here (ToArray) but the interface should be changed from IEnumerable to IList
            Tag[] alarmTags = ChildTagsFromPath(controllerTag, TagName.SpecificInterface(parent: null).Alarms()).ToArray();

            var alarms = new Collection <PossibleAlarm>();

            for (int i = 0; i < alarmTags.Count(); i++)
            {
                var alarmTag = alarmTags[i];

                var alarm = new PossibleAlarm();

                var almText = alarmTag.Childs.First(c => c.NestedName == "strText");
                tagListener.ReadTagSynchronously(almText);
                alarm.Text = (string)almText.Value;

                if (string.IsNullOrEmpty(alarm.Text))
                {
                    continue;
                }

                var almType = alarmTag.Childs.First(c => c.NestedName == "eAlmClass");
                tagListener.ReadTagSynchronously(almType);
                alarm.AlarmType = (short)almType.Value;

                alarm.FullControllerPath = controllerTag.GetScopedPath();

                Tag machineNumberTag = new Tag(NamingConventions.PathMachineNumber, NamingConventions.Global, "UDINT");
                tagListener.ReadTagSynchronously(machineNumberTag);

                // Alarm-ID calculation, see FB_Alm_Man.setAlarm
                // InAlmElement.udiNr := 100000*InAlmElement.udiMachineNr + INT_TO_UDINT(100*InAlmElement.intCtrlId) + InAlmElement.udiAlarmNr;
                var alarmId = 100000 * (uint)machineNumberTag.Value + 100 * controllerTag.GetControllerId() + i;
                alarm.AlarmId = (uint)alarmId;

                alarms.Add(alarm);
            }

            return(alarms);
        }