Ejemplo n.º 1
0
        /// <summary>
        /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false.
        /// </summary>
        /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns>
        public override bool ValidateInputs()
        {
            Logger.Instance.WriteMethodEntry();

            try
            {
                // Use the controller to validate standard activity controls
                // and return false if a problem was identified
                if (!this.controller.ValidateInputs())
                {
                    return(false);
                }

                ExpressionEvaluator evaluator = new ExpressionEvaluator();

                if (this.advanced.Value)
                {
                    if (this.queryResources.Value)
                    {
                        // Loop through all active query listings and make sure they are valid
                        foreach (DefinitionListing query in this.queries.DefinitionListings.Where(query => query.Active))
                        {
                            // If a value is missing for key or query, the definition
                            // will be null and the listing fails validation
                            if (query.Definition == null)
                            {
                                this.controller.ValidationError = ActivitySettings.QueryDefinitionValidationError;
                                return(false);
                            }

                            // Make sure that the specified query key is properly formatted
                            if (!Regex.Match(query.Definition.Left, RegexPattern).Success)
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionLeftValidationError, query.Definition.Left);
                                return(false);
                            }

                            // Make sure that the specified XPath filter is properly formatted
                            if (!ExpressionEvaluator.IsXPath(query.Definition.Right))
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionRightValidationError, query.Definition.Left);
                                return(false);
                            }
                        }
                    }

                    try
                    {
                        if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value))
                        {
                            evaluator.ParseExpression(this.activityExecutionCondition.Value);

                            // Verify that the activity execution condition resolves to a Boolean value
                            if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value))
                            {
                                this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError;
                                return(false);
                            }
                        }

                        if (!string.IsNullOrEmpty(this.iteration.Value))
                        {
                            evaluator.ParseExpression(this.iteration.Value);
                        }

                        if (GetActorType(this.actorType.Value) == ActorType.Resolve)
                        {
                            evaluator.ParseExpression(this.actorString.Value);
                        }
                    }
                    catch (WorkflowActivityLibraryException ex)
                    {
                        this.controller.ValidationError = ex.Message;
                        return(false);
                    }

                    if (this.applyAuthorizationPolicy.Value && GetActorType(this.actorType.Value) == ActorType.Service)
                    {
                        this.controller.ValidationError = ActivitySettings.RequestActorValidationError;
                        return(false);
                    }
                }

                // Loop through all active update listings and make sure they are valid
                foreach (DefinitionListing update in this.updates.DefinitionListings.Where(update => update.Active))
                {
                    if (update.Definition == null)
                    {
                        // If a value is missing for source or target, the definition
                        // will be null and the listing fails validation
                        this.controller.ValidationError = ActivitySettings.UpdateDefinitionValidationError;
                        return(false);
                    }

                    // Attempt to parse the source expression and target lookup or variable
                    // Fail validation if an exception is thrown for either
                    try
                    {
                        evaluator.ParseExpression(update.Definition.Left);
                        ParameterType targetType = ParameterType.Lookup;
                        try
                        {
                            targetType = ExpressionEvaluator.DetermineParameterType(update.Definition.Right);
                        }
                        catch (WorkflowActivityLibraryException)
                        {
                        }

                        // Target variables are valid
                        // Target lookups require further evaluation to determine if they represent a valid target
                        if (targetType != ParameterType.Variable)
                        {
                            LookupEvaluator lookup = new LookupEvaluator(update.Definition.Right);
                            if (!lookup.IsValidTarget)
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, update.Definition.Right);
                                return(false);
                            }
                        }
                    }
                    catch (WorkflowActivityLibraryException ex)
                    {
                        this.controller.ValidationError = ex.Message;
                        return(false);
                    }
                }

                // Verify that no [//Query/...] or [//Value/...] expressions exist
                // if the query resources or iteration options are not enabled, respectively
                bool containsQueryExpressions = false;
                bool containsValueExpressions = false;

                foreach (LookupEvaluator lookup in evaluator.LookupCache.Keys.Select(key => new LookupEvaluator(key)))
                {
                    if (lookup.Parameter == LookupParameter.Queries)
                    {
                        containsQueryExpressions = true;
                    }

                    if (lookup.Parameter == LookupParameter.Value)
                    {
                        containsValueExpressions = true;
                    }
                }

                if (!this.queryResources.Value && containsQueryExpressions)
                {
                    this.controller.ValidationError = ActivitySettings.QueryResourcesValidationError;
                    return(false);
                }

                if (string.IsNullOrEmpty(this.iteration.Value) && containsValueExpressions)
                {
                    this.controller.ValidationError = ActivitySettings.IterationValidationError;
                    return(false);
                }

                // If no errors were found, clear any validation error and return true
                this.controller.ValidationError = string.Empty;
                return(true);
            }
            catch (Exception e)
            {
                Logger.Instance.ReportError(e);
                throw;
            }
            finally
            {
                Logger.Instance.WriteMethodExit();
            }
        }
        /// <summary>
        /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false.
        /// </summary>
        /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns>
        public override bool ValidateInputs()
        {
            Logger.Instance.WriteMethodEntry();

            try
            {
                // Use the controller to validate standard activity controls
                // and return false if a problem was identified
                if (!this.controller.ValidateInputs())
                {
                    return(false);
                }

                ExpressionEvaluator evaluator = new ExpressionEvaluator();

                // Verify that the resource type is valid
                if (!Regex.Match(this.resourceType.Value, RegexPattern).Success)
                {
                    this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.ResourceTypeValidationError, this.resourceType.Value);
                    return(false);
                }

                if (this.advanced.Value)
                {
                    if (this.queryResources.Value)
                    {
                        // Loop through all active query listings and make sure they are valid
                        foreach (DefinitionListing query in this.queries.DefinitionListings)
                        {
                            if (query.Active)
                            {
                                // If a value is missing for key or query, the definition
                                // will be null and the listing fails validation
                                if (query.Definition == null)
                                {
                                    this.controller.ValidationError = ActivitySettings.QueryDefinitionValidationError;
                                    return(false);
                                }

                                // Make sure that the specified query key is properly formatted
                                if (!Regex.Match(query.Definition.Left, RegexPattern).Success)
                                {
                                    this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionLeftValidationError, query.Definition.Left);
                                    return(false);
                                }

                                // Make sure that the specified XPath filter is properly formatted
                                if (!ExpressionEvaluator.IsXPath(query.Definition.Right))
                                {
                                    this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionRightValidationError, query.Definition.Left);
                                    return(false);
                                }
                            }
                        }
                    }

                    try
                    {
                        if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value))
                        {
                            evaluator.ParseExpression(this.activityExecutionCondition.Value);

                            // Verify that the activity execution condition resolves to a Boolean value
                            if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value))
                            {
                                this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError;
                                return(false);
                            }
                        }

                        if (!string.IsNullOrEmpty(this.iteration.Value))
                        {
                            evaluator.ParseExpression(this.iteration.Value);
                        }

                        if (GetActorType(this.actorType.Value) == ActorType.Resolve)
                        {
                            evaluator.ParseExpression(this.actorString.Value);
                        }

                        // Verify that the supplied conflict filter is a valid XPath query, if necessary
                        if (this.checkForConflict.Value && !ExpressionEvaluator.IsXPath(this.conflictFilter.Value))
                        {
                            this.controller.ValidationError = ActivitySettings.ConflictResourceSearchFilterValidationError;
                            return(false);
                        }

                        // If necessary, parse the created resource ID target lookup to ensure its validity
                        if (!string.IsNullOrEmpty(this.createdResourceIdTarget.Value))
                        {
                            LookupEvaluator createdTargetLookup = new LookupEvaluator(this.createdResourceIdTarget.Value);
                            if (!createdTargetLookup.IsValidTarget)
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.createdResourceIdTarget.Value);
                                return(false);
                            }
                        }

                        // If necessary, parse the conflicting resource ID target lookup to ensure its validity
                        if (this.checkForConflict.Value && !string.IsNullOrEmpty(this.conflictingResourceIdTarget.Value))
                        {
                            LookupEvaluator conflictingTargetLookup = new LookupEvaluator(this.conflictingResourceIdTarget.Value);
                            if (!conflictingTargetLookup.IsValidTarget)
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.conflictingResourceIdTarget.Value);
                                return(false);
                            }
                        }
                    }
                    catch (WorkflowActivityLibraryException ex)
                    {
                        // If an exception was thrown while attempting to parse lookups, report the error
                        this.controller.ValidationError = ex.Message;
                        return(false);
                    }

                    if (this.applyAuthorizationPolicy.Value && GetActorType(this.actorType.Value) == ActorType.Service)
                    {
                        this.controller.ValidationError = ActivitySettings.RequestActorValidationError;
                        return(false);
                    }
                }

                // Loop through all active definition listings and make sure they are valid
                foreach (DefinitionListing listing in this.attributes.DefinitionListings)
                {
                    if (!listing.Active)
                    {
                        continue;
                    }

                    if (listing.Definition == null)
                    {
                        // If a value is missing for source or target, the definition
                        // will be null and the listing fails validation
                        // Because the activity allows for the creation of a resource without any attributes,
                        // we need to check if this is the only active listing for the form and, if so,
                        // verify that all fields have been left blank before failing validation
                        int countActive = this.attributes.DefinitionListings.Count(l => l.Active);
                        if (countActive != 1 ||
                            !string.IsNullOrEmpty(listing.State.Left) ||
                            !string.IsNullOrEmpty(listing.State.Right))
                        {
                            this.controller.ValidationError = ActivitySettings.AttributeDefinitionValidationError;
                            return(false);
                        }
                    }
                    else
                    {
                        // Attempt to parse the source expression and fail validation
                        // if an exception is thrown by the expression evaluator
                        try
                        {
                            evaluator.ParseExpression(listing.Definition.Left);
                        }
                        catch (WorkflowActivityLibraryException ex)
                        {
                            this.controller.ValidationError = ex.Message;
                            return(false);
                        }

                        ParameterType targetType = ParameterType.String;
                        try
                        {
                            targetType = ExpressionEvaluator.DetermineParameterType(listing.Definition.Right, true);
                        }
                        catch (WorkflowActivityLibraryException)
                        {
                        }

                        // Target variables are valid
                        // For anything else, make sure that the target attribute matches the regular
                        // expression for FIM attributes
                        if (targetType != ParameterType.Variable)
                        {
                            if (!Regex.Match(listing.Definition.Right, RegexPattern).Success)
                            {
                                this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetValidationError, listing.Definition.Right);
                                return(false);
                            }
                        }
                    }
                }

                // Verify that no [//Query/...] or [//Value/...] expressions exist
                // if the query resources or iteration options are not enabled, respectively
                bool containsQueryExpressions = false;
                bool containsValueExpressions = false;

                foreach (LookupEvaluator lookup in evaluator.LookupCache.Keys.Select(key => new LookupEvaluator(key)))
                {
                    if (lookup.Parameter == LookupParameter.Queries)
                    {
                        containsQueryExpressions = true;
                    }

                    if (lookup.Parameter == LookupParameter.Value)
                    {
                        containsValueExpressions = true;
                    }
                }

                if (!this.queryResources.Value && containsQueryExpressions)
                {
                    this.controller.ValidationError = ActivitySettings.QueryResourcesValidationError;
                    return(false);
                }

                if (string.IsNullOrEmpty(this.iteration.Value) && containsValueExpressions)
                {
                    this.controller.ValidationError = ActivitySettings.IterationValidationError;
                    return(false);
                }

                // If no errors were found, clear any validation error and return true
                this.controller.ValidationError = string.Empty;
                return(true);
            }
            catch (Exception e)
            {
                Logger.Instance.ReportError(e);
                throw;
            }
            finally
            {
                Logger.Instance.WriteMethodExit();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles the ExecuteCode event of the BuildRequests CodeActivity.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void BuildRequests_ExecuteCode(object sender, EventArgs e)
        {
            Logger.Instance.WriteMethodEntry(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode);

            try
            {
                foreach (UpdateLookupDefinition update in this.UpdateLookupDefinitions)
                {
                    LookupEvaluator lookup = new LookupEvaluator(update.TargetLookup);
                    if (lookup.TargetIsWorkflowDictionary)
                    {
                        // Get the parent workflow to facilitate access to the workflow dictionary
                        SequentialWorkflow parentWorkflow;
                        SequentialWorkflow.TryGetContainingWorkflow(this, out parentWorkflow);

                        // For simplicity, start by adding the key to the parent workflow dictionary so we can assume that its there
                        if (!parentWorkflow.WorkflowDictionary.ContainsKey(lookup.TargetAttribute))
                        {
                            parentWorkflow.WorkflowDictionary.Add(lookup.TargetAttribute, null);
                        }

                        if (update.Mode == UpdateMode.Modify)
                        {
                            parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = update.Value;
                        }
                        else if (update.Value != null)
                        {
                            // Use reflection to determine the expected List<> type based on the value
                            // Also get the Add and Remove methods for the list
                            Type       listType = typeof(List <>).MakeGenericType(new Type[] { update.Value.GetType() });
                            MethodInfo add      = listType.GetMethod("Add");
                            MethodInfo remove   = listType.GetMethod("Remove");

                            switch (update.Mode)
                            {
                            case UpdateMode.Insert:
                                if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null)
                                {
                                    parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = update.Value;
                                }
                                else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == update.Value.GetType())
                                {
                                    // Single value, create a new instance of the appropriate List<> type
                                    // and add both values: existing and new
                                    object existingValue = parentWorkflow.WorkflowDictionary[lookup.TargetAttribute];
                                    parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = Activator.CreateInstance(listType);
                                    add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { existingValue });
                                    add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value });
                                }
                                else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == listType)
                                {
                                    // The dictionary key is a list of the expected type, add the value
                                    add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value });
                                }
                                else
                                {
                                    // We have a problem and need to report an error
                                    throw Logger.Instance.ReportError(new WorkflowActivityLibraryException(Messages.UpdateLookup_InsertVariableError, update.Value.GetType(), lookup.TargetAttribute, parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType()));
                                }

                                break;

                            case UpdateMode.Remove:
                                if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null)
                                {
                                    // Do nothing
                                }
                                else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].Equals(update.Value))
                                {
                                    // A single matching value exists, clear the variable
                                    parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = null;
                                }
                                else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == listType)
                                {
                                    // The variable is a list of the expected type, attempt to remove the value
                                    remove.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value });

                                    // Check the count on the list to determine if we are down to a single value or have no value
                                    // If so, adjust the value of the variable accordingly to eliminate the list
                                    object listValue = null;
                                    int    i         = 0;
                                    foreach (object o in (IEnumerable)parentWorkflow.WorkflowDictionary[lookup.TargetAttribute])
                                    {
                                        i        += 1;
                                        listValue = o;
                                    }

                                    if (i <= 1)
                                    {
                                        parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = listValue;
                                    }
                                }

                                break;
                            }
                        }

                        // If we ended up with a null value in the workflow dictionary key,
                        // remove the key to cleanup after ourselves
                        if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null)
                        {
                            parentWorkflow.WorkflowDictionary.Remove(lookup.TargetAttribute);
                        }
                    }
                    else if (!string.IsNullOrEmpty(lookup.TargetResourceLookup) &&
                             this.TargetLookups.ContainsKey(lookup.TargetResourceLookup) &&
                             this.TargetLookups[lookup.TargetResourceLookup] != null)
                    {
                        // Based on the type of the resolved target lookup (should be Guid or List<Guid>)
                        // build the list of target resources for the update
                        List <Guid> targets = new List <Guid>();
                        if (this.TargetLookups[lookup.TargetResourceLookup] is Guid)
                        {
                            targets.Add((Guid)this.TargetLookups[lookup.TargetResourceLookup]);
                        }
                        else if (this.TargetLookups[lookup.TargetResourceLookup].GetType() == typeof(List <Guid>))
                        {
                            targets.AddRange((List <Guid>) this.TargetLookups[lookup.TargetResourceLookup]);
                        }

                        foreach (Guid target in targets)
                        {
                            // Add the target to the update requests dictionary, if it doesn't already exist,
                            // and add the new update request parameter
                            if (!this.PendingRequests.ContainsKey(target))
                            {
                                this.PendingRequests.Add(target, new List <UpdateRequestParameter>());
                            }

                            this.PendingRequests[target].Add(new UpdateRequestParameter(lookup.TargetAttribute, update.Mode, update.Value));
                        }
                    }
                }

                // If there are requests that need to be submitted to fulfill the updates,
                // assign the list of targets to the for each loop which will evaluate each change
                // to determine if they will result in changes
                if (this.PendingRequests.Count > 0)
                {
                    this.ForEachPending.InitialChildData = this.PendingRequests.Keys.ToList();
                }

                Logger.Instance.WriteVerbose(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode, "The number of requests that need to be submitted to fulfill the updates: '{0}'.", this.PendingRequests.Count);
            }
            finally
            {
                Logger.Instance.WriteMethodExit(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Evaluate a string based expression.
        /// </summary>
        /// <param name="expression">The expression to evaluate</param>
        /// <param name="variableLookup">A delegate that should return the value of the variable specified.</param>
        /// <returns>An evaluated expression</returns>
        public static int Evaluate(string expression, LookupEvaluator variableLookup)
        {
            // Get all tokens then remap and strip all whitespace //
            var tokens = Regex.Split(expression, "(?<=[-+*/(),])(?=.)|(?<=.)(?=[-+*/(),])")
                         .Select(element => Regex.Replace(element, "\\s+", ""))
                         .Where(element => element != "")
                         .ToArray();

            var OperationStack = new Stack <OperationToken>();
            var NumberStack    = new Stack <double>();

            // Will either be a 1 or -1
            int?sign = null;

            for (int i = 0; i < tokens.Length; i++)
            {
                var    token          = tokens[i];
                double?possibleNumber = getNumberOrNothing(token);
                var    operation      = new OperationToken
                {
                    Operation = token[0]
                };
                if (!operation.IsValid && !possibleNumber.HasValue)
                {
                    // Is a variable //
                    possibleNumber = variableLookup(token);
                }

                // Handle negatives and positives //
                if (sign.HasValue)
                {
                    possibleNumber = possibleNumber * sign;
                    sign           = null;
                }


                if (possibleNumber.HasValue)
                {
                    // Is number //

                    if (!OperationStack.IsEmpty())
                    {
                        var topOperation = OperationStack.Peek();
                        if (topOperation.IsDivision || topOperation.IsMultiplication)
                        {
                            if (NumberStack.Count < 1)
                            {
                                throw new ArgumentException("Invalid Syntax");
                            }

                            OperationStack.Pop(); // Passed our test, remove from stack //

                            var number = NumberStack.Pop();

                            NumberStack.Push(topOperation.Apply(number, possibleNumber.Value));

                            continue;
                        }
                    }

                    NumberStack.Push(possibleNumber.Value);
                }
                else
                {
                    if (operation.IsAddition || operation.IsSubtraction)
                    {
                        var previousIndex = i - 1;
                        if (previousIndex < 0)
                        {
                            // The sign provided was the first sign, it must be a + or - signifying that its positive or negative //
                            sign = operation.IsSubtraction ? -1 : 1;
                            continue;
                        }
                        else
                        {
                            var previousOperation = new OperationToken()
                            {
                                Operation = tokens[previousIndex][0]
                            };

                            // If the previous token was an operation then this token must mean positive or negative //
                            // Also make sure its not the last operation either //
                            if (previousOperation.IsOperation && i + 1 < tokens.Length)
                            {
                                sign = operation.IsSubtraction ? -1 : 1;
                                continue;
                            }
                            else if (!OperationStack.IsEmpty())
                            {
                                // There's a pending operation, let's do that instead //

                                var topOperation = OperationStack.Peek();
                                if (topOperation.IsAddition || topOperation.IsSubtraction)
                                {
                                    if (NumberStack.Count < 2)
                                    {
                                        throw new ArgumentException("Invalid Syntax");
                                    }

                                    OperationStack.Pop();

                                    var number1 = NumberStack.Pop();
                                    var number2 = NumberStack.Pop();

                                    NumberStack.Push(topOperation.Apply(number2, number1));
                                }
                            }
                        }


                        OperationStack.Push(operation);
                    }
                    else if (operation.IsMultiplication || operation.IsDivision || operation.IsOpenBrace)
                    {
                        // Nothing complex, just push operation to stack //
                        OperationStack.Push(operation);
                    }
                    else if (operation.IsClosingBrace)
                    {
                        if (!OperationStack.IsEmpty())
                        {
                            // If there's already a pending operation. //
                            var topOperation = OperationStack.Peek();
                            if (topOperation.IsAddition || topOperation.IsSubtraction)
                            {
                                if (NumberStack.Count < 2)
                                {
                                    throw new ArgumentException("Invalid Syntax");
                                }

                                OperationStack.Pop();

                                var number1 = NumberStack.Pop();
                                var number2 = NumberStack.Pop();

                                NumberStack.Push(topOperation.Apply(number2, number1));
                            }
                        }

                        // Check for ending parenthesis //
                        if (OperationStack.IsEmpty() || !OperationStack.Pop().IsOpenBrace)
                        {
                            throw new ArgumentException("Expecting '('. Invalid syntax.");
                        }

                        // Operation size could have changed, we need to check again //
                        if (!OperationStack.IsEmpty())
                        {
                            var topOperation = OperationStack.Peek();
                            if (topOperation.IsDivision || topOperation.IsMultiplication)
                            {
                                if (NumberStack.Count < 1)
                                {
                                    throw new ArgumentException("Invalid Syntax");
                                }

                                OperationStack.Pop(); // Passed our test, remove from stack //

                                var b = NumberStack.Pop();

                                if (!possibleNumber.HasValue)
                                {
                                    possibleNumber = NumberStack.Pop();
                                }

                                NumberStack.Push(topOperation.Apply(possibleNumber.Value, b));
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Invalid Syntax. Cannot handle given operation.");
                    }
                }
            }

            if (OperationStack.Count >= 2)
            {
                throw new ArgumentException("Invalid Syntax. Cannot handle given operation.");
            }

            if (OperationStack.Count == 1)
            {
                var b = NumberStack.Pop();
                var a = NumberStack.Pop();

                return((int)OperationStack.Pop().Apply(a, b));
            }
            else
            {
                return((int)NumberStack.Pop());
            }
        }
        /// <summary>
        /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false.
        /// </summary>
        /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns>
        public override bool ValidateInputs()
        {
            Logger.Instance.WriteMethodEntry();

            try
            {
                // Use the controller to validate standard activity controls
                // and return false if a problem was identified
                if (!this.controller.ValidateInputs())
                {
                    return(false);
                }

                try
                {
                    // Verify that the target lookup is valid
                    LookupEvaluator targetLookup = new LookupEvaluator(this.publicationTarget.Value);
                    if (!targetLookup.IsValidTarget)
                    {
                        this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.publicationTarget.Value);
                        return(false);
                    }
                }
                catch (WorkflowActivityLibraryException ex)
                {
                    // If an exception was thrown while attempting to parse lookups, report the error
                    this.controller.ValidationError = ex.Message;
                    return(false);
                }

                // Verify that the supplied conflict filter is a valid XPath query
                if (!ExpressionEvaluator.IsXPath(this.conflictFilter.Value))
                {
                    this.controller.ValidationError = ActivitySettings.ConflictFilterValidationError;
                    return(false);
                }

                // Verify that the supplied conflict filter contains the [//Value] lookup
                if (!this.conflictFilter.Value.ToUpperInvariant().Contains("[//VALUE]"))
                {
                    this.controller.ValidationError = ActivitySettings.ConflictFilterValueLookupValidationError;
                    return(false);
                }

                ExpressionEvaluator evaluator = new ExpressionEvaluator();

                if (this.queryLdap.Value)
                {
                    // Loop through all active query listings and make sure they are valid
                    foreach (DefinitionListing query in this.ldapQueries.DefinitionListings.Where(query => query.Active))
                    {
                        // If a value is missing for key or query, the definition
                        // will be null and the listing fails validation
                        if (query.Definition == null)
                        {
                            this.controller.ValidationError = ActivitySettings.LdapQueryDefinitionValidationError;
                            return(false);
                        }

                        // Make sure that the specified XPath filter is properly formatted
                        if (!query.Definition.Right.ToUpperInvariant().Contains("[//VALUE]"))
                        {
                            this.controller.ValidationError = ActivitySettings.LdapQueryDefinitionValueLookupValidationError;
                            return(false);
                        }

                        // If it's an expression, make sure it's properly formatted
                        if (ExpressionEvaluator.IsExpression(query.Definition.Left))
                        {
                            try
                            {
                                evaluator.ParseExpression(query.Definition.Left);
                            }
                            catch (WorkflowActivityLibraryException ex)
                            {
                                this.controller.ValidationError = ex.Message;
                                return(false);
                            }
                        }
                    }
                }

                // Count the active value expressions
                int count = this.valueExpressions.DefinitionListings.Count(valueExpression => valueExpression.Active);

                // Loop through all active update listings and make sure they are valid
                int i = 1;
                foreach (DefinitionListing valueExpression in this.valueExpressions.DefinitionListings.Where(valueExpression => valueExpression.Active))
                {
                    if (string.IsNullOrEmpty(valueExpression.State.Left))
                    {
                        // If a value is missing for the expression, fail validation
                        this.controller.ValidationError = ActivitySettings.ValueExpressionValidationError;
                        return(false);
                    }

                    // Attempt to parse the value expression
                    try
                    {
                        evaluator.ParseExpression(valueExpression.State.Left);
                    }
                    catch (WorkflowActivityLibraryException ex)
                    {
                        this.controller.ValidationError = ex.Message;
                        return(false);
                    }

                    // Verify that the [//UniquenessKey] lookup is only present in the last value expression
                    bool containsKey = valueExpression.State.Left.ToUpperInvariant().Contains("[//UNIQUENESSKEY]");
                    if (i < count && containsKey)
                    {
                        this.controller.ValidationError = ActivitySettings.ValueExpressionUniquenessKeyValidationError;
                        return(false);
                    }

                    if (i == count && !containsKey)
                    {
                        this.controller.ValidationError = ActivitySettings.ValueExpressionMissingUniquenessKeyValidationError;
                        return(false);
                    }

                    i += 1;
                }

                try
                {
                    if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value))
                    {
                        evaluator.ParseExpression(this.activityExecutionCondition.Value);

                        // Verify that the activity execution condition resolves to a Boolean value
                        if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value))
                        {
                            this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError;
                            return(false);
                        }
                    }
                }
                catch (WorkflowActivityLibraryException ex)
                {
                    this.controller.ValidationError = ex.Message;
                    return(false);
                }

                // If no errors were found, clear any validation error and return true
                this.controller.ValidationError = string.Empty;
                return(true);
            }
            catch (Exception e)
            {
                Logger.Instance.ReportError(e);
                throw;
            }
            finally
            {
                Logger.Instance.WriteMethodExit();
            }
        }