/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.VIEW_MERGE;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.INode;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.utils.Pair;

import org.eclipse.swt.graphics.Rectangle;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.RandomAccess;
import java.util.Set;

/**
 * The view hierarchy class manages a set of view info objects and performs find
 * operations on this set.
 */
public class ViewHierarchy {
    private static final boolean DUMP_INFO = false;

    private LayoutCanvas mCanvas;

    /**
     * Constructs a new {@link ViewHierarchy} tied to the given
     * {@link LayoutCanvas}.
     *
     * @param canvas The {@link LayoutCanvas} to create a {@link ViewHierarchy}
     *            for.
     */
    public ViewHierarchy(LayoutCanvas canvas) {
        mCanvas = canvas;
    }

    /**
     * The CanvasViewInfo root created by the last call to {@link #setSession}
     * with a valid layout.
     * <p/>
     * This <em>can</em> be null to indicate we're dealing with an empty document with
     * no root node. Null here does not mean the result was invalid, merely that the XML
     * had no content to display -- we need to treat an empty document as valid so that
     * we can drop new items in it.
     */
    private CanvasViewInfo mLastValidViewInfoRoot;

    /**
     * True when the last {@link #setSession} provided a valid {@link LayoutScene}.
     * <p/>
     * When false this means the canvas is displaying an out-dated result image & bounds and some
     * features should be disabled accordingly such a drag'n'drop.
     * <p/>
     * Note that an empty document (with a null {@link #mLastValidViewInfoRoot}) is considered
     * valid since it is an acceptable drop target.
     */
    private boolean mIsResultValid;

    /**
     * A list of invisible parents (see {@link CanvasViewInfo#isInvisible()} for
     * details) in the current view hierarchy.
     */
    private final List<CanvasViewInfo> mInvisibleParents = new ArrayList<CanvasViewInfo>();

    /**
     * A read-only view of {@link #mInvisibleParents}; note that this is NOT a copy so it
     * reflects updates to the underlying {@link #mInvisibleParents} list.
     */
    private final List<CanvasViewInfo> mInvisibleParentsReadOnly =
        Collections.unmodifiableList(mInvisibleParents);

    /**
     * Flag which records whether or not we have any exploded parent nodes in this
     * view hierarchy. This is used to track whether or not we need to recompute the
     * layout when we exit show-all-invisible-parents mode (see
     * {@link LayoutCanvas#showInvisibleViews}).
     */
    private boolean mExplodedParents;

    /**
     * Bounds of included views in the current view hierarchy when rendered in other context
     */
    private List<Rectangle> mIncludedBounds;

    /** The render session for the current view hierarchy */
    private RenderSession mSession;

    /** Map from nodes to canvas view infos */
    private Map<UiViewElementNode, CanvasViewInfo> mNodeToView = Collections.emptyMap();

    /** Map from DOM nodes to canvas view infos */
    private Map<Node, CanvasViewInfo> mDomNodeToView = Collections.emptyMap();

    /**
     * Disposes the view hierarchy content.
     */
    public void dispose() {
        if (mSession != null) {
            mSession.dispose();
            mSession = null;
        }
    }


