/// <summary>
        /// Unhide this connection, as well as all down-stream connections on any block
        /// attached to this connection.  This happens when a block is expanded.
        /// Also unhides down-stream comments.
        /// </summary>
        /// <returns>List of blocks to render.</returns>
        public Block[] unhideAll()
        {
            this.setHidden(false);
            // All blocks that need unhiding must be unhidden before any rendering takes
            // place, since rendering requires knowing the dimensions of lower blocks.
            // Also, since rendering a block renders all its parents, we only need to
            // render the leaf nodes.
            var renderList = new JsArray <Block>();

            if (this.type != Core.INPUT_VALUE && this.type != Core.NEXT_STATEMENT)
            {
                // Only spider down.
                return(renderList);
            }
            var block = this.targetBlock();

            if (block != null)
            {
                JsArray <RenderedConnection> connections;
                if (block.isCollapsed())
                {
                    // This block should only be partially revealed since it is collapsed.
                    connections = new JsArray <RenderedConnection>();
                    if (block.outputConnection != null)
                    {
                        connections.Push(block.outputConnection);
                    }
                    if (block.nextConnection != null)
                    {
                        connections.Push(block.nextConnection);
                    }
                    if (block.previousConnection != null)
                    {
                        connections.Push(block.previousConnection);
                    }
                }
                else
                {
                    // Show all connections of this block.
                    connections = block.getConnections_(true);
                }
                for (var i = 0; i < connections.Length; i++)
                {
                    renderList.PushRange(connections[i].unhideAll());
                }
                if (renderList.Length == 0)
                {
                    // Leaf block.
                    renderList[0] = block;
                }
            }
            return(renderList);
        }
        /// <summary>
        /// Returns all CSS class names applicable to the given control, based on its
        /// state.  The return value is an array of strings containing
        /// <ol>
        ///   <li>the renderer-specific CSS class returned by {@link #getCssClass},
        ///       followed by
        ///   <li>the structural CSS class returned by {@link getStructuralCssClass} (if
        ///       different from the renderer-specific CSS class), followed by
        ///   <li>any state-specific classes returned by {@link #getClassNamesForState},
        ///       followed by
        ///   <li>any extra classes returned by the control's {@code getExtraClassNames}
        ///       method and
        ///   <li>for IE6 and lower, additional combined classes from
        ///       {@link getAppliedCombinedClassNames_}.
        /// </ol>
        /// Since all controls have at least one renderer-specific CSS class name, this
        /// method is guaranteed to return an array of at least one element.
        /// </summary>
        /// <param name="control">Control whose CSS classes are to be
        /// returned.</param>
        /// <returns>Array of CSS class names applicable to the control.</returns>
        protected JsArray <string> getClassNames(Control control)
        {
            var cssClass = this.getCssClass();

            // Start with the renderer-specific class name.
            var classNames = new JsArray <string> {
                cssClass
            };

            // Add structural class name, if different.
            var structuralCssClass = this.getStructuralCssClass();

            if (structuralCssClass != cssClass)
            {
                classNames.Push(structuralCssClass);
            }

            // Add state-specific class names, if any.
            var classNamesForState = this.getClassNamesForState(control.getState());

            classNames.PushRange(classNamesForState);

            // Add extra class names, if any.
            var extraClassNames = control.getExtraClassNames();

            if (extraClassNames != null)
            {
                classNames.PushRange(extraClassNames);
            }

            // Add composite classes for IE6 support
            if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("7"))
            {
                classNames.PushRange(
                    this.getAppliedCombinedClassNames_(classNames));
            }

            return(classNames);
        }