/// <summary>
        /// Figure out the group(s) this item belongs in
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private IEnumerable <DashboardGroupViewModel> GetTargetGroups(ElementStateViewModel item)
        {
            IEnumerable <DashboardGroupViewModel> targets = null;

            if (!string.IsNullOrEmpty(item.Group))
            {
                targets = _groups.Where(g => g.Id == item.Group);
            }

            if (targets == null || !targets.Any())
            {
                targets = _defaultGroups;
            }

            return(targets);
        }
        /// <summary>
        /// Add item to a group (or groups)
        /// </summary>
        /// <param name="item"></param>
        private void AssignGroup(ElementStateViewModel item)
        {
            var targetGroups = GetTargetGroups(item);

            // Remove from any groups this item already exists in (excluding the 'target' groups)
            foreach (var group in _groups.Where(g => !targetGroups.Contains(g) && g.ElementStates.Select(i => i.Id).Contains(item.Id)))
            {
                group.ElementStates.Remove(item);
            }

            // Add to target groups
            foreach (var group in targetGroups)
            {
                if (!group.ElementStates.Contains(item))
                {
                    group.ElementStates.Add(item);
                }
            }
        }
        /// <summary>
        /// Update / Add DashItems based on source. Optionally remove those not in the list.
        /// </summary>
        private void Update(IEnumerable <ElementState> source, bool isFullRefresh = false)
        {
            foreach (var elementState in source)
            {
                var definition = GetElementDefinition(elementState.ElementId);

                // @todo: Having multiple test definitions with same test id on same dash breaks this
                var item = _groups.SelectMany(g => g.ElementStates).Where(d => d.Id == elementState.Id).Distinct().SingleOrDefault();
                if (item == null)
                {
                    IEnumerable <Map> metaData = null;
                    var test = _dashboard.Tests?.SingleOrDefault(t => t.Id == elementState.Id);
                    if (test == null)
                    {
                        metaData = _dashboard.Mapping;
                    }
                    else
                    {
                        metaData = test.Mapping;
                    }
                    item = new ElementStateViewModel(_dashboard, definition, elementState.Id);
                }

                item.Update(elementState);

                AssignGroup(item);
            }

            if (isFullRefresh)
            {
                // Remove any DashItems that do not appear in source
                foreach (var id in _groups.SelectMany(g => g.ElementStates).Where(i => !source.Select(s => s.Id).Contains(i.Id)).Select(x => x.Id).ToArray())
                {
                    foreach (var group in _groups)
                    {
                        group.ElementStates.Remove(group.ElementStates.SingleOrDefault(i => i.Id == id));
                    }
                }
            }

            LastUpdate = DateTime.Now;
        }