    /**
     * Sets the result of the layout rendering. The result object indicates if the layout
     * rendering succeeded. If it did, it contains a bitmap and the objects rectangles.
     *
     * Implementation detail: the bridge's computeLayout() method already returns a newly
     * allocated ILayourResult. That means we can keep this result and hold on to it
     * when it is valid.
     *
     * @param session The new session, either valid or not.
     * @param explodedNodes The set of individual nodes the layout computer was asked to
     *            explode. Note that these are independent of the explode-all mode where
     *            all views are exploded; this is used only for the mode (
     *            {@link LayoutCanvas#showInvisibleViews}) where individual invisible
     *            nodes are padded during certain interactions.
     */
    /* package */ void setSession(RenderSession session, Set<UiElementNode> explodedNodes,
            boolean layoutlib5) {
        // replace the previous scene, so the previous scene must be disposed.
        if (mSession != null) {
            mSession.dispose();
        }

        mSession = session;
        mIsResultValid = (session != null && session.getResult().isSuccess());
        mExplodedParents = false;
        mNodeToView = new HashMap<UiViewElementNode, CanvasViewInfo>(50);
        if (mIsResultValid && session != null) {
            List<ViewInfo> rootList = session.getRootViews();

            Pair<CanvasViewInfo,List<Rectangle>> infos = null;

            if (rootList == null || rootList.size() == 0) {
                // Special case: Look to see if this is really an empty <merge> view,
                // which shows up without any ViewInfos in the merge. In that case we
                // want to manufacture an empty view, such that we can target the view
                // via drag & drop, etc.
                if (hasMergeRoot()) {
                    ViewInfo mergeRoot = createMergeInfo(session);
                    infos = CanvasViewInfo.create(mergeRoot, layoutlib5);
                } else {
                    infos = null;
                }
            } else {
                if (rootList.size() > 1 && hasMergeRoot()) {
                    ViewInfo mergeRoot = createMergeInfo(session);
                    mergeRoot.setChildren(rootList);
                    infos = CanvasViewInfo.create(mergeRoot, layoutlib5);
                } else {
                    ViewInfo root = rootList.get(0);

                    if (root != null) {
                        infos = CanvasViewInfo.create(root, layoutlib5);
                        if (DUMP_INFO) {
                            dump(session, root, 0);
                        }
                    } else {
                        infos = null;
                    }
                }
            }
            if (infos != null) {
                mLastValidViewInfoRoot = infos.getFirst();
                mIncludedBounds = infos.getSecond();

                if (mLastValidViewInfoRoot.getUiViewNode() == null &&
                        mLastValidViewInfoRoot.getChildren().isEmpty()) {
                    GraphicalEditorPart editor = mCanvas.getEditorDelegate().getGraphicalEditor();
                    if (editor.getIncludedWithin() != null) {
                        // Somehow, this view was supposed to be rendered within another
                        // view, yet this view was rendered as part of the other view.
                        // In that case, abort attempting to show included in; clear the
                        // include context and trigger a standalone re-render.
                        editor.showIn(null);
                        return;
                    }
                }

            } else {
                mLastValidViewInfoRoot = null;
                mIncludedBounds = null;
            }

            updateNodeProxies(mLastValidViewInfoRoot);

            // Update the data structures related to tracking invisible and exploded nodes.
            // We need to find the {@link CanvasViewInfo} objects that correspond to
            // the passed in {@link UiElementNode} keys that were re-rendered, and mark
            // them as exploded and store them in a list for rendering.
            mExplodedParents = false;
            mInvisibleParents.clear();
            addInvisibleParents(mLastValidViewInfoRoot, explodedNodes);

            mDomNodeToView = new HashMap<Node, CanvasViewInfo>(mNodeToView.size());
            for (Map.Entry<UiViewElementNode, CanvasViewInfo> entry : mNodeToView.entrySet()) {
                mDomNodeToView.put(entry.getKey().getXmlNode(), entry.getValue());
            }

            // Update the selection
            mCanvas.getSelectionManager().sync();
        } else {
            mIncludedBounds = null;
            mInvisibleParents.clear();
            mDomNodeToView = Collections.emptyMap();
        }
    }

    private ViewInfo createMergeInfo(RenderSession session) {
        BufferedImage image = session.getImage();
        ControlPoint imageSize = ControlPoint.create(mCanvas,
                mCanvas.getHorizontalTransform().getMargin() + image.getWidth(),
                mCanvas.getVerticalTransform().getMargin() + image.getHeight());
        LayoutPoint layoutSize = imageSize.toLayout();
        UiDocumentNode model = mCanvas.getEditorDelegate().getUiRootNode();
        List<UiElementNode> children = model.getUiChildren();
        return new ViewInfo(VIEW_MERGE, children.get(0), 0, 0, layoutSize.x, layoutSize.y);
    }

    /**
     * Returns true if this view hierarchy corresponds to an editor that has a {@code
     * <merge>} tag at the root
     *
     * @return true if there is a {@code <merge>} at the root of this editor's document
     */
    private boolean hasMergeRoot() {
        UiDocumentNode model = mCanvas.getEditorDelegate().getUiRootNode();
        if (model != null) {
            List<UiElementNode> children = model.getUiChildren();
            if (children != null && children.size() > 0
                    && VIEW_MERGE.equals(children.get(0).getDescriptor().getXmlName())) {
                return true;
            }
        }

        return false;
    }

