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 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();
		}