Example #1
0
        private SymGraph(TADomain topValue, TADomain bottomValue, bool _)
        {
            this.egraph_id  = egraphIdGenerator++;
            this.const_root = FreshSymbol();

            TermMap = DoubleImmutableMap <SymValue, TFunc, SymValue> .Empty(SymValue.GetUniqueKey);

            MultiEdgeMap = DoubleImmutableMap <SymValue, MultiEdge <TFunc, TADomain>, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey);

            this.abs_map = ImmutableIntKeyMap <SymValue, TADomain> .Empty(SymValue.GetUniqueKey);

            this.forw_map = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey);

            EqualTermsMap = ImmutableIntKeyMap <SymValue, Sequence <SymGraphTerm <TFunc> > > .Empty(SymValue.GetUniqueKey);

            EqualMultiTermsMap = ImmutableIntKeyMap <SymValue, SymGraphTerm <TFunc> > .Empty(SymValue.GetUniqueKey);

            this.BottomPlaceHolder = FreshSymbol();
            this.abs_map           = this.abs_map.Add(this.BottomPlaceHolder, bottomValue);
            this.is_immutable      = false;
            this.history_size      = 1;
            this.Parent            = null;
            this.root_graph        = this;
            Updates = null;
            this.UnderlyingTopValue      = topValue;
            this.underlying_bottom_value = bottomValue;
        }
Example #2
0
        public TADomain this [SymValue symbol]
        {
            get
            {
                symbol = Find(symbol);
                if (this.abs_map.ContainsKey(symbol))
                {
                    return(this.abs_map [symbol]);
                }

                return(this.UnderlyingTopValue);
            }
            set
            {
                SymValue newSym = Find(symbol);
                if (this [symbol].Equals(value))
                {
                    return;
                }
                AddAbstractValueUpdate(newSym);
                if (value.IsTop)
                {
                    this.abs_map = this.abs_map.Remove(newSym);
                }
                else
                {
                    this.abs_map = this.abs_map.Add(newSym, value);
                }
            }
        }
Example #3
0
        public Domain <E, V> EdgeConversion(APC from, APC to, bool isJoinPoint, IImmutableMap <V, LispList <V> > data, Domain <E, V> state)
        {
            if (data == null)
            {
                return(state);
            }
            SetDomain <V> oldNonNulls = state.NonNulls;
            SetDomain <V> nonNulls    = SetDomain <V> .TopValue;

            SetDomain <V> oldNulls = state.Nulls;
            SetDomain <V> nulls    = SetDomain <V> .TopValue;

            foreach (V variable in data.Keys)
            {
                bool nonNullContains = oldNonNulls.Contains(variable);
                bool nullContains    = oldNulls.Contains(variable);

                if (nonNullContains || nullContains)
                {
                    foreach (V anotherVariable in data[variable].AsEnumerable())
                    {
                        if (nonNullContains)
                        {
                            nonNulls = nonNulls.Add(anotherVariable);
                        }
                        if (nullContains)
                        {
                            nulls = nulls.Add(anotherVariable);
                        }
                    }
                }
            }

            return(new Domain <E, V> (nonNulls, nulls));
        }
Example #4
0
 private static bool VisitedBefore(SymValue sv2,
                                   IImmutableSet <SymValue> backwardManifested,
                                   IImmutableMap <SymValue, SymValue> backward,
                                   out SymValue sv1)
 {
     sv1 = backward [sv2];
     return(sv1 != null || backwardManifested.Contains(sv2));
 }
Example #5
0
 public override Expr <TSymbolicValue> Substitute(IImmutableMap <TSymbolicValue, Sequence <TSymbolicValue> > substitutions)
 {
     if (substitutions.ContainsKey(this.Argument))
     {
         return(new IsInstExpr <TSymbolicValue> (substitutions [this.Argument].Head, this.Type));
     }
     return(null);
 }
        bool IImmutableMap <TKey, TValue> .TryAdd(TKey key, TValue value, out IImmutableMap <TKey, TValue> newTreeMap)
        {
            ImmutableTreeMap <TKey, TValue> newMap;
            var result = TryAdd(key, value, out newMap);

            newTreeMap = newMap;
            return(result);
        }
