/// <summary>
 /// The add expression to collection.
 /// </summary>
 /// <param name="source">
 /// The source.
 /// </param>
 /// <param name="hookType">
 /// The hook type.
 /// </param>
 /// <param name="description">
 /// The description.
 /// </param>
 /// <param name="processDescription">
 /// The process description.
 /// </param>
 /// <param name="expression">
 /// The expression.
 /// </param>
 /// <param name="sysid">
 /// The sysid.
 /// </param>
 private void AddExpressionToCollection(
     SourceDefinition source,
     SourceDefinition hookType,
     string description,
     DefinitionDescription processDescription,
     string expression,
     string sysid = "")
 {
     JobManager.RunInDispatcherThread(
         DebugWindowManager.DebugConsoleWindow.Dispatcher,
         DispatcherPriority.Normal,
         delegate
             {
                 try
                 {
                     switch (source)
                     {
                         case SourceDefinition.Field:
                             this.AddItemToCollection(
                                 processDescription.DictionaryExpressions,
                                 new SBExpression(processDescription.FileName, expression, hookType, sysid)
                                     {
                                         Description =
                                             description
                                     });
                             break;
                         case SourceDefinition.Screen:
                             /*
                             if (hookType == SourceDefinition.Process)
                             {
                                 //AddItemToCollection(processDescription.ProcessCollection, );
                                 this.AddProcessToCollection(
                                     description,
                                     processDescription,
                                     new SBExpression(processDescription.FileName, expression, hookType, sysid, expression)
                                         {
                                             Description
                                                 =
                                                 description
                                         });
                             }
                             else
                             {
     */
                             this.AddItemToCollection(
                                 processDescription.ScreenExpressions,
                                 new SBExpression(processDescription.FileName, expression, hookType, sysid)
                                     {
                                         Description =
                                             description
                                     });
                             /*
                             }
     */
                             break;
                         case SourceDefinition.Menu:
                             this.AddProcessToCollection(
                                 description,
                                 processDescription,
                                 new SBExpression(processDescription.FileName, expression, hookType, sysid, expression)
                                     {
                                         Description
                                             =
                                             description
                                     });
                             break;
                         case SourceDefinition.Paragraph:
                             this.AddItemToCollection(
                                 processDescription.Expressions,
                                 new SBExpression(processDescription.FileName, expression, hookType, sysid)
                                     {
                                         Description =
                                             description
                                     });
                             break;
                         case SourceDefinition.Unknown:
                             this.AddItemToCollection(
                                 processDescription.Expressions,
                                 new SBExpression(processDescription.FileName, expression, hookType, sysid)
                                     {
                                         Description =
                                             description
                                     });
                             break;
                     }
                 }
                 catch (Exception exception)
                 {
                     CustomLogger.LogException(exception, "Problem adding expression to the collection.");
                 }
             });
 }
        /// <summary>
        /// Loads the definition from xxPROCESS.
        /// </summary>
        /// <param name="pName">
        /// Name of the definition.
        /// </param>
        /// <param name="slotType"></param>
        /// <param name="parent">
        /// Parent <see cref="DefinitionDescription"/>, if this is null then it will be the root of the tree.
        /// </param>
        /// <param name="expression">
        /// The original expression that the definition name was derrived from.
        /// </param>
        /// <param name="hookPoint">
        /// The name of the definition slot where the definition was found.
        /// </param>
        /// <param name="sysid">
        /// The system id to use otherwise the current system id will be used.
        /// </param>
        /// <param name="source"></param>
        internal void LoadProcess(
            string pName,
            SourceDefinition source,
            SourceDefinition slotType,
            DefinitionDescription parent = null,
            string expression = "",
            string hookPoint = "",
            string sysid = "")
        {
            if (SBExpression.IsStandardSBExpression(expression))
            {
                // standard SB expression elements and therefore no need to try read the process, just add the element
                this.AddExpressionToCollection(parent, hookPoint, expression);
                return;
            }

            if (string.IsNullOrEmpty(expression))
            {
                expression = pName;
            }

            JobManager.RunInUIThread(
                DispatcherPriority.Input,
                delegate
                    {
                        var processFile = sysid;
                        if (string.IsNullOrEmpty(processFile))
                        {
                            processFile = SBPlusClient.Current.SystemId;
                        }

                        // read definition record from current xxProcess
                        processFile += "PROCESS";
                        // check if I already have the definition in the collection
                        lock (this.processCollection)
                        {
                            if (this.processCollection.ContainsKey(processFile, pName))
                            {
                                this.SetIsLoading(1);
                                this.AddProcessToCollection(pName, parent, this.processCollection[pName]);
                                this.SetIsLoading(-1);
                                return;
                            }
                        }

                        this.SetIsLoading(1);
                        SBFile.Read(
                            processFile,
                            pName,
                            this.ReadProcessCompleted,
                            new ProcessLoadState { HookPoint = hookPoint, ParentDefinitionDescription = parent, Expression = expression, Source = source, SlotType = slotType, SysId = sysid });
                    });
        }
        /// <summary>
        /// Loads the definition from expression.
        /// </summary>
        /// <param name="source">
        /// Where the expression is being called from.
        /// </param>
        /// <param name="hookType">
        /// If this is a process hook point or expression hook point.
        /// </param>
        /// <param name="expression">
        /// The original expression that the definition name was derrived from.
        /// </param>
        /// <param name="parent">
        /// Parent <see cref="DefinitionDescription"/>, if this is null then it will be the root of the tree.
        /// </param>
        /// <param name="hookPoint">
        /// The name of the definition slot where the definition was found.
        /// </param>
        /// <param name="sysid">
        /// The system id to use otherwise the current system id will be used.
        /// </param>
        internal void LoadProcessFromExpression(
            SourceDefinition source,
            SourceDefinition hookType,
            string expression,
            DefinitionDescription parent = null,
            string hookPoint = "",
            string sysid = "")
        {
            if (string.IsNullOrEmpty(expression))
            {
                // there is no expression so no need to try load it.
                return;
            }

            if (expression.StartsWith("P.CALL.PROCESS"))
            {
                // this is specific to American Auto Shield. The have a process used to call other processes so we can just remove it.
                expression = expression.Substring(15);
            }

            // Check to see if it is a constant, if so just add it to the collection.
            if (SBExpression.IsConstantValueExpression(expression))
            {
                this.AddExpressionToCollection(source, hookType, hookPoint, parent, expression);
                return;
            }

            var colonPos = expression.IndexOf(":", StringComparison.Ordinal);
            if (colonPos != 1)
            {
                // SB expression that have an identified, i.e. B: D: all have a single character then a ':'
                colonPos = 0;
            }

            // a field definition has no process hooks they are all expressions, etc. int help.
            if (source != SourceDefinition.Paragraph
                && (colonPos > 0 || source == SourceDefinition.Field || source == SourceDefinition.Expression))
            {
                this.AddExpressionToCollection(source, hookType, hookPoint, parent, expression);
                return;
            }

            string callType;
            var pName = GetProcessName(expression, out callType);
            if (!string.IsNullOrEmpty(pName))
            {
                switch (callType)
                {
                    case "C":
                        this.LoadProcess(pName, source, hookType, parent, expression, hookPoint, sysid);
                        break;
                    case "B":
                        this.LoadBasicProgramFromExpression(pName, parent, hookPoint);
                        break;
                    case "M":
                        break;
                    case "D":
                        this.AddExpressionToCollection(source, hookType, hookPoint, parent, expression);
                        break;
                    case "V":
                        this.AddExpressionToCollection(source, hookType, hookPoint, parent, expression);
                        break;
                    default:
                        this.LoadProcess(pName, source, hookType, parent, expression, hookPoint, sysid);
                        break;
                }
            }
        }
        /// <summary>
        /// The add process to collection.
        /// </summary>
        /// <param name="description">
        /// The description.
        /// </param>
        /// <param name="parentDefinitionDescription">
        /// The parent definition description.
        /// </param>
        /// <param name="processDescription">
        /// The process description.
        /// </param>
        /// <param name="source">Where is the process being called from.</param>
        private void AddProcessToCollection(
            string description,
            DefinitionDescription parentDefinitionDescription,
            DefinitionDescription processDescription,
            SourceDefinition source = SourceDefinition.Unknown)
        {
            JobManager.RunInDispatcherThread(
                DebugWindowManager.DebugConsoleWindow.Dispatcher,
                DispatcherPriority.Normal,
                delegate
                    {
                        if (parentDefinitionDescription == null)
                        {
                            this.Definition = processDescription;
                            this.ResetAnalysis();
                            this.ProcessStack.Push(this.Definition);
                        }
                        else
                        {
                            switch (source)
                            {
                                case SourceDefinition.Screen:
                                    if (processDescription is SBExpression)
                                    {
                                        this.AddItemToCollection(parentDefinitionDescription.ScreenExpressions, processDescription as SBExpression);
                                    }
                                    else
                                    {
                                        this.AddItemToCollection(
                                            parentDefinitionDescription.ProcessCollection,
                                            new ProcessCall { Description = description, ProcessDescription = processDescription });
                                    }
                                    break;
                                case SourceDefinition.Button:
                                    //this.AddItemToCollection(description, processDescription, parentDefinitionDescription.ProcessCollection);
                                    this.AddItemToCollection(
                                        parentDefinitionDescription.ProcessCollection,
                                        new ProcessCall { Description = description, ProcessDescription = processDescription });

                                    break;
                                default:
                                    this.AddItemToCollection(
                                        parentDefinitionDescription.ProcessCollection,
                                        new ProcessCall { Description = description, ProcessDescription = processDescription });
                                    break;
                            }
                        }
                    });
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SelectionProcessDescription"/> class.
 /// </summary>
 /// <param name="fileName">
 /// The file name.
 /// </param>
 /// <param name="name">
 /// The name.
 /// </param>
 /// <param name="definition">
 /// The definition.
 /// </param>
 public SelectionProcessDescription(string fileName, string name, SourceDefinition hookType, string sysId, SBString definition)
     : base(fileName, name, hookType, sysId)
 {
     this.Name = name;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SBExpression"/> class.
 /// </summary>
 /// <param name="fileName">
 /// The file name.
 /// </param>
 /// <param name="expression">
 /// The expression.
 /// </param>
 /// <param name="hookType">
 /// The hook type.
 /// </param>
 /// <param name="sysid">
 /// The sysid.
 /// </param>
 /// <param name="name">
 /// The name.
 /// </param>
 public SBExpression(string fileName, string expression, SourceDefinition hookType, string sysid, string name)
     : base(fileName, name, hookType, expression)
 {
     this.SystemId = sysid;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SBExpression"/> class.
 /// </summary>
 /// <param name="fileName">
 /// The file name.
 /// </param>
 /// <param name="expression">
 /// The expression.
 /// </param>
 /// <param name="hookType">
 /// The hook type.
 /// </param>
 /// <param name="sysid">
 /// The sysid.
 /// </param>
 public SBExpression(string fileName, string expression, SourceDefinition hookType, string sysid)
     : this(fileName, expression, hookType, sysid, string.Empty)
 {
 }
 public ButtonDefinitionDescription(string fileName, string name, SourceDefinition hookType, string expression)
     : base(fileName, name, hookType, expression)
 {
 }