public DustProcVisitProcess(DustSession session, DustInfoTray tray)
        {
            this.session        = session;
            this.infoTray       = tray;
            this.visitTray      = tray as DustVisitTray;
            callbackTray        = (null == visitTray) ? new DustVisitTray(tray, null) : new DustVisitTray(visitTray);
            callbackTray.entity = session.resolveEntity(tray.entity);

            empty = true;

            dip = tray.value as DustInfoProcessor;
//			dif = tray.value as DustInfoFilter;
            dvp = tray.value as DustVisitor;
        }
        public void visitEntity(object readerParent)
        {
            var e = session.resolveEntity(callbackTray.entity);

            if (null != e)
            {
                Exception procEx = null;

                try {
                    bool found = visitedEntities.ContainsKey(e);
                    bool nochk = callbackTray.cmd.HasFlag(VisitCommand.recNoCheck);
                    if (visitedEntities.ContainsKey(e) && !callbackTray.cmd.HasFlag(VisitCommand.recNoCheck))
                    {
                        callbackTray.readerObject = visitedEntities[e];
                        sendVisitEvent(VisitEvent.entityRevisit);
                    }
                    else
                    {
                        callbackTray.entity       = e;
                        callbackTray.readerParent = readerParent;
                        callbackTray.readerObject = VISITED;

                        if (sendVisitEvent(VisitEvent.entityStartOpt))
                        {
                            Object rh = callbackTray.readerObject;
                            visitedEntities[e] = rh ?? VISITED;

                            foreach (var ec in e.content.Keys)
                            {
                                callbackTray.key = ec;
                                var val = e.content[ec];

                                if (null != val)
                                {
                                    callbackTray.readerObject = rh;
                                    if (sendVisitEvent(VisitEvent.keyStartOpt))
                                    {
                                        var r = val as DustDataReference;

                                        if ((null == r) && callbackTray.cmd.HasFlag(VisitCommand.visitAtts))
                                        {
                                            callbackTray.value        = val;
                                            callbackTray.readerObject = rh;
                                            dip.processInfo(callbackTray);

                                            callbackTray.key          = ec;
                                            callbackTray.readerObject = rh;
                                            callbackTray.readerParent = readerParent;
                                            sendVisitEvent(VisitEvent.keyEnd);
                                        }
                                        else if ((null != r) && callbackTray.cmd.HasFlag(VisitCommand.visitRefs))
                                        {
                                            visitRef(e, ec, rh, false);
                                        }
                                    }
                                }
                            }

                            callbackTray.readerObject = rh;
                            callbackTray.readerParent = readerParent;
                            sendVisitEvent(VisitEvent.entityEnd);
                            visitedEntities[e] = callbackTray.readerObject ?? VISITED;
                        }
                    }
                } catch (Exception ex) {
                    callbackTray.readerObject = procEx = ex;
                    sendVisitEvent((ex is DustException) ? VisitEvent.visitAborted : VisitEvent.visitInternalError);
                } finally {
                    if (callbackTray.cmd.HasFlag(VisitCommand.recPathOnce))
                    {
                        visitedEntities.Remove(e);
                    }
                }

                if (null != procEx)
                {
                    throw procEx;
                }
            }
        }