Пример #1
0
        public async Task <Template> Unlink(TemplateLink link) //CLONE
        {
            var entity = await _templateStore.Load(link.TemplateId);

            if (entity == null || !entity.Workspace.CanEdit(User))
            {
                throw new InvalidOperationException();
            }

            if (entity.Parent != null)
            {
                TemplateUtility tu = new TemplateUtility(entity.Parent.Detail);

                tu.Name = entity.Name;

                tu.LocalizeDiskPaths(entity.Workspace.GlobalId, entity.GlobalId);

                entity.Detail = tu.ToString();

                entity.Parent = null;

                await _templateStore.Update(entity);
            }

            return(Mapper.Map <Template>(entity, WithActor()));
        }
Пример #2
0
        public async Task <ActionResult <Template> > Link([FromBody] TemplateLink link)
        {
            var result = await _templateService.Link(link);

            SendBroadcast(result, "added");

            return(Ok(result));
        }
Пример #3
0
 internal DeploymentProperties(object template, TemplateLink templateLink, object parameters, ParametersLink parametersLink, DeploymentMode mode, DebugSetting debugSetting)
 {
     Template       = template;
     TemplateLink   = templateLink;
     Parameters     = parameters;
     ParametersLink = parametersLink;
     Mode           = mode;
     DebugSetting   = debugSetting;
 }
        private void ProcessParameterFile(string parameterFile)
        {
            try
            {
                // Check that the JSON file is an ARM template parameter file
                var rootedParameterFile = PSRuleOption.GetRootedPath(parameterFile);
                var parameterObject     = ReadFile <JObject>(rootedParameterFile);
                if (parameterObject == null || !IsParameterFile(parameterObject))
                {
                    return;
                }

                // Check if metadata property exists
                if (!((TryMetadata(parameterObject, rootedParameterFile, out JObject metadata, out string templateFile)) || TryTemplateByName(parameterFile, out templateFile)))
                {
                    if (metadata == null && !_SkipUnlinked)
                    {
                        throw new InvalidTemplateLinkException(string.Format(CultureInfo.CurrentCulture, PSRuleResources.MetadataNotFound, parameterFile));
                    }

                    if (templateFile == null && !_SkipUnlinked)
                    {
                        throw new InvalidTemplateLinkException(string.Format(CultureInfo.CurrentCulture, PSRuleResources.TemplateLinkNotFound, parameterFile));
                    }

                    return;
                }

                var templateLink = new TemplateLink(templateFile, rootedParameterFile);

                // Populate remaining properties
                if (TryStringProperty(metadata, PROPERTYNAME_NAME, out string name))
                {
                    templateLink.Name = name;
                }

                if (TryStringProperty(metadata, PROPERTYNAME_DESCRIPTION, out string description))
                {
                    templateLink.Description = description;
                }

                Context.Writer.WriteObject(templateLink, false);
            }
            catch (InvalidOperationException ex)
            {
                Context.Writer.WriteError(ex, nameof(InvalidOperationException), ErrorCategory.InvalidOperation, parameterFile);
            }
            catch (FileNotFoundException ex)
            {
                Context.Writer.WriteError(ex, nameof(FileNotFoundException), ErrorCategory.ObjectNotFound, parameterFile);
            }
            catch (PipelineException ex)
            {
                Context.Writer.WriteError(ex, nameof(PipelineException), ErrorCategory.WriteError, parameterFile);
            }
        }
        private static string ToString(TemplateLink templateLink)
        {
            StringBuilder result = new StringBuilder();

            if (templateLink != null)
            {
                result.AppendLine();
                result.AppendLine(string.Format("{0, -15}: {1}", "Uri", templateLink.Uri));
                result.AppendLine(string.Format("{0, -15}: {1}", "ContentVersion", templateLink.ContentVersion));
            }

            return(result.ToString());
        }
Пример #6
0
 private void BuildTables(TemplateContainer node)
 {
     foreach (MetaTable table in model.Tables)
     {
         TemplateContainer arrnode = node.AddArrayValue(table.Id.ToString());
         arrnode.AddFromObject(table);
         TemplateLink listLink = arrnode.AddListLink("Columns", "/Columns");
         foreach (MetaColumn column in table.Columns)
         {
             listLink.AddListValue(table.Id.ToString() + "!" + column.Ix.ToString());
         }
     }
 }