Example #7
0
 public static ChildrenContainer Create(IImmutableMap <string, ChildStats> children)
 {
     if (children.IsEmpty)
     {
         return(EmptyChildrenContainer.Instance);
     }
     return(new NormalChildrenContainer(children));
 }
        bool IImmutableMap <TKey, TValue> .TryRemove(TKey key, out IImmutableMap <TKey, TValue> newMap)
        {
            ImmutableTreeMap <TKey, TValue> newTreeMap;
            var result = TryRemove(key, out newTreeMap);

            newMap = newTreeMap;
            return(result);
        }
Example #9
0
        public override Expr <TSymbolicValue> Substitute(IImmutableMap <TSymbolicValue, LispList <TSymbolicValue> > substitutions)
        {
            if (substitutions.ContainsKey(this.Left) && substitutions.ContainsKey(this.Right))
            {
                return(new BinaryExpr <TSymbolicValue> (substitutions [this.Left].Head, substitutions [this.Right].Head, this.Operator));
            }

            return(null);
        }
Example #10
0
        public override Expr <TSymbolicValue> Substitute(IImmutableMap <TSymbolicValue, LispList <TSymbolicValue> > substitutions)
        {
            if (substitutions.ContainsKey(this.Source))
            {
                return(new UnaryExpr <TSymbolicValue> (substitutions [this.Source].Head, this.Operator, this.Unsigned));
            }

            return(null);
        }
Example #11
0
        public IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > EdgeRenaming(Pair <APC, APC> edge, bool isJoinPoint)
        {
            IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > forwardRenaming;

            if (this.forwardRenamings.TryGetValue(edge, out forwardRenaming))
            {
                return(forwardRenaming);
            }

            IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > renaming = null;
            Domain afterBegin;

            PostStateLookup(edge.Key, out afterBegin);
            if (afterBegin == null || afterBegin.IsBottom)
            {
                return(null);
            }
            Domain beforeEnd;

            PreStateLookup(edge.Value, out beforeEnd);
            if (beforeEnd != null)
            {
                IImmutableMap <SymValue, Sequence <SymValue> > forward;
                if (!TryComputeFromJoinCache(afterBegin, beforeEnd, edge.Value, out forward))
                {
                    IImmutableMap <SymValue, SymValue> backward;
                    if (!afterBegin.LessEqual(beforeEnd, out forward, out backward))
                    {
                        throw new InvalidOperationException("Should never happen");
                    }
                    if (isJoinPoint && forward == null)
                    {
                        forward = afterBegin.GetForwardIdentityMap();
                    }
                }
                if (forward != null)
                {
                    renaming = ImmutableIntKeyMap <SymbolicValue, Sequence <SymbolicValue> > .Empty(SymbolicValue.GetUniqueKey);

                    foreach (SymValue sv in forward.Keys)
                    {
                        Sequence <SymbolicValue> targets = null;
                        foreach (SymValue target in forward[sv].AsEnumerable())
                        {
                            targets = targets.Cons(new SymbolicValue(target));
                        }
                        if (targets != null)
                        {
                            renaming = renaming.Add(new SymbolicValue(sv), targets);
                        }
                    }
                }
            }
            this.forwardRenamings.Add(edge, renaming);
            return(renaming);
        }
Example #12
0
        public bool Contains(A key1, B key2)
        {
            IImmutableMap <B, C> inner = this.map [key1];

            if (inner == null)
            {
                return(false);
            }
            return(inner.ContainsKey(key2));
        }
Example #13
0
 private void DumpMap(IImmutableMap <SymbolicValue, LispList <SymbolicValue> > sourceTargetMap)
 {
     Console.WriteLine("Source-Target assignment");
     foreach (SymbolicValue key in sourceTargetMap.Keys)
     {
         foreach (SymbolicValue value in sourceTargetMap[key].AsEnumerable())
         {
             Console.Write("{0} ", value);
         }
         Console.WriteLine(" := {0}", key);
     }
 }
Example #14
0
 public C this [A key1, B key2]
 {
     get
     {
         IImmutableMap <B, C> inner = this.map [key1];
         if (inner == null)
         {
             return(default(C));
         }
         return(inner [key2]);
     }
 }
Example #15
0
 private static bool GetMinAndMaxByCount(IImmutableMap <K, V> a, IImmutableMap <K, V> b,
                                         out IImmutableMap <K, V> min, out IImmutableMap <K, V> max)
 {
     if (a.Count < b.Count)
     {
         min = a;
         max = b;
         return(true);
     }
     max = a;
     min = b;
     return(false);
 }
