public ConstantSetup(SourceShader source, string techniqueName, Platform platform)
		{
			this.source = source;
			this.techniqueName = techniqueName;

			this.attributeNames = new List<string>();
			this.attributeFields = new List<CodeFieldReferenceExpression>();
			this.attributeArrayFields = new List<CodeFieldReferenceExpression>();
			this.attributeAssignment = new Dictionary<Type, List<CodeStatement>>();
			this.semanticMapping = new List<SemanticMapping>();
			this.globals = new List<GlobalAttribute>();

			this.asm = source.GetAsmTechnique(techniqueName, platform);

			ComputeAllValidSemantics();
		}
		public Preshaders(SourceShader source, string techniqueName, Platform platform)
		{
			technique = source.GetAsmTechnique(techniqueName, platform);

			if (technique.PixelPreShader != null)
			{
				pixelPreShaderStatements = new CodeStatementCollection();
				pixelPreShader = new PreshaderSrc(technique.PixelPreShader, pixelPreShaderStatements);

				technique.PixelShader.RegisterSet.SetMinFloatRegisterCount(pixelPreShader.MaxConstantRegisterAccess);
				technique.PixelShader.RegisterSet.SetMinBooleanRegisterCount(pixelPreShader.MaxBooleanConstantRegisterWrite);
			}

			if (technique.VertexPreShader != null)
			{
				vertexPreShaderStatements = new CodeStatementCollection();
				vertexPreShader = new PreshaderSrc(technique.VertexPreShader, vertexPreShaderStatements);

				technique.VertexShader.RegisterSet.SetMinFloatRegisterCount(vertexPreShader.MaxConstantRegisterAccess);
				technique.VertexShader.RegisterSet.SetMinBooleanRegisterCount(vertexPreShader.MaxBooleanConstantRegisterWrite);
			}
		}
		public ShaderRegisters(SourceShader source, string techniqueName, Platform platform, IExtensionStatementProvider extensionStatementProvider)
		{
			AsmTechnique technique = source.GetAsmTechnique(techniqueName, platform);
			this.extensionStatementProvider = extensionStatementProvider;

			vsReg = technique.VertexShader.RegisterSet;
			psReg = technique.PixelShader.RegisterSet;

			if (technique.InstancingShader != null)
				vsInstancingReg = technique.InstancingShader.RegisterSet;
			if (technique.BlendingShader != null)
				vsBlendingReg = technique.BlendingShader.RegisterSet;

			if (technique.TechniqueExtraData != null)
			{
				this.techniqueData = technique.TechniqueExtraData;

				psDefault = technique.TechniqueExtraData.PixelShaderConstants;
				vsDefault = technique.TechniqueExtraData.VertexShaderConstants;

				psBooleanDefault = technique.TechniqueExtraData.PixelShaderBooleanConstants;
				vsBooleanDefault = technique.TechniqueExtraData.VertexShaderBooleanConstants;
			}
		}
		public static byte[] Generate(SourceShader source, HlslTechnique technique, Platform platform)
		{

		//	ShaderExtensionGenerator exGen = new ShaderExtensionGenerator(source, platform);

			TokenRename vsRename, psRename;
			TokenRename vsBlendRename, vsInstanceRename;

			vsRename = new TokenRename(source, platform, "VS");
			psRename = new TokenRename(source, platform, "PS");

			vsBlendRename = new TokenRename(source, platform, "VS_B");
			vsInstanceRename = new TokenRename(source, platform, "VS_I");

			HlslMethod methodVS = source.GetMethod(technique.VertexShaderMethodName, platform);
			HlslMethod methodPS = source.GetMethod(technique.PixelShaderMethodName, platform);
			
			HlslMethod methodBlending = source.GetMethod(technique.BlendingShaderMethodName, platform);
			HlslMethod methodInstancing = source.GetMethod(technique.InstancingShaderMethodName, platform);

			if (methodPS == null || methodVS == null)
				return null;

			string vsPrefix, psPrefix;

			AsmTechnique asmTechnique = source.GetAsmTechnique(technique.Name, platform);
			vsPrefix = BuildMapping(asmTechnique, "vs", asmTechnique.VertexShader.RegisterSet);
			psPrefix = BuildMapping(asmTechnique, "ps", asmTechnique.PixelShader.RegisterSet);

			string blendingPrefix = null, instancingPrefix = null;
			if (asmTechnique.BlendingShader != null)
				blendingPrefix = BuildMapping(asmTechnique, "vsb", asmTechnique.BlendingShader.RegisterSet);
			if (asmTechnique.InstancingShader != null)
				instancingPrefix = BuildMapping(asmTechnique, "vsi", asmTechnique.InstancingShader.RegisterSet);

			//build the method bodies for the technique

			//process through all the methods used.
			vsRename.methodList.Add(methodVS);
			psRename.methodList.Add(methodPS);

			if (methodBlending != null) vsBlendRename.methodList.Add(methodBlending);
			if (methodInstancing != null) vsInstanceRename.methodList.Add(methodInstancing);

			//setup remapping for registers used
			MapRegistersToRenamer(vsRename, asmTechnique.VertexShader.RegisterSet, "vs");
			MapRegistersToRenamer(psRename, asmTechnique.PixelShader.RegisterSet, "ps");

			if (asmTechnique.BlendingShader != null)
			{
				MapRegistersToRenamer(vsBlendRename, asmTechnique.VertexShader.RegisterSet, "vs");
				MapRegistersToRenamer(vsBlendRename, asmTechnique.BlendingShader.RegisterSet, "vsb");
			}
			if (asmTechnique.InstancingShader != null)
			{
				MapRegistersToRenamer(vsInstanceRename, asmTechnique.VertexShader.RegisterSet, "vs");
				MapRegistersToRenamer(vsInstanceRename, asmTechnique.InstancingShader.RegisterSet, "vsi");
			}

			//finally, parse all the registers used by the Effect. Dump them in as 'unused'
			RegisterSet decompiledEffectRegisters = source.GetDecompiledEffect(platform).EffectRegisters;

			string unusedSamplerName = "__unused_sampler";
			string unusedFloatName = "__unused_";
			string unusedMatrixName = "__unused4x4_";
			string unusedArrayName = "__unused_array";

			foreach (Register reg in decompiledEffectRegisters)
			{
				if (reg.Name == null || reg.Category == RegisterCategory.Texture)
					continue;
				if (reg.Category == RegisterCategory.Sampler)
				{
					vsRename.unusedRemapping.Add(reg.Name, unusedSamplerName);
					psRename.unusedRemapping.Add(reg.Name, unusedSamplerName);
					vsBlendRename.unusedRemapping.Add(reg.Name, unusedSamplerName);
					vsInstanceRename.unusedRemapping.Add(reg.Name, unusedSamplerName);
				}
				else
				{
					vsRename.unusedRemapping.Add(reg.Name, reg.ArraySize > 0 ? unusedArrayName : (reg.Size > 1 ? unusedMatrixName : unusedFloatName));
					psRename.unusedRemapping.Add(reg.Name, reg.ArraySize > 0 ? unusedArrayName : (reg.Size > 1 ? unusedMatrixName : unusedFloatName));
					vsBlendRename.unusedRemapping.Add(reg.Name, reg.ArraySize > 0 ? unusedArrayName : (reg.Size > 1 ? unusedMatrixName : unusedFloatName));
					vsInstanceRename.unusedRemapping.Add(reg.Name, reg.ArraySize > 0 ? unusedArrayName : (reg.Size > 1 ? unusedMatrixName : unusedFloatName));
				}
			}
			//will write booleans down if the values are used.
			vsRename.unusedAccessed = new Dictionary<string, bool>();
			psRename.unusedAccessed = vsRename.unusedAccessed;
			vsBlendRename.unusedAccessed = vsRename.unusedAccessed;
			vsInstanceRename.unusedAccessed = vsRename.unusedAccessed;


			//note, the method list will be added to as new methods are needed by the base method.
			StringBuilder sb = new StringBuilder();

			//extract PS methods
			ExtractMethodBodies(sb, psRename);

			//extract VS methods
			ExtractMethodBodies(sb, vsRename);

			ExtractMethodBodies(sb, vsBlendRename);
			ExtractMethodBodies(sb, vsInstanceRename);

			string techniqueVsName = GetTechniqueInvoke(vsRename, sb, methodVS, technique.VertexShaderArgs);
			string techniquePsName = GetTechniqueInvoke(psRename, sb, methodPS, technique.PixelShaderArgs);

			string techniqueBlendingName = null, techniqueInstancingName = null;

			if (asmTechnique.BlendingShader != null)
				techniqueBlendingName = GetTechniqueInvoke(vsBlendRename, sb, methodBlending, technique.BlendingShaderArgs);
			if (asmTechnique.InstancingShader != null)
				techniqueInstancingName = GetTechniqueInvoke(vsInstanceRename, sb, methodInstancing, technique.InstancingShaderArgs);

			StringBuilder constants = new StringBuilder();

			//work out if any unused values were touched...
			//if so, add them.
			bool addUnusedSampler = false;
			bool addUnusedFloat = false;

			foreach (KeyValuePair<string,bool> item in vsRename.unusedAccessed)
			{
				if (item.Value)
				{
					//something has been used unexpectadly.
					Register reg;
					if (decompiledEffectRegisters.TryGetRegister(item.Key,out reg))
					{
						if (reg.Category == RegisterCategory.Sampler)
							addUnusedSampler = true;
						else
							addUnusedFloat = true;
					}
				}
			}
			if (addUnusedSampler)
				constants.AppendLine("sampler " + unusedSamplerName + ";");
			if (addUnusedFloat)
			{
				constants.AppendLine("const static float4 " + unusedFloatName + " = 0;");
				constants.AppendLine("const static float4x4 " + unusedMatrixName + " = 0;");
				constants.AppendLine("#define " + unusedArrayName + "(__INDEX__) " + unusedFloatName);
			}


			//setup the VS/PS constants
			asmTechnique.ConstructTechniqueConstants(constants, true);

			constants.Append(vsPrefix);
			constants.Append(psPrefix);
			if (blendingPrefix != null) constants.Append(blendingPrefix);
			if (instancingPrefix != null) constants.Append(instancingPrefix);

			constants.AppendLine(ExtractFixedDeclarations(source.HlslShader));

			//finally, build the technique delcaration
			string techniqueStructure =
@"{2}
{3}
technique Shader
{0}
	pass
	{0}
		VertexShader = compile {4} {5};
		PixelShader  = compile {6} {7};
	{1}
{8}{9}{1}";

			string extensionPass =
@"	pass {2}
	{0}
		VertexShader = compile {3} {4};
		PixelShader  = compile {5} {6};
	{1}
";
			string blendExtension = "", instanceExtension = "";

			if (asmTechnique.BlendingShader != null)
			{
				blendExtension = string.Format(extensionPass, "{", "}", "Blending", technique.GetVertexShaderVersion(platform), techniqueBlendingName, technique.GetPixelShaderVersion(platform), techniquePsName);
			}
			if (asmTechnique.InstancingShader != null)
			{
				instanceExtension = string.Format(extensionPass, "{", "}", "Instancing", "vs_3_0", techniqueInstancingName, "ps_3_0", techniquePsName);
			}

			string techniqueSource = string.Format(techniqueStructure, "{", "}", constants, sb,
				technique.GetVertexShaderVersion(platform), techniqueVsName,
				technique.GetPixelShaderVersion(platform), techniquePsName,
				blendExtension,instanceExtension);

			var types = typeof(EffectCompiler).Assembly.GetType("Xen.Graphics.ShaderSystem.EffectCompiler");
			var method = types.GetMethod("CompileEffect");

			CompileEffect effect = Delegate.CreateDelegate(typeof(CompileEffect), types.GetMethod("CompileEffect")) as CompileEffect;

			string compileErrors;
			byte[] compiledEffect = EffectCompiler.CompileEffect(techniqueSource, source.FileName, platform == Platform.Xbox, out compileErrors);

			if (compileErrors != null)
			{
				string[] errors = SanitizeConversionErrorMessage(compileErrors, techniqueSource, source.ShaderSource, source);

				if (source.ManualExtensions == false)
				{
					string errorsLine = "";
					foreach (var error in errors)
						errorsLine += error + Environment.NewLine;

					//error occured in generated code!
					ShaderExtensionGenerator.ThrowGeneratorError(errorsLine.Trim(), source.FileName);
				}
				else
				{
					string header = "XenFX Platform Technique Extraction Failed:";

					if (errors == null)
						Common.ThrowError(header, compileErrors);
					else
						Common.ThrowError(header, errors);
				}
			}

			return compiledEffect;
		}
		private void GenerateTechnique(SourceShader shader, HlslTechnique technique, AsmTechnique asmTechnique, Platform platform)
		{
			string blendVS = ProcessTechniqueVS(shader, technique, asmTechnique, ShaderExtension.Blending, platform);
			string instVS = ProcessTechniqueVS(shader, technique, asmTechnique, ShaderExtension.Instancing, platform);
			
			footer.AppendLine();

			////append the new technique
			string techniqueName = technique.Name + techniquePostfix;
			string code = @"
technique {0} {11}
{9}
	pass
	{9}
		VertexShader = compile {1} {5}({6});
		PixelShader = compile {2} {3}({4});
	{10}
	pass Blending
	{9}
		VertexShader = compile {1} {7}({6});
	{10}
	pass Instancing
	{9}
		VertexShader = compile {1} {8}({6});
	{10}
{10}
";

			var annotation = new StringBuilder();

			var asm = shader.GetAsmTechnique(technique.Name, platform);

			if (asm != null && asm.TechniqueExtraData != null &&
				asm.TechniqueExtraData.ClassBaseTypes != null && asm.TechniqueExtraData.ClassBaseTypes.Length > 0)
			{
				annotation.Append("< string  BaseTypes = \"");

				bool first = true;
				foreach (var baseType in asm.TechniqueExtraData.ClassBaseTypes)
				{
					if (!first)
						annotation.Append(", ");
					first = false;
					annotation.Append(baseType);
				}

				annotation.Append("\"; >");
			}
			
			footer.AppendFormat(
				code,
				techniqueName,
				technique.GetVertexShaderVersion(platform),
				technique.GetPixelShaderVersion(platform),
				technique.PixelShaderMethodName,
				CombineArgs(technique.PixelShaderArgs),
				technique.VertexShaderMethodName,
				CombineArgs(technique.VertexShaderArgs),
				blendVS,
				instVS,
				"{","}",
				annotation);

		}
		private ShaderExtensionGenerator(SourceShader shader, Platform platform, string techniquePostfix)
		{
			this.techniquePostfix = techniquePostfix;

			//this method temporary modifies the HlslStructure stored in the source shader, so take a backup first.
			structureBackup = new Dictionary<HlslStructure, HlslStructure.ShaderStatement[]>();
			BackupStructure(shader.HlslShader);
			

			RegisterSet registers     = shader.GetDecompiledEffect(platform).EffectRegisters;

			List<string> addRegisters = new List<string>();

			methodList = shader.GetAllMethods(platform, true).ToArray();

			foreach (var method in methodList)
			{
				if (methodNames.ContainsKey(method.Name))
					continue;

				bool open = false;
				bool args = false;

				//work out if this method takes args
				foreach (var element in method.HlslShader.Elements)
				{
					if (open)
					{
						if (element == ")")
							open = false;
						else
							args = true;
					}
					if (element == "(")
						open = true;
				}

				methodNames.Add(method.Name,args);
			}

			//collect up the declared world matrices
			foreach (var reg in registers)
			{
				if (reg.Semantic != null && reg.Semantic.StartsWith("WORLD", StringComparison.InvariantCultureIgnoreCase))
				{
					string replaceWith = reg.Semantic.Substring(5);

					//see if the replacement exists.
					if (replaceWith.Length > 0)
					{
						bool createReg = true;

						foreach (var r2 in registers)
						{
							if (r2.Semantic != null && r2.Semantic.Equals(replaceWith, StringComparison.InvariantCultureIgnoreCase))
							{
								createReg = false;
								matrixRemap.Add(reg.Name, new MatrixMapping() { Name = reg.Name, RemapTo = r2.Name + worldMatrixName, BaseName  = r2.Name});
							}
						}

						if (createReg)
						{
							addRegisters.Add(replaceWith);
							matrixRemap.Add(reg.Name, new MatrixMapping() { Name = reg.Name, RemapTo = ToInternalMatrixName(reg.Name), BaseName = ToInternalMatrixName(replaceWith) }); 
						}
					}
					else
						worldMatrix = reg;
				}
			}

			header.AppendLine();
			header.AppendFormat("float4 {0}[216] : BLENDMATRICES; ", blendMatricesName);
			header.AppendLine();
			//add the new registers
			foreach (var reg in addRegisters)
			{
				header.AppendFormat("float4x4 {0} : {1}; ", ToInternalMatrixName(reg), reg);
				header.AppendLine();
			}

			methodSignatureAppend = "";
			methodCallAppend      = "";

			foreach (var remap in matrixRemap.Values)
			{
				methodSignatureAppend += string.Format("float4x4 {0}, ", remap.RemapTo);
				methodCallAppend      += string.Format("{0}, ", remap.RemapTo);
			}
			methodSignatureAppend += "float4x4 " + worldMatrixName;
			methodCallAppend      += worldMatrixName;

			if (worldMatrix.Name != null)
			{
				matrixRemap.Add(worldMatrix.Name, new MatrixMapping() { Name = worldMatrix.Name, RemapTo = worldMatrixName });
			}


			BuildTechniqueMethod(shader, ShaderExtension.Blending);
			BuildTechniqueMethod(shader, ShaderExtension.Instancing);

			foreach (var tech in shader.GetAllTechniques())
			{
				if (tech.Platform == platform || tech.Platform == Platform.Both)
				{
					AsmTechnique asmTechnique = shader.GetAsmTechnique(tech.Name, platform);
					rootVsMethodName = tech.VertexShaderMethodName;
					GenerateTechnique(shader, tech, asmTechnique, platform);
				}
			}

			header.Append(builtShader);
			header.Append(footer);

			result = header.ToString();
		}
		public ShaderTextures(SourceShader source, string techniqueName, Platform platform)
		{
			this.psSamplers = new List<Register>();
			this.vsSamplers = new List<Register>();
			this.allSamplers = new Dictionary<string, SharedSampler>();

			AsmTechnique technique = source.GetAsmTechnique(techniqueName, platform);
			TechniqueExtraData extras = technique.TechniqueExtraData;

			//pull out the textures that will be used
			textures = new TextureAssociation[extras.TechniqueTextures.Length];
			for (int i = 0; i < extras.TechniqueTextures.Length; i++)
				textures[i] = new TextureAssociation(extras.TechniqueTextures[i]);

			//now do the samplers
			RegisterSet set = technique.PixelShader.RegisterSet;

			//pixel first
			foreach (Register reg in set)
			{
				if (reg.Category == RegisterCategory.Sampler)
				{
					psSamplers.Add(reg);

					int textureIndex = extras.PixelSamplerTextureIndex[reg.Index];

					if (textureIndex == -1)
						ThrowSamplerNoTextureException(reg);

					textures[textureIndex].PsSamplers.Add(reg.Index);

					//add the sampler to 'allSamplers'
					SharedSampler ss = new SharedSampler();
					ss.PsIndex = reg.Index;
					ss.SamplerDetails = reg;
					ss.Index = allSamplers.Count;
					ss.DefaultState = extras.PixelSamplerStates[reg.Index];
					allSamplers.Add(reg.Name, ss);
				}
			}

			set = technique.VertexShader.RegisterSet;

			//now vertex
			foreach (Register reg in set)
			{
				if (reg.Category == RegisterCategory.Sampler)
				{
					vsSamplers.Add(reg);

					int textureIndex = extras.VertexSamplerTextureIndex[reg.Index];
					if (textureIndex == -1)
						ThrowSamplerNoTextureException(reg);

					textures[textureIndex].VsSamplers.Add(reg.Index);

					//add the sampler to 'allSamplers'
					SharedSampler ss;
					if (!allSamplers.TryGetValue(reg.Name, out ss))
					{
						ss = new SharedSampler();
						ss.SamplerDetails = reg;
						ss.Index = allSamplers.Count;
						ss.DefaultState = extras.VertexSamplerStates[reg.Index];
						allSamplers.Add(reg.Name, ss);
					}
					ss.VsIndex = reg.Index;
				}
			}
		}