internal ProtobuildStandardDefinition (ProtobuildModuleInfo modulel, ProtobuildDefinitionInfo definitionl, XmlDocument document, IProtobuildModule moduleObj) {
			module = modulel;
			definition = definitionl;
			this.document = document;
			this.moduleObj = moduleObj;

			Initialize(this);
		}
		public ProtobuildSubmodule (ProtobuildModuleInfo latestModuleInfo, ProtobuildModuleInfo submodule, SolutionFolder rootFolder)
        {
            parentModule = latestModuleInfo;
            currentModule = submodule;
			RootFolder = rootFolder;
			Packages = new ProtobuildPackages(this);
			Definitions = new ItemCollection<IProtobuildDefinition>();
			Submodules = new ItemCollection<ProtobuildSubmodule>();
		}
		protected ProtobuildNonStandardDefinition (ProtobuildModuleInfo modulel, ProtobuildDefinitionInfo definitionl, XmlDocument document, IProtobuildModule moduleObj)
        {
            module = modulel;
			definition = definitionl;
			this.document = document;
			this.moduleObj = moduleObj;

			Items = new ProjectItemCollection();

			Initialize(this);
		}
		public ProtobuildPackage (ProtobuildModuleInfo moduleInfo, ProtobuildPackageRef reference, IProtobuildModule parentModule)
        {
            module = moduleInfo;
            package = reference;
			parentModuleRef = parentModule;
			Packages = new ProtobuildPackages(this);
			Definitions = new ItemCollection<IProtobuildDefinition>();
			Submodules = new ItemCollection<ProtobuildSubmodule>();

			IsBinary = File.Exists(Path.Combine(FullPath, ".pkg")) &&
				!File.Exists(Path.Combine(FullPath, ".git")) &&
				!Directory.Exists(Path.Combine(FullPath, ".git"));
        }
		public static IProtobuildDefinition CreateDefinition(ProtobuildModuleInfo modulel, ProtobuildDefinitionInfo definitionl, IProtobuildModule moduleObj)
		{
			var document = new XmlDocument ();
			document.Load(definitionl.DefinitionPath);

			switch (definitionl.Type) {
			case "External":
				return new ProtobuildExternalDefinition(modulel, definitionl, document, moduleObj);
			case "Content":
				return new ProtobuildContentDefinition(modulel, definitionl, document, moduleObj);
			default:
				return new ProtobuildStandardDefinition(modulel, definitionl, document, moduleObj);
			}
		}
		internal ProtobuildExternalDefinition (ProtobuildModuleInfo modulel, ProtobuildDefinitionInfo definitionl, XmlDocument document, IProtobuildModule moduleObj)
			: base(modulel, definitionl, document, moduleObj) {
			Initialize(this);
		}
            public void SaveModule(ProtobuildModuleInfo moduleInfo)
            {
                var moduleInfoType = internalAssembly.GetType("Protobuild.ModuleInfo");
                var moduleInfoLoad = moduleInfoType.GetMethod("Load");
                dynamic moduleRef = moduleInfoLoad.Invoke(null, new object[] { Path.Combine(moduleInfo.Path, "Build", "Module.xml") });

                moduleRef.Name = moduleInfo.Name;
                moduleRef.DefaultLinuxPlatforms = moduleInfo.DefaultLinuxPlatforms;
                moduleRef.DefaultWindowsPlatforms = moduleInfo.DefaultWindowsPlatforms;
                moduleRef.DefaultMacOSPlatforms = moduleInfo.DefaultMacOSPlatforms;
                moduleRef.DefaultStartupProject = moduleInfo.DefaultStartupProject;
                moduleRef.DisableSynchronisation = moduleInfo.DisableSynchronisation;
                moduleRef.GenerateNuGetRepositories = moduleInfo.GenerateNuGetRepositories;
                moduleRef.SupportedPlatforms = moduleInfo.SupportedPlatforms;
                moduleRef.DefaultAction = moduleInfo.DefaultAction;

                // TODO: Save package references (we need to dynamically create PackageRefs from the Protobuild module).

                moduleRef.Save(Path.Combine(moduleInfo.Path, "Build", "Module.xml"));
            }
            public ProtobuildModuleInfo LoadModule(string rootPath) 
			{
				var moduleInfoType = internalAssembly.GetType("Protobuild.ModuleInfo");
				var moduleInfoLoad = moduleInfoType.GetMethod("Load");
				dynamic moduleRef = moduleInfoLoad.Invoke(null, new object[] { Path.Combine(rootPath, "Build", "Module.xml") });

			    /*if (monitor != null) {
			        monitor.BeginStepTask ("Loading " + moduleRef.Name + "...", 1, 5);
			    }*/

			    var moduleInfo = new ProtobuildModuleInfo();
                moduleInfo.Name = moduleRef.Name;
				moduleInfo.Path = moduleRef.Path;
			    moduleInfo.DefaultAction = moduleRef.DefaultAction;
                moduleInfo.DefaultLinuxPlatforms = moduleRef.DefaultLinuxPlatforms;
                moduleInfo.DefaultWindowsPlatforms = moduleRef.DefaultWindowsPlatforms;
                moduleInfo.DefaultMacOSPlatforms = moduleRef.DefaultMacOSPlatforms;
                moduleInfo.DisableSynchronisation = moduleRef.DisableSynchronisation;
                moduleInfo.GenerateNuGetRepositories = moduleRef.GenerateNuGetRepositories;
                moduleInfo.SupportedPlatforms = moduleRef.SupportedPlatforms;
			    moduleInfo.DefaultStartupProject = moduleRef.DefaultStartupProject;

                moduleInfo.LoadedDefinitions = new List<ProtobuildDefinitionInfo> ();

			    foreach (var definition in moduleRef.GetDefinitions ()) {
			        var definitionInfo = new ProtobuildDefinitionInfo ();
					definitionInfo.Name = definition.Name;
					try
					{
						// Newer versions of Protobuild name this property RelativePath.
						definitionInfo.Path = definition.RelativePath;
					}
					catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
					{
						definitionInfo.Path = definition.Path;
					}
			        definitionInfo.Type = definition.Type;
			        definitionInfo.DefinitionPath = definition.DefinitionPath;
			        definitionInfo.ModulePath = definition.ModulePath;
			        definitionInfo.SkipAutopackage = definition.SkipAutopackage;
			        moduleInfo.LoadedDefinitions.Add (definitionInfo);
                }

                moduleInfo.Packages = new List<ProtobuildPackageRef>();

                foreach (var package in moduleRef.Packages)
                {
                    var packageInfo = new ProtobuildPackageRef();
                    packageInfo.Uri = package.Uri;
                    packageInfo.GitRef = package.GitRef;
                    packageInfo.Folder = package.Folder;
                    moduleInfo.Packages.Add(packageInfo);
                }

			    moduleInfo.LoadedSubmodules = new List<ProtobuildModuleInfo> ();

			    foreach (var submodule in moduleRef.GetSubmodules ()) {
			        moduleInfo.LoadedSubmodules.Add (LoadModule (submodule.Path));
			    }

				return moduleInfo;
			}
 public void SaveModule(ProtobuildModuleInfo latestModuleInfo)
 {
     domainBehaviour.SaveModule(latestModuleInfo);
 }
		public void RunExecutableWithArguments(ProtobuildModuleInfo module, string args, Action<string> lineOutputted)
		{
			var protobuildPath = System.IO.Path.Combine(module.Path, "Protobuild.exe");

			try
			{
				var chmodStartInfo = new ProcessStartInfo
				{
					FileName = "chmod",
					Arguments = "a+x Protobuild.exe",
					WorkingDirectory = module.Path,
					CreateNoWindow = true,
					UseShellExecute = false
				};
				Process.Start(chmodStartInfo);
			}
			catch
			{
			}

			if (File.Exists(protobuildPath))
			{
				var pi = new ProcessStartInfo
				{
					FileName = protobuildPath,
					Arguments = args,
					WorkingDirectory = module.Path,
					CreateNoWindow = true,
					RedirectStandardError = true,
					RedirectStandardInput = true,
					RedirectStandardOutput = true,
					UseShellExecute = false
				};
				var p = new Process { StartInfo = pi };
				p.OutputDataReceived += (sender, eventArgs) =>
				{
					if (!string.IsNullOrEmpty(eventArgs.Data))
					{
						lineOutputted(eventArgs.Data);
						Console.WriteLine(eventArgs.Data);
						//monitor.Log.WriteLine(eventArgs.Data);
					}
				};
				p.ErrorDataReceived += (sender, eventArgs) =>
				{
					if (!string.IsNullOrEmpty(eventArgs.Data))
					{
						lineOutputted(eventArgs.Data);
						Console.Error.WriteLine(eventArgs.Data);
						//monitor.Log.WriteLine(eventArgs.Data);
					}
				};
				p.Start();
				p.BeginOutputReadLine();
				p.BeginErrorReadLine();
				Console.WriteLine("(Started Protobuild)");
				p.WaitForExit();
				Console.WriteLine("(Protobuild Exited)");

				if (p.ExitCode == 0) {
					lineOutputted("Protobuild.exe " + args + " completed with exit code 0.");
				} else {
					lineOutputted("Protobuild.exe " + args + " failed with non-zero exit code.");
				}
			}
        }
	    private void LoadSubmodule (IProtobuildModule folder, ProtobuildModuleInfo moduleInfo)
        {
	        if (folder.Packages == null) {
	            folder.Packages = new ProtobuildPackages (folder);
	        }

	        if (folder.Definitions == null) {
	            folder.Definitions = new ItemCollection<IProtobuildDefinition> ();
	        }

	        if (folder.Submodules == null) {
	            folder.Submodules = new ItemCollection<ProtobuildSubmodule> ();
	        }

	        var packagesByFolder = new Dictionary<string, ProtobuildPackage> ();

            foreach (var package in moduleInfo.Packages)
            {
				var packageItem = new ProtobuildPackage(moduleInfo, package, folder);
                //packageItem.SetItemHandler(new MSBuildHandler(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()));
                folder.Packages.Add(packageItem);
				packagesByFolder.Add(moduleInfo.Path + '/' + package.Folder.Replace ('\\','/'), packageItem);
            }

            foreach (var submodule in moduleInfo.LoadedSubmodules) {
				//var submoduleRelativeFolder = GetRelativePath(moduleInfo.Path, submodule.Path);
                //submoduleRelativeFolder = submoduleRelativeFolder.Replace ('\\', '/');

				if (packagesByFolder.ContainsKey (submodule.Path)) {
                    // Place all the projects under the package's folder instead.
					LoadSubmodule(packagesByFolder[submodule.Path], submodule);
                }
                else
                {
					var submoduleItem = new ProtobuildSubmodule(moduleInfo, submodule, this.RootFolder);
                    //submoduleItem.SetItemHandler(new MSBuildHandler(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()));
                    folder.Submodules.Add(submoduleItem);

                    LoadSubmodule(submoduleItem, submodule);
                }
            }

            foreach (var definition in moduleInfo.LoadedDefinitions)
            {
				var definitionItem = ProtobuildDefinitionLoader.CreateDefinition(moduleInfo, definition, folder);
				var standardDefinition = definitionItem as ProtobuildStandardDefinition;
				if (standardDefinition != null) {
					standardDefinition.ModuleOwnerForConfiguration = this;
				}
                //definitionItem.SetItemHandler(new MSBuildHandler(definition.Guid.ToString(), definition.Guid.ToString()));
                folder.Definitions.Add(definitionItem);

				// Add the definition to the root folder as well so that events
				// get hooked up correctly.
				folder.RootFolder.Items.Add((SolutionFolderItem)definitionItem);

				if (standardDefinition != null) {
					foreach (var config in standardDefinition.GetConfigurations ()) {
						EnsureConfigurationPresent (config, standardDefinition);
	                }
				}

                if (moduleInfo.DefaultStartupProject == definition.Name) {
                    this.SingleStartup = true;
					if (standardDefinition != null) {
						this.StartupItem = standardDefinition;
					}
                }
            }
		}
	    void HandleProtobuildChangedEvent (object sender, EventArgs e)
		{
            latestModuleInfo = appDomain.LoadModule(null);

            ReloadProjects();
		}
	    public async Task Load(string path, ProgressMonitor monitor)
	    {
			if (appDomain != null)
			{
                monitor.BeginTask ("Stopping Protobuild...", 1);
				monitor.BeginStep();
				appDomain.UnloadAppDomain();
				appDomain.ProtobuildChangedEvent -= HandleProtobuildChangedEvent;
				appDomain = null;
				monitor.EndTask();
			}

            monitor.BeginTask("Starting Protobuild...", 1);
			monitor.BeginStep();
			appDomain = new ProtobuildAppDomain(path);
			appDomain.ProtobuildChangedEvent += HandleProtobuildChangedEvent;
            latestModuleInfo = appDomain.LoadModule(monitor);

            FileName = path;

            // We have to perform an initial generation on load so we have a set of
            // projects that can be used for the type system.  Also we generate before
            // loading projects because generation might trigger package resolution.
	        //ActiveConfiguration = appDomain.HostPlatform;
			//IdeApp.Workspace.ActiveConfigurationId = appDomain.HostPlatform;
            //await EnsureProjectsAreGeneratedForPlatform(appDomain.HostPlatform, monitor);

            //monitor.BeginStepTask("Loading projects...", 1, 1);
		    ReloadProjects ();

			monitor.EndTask();
		}