Example #16
0
        public bool LessEqual(SymGraph <TFunc, TADomain> that,
                              out IImmutableMap <SymValue, Sequence <SymValue> > forward,
                              out IImmutableMap <SymValue, SymValue> backward)
        {
            if (!IsSameEGraph(that))
            {
                return(InternalLessEqual(this, that, out forward, out backward));
            }

            forward  = null;
            backward = null;
            return(true);
        }
Example #17
0
        public EnvironmentDomain <K, V> Join(EnvironmentDomain <K, V> that, bool widening, out bool weaker)
        {
            weaker = false;
            if (this.map == that.map || IsTop)
            {
                return(this);
            }
            if (that.IsTop)
            {
                weaker = !IsTop;
                return(that);
            }
            if (IsBottom)
            {
                weaker = !that.IsBottom;
                return(that);
            }
            if (that.IsBottom)
            {
                return(this);
            }

            IImmutableMap <K, V> min;
            IImmutableMap <K, V> max;

            GetMinAndMaxByCount(this.map, that.map, out min, out max);

            IImmutableMap <K, V> intersect = min;

            foreach (K key in min.Keys)
            {
                if (!max.ContainsKey(key))
                {
                    intersect = intersect.Remove(key);
                }
                else
                {
                    bool keyWeaker;
                    V    join = min [key].Join(max [key], widening, out keyWeaker);
                    if (keyWeaker)
                    {
                        weaker    = true;
                        intersect = join.IsTop ? intersect.Remove(key) : intersect.Add(key, join);
                    }
                }
            }

            weaker |= intersect.Count < this.map.Count;
            return(new EnvironmentDomain <K, V> (intersect));
        }
Example #18
0
        public int Keys2Count(A key1)
        {
            if (key1 == null)
            {
                return(0);
            }
            IImmutableMap <B, C> inner = this.map [key1];

            if (inner == null)
            {
                return(0);
            }
            return(inner.Count);
        }
Example #19
0
        private IImmutableMap <SymValue, Sequence <SymValue> > GetForwardGraphMap(Func <Tuple <SymValue, SymValue, SymValue>, SymValue> sourceSelector)
        {
            IImmutableMap <SymValue, Sequence <SymValue> > res = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey);

            foreach (var tuple in this.merge_triples.AsEnumerable())
            {
                SymValue sv = sourceSelector(tuple);
                if (sv != null)
                {
                    res = res.Add(sv, res [sv].Cons(tuple.Item3));
                }
            }
            return(res);
        }
Example #20
0
        private static IImmutableMap <SymValue, SymValue> CompleteWithCommon(IImmutableMap <SymValue, SymValue> map,
                                                                             SymGraph <TFunc, TADomain> thisGraph, int lastCommonId)
        {
            IEnumerable <SymValue> symValues = thisGraph.EqualTermsMap.Keys.Concat(thisGraph.EqualMultiTermsMap.Keys);

            foreach (SymValue sv in symValues)
            {
                if (IsCommon(sv, lastCommonId) && !map.ContainsKey(sv))
                {
                    map = map.Add(sv, sv);
                }
            }
            return(map);
        }
Example #21
0
        public IEnumerable <B> Keys2(A key1)
        {
            if (key1 == null)
            {
                return(this.EmptyCache);
            }

            IImmutableMap <B, C> inner = this.map [key1];

            if (inner == null)
            {
                return(this.EmptyCache);
            }
            return(inner.Keys);
        }
Example #22
0
        public DoubleImmutableMap <A, B, C> Remove(A key1, B key2)
        {
            IImmutableMap <B, C> inner = this.map [key1];

            if (inner == null)
            {
                return(this);
            }
            IImmutableMap <B, C> newInner = inner.Remove(key2);

            if (newInner == inner)
            {
                return(this);
            }
            return(new DoubleImmutableMap <A, B, C> (this.map.Add(key1, newInner)));
        }
Example #23
0
 public void Dump(TextWriter tw, string prefix, IImmutableMap <SymValue, Sequence <SymValue> > edgeData)
 {
     if (edgeData == null)
     {
         return;
     }
     edgeData.Visit((key, targets) => {
         tw.Write("  {0} -> ", key);
         foreach (var target in targets.AsEnumerable())
         {
             tw.Write("{0} ", target);
         }
         tw.WriteLine();
         return(VisitStatus.ContinueVisit);
     });
 }
