/// <summary>
    /// Places the control in search mode.
    /// </summary>
    private void EnterSearchMode()
    {
        _inSearchMode = true;

        BeginUpdate();

        _normalSelectedNode = SelectedNode;

        // copy normal nodes
        _normalNodes.Clear();
        _normalNodes.AddRange(Nodes);

        // clear and make way for search results
        Nodes.Clear();
        SelectedNode = null;

        EndUpdate();

        DropDownControl.ProcessKeys = false;
        Cursor = Cursors.IBeam;
    }
    void _services_TextChanged(object sender, EventArgs e)
    {
        // cancel any existing search operation
        if (_cts != null)
        {
            _cts.Cancel();
            _cts.Dispose();
            _cts = null;
        }

        if (_services.Length > 0)
        {
            if (!_inSearchMode)
            {
                EnterSearchMode();
            }

            if (_services.Length >= MinSearchTermLength)
            {
                // start async search operation
                BeginUpdate();
                Nodes.Clear();
                Nodes.Add(new ComboTreeNode("Searching...")
                {
                    Selectable = false, FontStyle = FontStyle.Italic
                });
                EndUpdate();

                _cts = new CancellationTokenSource();
                ComboTreeNodeCollection results = new ComboTreeNodeCollection(null);

                var task = Task.Factory.StartNew(() => OnPerformSearch(new PerformSearchEventArgs(_services.Text, _cts.Token, results)), _cts.Token);

                task.ContinueWith(t => {
                    if (t.IsFaulted)
                    {
                        results.Clear();
                        string errorText = t.Exception.InnerExceptions.Select(x => x.Message).FirstOrDefault() ?? "an error occured";
                        results.Add(new ComboTreeNode(String.Format("({0})", errorText))
                        {
                            Selectable = false, FontStyle = FontStyle.Italic
                        });
                    }

                    if (!t.IsCanceled)
                    {
                        ApplySearchResults(results);
                    }
                });
            }
            else
            {
                // wait until the search term is long enough
                BeginUpdate();
                Nodes.Clear();
                string msg = String.Format("(type at least {0} characters)", MinSearchTermLength);
                Nodes.Add(new ComboTreeNode(msg)
                {
                    Selectable = false, FontStyle = FontStyle.Italic
                });
                EndUpdate();
            }
        }
        else
        {
            if (_inSearchMode)
            {
                LeaveSearchMode(false);
            }
        }
    }