public void Update(Selection selection, bool fullSnapshot)
        {
            Price = selection.Price;
            Status = selection.Status;
            Tradability = selection.Tradable;

            if (fullSnapshot)
            {
                _tags = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

                foreach (var key in selection.TagKeys)
                    _tags.Add(key, selection.GetTagValue(key));

                Name = selection.Name;

                // Result and PlaceResult (in the context of racing fixtures) 
                // are only present on a full snapshot
                if (selection.Result != null)
                {
                    if (Result == null)
                        Result = new SelectionResultState(selection.Result);
                    else
                        ((IUpdatableSelectionResultState)Result).Update(selection.Result);
                }

                if (selection.PlaceResult != null)
                {
                    if (PlaceResult == null)
                        PlaceResult = new SelectionResultState(selection.PlaceResult);
                    else
                        ((IUpdatableSelectionResultState)PlaceResult).Update(selection.PlaceResult);
                }
            }

            UpdateLineOnRollingSelection(selection);
        }
        public bool IsEquivalentTo(Selection selection, bool checkTags)
        {
            if (selection == null)
                return false;

            if (selection.Id != Id)
                return false;

            if (checkTags)
            {
                if (selection.TagsCount != TagsCount)
                    return false;


                if (selection.TagKeys.Any(tag => !HasTag(tag) || GetTagValue(tag) != selection.GetTagValue(tag)))
                    return false;

                // if we are here, there is no difference between the stored tags
                // and those contained within the selection object...
                // we can then proceed to check the selection's fields
                // Note that Selection.Name is a shortcut for Selection.GetTagValue("name")

                // as Result and PlaceResult are only present when dealing with full snapshots
                // we only check these properties if checkTags is true

                if (selection.Result != null)
                {
                    if (Result == null)
                        return false;

                    if (!Result.IsEquivalentTo(selection.Result))
                        return false;
                }

                if (selection.PlaceResult != null)
                {
                    if (PlaceResult == null)
                        return false;

                    if (!PlaceResult.IsEquivalentTo(selection.PlaceResult))
                        return false;
                }
            }

            var result = Price == selection.Price &&
                         Status == selection.Status &&
                         Tradability == selection.Tradable;

            
            if (IsRollingSelection)
                return result &= Line == ((RollingSelection)selection).Line;

            return result;
        }