public IHttpActionResult Insert([FromBody] CreateScreenVm value)
        {
            var queryBuilder = new FluentQueryBuilder();
            var templates = Enum.GetValues(typeof(TemplateEnum)).Cast<TemplateEnum>().ToList().Select(t => t.ToTemplateVm());

            var matchingTemplate = templates.First(t => t.name == value.screen.template.name);

            var screen = new Screen() { guid = Guid.NewGuid().ToString("N"), name = "New Screen" };
            var template = new Template()
            {
                guid = Guid.NewGuid().ToString("N"),
                name = value.screen.template.name,
                location = matchingTemplate.location
            };

            queryBuilder
                .Create(screen)
                .Create(template)
                .RelateTo(screen, new HasTemplate(), template)
                .RelateTo(StagedDbContext._application, new HasScreen { screenType = value.screen.screenType }, screen)
                
                ;


            foreach (var widget in value.screen.template.widgets)
            {
                var widgetNode = new Widget { guid = Guid.NewGuid().ToString("N"), widgetSchema = widget.widget };

                var propertyNode = new Property() { guid = widget.data.guid };


                queryBuilder
                    .Create(widgetNode)
                    .RelateTo(template, new HasWidget(), widgetNode)
                    .RelateTo(widgetNode, new DisplaysValueFor(), propertyNode)
                    ;

                if (widget.data.next == null || widget.data.next.guid == null) continue;


                if (widget.data.next.next == null || widget.data.next.next.guid == null)
                {
                    var entityPropertyNode = new Property() { guid = widget.data.next.guid };
                    queryBuilder
                        .RelateTo(widgetNode, new ForThisHeaderProperty(), entityPropertyNode);
                }
                else
                {
                    var entityPropertyNode = new Property() { guid = widget.data.next.next.guid };
                    queryBuilder
                        .RelateTo(widgetNode, new ForThisHeaderProperty(), entityPropertyNode);
                }





            }
            

            queryBuilder.Execute(StagedDbContext.Instance.GraphClient.Cypher);

            
            return Ok();
        }
        public IEnumerable<dynamic> GetByFilter([FromUri] EntityDetailsScreenFilter filter)
        {



            var screenEntity = new Entity { guid = filter.entity };
            var screenInstance = new Screen { guid = filter.screen };
            var application = new Application() { guid = ConfigurationManager.AppSettings["application_guid"] };

            var match = string.Format("{0}, {1}",
                  string.Format("{0}", screenEntity.MatchNode("entity")),
                  string.Format("{0}-[hasScreen:HAS_SCREEN]->{1}-[:HAS_TEMPLATE]->(template:Template)-[hasWidget:HAS_WIDGET*]->(widget:Widget)",
                  application.MatchNode(),
                  screenInstance.MatchNode("screen")));

            var optionalMatch = "(widget)-[:DISPLAYS_VALUE_FOR]->(property:Property)";
            var optionalMatch1 = "(widget)<-[:HAS_WIDGET]-(parentWidget:Widget)";
            var optionalMatch4 = "(widget)-[:HAS_ACTION]->(action:WidgetActionCommand)-[:RELATED_ACTION_SCREEN]->(relatedScreen:Screen)";

            var matchEntityProperties = "(property)<-[:HAS_PROPERTY]-(entity)";
            var matchSupportingEntityProperties = "(entity)<-[:FOR_ENTITY]-(property)<-[:HAS_PROPERTY]-(supportingEntity:Entity)";
            var matchEntityPropertiesAudits = "(widget)-[:FOR_THIS_HEADER_PROPERTY]->(headEntityProperty:Property)<-[:HAS_PROPERTY]-(entity)";
            var matchDataPropertiesOfEntityProperties = 
                "(headEntityProperty)-[:FOR_ENTITY]->                                                                                                  (entityPropertyEntity:Entity)-[:HAS_PROPERTY]->(property)<-[:DISPLAYS_VALUE_FOR]-(widget)-[:FOR_THIS_HEADER_PROPERTY]->(headEntityProperty)<-[:HAS_PROPERTY]-(entity)";
            var matchDataPropertiesOfEntityPropertiesOfTheEntitiesWhichAreEntityProperties = 
                "(headEntityProperty)-[:FOR_ENTITY]->(headEntityPropertyEntity:Entity)-[:HAS_PROPERTY]->(subEntityProperty:Property)-[:FOR_ENTITY]->(subEntityPropertyEntity:Entity)-[:HAS_PROPERTY]->(property)<-[:DISPLAYS_VALUE_FOR]-(widget)-[:FOR_THIS_HEADER_PROPERTY]->(headEntityProperty)<-[:HAS_PROPERTY]-(entity)";


            var query = StagedDbContext.Instance.GraphClient.Cypher
                .Match(match)
                .OptionalMatch(optionalMatch)
                .OptionalMatch(optionalMatch1)
                .OptionalMatch(optionalMatch4)
                .OptionalMatch(matchEntityProperties)
                .OptionalMatch(matchSupportingEntityProperties)
                .OptionalMatch(matchEntityPropertiesAudits)
                .OptionalMatch(matchDataPropertiesOfEntityProperties)
                .OptionalMatch(matchDataPropertiesOfEntityPropertiesOfTheEntitiesWhichAreEntityProperties)
                .Return((screen, entity, template, container, hasScreen, property, headEntityProperty, widget, parentWidget, entityPropertyEntity, subEntityProperty, headEntityPropertyEntity, supportingEntity, action, relatedScreen) => new
                {
                    screen = (screen.As<Screen>()),
                    entity = (entity.As<Entity>()),
                    supportingEntity = (supportingEntity.As<Entity>()),
                    template = (template.As<Template>()),

                    hasScreen = (hasScreen.As<HasScreen>()),

                    widget = (widget.As<Widget>()),
                    parentWidget = (parentWidget.As<Widget>()),
                    property = (property.As<Property>()),
                    headEntityProperty = (headEntityProperty.As<Property>()),
                    subEntityProperty = (subEntityProperty.As<Property>()),
                    entityPropertyEntity = entityPropertyEntity.As<Entity>(),
                    headEntityPropertyEntity = headEntityPropertyEntity.As<Entity>(),
                    action = action.As<WidgetActionCommand>(),
                    relatedScreen = (relatedScreen.As<Screen>()),
                });


            var returned = query.Results.GroupBy(x =>
                new
                {
                    screenGuid = x.screen.guid,
                    screenName = x.screen.name,
                    screenType = x.hasScreen.screenType,
                    templateGuid = x.template.guid,
                    templateName = x.template.name,
                    templateLocation = x.template.location,
                }
                )
                .Select(e =>
                new ScreenVm
                {
                    guid = e.Key.screenGuid,
                    name = e.Key.screenName,
                    screenType = e.Key.screenType,
                    template = new EntityDetailsTemplateInstanceVm
                    {
                        name = e.Key.templateName,
                        location = e.Key.templateLocation,
                        guid = e.Key.templateGuid,
                        widgets = e.GroupBy(gw => new
                        {
        
                            widgetGuid = gw.widget.guid,
                            widgetContainer = gw.widget.container,
                            widgetSchema = gw.widget.widgetSchema,
                            parentWidget = gw.parentWidget,
                            relatedScreen = gw.relatedScreen,
                            action = gw.action,
                            property = gw.property,
                            headEntityProperty = gw.headEntityProperty,
                            subEntityProperty = gw.subEntityProperty,
                            entity = gw.entity,
                            supportingEntity = gw.supportingEntity,
                            entityPropertyEntity = gw.entityPropertyEntity,
                            headEntityPropertyEntity = gw.headEntityPropertyEntity,        
                        })
                        .Select(w => new WidgetVm
                        {
                            guid = w.Key.widgetGuid,
                            container = w.Key.widgetContainer,
                            widgetSchema = w.Key.widgetSchema,
                            parentWidgetGuid = w.Key.parentWidget == null ? null : w.Key.parentWidget.guid,
                            action = w.Key.action == null ? null : new WidgetActionCommandVm
                            {
                                guid = w.Key.action.guid,
                                type = w.Key.action.type,
                                relatedScreen = w.Key.relatedScreen == null ? null : new RelatedScreenVm { guid = w.Key.relatedScreen.guid, name = w.Key.relatedScreen.name }
                            },
                            data = w.Key.property == null ? null : new WidgetDataChainCommandVm
                            {
                                type = "entity",
                                guid = w.Key.supportingEntity == null ? w.Key.entity.guid : w.Key.supportingEntity.guid,
                                next = w.Key.entityPropertyEntity == null && w.Key.headEntityPropertyEntity == null ? new WidgetDataChainCommandVm
                                {
                                    type = w.Key.property.dataType == DataTypeEnum.EntityInstance ? "entityProperty" : "dataProperty",
                                    guid = w.Key.property.guid
                                }
                                : w.Key.entityPropertyEntity != null && w.Key.headEntityPropertyEntity == null ? new WidgetDataChainCommandVm
                                {
                                    type = "entityProperty",
                                    guid = w.Key.headEntityProperty.guid,
                                    next = new WidgetDataChainCommandVm
                                    {
                                        type = "dataProperty",
                                        guid = w.Key.property.guid
                                    }
                                }
                                :
                                new WidgetDataChainCommandVm
                                {
                                    type = "entityProperty",
                                    guid = w.Key.headEntityProperty.guid,
                                    next = w.Key.subEntityProperty == null ? new WidgetDataChainCommandVm
                                    {
                                        type = "dataProperty",
                                        guid = w.Key.property.guid
                                    }
                                    : new WidgetDataChainCommandVm
                                    {
                                        type = "entityProperty",
                                        guid = w.Key.subEntityProperty.guid,
                                        next = new WidgetDataChainCommandVm
                                        {
                                            type = "dataProperty",
                                            guid = w.Key.property.guid
                                        }
                                        
                                    }
                                }
                            }
                        }).ToList()
  
                    }

                }

            ).ToList();

            //Aggregate container widgets 
            returned.ForEach(container => container.template.widgets = BuildWidgetTree(container.template.widgets));

            return returned;


        }