Example #24
0
        protected IntervalEnvironmentBase <TVar, TExpr, TInterval, TNumeric> AssumeConstraints
            (IImmutableMap <TVar, Sequence <TInterval> > constraints,
            IntervalEnvironmentBase <TVar, TExpr, TInterval, TNumeric> env)
        {
            var res = env;

            foreach (var v in constraints.Keys)
            {
                var seq = constraints[v];
                foreach (var intv in seq.AsEnumerable())
                {
                    res = res.RefineVariable(v, intv);
                }
            }

            return(res);
        }
Example #25
0
        public EnvironmentDomain <K, V> Meet(EnvironmentDomain <K, V> that)
        {
            if (this.map == that.map)
            {
                return(this);
            }
            if (IsTop)
            {
                return(that);
            }
            if (that.IsTop || IsBottom)
            {
                return(this);
            }
            if (that.IsBottom)
            {
                return(that);
            }

            IImmutableMap <K, V> min;
            IImmutableMap <K, V> max;

            GetMinAndMaxByCount(this.map, that.map, out min, out max);

            IImmutableMap <K, V> union = max;

            foreach (K key in min.Keys)
            {
                if (!max.ContainsKey(key))
                {
                    union = union.Add(key, min [key]);
                }
                else
                {
                    V meet = min [key].Meet(max [key]);
                    union = union.Add(key, meet);
                }
            }

            return(new EnvironmentDomain <K, V> (union));
        }
Example #26
0
        private SymGraph(SymGraph <TFunc, TADomain> from)
        {
            this.egraph_id         = egraphIdGenerator++;
            this.const_root        = from.const_root;
            this.BottomPlaceHolder = from.BottomPlaceHolder;
            TermMap                      = from.TermMap;
            MultiEdgeMap                 = from.MultiEdgeMap;
            IdGenerator                  = from.IdGenerator;
            this.abs_map                 = from.abs_map;
            this.forw_map                = from.forw_map;
            EqualTermsMap                = from.EqualTermsMap;
            EqualMultiTermsMap           = from.EqualMultiTermsMap;
            this.UnderlyingTopValue      = from.UnderlyingTopValue;
            this.underlying_bottom_value = from.underlying_bottom_value;
            Updates                      = from.Updates;
            this.Parent                  = from;
            this.root_graph              = from.root_graph;
            this.history_size            = from.history_size + 1;

            from.MarkAsImmutable();
        }
Example #27
0
        private void DrainEqualityWorkList(WorkList <EqualityPair <TFunc, TADomain> > workList)
        {
            while (!workList.IsEmpty())
            {
                EqualityPair <TFunc, TADomain> equalityPair = workList.Pull();
                SymValue sv1 = Find(equalityPair.Sv1);
                SymValue sv2 = Find(equalityPair.Sv2);
                if (sv1 != sv2)
                {
                    if (sv1.UniqueId < sv2.UniqueId)
                    {
                        SymValue tmp = sv1;
                        sv1 = sv2;
                        sv2 = tmp;
                    }

                    foreach (TFunc function in Functions(sv1))
                    {
                        SymValue v2 = LookupWithoutManifesting(sv2, function);
                        if (v2 == null)
                        {
                            this [sv2, function] = this [sv1, function];
                        }
                        else
                        {
                            TryPushEquality(workList, this [sv1, function], v2);
                        }
                    }
                    TADomain thisValue = this [sv1];
                    TADomain thatValue = this [sv2];
                    foreach (var elem in EqualTermsMap[sv1].AsEnumerable())
                    {
                        EqualTermsMap = EqualTermsMap.Add(sv2, EqualTermsMap [sv2].Cons(elem));
                    }

                    this.forw_map = this.forw_map.Add(sv1, sv2);
                    this [sv2]    = thisValue.Meet(thatValue);
                }
            }
        }
Example #28
0
 private EnvironmentDomain(IImmutableMap <K, V> map)
 {
     this.map = map;
 }
 private NormalChildrenContainer(IImmutableMap<string, IChildStats> children)
     : base(children)
 {
 }
 public static IChildrenContainer Create(IImmutableMap<string, IChildStats> children)
 {
     if (children.IsEmpty) return EmptyChildrenContainer.Instance;
     return new NormalChildrenContainer(children);
 }
