private Object _EvaluateNode(SDK.ILogger logger, Guid nodeId, bool previewMode)
        {
            _ThreadAffinity.Check();

            CheckCancellation();

            logger?.LogInfo(nodeId.ToString(), "Begin Evaluation...");

            // Get the current node being evaluated
            var nodeInst = _InstanceFunc(nodeId);

            if (nodeInst == null)
            {
                return(null);
            }
            if (nodeInst is _UnknownNode)
            {
                return(null);
            }

            // Next, we retrieve the property values for this node from the DOM
            var nodeProps = _PropertiesFunc(nodeId).AsReadOnly();

            if (nodeProps == null)
            {
                return(null);
            }

            // Assign values and node dependencies. Dependecies are evaluated to its values.
            // NOTE: even in preview mode, dependent nodes are evaluated normally
            nodeInst.EvaluateBindings(nodeProps, xid => _EvaluateNode(logger, xid, false));

            CheckCancellation();

            // evaluate the current node

            try
            {
                var localMonitor = GetLocalProgressMonitor(nodeId);

                if (nodeInst is SDK.ContentFilter filterInst)
                {
                    if (previewMode)
                    {
                        return(SDK.PreviewNode(filterInst, localMonitor, logger));
                    }
                    else
                    {
                        if (System.Diagnostics.Debugger.IsAttached)
                        {
                            return(SDK.DebugNode(filterInst, localMonitor, logger));
                        }
                        else
                        {
                            return(SDK.EvaluateNode(filterInst, localMonitor, logger));
                        }
                    }
                }
                else if (nodeInst is SDK.ContentObject)
                {
                    return(nodeInst);
                }
            }
            catch (Exception ex)
            {
                throw new PluginException(ex);
            }

            throw new NotImplementedException();
        }