Пример #7
0
        private async Task _validate(TemplateLink model)
        {
            if ((await Exists(model.TemplateId)).Equals(false))
            {
                throw new ResourceNotFound();
            }

            if ((await _store.DbContext.Workspaces.FindAsync(model.WorkspaceId)) == null)
            {
                throw new ResourceNotFound();
            }

            await Task.CompletedTask;
        }
Пример #8
0
        private void ProcessTemplateFile(string templateFile)
        {
            try
            {
                var rootedTemplateFile = PSDocumentOption.GetRootedPath(templateFile);

                // Check if metadata property exists
                if (!TryTemplateFile(rootedTemplateFile, out string version, out JObject metadata))
                {
                    return;
                }

                var templateLink = new TemplateLink(rootedTemplateFile, version);

                // Populate remaining properties
                if (TryStringProperty(metadata, PROPERTYNAME_NAME, out string name))
                {
                    templateLink.Name = name;
                }

                if (TryStringProperty(metadata, PROPERTYNAME_DESCRIPTION, out string description))
                {
                    templateLink.Description = description;
                }

                if (TryMetadata(metadata, out Hashtable meta))
                {
                    templateLink.Metadata = meta;
                }

                // var pso = PSObject.AsPSObject(templateLink);
                // var instanceNameProp = new PSNoteProperty("InstanceName", string.Concat(templateLink.Name, "_v", templateLink.Version.Major));
                // pso.Members.Add(new PSMemberSet("PSDocs", new PSMemberInfo[] { instanceNameProp }));

                Writer.WriteObject(templateLink, false);
            }
            catch (InvalidOperationException ex)
            {
                Writer.WriteError(ex, nameof(InvalidOperationException), ErrorCategory.InvalidOperation, templateFile);
            }
            catch (FileNotFoundException ex)
            {
                Writer.WriteError(ex, nameof(FileNotFoundException), ErrorCategory.ObjectNotFound, templateFile);
            }
            catch (PipelineException ex)
            {
                Writer.WriteError(ex, nameof(PipelineException), ErrorCategory.WriteError, templateFile);
            }
        }
Пример #9
0
        public async Task <ActionResult <Template> > UnLinkTemplate([FromBody] TemplateLink model)
        {
            await Validate(model);

            AuthorizeAny(
                () => Actor.IsAdmin,
                () => _svc.CanEdit(model.TemplateId, Actor.Id).Result
                );

            var result = await _svc.Unlink(model);

            SendBroadcast(result, "updated");

            return(Ok(result));
        }
Пример #10
0
        public async Task <ActionResult <Template> > LinkTemplate([FromBody] TemplateLink model)
        {
            await Validate(model);

            AuthorizeAny(
                () => Actor.IsAdmin,
                () => _svc.CanEditWorkspace(model.WorkspaceId, Actor.Id).Result
                );

            var result = await _svc.Link(model, Actor.IsCreator);

            SendBroadcast(result, "added");

            return(Ok(result));
        }
        private static string ConstructTemplateLinkView(TemplateLink templateLink)
        {
            if (templateLink == null)
            {
                return(string.Empty);
            }

            StringBuilder result = new StringBuilder();

            result.AppendLine();
            result.AppendLine(string.Format("{0, -15}: {1}", "Uri", templateLink.Uri));
            result.AppendLine(string.Format("{0, -15}: {1}", "ContentVersion", templateLink.ContentVersion));

            return(result.ToString());
        }
        private void ProcessParameterFile(string parameterFile)
        {
            try
            {
                var rootedParameterFile = PSRuleOption.GetRootedPath(parameterFile);

                // Check if metadata property exists
                if (!TryMetadata(rootedParameterFile, out JObject metadata))
                {
                    return;
                }

                if (!TryTemplateFile(metadata, rootedParameterFile, out string templateFile))
                {
                    return;
                }

                var templateLink = new TemplateLink(templateFile, rootedParameterFile);

                // Populate remaining properties
                if (TryStringProperty(metadata, PROPERTYNAME_NAME, out string name))
                {
                    templateLink.Name = name;
                }

                if (TryStringProperty(metadata, PROPERTYNAME_DESCRIPTION, out string description))
                {
                    templateLink.Description = description;
                }

                Writer.WriteObject(templateLink, false);
            }
            catch (InvalidOperationException ex)
            {
                Writer.WriteError(ex, nameof(InvalidOperationException), ErrorCategory.InvalidOperation, parameterFile);
            }
            catch (FileNotFoundException ex)
            {
                Writer.WriteError(ex, nameof(FileNotFoundException), ErrorCategory.ObjectNotFound, parameterFile);
            }
            catch (PipelineException ex)
            {
                Writer.WriteError(ex, nameof(PipelineException), ErrorCategory.WriteError, parameterFile);
            }
        }
