private double MemoizeCalculateResult(IterationDefinition iterationDefinition, string formula,
                                              int numberOfSimbolsAfterComma)
        {
            if (_iterationDefinitionsCache.ContainsKey(formula))
            {
                IterationDefinition iteration = _iterationDefinitionsCache[formula]
                                                .FirstOrDefault(definition => definition.CheckEquality(iterationDefinition));
                if (iteration != null)
                {
                    return(iteration.Result);
                }
            }

            Expression      expression = new Expression(formula);
            List <Argument> arguments  = new List <Argument>();

            for (int i = 0; i < iterationDefinition.ArgumentValues.Count; i++)
            {
                arguments.Add(new Argument(iterationDefinition.ArgumentNames[i],
                                           iterationDefinition.ArgumentValues[i]));
            }

            expression.addArguments(arguments.ToArray());
            double result = expression.calculate();

            if (Double.IsNaN(result))
            {
                throw new ArgumentException();
            }

            result = Math.Round(result, numberOfSimbolsAfterComma);

            iterationDefinition.Result = result;
            if (_iterationDefinitionsCache.ContainsKey(formula))
            {
                _iterationDefinitionsCache[formula].Add(iterationDefinition);
            }
            else
            {
                _iterationDefinitionsCache.TryAdd(formula,
                                                  new ConcurrentBag <IterationDefinition>()
                {
                    iterationDefinition
                });
            }

            return(result);
        }
        //public async Task<IFormattedValue> VisitFormulaFormatter(IUshortsFormatter formatter)
        //{
        //    INumericValue formattedValue = _typesContainer.Resolve<INumericValue>();
        //    IterationDefinition iterationDefinition = new IterationDefinition();
        //    IFormulaFormatter formulaFormatter = formatter as IFormulaFormatter;

        //    iterationDefinition.FormulaString = formulaFormatter.FormulaString;

        //    iterationDefinition.ArgumentNames = new List<string>();
        //    iterationDefinition.ArgumentValues = new List<double>();
        //    iterationDefinition.ArgumentNames.Add("x");
        //    iterationDefinition.ArgumentValues.Add(_ushortsPayload[0]);
        //    iterationDefinition.NumberOfSimbolsAfterComma = formulaFormatter.NumberOfSimbolsAfterComma;
        //    if (formulaFormatter.UshortFormattableResources != null)
        //    {
        //        //  int index = 1;
        //        //  foreach (IUshortFormattable formattableUshortResource in formulaFormatter.UshortFormattableResources)
        //        //  {
        //        // if (formattableUshortResource is IDeviceValueContaining)
        //        // {
        //        //     IFormattedValue value = formattableUshortResource.UshortsFormatter
        //        //        .Format((formattableUshortResource as IDeviceValueContaining).DeviceUshortsValue);
        //        //    if (value is INumericValue)
        //        //   {
        //        //       double num = (value as INumericValue).NumValue;
        //        //        iterationDefinition.ArgumentNames.Add("x" + index++);
        //        //       iterationDefinition.ArgumentValues.Add(num);
        //        //    }
        //        //  }
        //        // }
        //    }

        //    formattedValue.NumValue = MemoizeCalculateResult(iterationDefinition, formulaFormatter.FormulaString,
        //        formulaFormatter.NumberOfSimbolsAfterComma);
        //    return formattedValue;
        //}

        public async Task <IFormattedValue> VisitFormulaFormatter(IUshortsFormatter formatter)
        {
            INumericValue       formattedValue      = _typesContainer.Resolve <INumericValue>();
            IterationDefinition iterationDefinition = new IterationDefinition();
            IFormulaFormatter   formulaFormatter    = formatter as IFormulaFormatter;

            iterationDefinition.FormulaString = formulaFormatter.FormulaString;

            iterationDefinition.ArgumentNames  = new List <string>();
            iterationDefinition.ArgumentValues = new List <double>();
            iterationDefinition.ArgumentNames.Add("x");
            iterationDefinition.ArgumentValues.Add(_ushortsPayload[0]);
            iterationDefinition.NumberOfSimbolsAfterComma = formulaFormatter.NumberOfSimbolsAfterComma;
            if (formulaFormatter.UshortFormattableResources != null)
            {
                int index = 1;
                foreach (string formattableUshortResource in formulaFormatter.UshortFormattableResources)
                {
                    var resource = _formattingContext.DeviceContext.DeviceSharedResources.SharedResourcesInContainers.FirstOrDefault(
                        container => container.ResourceName == formattableUshortResource);

                    var propValue = await StaticContainer.Container.Resolve <IPropertyValueService>()
                                    .GetValueOfProperty(resource.Resource, _formattingContext.DeviceContext, true, _isLocal);

                    if (propValue.Item is INumericValue numericValue)
                    {
                        double num = numericValue.NumValue;
                        iterationDefinition.ArgumentNames.Add("x" + index++);
                        iterationDefinition.ArgumentValues.Add(num);
                    }
                }
            }

            formattedValue.NumValue = MemoizeCalculateResult(iterationDefinition, formulaFormatter.FormulaString,
                                                             formulaFormatter.NumberOfSimbolsAfterComma);
            return(formattedValue);
        }