Example #31
0
        private static bool InternalLessEqual(SymGraph <TFunc, TADomain> thisG, SymGraph <TFunc, TADomain> thatG,
                                              out IImmutableMap <SymValue, Sequence <SymValue> > forward,
                                              out IImmutableMap <SymValue, SymValue> backward)
        {
            int updateSize;
            SymGraph <TFunc, TADomain> commonTail = ComputeCommonTail(thisG, thatG, out updateSize);

            if (thisG.IsImmutable)
            {
                thisG = thisG.Clone();
            }

            var workList = new WorkList <EqualityPair <TFunc, TADomain> > ();

            workList.Add(new EqualityPair <TFunc, TADomain> (thisG.const_root, thatG.const_root));
            IImmutableSet <SymValue> backwardManifested = ImmutableSet <SymValue> .Empty(SymValue.GetUniqueKey);

            IImmutableMap <SymValue, SymValue> backwardMap = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey);

            IImmutableMap <SymValue, Sequence <SymValue> > forwardMap = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey);

            IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey);

            while (!workList.IsEmpty())
            {
                EqualityPair <TFunc, TADomain> equalityPair = workList.Pull();
                SymValue sv1 = equalityPair.Sv1;
                SymValue sv2 = equalityPair.Sv2;

                SymValue s;
                if (VisitedBefore(sv2, backwardManifested, backwardMap, out s))
                {
                    if (s != null && s == sv1)
                    {
                        continue;
                    }

                    if (DebugOptions.Debug)
                    {
                        Console.WriteLine("---LessEqual fails due to pre-existing relation: {0} <- {1}", s, sv2);
                    }
                    forward  = null;
                    backward = null;
                    return(false);
                }

                TADomain val1 = sv1 == null?thisG.UnderlyingTopValue.ForManifestedField() : thisG [sv1];

                TADomain val2 = thatG [sv2];
                if (!val1.LessEqual(val2))
                {
                    if (DebugOptions.Debug)
                    {
                        Console.WriteLine("---LessEqual fails due to abstract values: !({0} <= {1})", val1, val2);
                    }
                    forward  = null;
                    backward = null;
                    return(false);
                }
                if (sv1 != null)
                {
                    backwardMap = backwardMap.Add(sv2, sv1);
                    forwardMap  = forwardMap.Add(sv1, forwardMap [sv1].Cons(sv2));
                }
                else
                {
                    backwardManifested = backwardManifested.Add(sv2);
                }
                if (thisG.HasAllBottomFields(sv1))
                {
                    continue;
                }
                if (thatG.HasAllBottomFields(sv2))
                {
                    if (DebugOptions.Debug)
                    {
                        Console.WriteLine("---LessEqual fails due to bottom field difference");
                    }
                    forward  = null;
                    backward = null;
                    return(false);
                }

                foreach (TFunc function in thatG.Functions(sv2))
                {
                    SymValue v1 = thisG [function, sv1];
                    SymValue v2 = thatG [function, sv2];
                    if (DebugOptions.Debug)
                    {
                        Console.WriteLine("    {0}-{1}->{2} <=? {3}-{4}->{5}", sv1, function, v1, sv2, function, v2);
                    }
                    workList.Add(new EqualityPair <TFunc, TADomain> (v1, v2));
                }

                foreach (var e in thatG.MultiEdges(sv2))
                {
                    foreach (SymValue sv in thatG.MultiEdgeMap[sv2, e].AsEnumerable())
                    {
                        if (!UpdateTrigger(sv, e, ref triggers))
                        {
                            continue;
                        }

                        SymGraphTerm <TFunc> term = thatG.EqualMultiTermsMap [sv];
                        var args = new SymValue[term.Args.Length];
                        for (int i = 0; i < args.Length; i++)
                        {
                            args [i] = backwardMap [term.Args [i]];
                        }

                        SymValue v1 = thisG.LookupWithoutManifesting(args, e.Function);
                        if (v1 == null)
                        {
                            if (DebugOptions.Debug)
                            {
                                Console.WriteLine("---LessEqual fails due to missing multi term {0}({1})",
                                                  e.Function,
                                                  string.Join(", ", term.Args.Select(it => it.ToString())));
                            }
                            forward  = null;
                            backward = null;
                            return(false);
                        }

                        workList.Add(new EqualityPair <TFunc, TADomain> (v1, sv));
                    }
                }
            }
            forward  = forwardMap;
            backward = CompleteWithCommon(backwardMap, thisG, commonTail.IdGenerator);
            return(true);
        }
 public TerminatingChildrenContainer(IImmutableMap<string, IChildStats> children, IActorRef toDie, SuspendReason reason)
     : this(children, ImmutableTreeSet<IActorRef>.Create(toDie), reason)
 {
     //Intentionally left blank
 }
 public TerminatingChildrenContainer(IImmutableMap<string, IChildStats> children, IImmutableSet<IActorRef> toDie, SuspendReason reason)
     : base(children)
 {
     _toDie = toDie;
     _reason = reason;
 }