Пример #13
0
        public async Task <Template> Link(TemplateLink newlink)
        {
            var workspace = await _workspaceStore.Load(newlink.WorkspaceId);

            if (workspace == null || !workspace.CanEdit(User))
            {
                throw new InvalidOperationException();
            }

            var entity = await _templateStore.Load(newlink.TemplateId);

            if (entity == null || entity.Parent != null || !entity.IsPublished)
            {
                throw new InvalidOperationException();
            }

            if (!User.IsCreator &&
                await _templateStore.AtTemplateLimit(newlink.WorkspaceId))
            {
                throw new TemplateLimitReachedException();
            }

            var newTemplate = new Data.Template
            {
                ParentId    = entity.Id,
                WorkspaceId = newlink.WorkspaceId,
                Name        = $"{entity.Name}-{new Random().Next(100, 999).ToString()}",
                Description = entity.Description,
                Iso         = entity.Iso,
                Networks    = entity.Networks,
                Guestinfo   = entity.Guestinfo
            };

            await _templateStore.Add(newTemplate);

            //TODO: streamline object graph hydration
            newTemplate = await _templateStore.Load(newTemplate.Id);

            return(Mapper.Map <Template>(newTemplate, WithActor()));
        }
Пример #14
0
        public async Task <Template> Link(TemplateLink newlink, bool sudo)
        {
            var entity = await _store.Retrieve(newlink.TemplateId);

            if (entity.IsPublished.Equals(false))
            {
                throw new TemplateNotPublished();
            }

            if (!sudo && await _store.AtTemplateLimit(newlink.WorkspaceId))
            {
                throw new TemplateLimitReached();
            }

            var workspace = await _store.DbContext.Workspaces
                            .FirstOrDefaultAsync(w => w.Id == newlink.WorkspaceId)
            ;

            string name = entity.Name.Length > 60
                ? entity.Name.Substring(0, 60)
                : entity.Name
            ;

            var newTemplate = new Data.Template
            {
                ParentId    = entity.Id,
                WorkspaceId = workspace.Id,
                Name        = $"{name}-{new Random().Next(100, 999).ToString()}",
                Description = entity.Description,
                Iso         = entity.Iso,
                Networks    = entity.Networks,
                Guestinfo   = entity.Guestinfo
            };

            await _store.Create(newTemplate);

            return(Mapper.Map <Template>(
                       await _store.Load(newTemplate.Id)
                       ));
        }
