/// <see cref="Translator.Translate"/>
            public override void Translate(ScriptCompiler compiler, AbstractNode node)
            {
                var obj = (ObjectAbstractNode)node;

                var compositor = (Compositor)obj.Parent.Context;

                this._Technique = compositor.CreateTechnique();
                obj.Context     = this._Technique;

                foreach (var i in obj.Children)
                {
                    if (i is ObjectAbstractNode)
                    {
                        processNode(compiler, i);
                    }
                    else if (i is PropertyAbstractNode)
                    {
                        var prop = (PropertyAbstractNode)i;
                        switch ((Keywords)prop.Id)
                        {
                            #region ID_TEXTURE

                        case Keywords.ID_TEXTURE:
                        {
                            var atomIndex = 1;

                            var it = getNodeAt(prop.Values, 0);

                            if (it is AtomAbstractNode)
                            {
                                compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                return;
                            }
                            // Save the first atom, should be name
                            var atom0 = (AtomAbstractNode)it;

                            int   width = 0, height = 0;
                            float widthFactor = 1.0f, heightFactor = 1.0f;
                            bool  widthSet = false, heightSet = false, formatSet = false;
                            var   pooled       = false;
                            var   hwGammaWrite = false;
                            var   fsaa         = true;

                            var scope   = CompositionTechnique.TextureScope.Local;
                            var formats = new List <PixelFormat>();

                            while (atomIndex < prop.Values.Count)
                            {
                                it = getNodeAt(prop.Values, atomIndex++);
                                if (!(it is AtomAbstractNode))
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                    return;
                                }
                                var atom = (AtomAbstractNode)it;

                                switch ((Keywords)atom.Id)
                                {
                                case Keywords.ID_TARGET_WIDTH:
                                    width    = 0;
                                    widthSet = true;
                                    break;

                                case Keywords.ID_TARGET_HEIGHT:
                                    height    = 0;
                                    heightSet = true;
                                    break;

                                case Keywords.ID_TARGET_WIDTH_SCALED:
                                case Keywords.ID_TARGET_HEIGHT_SCALED:
                                {
                                    var   pSetFlag = false;
                                    var   pSize    = 0;
                                    float pFactor  = 0;
                                    if (atom.Id == (uint)Keywords.ID_TARGET_WIDTH_SCALED)
                                    {
                                        pSetFlag = widthSet;
                                        pSize    = width;
                                        pFactor  = widthFactor;
                                    }
                                    else
                                    {
                                        pSetFlag = heightSet;
                                        pSize    = height;
                                        pFactor  = heightFactor;
                                    }
                                    // advance to next to get scaling
                                    it = getNodeAt(prop.Values, atomIndex++);
                                    if (it == null || !(it is AtomAbstractNode))
                                    {
                                        compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                        return;
                                    }
                                    atom = (AtomAbstractNode)it;
                                    if (!atom.IsNumber)
                                    {
                                        compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                        return;
                                    }

                                    pSize    = 0;
                                    pFactor  = atom.Number;
                                    pSetFlag = true;
                                }
                                break;

                                case Keywords.ID_POOLED:
                                    pooled = true;
                                    break;

                                case Keywords.ID_SCOPE_LOCAL:
                                    scope = CompositionTechnique.TextureScope.Local;
                                    break;

                                case Keywords.ID_SCOPE_CHAIN:
                                    scope = CompositionTechnique.TextureScope.Chain;
                                    break;

                                case Keywords.ID_SCOPE_GLOBAL:
                                    scope = CompositionTechnique.TextureScope.Global;
                                    break;

                                case Keywords.ID_GAMMA:
                                    hwGammaWrite = true;
                                    break;

                                case Keywords.ID_NO_FSAA:
                                    fsaa = false;
                                    break;

                                default:
                                    if (atom.IsNumber)
                                    {
                                        if (atomIndex == 2)
                                        {
                                            width    = (int)atom.Number;
                                            widthSet = true;
                                        }
                                        else if (atomIndex == 3)
                                        {
                                            height    = (int)atom.Number;
                                            heightSet = true;
                                        }
                                        else
                                        {
                                            compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        // pixel format?
                                        var format = PixelUtil.GetFormatFromName(atom.Value, true);
                                        if (format == PixelFormat.Unknown)
                                        {
                                            compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line);
                                            return;
                                        }
                                        formats.Add(format);
                                        formatSet = true;
                                    }
                                    break;
                                }
                            }
                            if (!widthSet || !heightSet || !formatSet)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                                return;
                            }

                            // No errors, create
                            var def = this._Technique.CreateTextureDefinition(atom0.Value);
                            def.Width        = width;
                            def.Height       = height;
                            def.WidthFactor  = widthFactor;
                            def.HeightFactor = heightFactor;
                            def.PixelFormats = formats;
                            def.HwGammaWrite = hwGammaWrite;
                            def.Fsaa         = fsaa;
                            def.Pooled       = pooled;
                            def.Scope        = scope;
                        }
                        break;

                            #endregion ID_TEXTURE

                            #region ID_TEXTURE_REF

                        case Keywords.ID_TEXTURE_REF:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count != 3)
                            {
                                compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                  "texture_ref only supports 3 argument");
                            }
                            else
                            {
                                string texName = string.Empty, refCompName = string.Empty, refTexName = string.Empty;

                                var it = getNodeAt(prop.Values, 0);
                                if (!getString(it, out texName))
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "texture_ref must have 3 string arguments");
                                }

                                it = getNodeAt(prop.Values, 1);
                                if (!getString(it, out refCompName))
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "texture_ref must have 3 string arguments");
                                }

                                it = getNodeAt(prop.Values, 2);
                                if (!getString(it, out refTexName))
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "texture_ref must have 3 string arguments");
                                }

                                var refTexDef = this._Technique.CreateTextureDefinition(texName);

                                refTexDef.ReferenceCompositorName = refCompName;
                                refTexDef.ReferenceTextureName    = refTexName;
                            }
                            break;

                            #endregion ID_TEXTURE_REF

                            #region ID_SCHEME

                        case Keywords.ID_SCHEME:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 1)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
                                                  "scheme only supports 1 argument");
                            }
                            else
                            {
                                var i0     = getNodeAt(prop.Values, 0);
                                var scheme = string.Empty;

                                if (getString(i0, out scheme))
                                {
                                    this._Technique.SchemeName = scheme;
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "scheme must have 1 string argument");
                                }
                            }
                            break;

                            #endregion ID_SCHEME

                            #region ID_COMPOSITOR_LOGIC

                        case Keywords.ID_COMPOSITOR_LOGIC:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 1)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
                                                  "compositor logic only supports 1 argument");
                            }
                            else
                            {
                                var i0        = getNodeAt(prop.Values, 0);
                                var logicName = string.Empty;

                                if (getString(i0, out logicName))
                                {
                                    this._Technique.CompositorLogicName = logicName;
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "compositor logic must have 1 string argument");
                                }
                            }
                            break;

                            #endregion ID_COMPOSITOR_LOGIC

                        default:
                            compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line,
                                              "token \"" + prop.Name + "\" is not recognized");
                            break;
                        }
                    }
                }
            }