Example #34
0
        public void Dump(TextWriter tw)
        {
            var set      = new HashSet <SymValue> ();
            var workList = new WorkList <SymValue> ();
            IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey);

            tw.WriteLine("EGraphId: {0}", this.egraph_id);
            tw.WriteLine("LastSymbolId: {0}", LastSymbolId);

            foreach (TFunc function in TermMap.Keys2(this.const_root))
            {
                SymValue sv = this [this.const_root, function];
                tw.WriteLine("{0} = {1}", function, sv);
                workList.Add(sv);
            }

            while (!workList.IsEmpty())
            {
                SymValue sv = workList.Pull();
                if (!set.Add(sv))
                {
                    continue;
                }

                foreach (TFunc function in TermMap.Keys2(sv))
                {
                    SymValue target = this [sv, function];

                    tw.WriteLine("{0}({2}) = {1})", function, target, sv);
                    workList.Add(target);
                }
                foreach (var edge in MultiEdgeMap.Keys2(sv))
                {
                    foreach (SymValue target in MultiEdgeMap[sv, edge].AsEnumerable())
                    {
                        if (!UpdateTrigger(target, edge, ref triggers))
                        {
                            continue;
                        }
                        SymGraphTerm <TFunc> term = EqualMultiTermsMap [target];
                        if (term.Args != null)
                        {
                            tw.WriteLine("{0}({1}) = {2}",
                                         term.Function,
                                         term.Args.ToString(", "), target);
                            workList.Add(target);
                        }
                    }
                }
            }

            tw.WriteLine("**Abstract value map");
            foreach (SymValue sv in set)
            {
                TADomain abstractValue = this [sv];
                if (!abstractValue.IsTop)
                {
                    tw.WriteLine("{0} -> {1}", sv, abstractValue);
                }
            }
        }
Example #35
0
        public HubConnection(IUntypedActorContext parentContext)
        {
            _parentContext = parentContext;
            
            Receive<Tcp.Received>(received =>
            {
                var messages = MessageSeriliazer.Deserialize(Context.System, received.Data);
                messages.ForEach(Self.Forward);
            });

            Receive<Tcp.ConnectionClosed>(closed =>
            {
                _log.Info($"Client connection {Self.Path.Name} was closed. Reason: {closed.GetErrorCause()}");

                foreach (var hubPair in _hubs.AllMinToMax)
                {
                    var name = hubPair.Key;
                    var hub = hubPair.Value;

                    hub.Forward(new Signal.Leave(name));
                }

                Context.Stop(Self);
            });

            Receive<Signal.Join>(join =>
            {
                if (_hubs.Contains(join.HubName))
                    return;

                var hub = _parentContext.Child(join.HubName);
                if (hub.IsNobody())
                {
                    Sender.Tell(WriteObject(new Signal.NotFound(join.HubName)));
                    return;
                }

                _hubs = _hubs.Add(join.HubName, hub);
                hub.Forward(join);
            });

            Receive<Signal.Leave>(leave =>
            {
                if (!_hubs.Contains(leave.HubName))
                    return;

                var hub = _parentContext.Child(leave.HubName);
                if (hub.IsNobody())
                {
                    Sender.Tell(WriteObject(new Signal.NotFound(leave.HubName)));
                    return;
                }

               _hubs = _hubs.Remove(leave.HubName);
                hub.Forward(leave);
            });

            Receive<Signal.Broadcast>(broadcast =>
            {
                var hub = _parentContext.Child(broadcast.HubName);
                if (hub.IsNobody())
                {
                    Sender.Tell(WriteObject(new Signal.NotFound(broadcast.HubName)));
                    return;
                }

                hub.Forward(broadcast);
            });
        }
 protected ChildrenContainerBase(IImmutableMap<string, ChildStats> children)
 {
     _children = children;
 }