Пример #15
0
        public async Task <Template> Unlink(TemplateLink link) //CLONE
        {
            var entity = await _store.LoadWithParent(link.TemplateId);

            if (entity.IsLinked)
            {
                TemplateUtility tu = new TemplateUtility(entity.Parent.Detail);

                tu.Name = entity.Name;

                tu.LocalizeDiskPaths(entity.Workspace.Id, entity.Id);

                entity.Detail = tu.ToString();

                entity.Parent = null;

                await _store.Update(entity);
            }

            return(Mapper.Map <Template>(
                       await _store.Load(link.TemplateId)
                       ));
        }
        /// <summary>Analyze a cell of the template part</summary>
        private IDefinitionPart AnalyzeCell(ExcelTemplateDefinitionPart templateDefinitionPart, ExcelInterop.Range cell)
        {
            IDefinitionPart part = null;

            if (cell.Value2 != null)
            {
                string value = cell.Value2.ToString();
                if (!string.IsNullOrEmpty(value))
                {
                    string trimmedValue = value.Trim();
                    if (trimmedValue.StartsWith(LINKED_TEMPLATE_PREFIX))
                    {
                        try
                        {
                            XmlTemplateLink xmlTemplateLink = trimmedValue.Deserialize <XmlTemplateLink>();
                            TemplateLink    templateLink    = TemplateLink.CreateInstance(xmlTemplateLink);

                            ExcelTemplateDefinition  templateDefinition       = (ETKExcel.TemplateManager as ExcelTemplateManager).GetTemplateDefinitionFromLink(templateDefinitionPart, templateLink);
                            LinkedTemplateDefinition linkedTemplateDefinition = new LinkedTemplateDefinition(templateDefinitionPart.Parent, templateDefinition, templateLink);
                            templateDefinitionPart.AddLinkedTemplate(linkedTemplateDefinition);
                            part = linkedTemplateDefinition;
                        }
                        catch (Exception ex)
                        {
                            string message = $"Cannot create the linked template dataAccessor '{trimmedValue}'. {ex.Message}";
                            throw new EtkException(message, false);
                        }
                    }
                    else
                    {
                        if (trimmedValue.StartsWith(ExcelBindingFilterDefinition.Filter_PREFIX))
                        {
                            ExcelBindingFilterDefinition filterdefinition = ExcelBindingFilterDefinition.CreateInstance(templateDefinitionPart, trimmedValue);
                            templateDefinitionPart.AddFilterDefinition(filterdefinition);
                            part = filterdefinition;
                        }
                        else if (trimmedValue.StartsWith(ExcelBindingSearchDefinition.Search_PREFIX))
                        {
                            ExcelBindingSearchDefinition searchdefinition = ExcelBindingSearchDefinition.CreateInstance(trimmedValue);
                            templateDefinitionPart.AddSearchDefinition(searchdefinition);
                            part = searchdefinition;
                        }
                        else
                        {
                            try
                            {
                                IBindingDefinition bindingDefinition = CreateBindingDefinition(templateDefinitionPart, value, trimmedValue);
                                templateDefinitionPart.AddBindingDefinition(bindingDefinition);
                                part = bindingDefinition;
                            }
                            catch (Exception ex)
                            {
                                string message = $"Cannot create the binding definition for '{trimmedValue}'. {ex.Message}";
                                throw new EtkException(message, false);
                            }
                        }
                    }
                }
            }
            return(part);
        }
Пример #17
0
        private static string ConstructTemplateLinkView(TemplateLink templateLink)
        {
            if (templateLink == null)
            {
                return string.Empty;
            }

            StringBuilder result = new StringBuilder();

            result.AppendLine();
            result.AppendLine(string.Format("{0, -15}: {1}", "Uri", templateLink.Uri));
            result.AppendLine(string.Format("{0, -15}: {1}", "ContentVersion", templateLink.ContentVersion));

            return result.ToString();
        }
 internal DeploymentWhatIfProperties(object template, TemplateLink templateLink, object parameters, ParametersLink parametersLink, DeploymentMode mode, DebugSetting debugSetting, OnErrorDeployment onErrorDeployment, DeploymentWhatIfSettings whatIfSettings) : base(template, templateLink, parameters, parametersLink, mode, debugSetting, onErrorDeployment)
 {
     WhatIfSettings = whatIfSettings;
 }
