public static string createProjectFile(this string projectName, string sourceFile, string pathToAssemblies, string targetDir, List<string> extraEmbebbedResources, Action<List<string>> beforeAddingReferences, Action<List<string>> beforeEmbedingFiles)
        {
            var apiCreateExe = new API_Create_Exe();
            if (sourceFile.empty())
                return null;

            sourceFile.file_Copy(targetDir);
            var assemblyFiles = pathToAssemblies.files(false,"*.dll","*.exe");

            var projectFile =  targetDir.pathCombine(projectName + ".csproj");

            var projectCollection = new ProjectCollection();

            var outputPath = "bin";
            Project project = new Project(projectCollection);
            project.SetProperty("DefaultTargets", "Build");

            var propertyGroup = project.Xml.CreatePropertyGroupElement();
            project.Xml.InsertAfterChild(propertyGroup, project.Xml.LastChild);
            //propertyGroup.AddProperty("TargetFrameworkVersion", "v4.0");
            propertyGroup.AddProperty("TargetFrameworkVersion", "v4.5");
            propertyGroup.AddProperty("ProjectGuid", Guid.NewGuid().str());
            propertyGroup.AddProperty("OutputType", "WinExe");
            propertyGroup.AddProperty("OutputPath", outputPath);
            propertyGroup.AddProperty("AssemblyName", projectName);
            propertyGroup.AddProperty("PlatformTarget", "x86");

            var targets = project.Xml.AddItemGroup();
            targets.AddItem("Compile", sourceFile.fileName());

            var references = project.Xml.AddItemGroup();
            references.AddItem("Reference", "mscorlib");
            references.AddItem("Reference", "System");
            references.AddItem("Reference", "System.Core");
            references.AddItem("Reference", "System.Windows.Forms");

            beforeAddingReferences.invoke(assemblyFiles);
            foreach(var assemblyFile in assemblyFiles)
            {
                var assembly =  assemblyFile.fileName().assembly(); // first load from local AppDomain (so that we don't lock the dll in the target folder)
                if (assembly.isNull())
                    assembly  =  assemblyFile.assembly();
                //only load the O2 assemblies
                if (assembly.str().lower().contains("o2") || assembly.str().lower().contains("fluentsharp"))
                {
                    var item = references.AddItem("Reference",assemblyFile.fileName_WithoutExtension());
                    item.AddMetadata("HintPath",assemblyFile.fileName());
                    item.AddMetadata("Private",@"False");
                }
            }

            var gzAssemblyFiles = new List<string>();
            beforeEmbedingFiles.invoke(assemblyFiles);

            var embeddedResources = project.Xml.AddItemGroup();

            foreach(var assemblyFile in gzAssemblyFiles)
                embeddedResources.AddItem("EmbeddedResource",assemblyFile.fileName());

            var defaultIcon = "O2Logo.ico";
            extraEmbebbedResources.add(assemblyFiles);

            foreach(var extraResource in extraEmbebbedResources)
            {
                if (extraResource.extension(".dll") || extraResource.extension(".exe"))
                {
                    //ignore these since they are already embded in the FluentSharp.REPL.exe dll
                    if(extraEmbebbedResources.fileNames().contains("FluentSharp.REPL.exe") &&
                       (extraResource.contains("Mono.Cecil.dll" )))
                    {
                        continue;
                    }
                    var gzFile = targetDir.pathCombine(extraResource.fileName() + ".gz");
                    extraResource.fileInfo().compress(gzFile);
                    extraResource.file_Copy(targetDir);
                    embeddedResources.AddItem("EmbeddedResource",gzFile.fileName());
                }
                else
                {
                    extraResource.file_Copy(targetDir);
                    embeddedResources.AddItem("EmbeddedResource",extraResource.fileName());
                    if (extraResource.extension(".ico"))
                        defaultIcon = extraResource;
                }
            }

            //add two extra folders (needs refactoring)
            Action<string> addSpecialResources =
                (resourceFolder)=>{
                                      var folder = targetDir.pathCombine(resourceFolder);
                                      if (folder.dirExists())
                                      {
                                          "found {0} Folder so adding it as a zip:{1}".debug(resourceFolder, folder);
                                          var zipFile = folder.zip_Folder(folder + ".zip");
                                          embeddedResources.AddItem("EmbeddedResource",zipFile.fileName());
                                          if (folder.files("*.ico").size()>0)
                                          {
                                              var icon = folder.files("*.ico").first();
                                              "Found default application ICON: {0}".debug(icon);
                                              defaultIcon = icon;
                                          }
                                      }
                };
            addSpecialResources("O2.Platform.Scripts");

            //now add the icon
            propertyGroup.AddProperty("ApplicationIcon", defaultIcon);

            var importElement = project.Xml.CreateImportElement(@"$(MSBuildToolsPath)\Microsoft.CSharp.targets");
            project.Xml.InsertAfterChild(importElement, project.Xml.LastChild);

            project.Save(projectFile);

            var o2Logo = apiCreateExe.path_O2Logo_Icon();
            o2Logo.file_Copy(targetDir);

            return projectFile;
        }
 public static bool if_True(this bool value, Action callback)
 {
     if(value.isTrue())
         callback.invoke();
     return value;
 }
 /// <summary>
 /// invokes callback if the target starts with value (note that the callback string is the target.subString_After(value)
 /// </summary>
 /// <param name="target"></param>
 /// <param name="value"></param>
 /// <param name="callback"></param>
 /// <returns></returns>
 public static string if_Starts(this string target, string value, Action<string> callback)
 {
     if(target.equal(value))
         callback.invoke(target.subString_After(value));
     return target;
 }
 public static string if_Starts(this string target, string value, Action callback)
 {
     if(target.starts(value))
         callback.invoke();
     return target;
 }
 public static string if_Equal(this string target, string value, Action<string> callback)
 {
     if(target.equal(value))
         callback.invoke(value);
     return target;
 }
		public Ctrl_ProcessFinder onProcessChange(Action<Process> callback)
		{
			if(callback.notNull())
				this.ActiveWindowChanged  += (sender, e)=> callback.invoke(this.TargetProcess);	
			return this;
		}