/// <summary>
        /// The create paragraph description.
        /// </summary>
        /// <param name="processFileName">
        /// The process file name.
        /// </param>
        /// <param name="pName">
        /// The p name.
        /// </param>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="defn">
        /// The defn.
        /// </param>
        /// <returns>
        /// The <see cref="ParagraphDescription"/>.
        /// </returns>
        private ParagraphDescription CreateParagraphDescription(string processFileName, string pName, string expression, SBString defn)
        {
            var processDescription = new ParagraphDescription(processFileName, pName, expression, defn);

            // Now parse out the paragraph to find definition and basic program calls
            var paragraphExpression = defn.Extract(3).Value;

            var elements = paragraphExpression.Split(GenericConstants.CHAR_ARRAY_SEMI_COLON);
            // C0;AP4;P4;C1;=;I2;EP.BRANCH,INT.CALL;J5;P4;C2;=;I1;BBASIC.PROGRAM
            foreach (var element in elements)
            {
                if (string.IsNullOrEmpty(element.Trim()))
                {
                    continue;
                }

                switch (element.Substring(0, 1))
                {
                    case "E":
                        this.LoadProcessFromExpression(
                            SourceDefinition.Paragraph,
                            SourceDefinition.Process,
                            element.Substring(1),
                            processDescription,
                            "Execute");
                        break;
                    case "B":
                        this.LoadBasicProgramFromExpression(element.Substring(1), processDescription, "Call");
                        break;
                }
            }

            return processDescription;
        }
        /// <summary>
        /// This method will parse out the definition and figure out the type of definition.
        /// </summary>
        /// <param name="processFileName">
        /// The name of the file that contains the process.
        /// </param>
        /// <param name="pName">
        /// The name of the definition.
        /// </param>
        /// <param name="defn">
        /// The definition description.
        /// </param>
        /// <param name="processLoadState">
        /// The information about the definition definition passed from the calling routine.
        /// </param>
        /// <returns>
        /// The <see cref="DefinitionDescription"/>.
        /// </returns>
        private DefinitionDescription CreateProcessDescription(
            string processFileName,
            string pName,
            SBString defn,
            ProcessLoadState processLoadState)
        {
            DefinitionDescription processDescription;
            if (defn == null)
            {
                if (processLoadState.Source == SourceDefinition.Button)
                {
            /*
                    processDescription = new ButtonDefinitionDescription()
                                             {
                                                 Description = processLoadState.HookPoint,
                                                 pName,
                                                 Source
                                             };
            */
                    processDescription = new ButtonDefinitionDescription(
                        processFileName,
                        pName,
                        SourceDefinition.Process,
                        processLoadState.Expression);
                }
                else
                {
                    processDescription = new DefinitionDescription(
                                                processFileName,
                                                pName,
                                                SourceDefinition.Process,
                                                processLoadState.Expression)
                                                {
                                                    IsError = true
                                                };

                }
                return processDescription;
            }

            switch (defn.Extract(1).Value)
            {
                case "I":
                    processDescription = new InputDefinitionDescription(processFileName, pName, processLoadState.Expression, defn);
                    break;
                case "O":
                    processDescription = new OutputDefinitionDescription(processFileName, pName, processLoadState.Expression, defn);
                    break;
                case "P":
                    processDescription = this.CreateParagraphDescription(processFileName, pName, processLoadState.Expression, defn);
                    break;
                case "SCREEN":
                    processDescription = new ScreenDefintion(processFileName, pName, string.Empty, defn);
                    break;
                case "F":
                    processDescription = new FileUpdateDefinitionDescription(processFileName, pName, string.Empty, defn);
                    break;
                case "M":
                    processDescription = new MenuDefinitionDescription(processFileName, pName, string.Empty, defn);
                    break;
                case "S":
                    processDescription = new SelectionProcessDescription(processFileName, pName, SourceDefinition.Process, processLoadState.SysId, defn);
                    break;
                default:
                    processDescription = new DefinitionDescription(
                        processFileName,
                        pName,
                        SourceDefinition.Process,
                        processLoadState.Expression);
                    break;
            }

            return processDescription;
        }
        /// <summary>
        /// The parse definition.
        /// </summary>
        /// <param name="definition">
        /// The definition.
        /// </param>
        private void ParseDefinition(SBString definition)
        {
            /*
            Type                                               2
            1: vertical box
            2: horiz boxtype.
            3: user painted
            4: as 3 + select no
            5: horiz box with linked sub-menus (for GUI)
             *
             * Option Description                                 6.M     C
             * Name                                               7.M     D
             * Type (M/P/T/>/H/C/X)                               8.M     D

             *
             * Process before menu display                       13.1
             * Process after display                             13.2
             * Process after select option                       13.3
             * Process after execution of option                 13.4
             * Process after escaping this menu                  13.5
             * Process before returning to SYSMENU or LOGIN      13.6
             * Process to determine box cords                    13.7
             * Subroutine to call at start                       13.8

            */
            switch (definition.Extract(MenuType).Value)
            {
                case "1":
                    this.ProcessMenuOptions(definition);
                    break;
                case "2":
                    this.ProcessMenuOptions(definition);
                    break;
                case "3":
                    break;
                case "4":
                    break;
                case "5":
                    break;
            }
        }
 /// <summary>
 /// The process menu options.
 /// </summary>
 /// <param name="definition">
 /// The definition.
 /// </param>
 private void ProcessMenuOptions(SBString definition)
 {
     try
     {
         var noOptions = definition.Extract(MenuOptionType).Dcount();
         for (int optNo = 1; optNo <= noOptions; optNo++)
         {
             var desc = definition.Extract(Options, optNo).Value;
             var type = definition.Extract(MenuOptionType, optNo).Value;
             var process = definition.Extract(ProcessName, optNo).Value;
             if (type.Equals("P") && !string.IsNullOrEmpty(process))
             {
                 DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                     SourceDefinition.Menu,
                     SourceDefinition.Process,
                     process,
                     this,
                     desc);
             }
         }
     }
     catch (Exception exception)
     {
         this.IsError = true;
         CustomLogger.LogException(exception, "There was a problem process the menu '" + this.Name + "'");
     }
 }
        /// <summary>
        /// The update definition stack.
        /// </summary>
        /// <param name="add">
        /// The add.
        /// </param>
        /// <param name="processName">
        /// The definition name.
        /// </param>
        /// <param name="paramaters">
        /// The proc name.
        /// </param>
        public static void UpdateProcessStack(bool add, string processName, SBString paramaters)
        {
            var actionTime = DateTime.Now;
            try
            {
                int serverActionTime = 0;
                if (paramaters.Extract(1, 1).Dcount() > 1)
                {
                    int.TryParse(paramaters.Extract(1, 1, 1).Value, out serverActionTime);
                    CustomLogger.LogDebug(() => string.Format("Add {0} {1} at {2}.", add, processName, serverActionTime));
                }
                else
                {
                    CustomLogger.LogDebug(() => string.Format("Add {0} {1}.", add, processName));
                }

                if (DebugWindowManager.DebugConsoleWindow == null)
                {
                    // no debug windows.
                    return;
                }

                if (Thread.CurrentThread.ManagedThreadId != DebugWindowManager.DebugConsoleWindow.Dispatcher.Thread.ManagedThreadId)
                {
                    JobManager.RunInDispatcherThread(
                        DebugWindowManager.DebugConsoleWindow.Dispatcher, 
                        DispatcherPriority.Normal, 
                        () => DoUpdateProcessStack(add, processName, actionTime, serverActionTime));
                }
                else
                {
                    DoUpdateProcessStack(add, processName, actionTime, serverActionTime);
                }
            }
            catch (Exception exception)
            {
                SBPlusClient.LogError("Exception caught.", exception);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ScreenProcessDescription"/> class.
        /// </summary>
        /// <param name="fileName">
        /// The name of the file that contains the screen.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="definition">
        /// The definition.
        /// </param>
        public ScreenProcessDescription(string fileName, string name, string expression, SBString definition)
            : this(fileName, name, expression)
        {
            if (!string.IsNullOrWhiteSpace(definition.Extract(5, 1).Value))
            {
                this.Dictionary = definition.Extract(5, 1).Value;
                this.ProcessCollection.Add(
                    new ProcessCall { Description = "Dictionary", ProcessDescription = new DictionaryDescription(this.Dictionary) });
            }

            if (!string.IsNullOrWhiteSpace(definition.Extract(6).Value))
            {
                this.ScreenName = definition.Extract(6).Value;
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadScreen(this.ScreenName, this.Dictionary, this, "Screen");

                // Now check if there are linked screens. To do this see if the last character is numeric. If it is go back until you find the first non-numeric. Now
                // we have a starting point, loop adding 1 untill there is no hit.
                int startIndex = this.ScreenName.Length - 1;
                while (SBXA.Shared.Utilities.IsNumber(this.ScreenName.Substring(startIndex)))
                {
                    startIndex++;
                }

                startIndex--; // because it would have been incremented one beyond.
                if (!string.IsNullOrEmpty(this.ScreenName.Substring(startIndex))
                    && Utilities.IsNumber(this.ScreenName.Substring(startIndex)))
                {
                    var nextScreen = Convert.ToInt16(this.ScreenName.Substring(startIndex)) + 1;
                    var prefix = this.ScreenName.Substring(0, startIndex);
                    DebugViewModel.Instance.ProcessAnalysisViewModel.SetIsLoading(1);
                    // I have a starting point, now read the definition.
                    SBFile.ReadDictionaryItem(
                        this.Dictionary,
                        prefix + nextScreen,
                        new object[] { nextScreen, prefix, this.Dictionary },
                        this.ReadLinkedScreenCompleted);
                }
            }

            // load the list of processes
            if (!string.IsNullOrWhiteSpace(definition.Extract(8, 1).Value))
            {
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                    SourceDefinition.Screen,
                    SourceDefinition.Process,
                    definition.Extract(8, 1).Value,
                    this,
                    "Before");
            }

            if (!string.IsNullOrWhiteSpace(definition.Extract(8, 2).Value))
            {
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                    SourceDefinition.Screen,
                    SourceDefinition.Process,
                    definition.Extract(8, 2).Value,
                    this,
                    "After");
            }

            if (!string.IsNullOrWhiteSpace(definition.Extract(8, 7).Value))
            {
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                    SourceDefinition.Screen,
                    SourceDefinition.Process,
                    definition.Extract(8, 7).Value,
                    this,
                    "Before Display");
            }

            if (!string.IsNullOrWhiteSpace(definition.Extract(8, 8).Value))
            {
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                    SourceDefinition.Screen,
                    SourceDefinition.Process,
                    definition.Extract(8, 8).Value,
                    this,
                    "Before Action Bar Option");
            }

            if (!string.IsNullOrWhiteSpace(definition.Extract(8, 4).Value))
            {
                DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                    SourceDefinition.Screen,
                    SourceDefinition.Process,
                    definition.Extract(8, 4).Value,
                    this,
                    "After Action Bar Option");
            }
        }
        /// <summary>
        /// The parse screen definition.
        /// </summary>
        /// <param name="definition">
        /// The definition.
        /// </param>
        private void ParseScreenDefinition(SBString definition)
        {
            const int ButtonDesc = 11;
            const int Buttons = 12;
            const int Fields = 15;
            const int ProcessesBefore = 25;
            const int ProcessesAfter = 26;
            const int IntHelp = 27;
            const int FieldPos = 31;
            const int ConversionCode = 34;
            const int DefaultDerived = 35;
            const int Validation = 36;
            // So far I have not found where or what this is, in the BRANCH S1 screen it looks like a hangove from rev control. const int InputConversion   = 39;
            const int StyleName = 51;

            try
            {
                // fields
                var noFields = definition.Dcount(Fields);
                for (int fno = 1; fno <= noFields; fno++)
                {
                    var processBefore = (definition.Dcount() >= ProcessesBefore && definition.Extract(ProcessesBefore).Dcount() >= fno)
                                            ? definition.Extract(ProcessesBefore, fno).Value
                                            : string.Empty;
                    var processAfter = (definition.Dcount() >= ProcessesAfter && definition.Extract(ProcessesAfter).Dcount() >= fno)
                                           ? definition.Extract(ProcessesAfter, fno).Value
                                           : string.Empty;
                    var intuitiveHelp = (definition.Dcount() >= IntHelp && definition.Extract(IntHelp).Dcount() >= fno)
                                            ? definition.Extract(IntHelp, fno).Value
                                            : string.Empty;
                    var conversionCode = (definition.Dcount() >= ConversionCode && definition.Extract(ConversionCode).Dcount() >= fno)
                                             ? definition.Extract(ConversionCode, fno).Value
                                             : string.Empty;
                    var fieldDefault = string.Empty;
                    if (definition.Dcount() >= FieldPos && definition.Extract(FieldPos).Dcount() >= fno)
                    {
                        fieldDefault = (!string.IsNullOrEmpty(definition.Extract(FieldPos, fno).Value)
                                        && definition.Extract(FieldPos, fno).Value.Substring(0, 1).Equals("0"))
                                           ? string.Empty
                                           : definition.Extract(DefaultDerived, fno).Value;
                    }

                    var derived = string.Empty;
                    if (definition.Dcount() >= FieldPos && definition.Extract(FieldPos).Dcount() >= fno)
                    {
                        derived = (!string.IsNullOrEmpty(definition.Extract(FieldPos, fno).Value)
                                   && definition.Extract(FieldPos, fno).Value.Substring(0, 1).Equals("0"))
                                      ? string.Empty
                                      : definition.Extract(DefaultDerived, fno).Value;
                    }

                    var validation = (definition.Dcount() >= Validation && definition.Extract(Validation).Dcount() >= fno)
                                         ? definition.Extract(Validation, fno).Value
                                         : string.Empty;
                    var styleName = (definition.Dcount() >= StyleName && definition.Extract(StyleName).Dcount() >= fno)
                                        ? definition.Extract(StyleName, fno).Value
                                        : string.Empty;

                    this.FieldDescriptions.Add(
                        new ScreenFieldDefinition(this.FileName, definition.Extract(Fields, fno).Value)
                            {
                                ProcessBefore = processBefore,
                                ProcessAfter = processAfter,
                                IntuitiveHelp = intuitiveHelp,
                                ConversionCode = conversionCode,
                                FieldDefault = fieldDefault,
                                Derived = derived,
                                Validation = validation,
                                StyleName = styleName
                            });
                }

                // Buttons
                var noButtons = definition.Dcount(Buttons);
                for (int bNo = 1; bNo <= noButtons; bNo++)
                {
                    if (!definition.Extract(Buttons, bNo).IsNullOrEmpty())
                    {
                        DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                            SourceDefinition.Button,
                            SourceDefinition.Process,
                            definition.Extract(Buttons, bNo).Value,
                            this,
                            "Button " + definition.Extract(ButtonDesc, bNo).Value);
                    }
                }

                // load the list of processes
                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 1).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 1).Value,
                        this,
                        "Before Screen Display");
                }

                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 2).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 2).Value,
                        this,
                        "After Screen Display");
                }

                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 3).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 3).Value,
                        this,
                        "After Read Record");
                }

                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 4).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 4).Value,
                        this,
                        "After Accept");
                }

                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 5).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 5).Value,
                        this,
                        "After Update");
                }

                if (!string.IsNullOrWhiteSpace(definition.Extract(7, 6).Value))
                {
                    DebugViewModel.Instance.ProcessAnalysisViewModel.LoadProcessFromExpression(
                        SourceDefinition.Screen,
                        SourceDefinition.Process,
                        definition.Extract(7, 6).Value,
                        this,
                        "If Escape");
                }

                // Buttons
            }
            catch (Exception exception)
            {
                CustomLogger.LogException(exception, "Exception parsing screen definition");
                // MessageBox.Show("Exception parsing screen definition (" + exception.Message + ")");
            }
        }