Пример #19
0
        internal ExcelTemplateDefinition GetTemplateDefinitionFromLink(ExcelTemplateDefinitionPart parent, TemplateLink templateLink)
        {
            try
            {
                string[] tos = templateLink.To.Split('.');
                ExcelInterop.Worksheet sheetContainer = null;
                string templateName;
                if (tos.Count() == 1)
                {
                    sheetContainer = parent.DefinitionCells.Worksheet;
                    templateName   = tos[0].EmptyIfNull().Trim();
                }
                else
                {
                    string worksheetContainerName = tos[0].EmptyIfNull().Trim();
                    templateName = tos[1].EmptyIfNull().Trim();

                    ExcelInterop.Worksheet parentWorkSheet = parent.DefinitionCells.Worksheet;
                    ExcelInterop.Workbook  workbook        = parentWorkSheet.Parent as ExcelInterop.Workbook;
                    if (workbook == null)
                    {
                        throw new EtkException("Cannot retrieve the workbook that owned the template destination sheet");
                    }

                    List <ExcelInterop.Worksheet> sheets = new List <ExcelInterop.Worksheet>(workbook.Worksheets.Cast <ExcelInterop.Worksheet>());
                    sheetContainer = sheets.FirstOrDefault(s => !string.IsNullOrEmpty(s.Name) && s.Name.Equals(worksheetContainerName));
                    if (sheetContainer == null)
                    {
                        throw new EtkException($"Cannot find the sheet '{worksheetContainerName}' in the current workbook", false);
                    }

                    ExcelApplication.ReleaseComObject(workbook);
                    workbook = null;
                }

                string templateDescriptionKey = $"{sheetContainer.Name}-{templateName}";
                ExcelTemplateDefinition templateDefinition = bindingTemplateManager.GetTemplateDefinition(templateDescriptionKey) as ExcelTemplateDefinition;
                if (templateDefinition == null)
                {
                    ExcelInterop.Range range = sheetContainer.Cells.Find(string.Format(TEMPLATE_START_FORMAT, templateName), Type.Missing, ExcelInterop.XlFindLookIn.xlValues, ExcelInterop.XlLookAt.xlPart, ExcelInterop.XlSearchOrder.xlByRows, ExcelInterop.XlSearchDirection.xlNext, false);
                    if (range == null)
                    {
                        throw new EtkException($"Cannot find the template '{templateName.EmptyIfNull()}' in sheet '{sheetContainer.Name.EmptyIfNull()}'");
                    }
                    templateDefinition = ExcelTemplateDefinitionFactory.CreateInstance(templateName, range);
                    bindingTemplateManager.RegisterTemplateDefinition(templateDefinition);

                    range = null;
                }

                ExcelApplication.ReleaseComObject(sheetContainer);
                sheetContainer = null;
                return(templateDefinition);
            }
            catch (Exception ex)
            {
                string message = $"Cannot create the template dataAccessor. {ex.Message}";
                throw new EtkException(message, false);
            }
        }