    /**
     * Creates or updates the node proxy for this canvas view info.
     * <p/>
     * Since proxies are reused, this will update the bounds of an existing proxy when the
     * canvas is refreshed and a view changes position or size.
     * <p/>
     * This is a recursive call that updates the whole hierarchy starting at the given
     * view info.
     */
    private void updateNodeProxies(CanvasViewInfo vi) {
        if (vi == null) {
            return;
        }

        UiViewElementNode key = vi.getUiViewNode();

        if (key != null) {
            mCanvas.getNodeFactory().create(vi);
            mNodeToView.put(key, vi);
        }

        for (CanvasViewInfo child : vi.getChildren()) {
            updateNodeProxies(child);
        }
    }

    /**
     * Make a pass over the view hierarchy and look for two things:
     * <ol>
     * <li>Invisible parents. These are nodes that can hold children and have empty
     * bounds. These are then added to the {@link #mInvisibleParents} list.
     * <li>Exploded nodes. These are nodes that were previously marked as invisible, and
     * subsequently rendered by a recomputed layout. They now no longer have empty bounds,
     * but should be specially marked via {@link CanvasViewInfo#setExploded} such that we
     * for example in selection operations can determine if we need to recompute the
     * layout.
     * </ol>
     *
     * @param vi
     * @param invisibleNodes
     */
    private void addInvisibleParents(CanvasViewInfo vi, Set<UiElementNode> invisibleNodes) {
        if (vi == null) {
            return;
        }

        if (vi.isInvisible()) {
            mInvisibleParents.add(vi);
        } else if (invisibleNodes != null) {
            UiViewElementNode key = vi.getUiViewNode();

            if (key != null && invisibleNodes.contains(key)) {
                vi.setExploded(true);
                mExplodedParents = true;
                mInvisibleParents.add(vi);
            }
        }

        for (CanvasViewInfo child : vi.getChildren()) {
            addInvisibleParents(child, invisibleNodes);
        }
    }

    /**
     * Returns the current {@link RenderSession}.
     * @return the session or null if none have been set.
     */
    public RenderSession getSession() {
        return mSession;
    }

    /**
     * Returns true when the last {@link #setSession} provided a valid
     * {@link RenderSession}.
     * <p/>
     * When false this means the canvas is displaying an out-dated result image & bounds and some
     * features should be disabled accordingly such a drag'n'drop.
     * <p/>
     * Note that an empty document (with a null {@link #getRoot()}) is considered
     * valid since it is an acceptable drop target.
     * @return True when this {@link ViewHierarchy} contains a valid hierarchy of views.
    */
    public boolean isValid() {
        return mIsResultValid;
    }

    /**
     * Returns true if the last valid content of the canvas represents an empty document.
     * @return True if the last valid content of the canvas represents an empty document.
     */
    public boolean isEmpty() {
        return mLastValidViewInfoRoot == null;
    }

    /**
     * Returns true if we have parents in this hierarchy that are invisible (e.g. because
     * they have no children and zero layout bounds).
     *
     * @return True if we have invisible parents.
     */
    public boolean hasInvisibleParents() {
        return mInvisibleParents.size() > 0;
    }

    /**
     * Returns true if we have views that were exploded during rendering
     * @return True if we have exploded parents
     */
    public boolean hasExplodedParents() {
        return mExplodedParents;
    }

    /** Locates and return any views that overlap the given selection rectangle.
     * @param topLeft The top left corner of the selection rectangle.
     * @param bottomRight The bottom right corner of the selection rectangle.
     * @return A collection of {@link CanvasViewInfo} objects that overlap the
     *   rectangle.
     */
    public Collection<CanvasViewInfo> findWithin(
            LayoutPoint topLeft,
            LayoutPoint bottomRight) {
        Rectangle selectionRectangle = new Rectangle(topLeft.x, topLeft.y, bottomRight.x
                - topLeft.x, bottomRight.y - topLeft.y);
        List<CanvasViewInfo> infos = new ArrayList<CanvasViewInfo>();
        addWithin(mLastValidViewInfoRoot, selectionRectangle, infos);
        return infos;
    }

