private void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                logger.Warn("Cancelled before start.");
                return;
            }

            foreach (var person in this.model.Nodes.OfType <Person>())
            {
                var pm = new PartialMatch(person, framework, model);
                pm.MatchFound    += ReportMatchFound;
                pm.MatchNotFound += UnsubscribeFromMatcher;

                pm.StartAsync();
                pm.Wait();

                switch (pm.State)
                {
                case PartialMatchState.MatchFound:
                    return;

                case PartialMatchState.Pending:
                    this.matchers.Add(pm);
                    continue;
                }

                ct.ThrowIfCancellationRequested();
            }
            OnDone(new IPattern[0]);
        }
        private void UnsubscribeFromMatcher(PartialMatch sender)
        {
            sender.MatchFound    -= ReportMatchFound;
            sender.MatchNotFound -= UnsubscribeFromMatcher;

            lock (this)
            {
                this.matchers.Remove(sender);
            }
        }
 private void ReportMatchFound(PartialMatch sender, Pattern match)
 {
     UnsubscribeFromMatcher(sender);
     OnDone(new IPattern[] { match });
 }