Пример #20
0
        public static DeploymentOrchestrationInput Parse(Resource resource,
                                                         DeploymentContext deploymentContext,
                                                         ARMFunctions functions,
                                                         IInfrastructure infrastructure)
        {
            var armContext = new Dictionary <string, object>()
            {
                { ContextKeys.ARM_CONTEXT, deploymentContext },
                { ContextKeys.IS_PREPARE, true }
            };

            using var doc = JsonDocument.Parse(resource.Properties);
            var rootElement = doc.RootElement;

            var mode = DeploymentMode.Incremental;

            if (rootElement.TryGetProperty("mode", out JsonElement _mode))
            {
                if (_mode.GetString().Equals(DeploymentMode.Complete.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    mode = DeploymentMode.Complete;
                }
                if (_mode.GetString().Equals(DeploymentMode.OnlyCreation.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    mode = DeploymentMode.OnlyCreation;
                }
            }
            string template = string.Empty;

            if (rootElement.TryGetProperty("template", out JsonElement _template))
            {
                template = _template.GetRawText();
            }
            TemplateLink templateLink = null;

            if (rootElement.TryGetProperty("templateLink", out JsonElement _templateLink))
            {
                templateLink = new TemplateLink()
                {
                    ContentVersion = _templateLink.GetProperty("contentVersion").GetString(),
                    Uri            = functions.Evaluate(_templateLink.GetProperty("uri").GetString(), armContext).ToString()
                };
            }
            // https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/linked-templates#scope-for-expressions-in-nested-templates
            string         parameters     = string.Empty;
            ParametersLink parametersLink = null;

            if (rootElement.TryGetProperty("expressionEvaluationOptions", out JsonElement _expressionEvaluationOptions) &&
                _expressionEvaluationOptions.GetProperty("scope").GetString().Equals("inner", StringComparison.OrdinalIgnoreCase))
            {
                if (rootElement.TryGetProperty("parameters", out JsonElement _parameters))
                {
                    parameters = _parameters.GetRawText();
                }
                if (rootElement.TryGetProperty("parametersLink", out JsonElement _parametersLink))
                {
                    parametersLink = new ParametersLink()
                    {
                        ContentVersion = _parametersLink.GetProperty("contentVersion").GetString(),
                        Uri            = functions.Evaluate(_parametersLink.GetProperty("uri").GetString(), armContext).ToString()
                    };
                }
            }
            else
            {
                parameters                  = deploymentContext.Parameters;
                using MemoryStream ms       = new MemoryStream();
                using Utf8JsonWriter writer = new Utf8JsonWriter(ms);
                writer.WriteStartObject();
                using var doc1 = JsonDocument.Parse(template);
                var root1 = doc1.RootElement;
                foreach (var node in root1.EnumerateObject())
                {
                    if (node.Name.Equals("parameters", StringComparison.OrdinalIgnoreCase) ||
                        node.Name.Equals("variables", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }
                    writer.WritePropertyName(node.Name);
                    node.Value.WriteTo(writer);
                }
                if (!string.IsNullOrWhiteSpace(deploymentContext.Template.Parameters))
                {
                    using var p = JsonDocument.Parse(deploymentContext.Template.Parameters);
                    writer.WritePropertyName("parameters");
                    p.RootElement.WriteTo(writer);
                }
                if (!string.IsNullOrWhiteSpace(deploymentContext.Template.Variables))
                {
                    using var v = JsonDocument.Parse(deploymentContext.Template.Variables);
                    writer.WritePropertyName("variables");
                    v.RootElement.WriteTo(writer);
                }

                writer.WriteEndObject();
                writer.Flush();
                template = Encoding.UTF8.GetString(ms.ToArray());
            }
            var(groupId, groupType, hierarchyId) = infrastructure.GetGroupInfo(resource.ManagementGroupId, resource.SubscriptionId, resource.ResourceGroup);
            var deployInput = new DeploymentOrchestrationInput()
            {
                RootId            = deploymentContext.RootId,
                DeploymentId      = Guid.NewGuid().ToString("N"),
                ParentId          = deploymentContext.GetResourceId(infrastructure),
                GroupId           = groupId,
                GroupType         = groupType,
                HierarchyId       = hierarchyId,
                CorrelationId     = deploymentContext.CorrelationId,
                SubscriptionId    = resource.SubscriptionId,
                ManagementGroupId = resource.ManagementGroupId,
                ResourceGroup     = resource.ResourceGroup,
                DeploymentName    = resource.Name,
                Mode            = mode,
                TemplateContent = template,
                TemplateLink    = templateLink,
                Parameters      = parameters,
                ParametersLink  = parametersLink,
                ApiVersion      = resource.ApiVersion,
                CreateByUserId  = deploymentContext.CreateByUserId,
                LastRunUserId   = deploymentContext.LastRunUserId,
                DependsOn       = resource.DependsOn,
                Extensions      = deploymentContext.Extensions,
                TenantId        = deploymentContext.TenantId
            };

            return(Validate(deployInput, functions, infrastructure));
        }
Пример #21
0
        /// <summary>
        /// Evals the specified token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">
        /// Evaluator cannot be in returning state when entering eval
        /// or
        /// Unrecognized prefix operator  + token[0].Text
        /// or
        /// Invalid left value  + token[0].Name
        /// or
        /// Unrecognized token type  + token.Name
        /// </exception>
        public dynamic Eval(Token token)
        {
            if (this.isReturning)
            {
                throw new Exception("Evaluator cannot be in returning state when entering eval");
            }
            switch (token.Name)
            {
            case "Return":
                this.result      = token.NodeCount == 1 ? Eval(token[0]) : null;
                this.isReturning = true;
                return(result);

            case "Script":
            case "Block":
                return(this.EvalScoped(() => EvalTokens(token.Tokens)));

            case "AnonFunc":
                return(new JSFunction(this.environment, token));

            case "If":
                if (Eval(token[0]) ?? false)
                {
                    return(Eval(token[1]));
                }
                if (token.NodeCount > 2)
                {
                    return(Eval(token[2]));
                }
                return(null);

            case "Else":
                return(Eval(token[0]));

            case "VarDecl":
                return(this.AddVariable(token[0].Text, token.NodeCount > 1 ? Eval(token[1]) : null));

            case "Empty":
                return(null);

            case "ExprtStatement":
                return(Eval(token[0]));

            case "For":
                return(EvalScoped(() =>
                {
                    // Initialize...
                    Eval(token[0]);
                    dynamic r = null;
                    // Check condition...
                    while (!this.isReturning && (Eval(token[1]) ?? false))
                    {
                        // increment....
                        Eval(token[3]);
                        // execution...
                        r = Eval(token[2]);
                    }
                    return r;
                }));

            case "Foreach":
                return(EvalScoped(() =>
                {
                    dynamic r = null;
                    object containerVar = this.container.GetByPath(token[1].Text);
                    if (containerVar is TemplateContainer)
                    {
                        TemplateContainer listContainer = (TemplateContainer)containerVar;
                        if (!listContainer.IsList)
                        {
                            throw new Exception("container is not a list");
                        }
                        foreach (TemplateContainer value in listContainer.ArrayValues)
                        {
                            this.container.AddChild(token[0].Text, value);
                            r = Eval(token[2]);
                        }
                    }
                    else if (containerVar is TemplateLink)
                    {
                        TemplateLink listLInk = (TemplateLink)containerVar;
                        if (!listLInk.IsList)
                        {
                            throw new Exception("container is not a list");
                        }
                        foreach (string path in listLInk.ListValues)
                        {
                            string fullpath = listLInk.Link + "[" + path + "]";
                            object foundobj = this.container.GetByPath(fullpath);
                            if (foundobj is TemplateContainer)
                            {
                                this.container.AddChild(token[0].Text, foundobj as TemplateContainer);
                                r = Eval(token[2]);
                            }
                        }
                    }
                    return r;
                }));

            case "BinaryExpr":
            {
                return(Primitives.Eval(token[1].Text, Eval(token[0]), Eval(token[2])));
            }

            case "PrefixExpr":
                switch (token[0].Text)
                {
                case "!":
                    return(!Eval(token[1]));

                case "~":
                    return(~Eval(token[1]));

                case "-":
                    return(-Eval(token[1]));

                default:
                    throw new Exception("Unrecognized prefix operator " + token[0].Text);
                }

            case "FieldExpr":
            {
                var obj   = Eval(token[0]);
                var field = token[1][0].Text;
                if (obj is TemplateContainer)
                {
                    return((obj as TemplateContainer).GetByPath(field));
                }
                else
                {
                    return(obj[field]);
                }
            }

            case "IndexExpr":
            {
                var index = Eval(token[1]);
                var array = Eval(token[0]);
                if (array is TemplateContainer)
                {
                    TemplateContainer tc    = array as TemplateContainer;
                    TemplateContainer sontc = tc.GetByPath("[" + index.ToString() + "]");
                    return(sontc);
                }
                else
                {
                    return(array[index]);
                }
            }

            case "CallExpr":
            {
                var func = Eval(token[0]);
                var args = token[1].Tokens.Select(Eval).ToArray();
                return(func.Apply(this, null, args));
            }

            case "MethodCallExpr":
            {
                var obj  = Eval(token[0]);
                var func = Eval(token[1]);
                var args = token[2].Tokens.Select(Eval).ToArray();
                return(func.Apply(this, obj, args));
            }

            case "NewExpr":
            {
                var func = Eval(token[0]);
                var args = token[1].Tokens.Select(Eval).ToArray();
                return(func.Apply(this, new JsonObject(), args));
            }

            case "AssignExpr":
            {
                var lnode  = token[0];
                var rnode  = token[2];
                var rvalue = Eval(rnode);
                switch (lnode.Name)
                {
                case "FieldExpr":
                {
                    var obj  = Eval(lnode[0]);
                    var name = lnode[1].Text;
                    return(obj[name] = rvalue);
                }

                case "IndexExpr":
                {
                    var obj   = Eval(lnode[0]);
                    var index = Eval(lnode[1]);
                    return(obj[index] = rvalue);
                }

                case "Identifier":
                {
                    var name = lnode.Text;
                    return(RebindGlobal(name, rvalue));
                }

                default:
                    throw new Exception("Invalid left value " + token[0].Name);
                }
            }

            case "Identifier":
                if (this.environment.ExistsVariable(token.Text))
                {
                    return(this.environment[token.Text]);
                }
                else
                {
                    return(this.container.GetByPath(token.Text));
                }

            case "Object":
            {
                var r = new JsonObject();
                foreach (var pair in token.Tokens)
                {
                    var name  = pair[0].Text;
                    var value = Eval(pair[1]);
                    r[name] = value;
                }
                return(r);
            }

            case "Array":
                return(token.Tokens.Select(Eval).ToArray());

            case "Integer":
                return(Int32.Parse(token.Text));

            case "Index":
                return(Eval(token[0]));

            case "Float":
                return(Double.Parse(token.Text));

            case "String":
                return(token.Text.Substring(1, token.Text.Length - 2));

            case "True":
                return(true);

            case "False":
                return(false);

            case "Null":
                return(null);

            default:
                throw new Exception("Unrecognized token type " + token.Name);
            }
        }