    /**
     * Recursive internal version of {@link #findViewInfoAt(int, int)}. Please don't use directly.
     * <p/>
     * Tries to find the inner most child matching the given x,y coordinates in the view
     * info sub-tree. This uses the potentially-expanded selection bounds.
     *
     * Returns null if not found.
     */
    private void addWithin(
            CanvasViewInfo canvasViewInfo,
            Rectangle canvasRectangle,
            List<CanvasViewInfo> infos) {
        if (canvasViewInfo == null) {
            return;
        }
        Rectangle r = canvasViewInfo.getSelectionRect();
        if (canvasRectangle.intersects(r)) {

            // try to find a matching child first
            for (CanvasViewInfo child : canvasViewInfo.getChildren()) {
                addWithin(child, canvasRectangle, infos);
            }

            if (canvasViewInfo != mLastValidViewInfoRoot) {
                infos.add(canvasViewInfo);
            }
        }
    }

    /**
     * Locates and returns the {@link CanvasViewInfo} corresponding to the given
     * node, or null if it cannot be found.
     *
     * @param node The node we want to find a corresponding
     *            {@link CanvasViewInfo} for.
     * @return The {@link CanvasViewInfo} corresponding to the given node, or
     *         null if no match was found.
     */
    @Nullable
    public CanvasViewInfo findViewInfoFor(@Nullable Node node) {
        CanvasViewInfo vi = mDomNodeToView.get(node);

        if (vi == null) {
            if (node == null) {
                return null;
            } else if (node.getNodeType() == Node.TEXT_NODE) {
                return mDomNodeToView.get(node.getParentNode());
            } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
                return mDomNodeToView.get(((Attr) node).getOwnerElement());
            } else if (node.getNodeType() == Node.DOCUMENT_NODE) {
                return mDomNodeToView.get(((Document) node).getDocumentElement());
            }
        }

