public static Task <IList <NodeInstance> > ConvertToNodeInstances(INodeTemplateFactory factory, EtsProject project, NodeInstance knxInterface)
        {
            IList <NodeInstance> nodes = new List <NodeInstance>();

            if (project.GroupAddressStyle != GroupAddressStyle.ThreeLevel)
            {
                throw new NotImplementedException();
            }

            var mainGroupItems = knxInterface.InverseThis2ParentNodeInstanceNavigation;

            foreach (var item in project.Children)
            {
                var mainAddress = ((EtsGroup)item).GroupIndex;

                var mainGroup = FindByAddressProperty(mainAddress, mainGroupItems);
                if (mainGroup == null)
                {
                    mainGroup = factory.CreateNodeInstance(KnxIpDriverFactory.KnxIp3LevelMainAddress);
                    mainGroup.This2ParentNodeInstance = knxInterface.ObjId;
                }

                mainGroup.Name        = item.Name;
                mainGroup.Description = item.Description;
                mainGroup.SetProperty("knx-address", item.GetMainGroup());
                nodes.Add(mainGroup);


                var middleGroupItems = mainGroup.InverseThis2ParentNodeInstanceNavigation;
                foreach (var middle in ((EtsGroup)item).Children)
                {
                    var middleGroup = FindByAddressProperty(((EtsGroup)middle).GroupIndex, middleGroupItems);

                    if (middleGroup == null)
                    {
                        middleGroup = factory.CreateNodeInstance(KnxIpDriverFactory.KnxIp3LevelMiddleAddress);

                        middleGroup.This2ParentNodeInstance = mainGroup.ObjId;
                    }

                    middleGroup.Name        = middle.Name;
                    middleGroup.Description = middle.Description;
                    middleGroup.SetProperty("knx-address", middle.GetMiddleGroup());


                    mainGroup.InverseThis2ParentNodeInstanceNavigation.Add(middleGroup);
                    var dpItems = middleGroup.InverseThis2ParentNodeInstanceNavigation;

                    foreach (var datapoint in ((EtsGroup)middle).Children)
                    {
                        var dp     = (EtsDatapoint)datapoint;
                        var dpNode = FindByAddressProperty(dp.Address, dpItems);

                        if (dpNode == null) // already existing
                        {
                            dpNode = CreateNodeTemplateFromEtsDatapoint(dp, factory);
                            if (dpNode == null) // not supported
                            {
                                continue;
                            }
                            dpNode.This2ParentNodeInstance = middleGroup.ObjId;
                        }
                        middleGroup.InverseThis2ParentNodeInstanceNavigation.Add(dpNode);
                    }
                }
            }

            return(Task.FromResult(nodes));
        }