        return vi;
    }

    /**
     * Tries to find the inner most child matching the given x,y coordinates in
     * the view info sub-tree, starting at the last know view info root. This
     * uses the potentially-expanded selection bounds.
     * <p/>
     * Returns null if not found or if there's no view info root.
     *
     * @param p The point at which to look for the deepest match in the view
     *            hierarchy
     * @return A {@link CanvasViewInfo} that intersects the given point, or null
     *         if nothing was found.
     */
    public CanvasViewInfo findViewInfoAt(LayoutPoint p) {
        if (mLastValidViewInfoRoot == null) {
            return null;
        }

        return findViewInfoAt_Recursive(p, mLastValidViewInfoRoot);
    }

    /**
     * Recursive internal version of {@link #findViewInfoAt(int, int)}. Please don't use directly.
     * <p/>
     * Tries to find the inner most child matching the given x,y coordinates in the view
     * info sub-tree. This uses the potentially-expanded selection bounds.
     *
     * Returns null if not found.
     */
    private CanvasViewInfo findViewInfoAt_Recursive(LayoutPoint p, CanvasViewInfo canvasViewInfo) {
        if (canvasViewInfo == null) {
            return null;
        }
        Rectangle r = canvasViewInfo.getSelectionRect();
        if (r.contains(p.x, p.y)) {

            // try to find a matching child first
            // Iterate in REVERSE z order such that siblings on top
            // are checked before earlier siblings (this matters in layouts like
            // FrameLayout and in <merge> contexts where the views are sitting on top
            // of each other and we want to select the same view as the one drawn
            // on top of the others
            List<CanvasViewInfo> children = canvasViewInfo.getChildren();
            assert children instanceof RandomAccess;
            for (int i = children.size() - 1; i >= 0; i--) {
                CanvasViewInfo child = children.get(i);
                CanvasViewInfo v = findViewInfoAt_Recursive(p, child);
                if (v != null) {
                    return v;
                }
            }

            // if no children matched, this is the view that we're looking for
            return canvasViewInfo;
        }

        return null;
    }

    /**
     * Returns a list of all the possible alternatives for a given view at the given
     * position. This is used to build and manage the "alternate" selection that cycles
     * around the parents or children of the currently selected element.
     */
    /* package */ List<CanvasViewInfo> findAltViewInfoAt(LayoutPoint p) {
        if (mLastValidViewInfoRoot != null) {
            return findAltViewInfoAt_Recursive(p, mLastValidViewInfoRoot, null);
        }

        return null;
    }

    /**
     * Internal recursive version of {@link #findAltViewInfoAt(int, int, CanvasViewInfo)}.
     * Please don't use directly.
     */
    private List<CanvasViewInfo> findAltViewInfoAt_Recursive(
            LayoutPoint p, CanvasViewInfo parent, List<CanvasViewInfo> outList) {
        Rectangle r;

        if (outList == null) {
            outList = new ArrayList<CanvasViewInfo>();

            if (parent != null) {
                // add the parent root only once
                r = parent.getSelectionRect();
                if (r.contains(p.x, p.y)) {
                    outList.add(parent);
                }
            }
        }

        if (parent != null && !parent.getChildren().isEmpty()) {
            // then add all children that match the position
            for (CanvasViewInfo child : parent.getChildren()) {
                r = child.getSelectionRect();
                if (r.contains(p.x, p.y)) {
                    outList.add(child);
                }
            }

            // finally recurse in the children
            for (CanvasViewInfo child : parent.getChildren()) {
                r = child.getSelectionRect();
                if (r.contains(p.x, p.y)) {
                    findAltViewInfoAt_Recursive(p, child, outList);
                }
            }
        }

        return outList;
    }

    /**
     * Locates and returns the {@link CanvasViewInfo} corresponding to the given
     * node, or null if it cannot be found.
     *
     * @param node The node we want to find a corresponding
     *            {@link CanvasViewInfo} for.
     * @return The {@link CanvasViewInfo} corresponding to the given node, or
     *         null if no match was found.
     */
    public CanvasViewInfo findViewInfoFor(INode node) {
        return findViewInfoFor((NodeProxy) node);
    }

    /**
     * Tries to find a child with the same view key in the view info sub-tree.
     * Returns null if not found.
     *
     * @param viewKey The view key that a matching {@link CanvasViewInfo} should
     *            have as its key.
     * @return A {@link CanvasViewInfo} matching the given key, or null if not
     *         found.
     */
    public CanvasViewInfo findViewInfoFor(UiElementNode viewKey) {
        return mNodeToView.get(viewKey);
    }

    /**
     * Tries to find a child with the given node proxy as the view key.
     * Returns null if not found.
     *
     * @param proxy The view key that a matching {@link CanvasViewInfo} should
     *            have as its key.
     * @return A {@link CanvasViewInfo} matching the given key, or null if not
     *         found.
     */
    @Nullable
    public CanvasViewInfo findViewInfoFor(@Nullable NodeProxy proxy) {
        if (proxy == null) {
            return null;
        }
        return mNodeToView.get(proxy.getNode());
    }

    /**
     * Returns a list of ALL ViewInfos (possibly excluding the root, depending
     * on the parameter for that).
     *
     * @param includeRoot If true, include the root in the list, otherwise
     *            exclude it (but include all its children)
     * @return A list of canvas view infos.
     */
    public List<CanvasViewInfo> findAllViewInfos(boolean includeRoot) {
        List<CanvasViewInfo> infos = new ArrayList<CanvasViewInfo>();
        if (mIsResultValid && mLastValidViewInfoRoot != null) {
            findAllViewInfos(infos, mLastValidViewInfoRoot, includeRoot);
        }

        return infos;
    }

    private void findAllViewInfos(List<CanvasViewInfo> result, CanvasViewInfo canvasViewInfo,
            boolean includeRoot) {
        if (canvasViewInfo != null) {
            if (includeRoot || !canvasViewInfo.isRoot()) {
                result.add(canvasViewInfo);
            }
            for (CanvasViewInfo child : canvasViewInfo.getChildren()) {
                findAllViewInfos(result, child, true);
            }
        }
    }

    /**
     * Returns the root of the view hierarchy, if any (could be null, for example
     * on rendering failure).
     *
     * @return The current view hierarchy, or null
     */
    public CanvasViewInfo getRoot() {
        return mLastValidViewInfoRoot;
    }

    /**
     * Returns a collection of views that have zero bounds and that correspond to empty
     * parents. Note that the views may not actually have zero bounds; in particular, if
     * they are exploded ({@link CanvasViewInfo#isExploded()}, then they will have the
     * bounds of a shown invisible node. Therefore, this method returns the views that
     * would be invisible in a real rendering of the scene.
     *
     * @return A collection of empty parent views.
     */
    public List<CanvasViewInfo> getInvisibleViews() {
        return mInvisibleParentsReadOnly;
    }

    /**
     * Returns the invisible nodes (the {@link UiElementNode} objects corresponding
     * to the {@link CanvasViewInfo} objects returned from {@link #getInvisibleViews()}.
     * We are pulling out the nodes since they preserve their identity across layout
     * rendering, and in particular we return it as a set such that the layout renderer
     * can perform quick identity checks when looking up attribute values during the
     * rendering process.
     *
     * @return A set of the invisible nodes.
     */
    public Set<UiElementNode> getInvisibleNodes() {
        if (mInvisibleParents.size() == 0) {
            return Collections.emptySet();
        }

        Set<UiElementNode> nodes = new HashSet<UiElementNode>(mInvisibleParents.size());
        for (CanvasViewInfo info : mInvisibleParents) {
            UiViewElementNode node = info.getUiViewNode();
            if (node != null) {
                nodes.add(node);
            }
        }

        return nodes;
    }

    /**
     * Returns the list of bounds for included views in the current view hierarchy. Can be null
     * when there are no included views.
     *
     * @return a list of included view bounds, or null
     */
    public List<Rectangle> getIncludedBounds() {
        return mIncludedBounds;
    }

    /**
     * Returns a map of the default properties for the given view object in this session
     *
     * @param viewObject the object to look up the properties map for
     * @return the map of properties, or null if not found
     */
    @Nullable
    public Map<String, String> getDefaultProperties(@NonNull Object viewObject) {
        if (mSession != null) {
            return mSession.getDefaultProperties(viewObject);
        }

        return null;
    }

    /**
     * Dumps a {@link ViewInfo} hierarchy to stdout
     *
     * @param session the corresponding session, if any
     * @param info the {@link ViewInfo} object to dump
     * @param depth the depth to indent it to
     */
    public static void dump(RenderSession session, ViewInfo info, int depth) {
        if (DUMP_INFO) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < depth; i++) {
                sb.append("    "); //$NON-NLS-1$
            }
            sb.append(info.getClassName());
            sb.append(" ["); //$NON-NLS-1$
            sb.append(info.getLeft());
            sb.append(","); //$NON-NLS-1$
            sb.append(info.getTop());
            sb.append(","); //$NON-NLS-1$
            sb.append(info.getRight());
            sb.append(","); //$NON-NLS-1$
            sb.append(info.getBottom());
            sb.append("]"); //$NON-NLS-1$
            Object cookie = info.getCookie();
            if (cookie instanceof UiViewElementNode) {
                sb.append(" "); //$NON-NLS-1$
                UiViewElementNode node = (UiViewElementNode) cookie;
                sb.append("<"); //$NON-NLS-1$
                sb.append(node.getDescriptor().getXmlName());
                sb.append(">"); //$NON-NLS-1$

                String id = node.getAttributeValue(ATTR_ID);
                if (id != null && !id.isEmpty()) {
                    sb.append(" ");
                    sb.append(id);
                }
            } else if (cookie != null) {
                sb.append(" " + cookie); //$NON-NLS-1$
            }
            /* Display defaults?
            if (info.getViewObject() != null) {
                Map<String, String> defaults = session.getDefaultProperties(info.getCookie());
                sb.append(" - defaults: "); //$NON-NLS-1$
                sb.append(defaults);
                sb.append('\n');
            }
            */

            System.out.println(sb.toString());

            for (ViewInfo child : info.getChildren()) {
                dump(session, child, depth + 1);
            }
        }
    }
}
