Implementation of the 2.0 session state model
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Project.cs
index 31922599884f882a29c3ecea339a260c5390c464..fbd9517409dd76b5f06f3ec3e0543caff056106d 100644 (file)
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+#if NET_2_0
+
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.IO;
 using System.Text;
 using System.Xml;
 using System.Xml.Schema;
 using Microsoft.Build.Framework;
-using Mono.XBuild.Shared;
+using Mono.XBuild.Framework;
 
 namespace Microsoft.Build.BuildEngine {
-       public class Project : IProject {
-               static string separator = ";";
+       public class Project {
        
                bool                            buildEnabled;
-               IDictionary                     conditionedProperties;
-               Encoding                                currentEncoding;
+               Dictionary <string, List <string>>      conditionedProperties;
                string[]                        defaultTargets;
-               IList                           directlyImportedProjects;
-               BuildPropertyGroup              environmentProperties;
+               Encoding                        encoding;
                BuildItemGroup                  evaluatedItems;
                BuildItemGroup                  evaluatedItemsIgnoringCondition;
-               IDictionary                     evaluatedItemsByName;
-               IDictionary                     evaluatedItemsByNameIgnoringCondition;
+               Dictionary <string, BuildItemGroup>     evaluatedItemsByName;
+               Dictionary <string, BuildItemGroup>     evaluatedItemsByNameIgnoringCondition;
                BuildPropertyGroup              evaluatedProperties;
                string                          firstTargetName;
                string                          fullFileName;
                BuildPropertyGroup              globalProperties;
-               GroupingCollection              groups;
+               GroupingCollection              groupingCollection;
                bool                            isDirty;
                bool                            isValidated;
-               bool                            isReset;
                BuildItemGroupCollection        itemGroups;
-               IDictionary                     importedProjects;
+               ImportCollection                imports;
+               string                          initialTargets;
                Engine                          parentEngine;
                BuildPropertyGroupCollection    propertyGroups;
-               BuildPropertyGroup              reservedProperties;
                string                          schemaFile;
                TaskDatabase                    taskDatabase;
                TargetCollection                targets;
                DateTime                        timeOfLastDirty;
-               IList                           usingTaskElements;
+               UsingTaskCollection             usingTasks;
                XmlDocument                     xmlDocument;
-               XmlElement                      xmlElement;
+               bool                            unloaded;
+
+               static XmlNamespaceManager      manager;
+               static string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
 
                public Project ()
-                       : this (null)
+                       : this (Engine.GlobalEngine)
                {
                }
 
                public Project (Engine engine)
                {
+                       buildEnabled = engine.BuildEnabled;
                        parentEngine  = engine;
                        xmlDocument = new XmlDocument ();
-                       evaluatedItems = new BuildItemGroup (this);
-                       evaluatedItemsByName = new Hashtable (new CaseInsensitiveHashCodeProvider (), new CaseInsensitiveComparer ());
-                       evaluatedItemsByNameIgnoringCondition = new Hashtable (new CaseInsensitiveHashCodeProvider (), new CaseInsensitiveComparer ());
-                       evaluatedItemsIgnoringCondition = new BuildItemGroup (this);
-                       evaluatedProperties = new BuildPropertyGroup (false, null);
-                       groups = new GroupingCollection ();
-                       itemGroups = new BuildItemGroupCollection (groups);
-                       propertyGroups = new BuildPropertyGroupCollection (groups);
+                       groupingCollection = new GroupingCollection (this);
+                       imports = new ImportCollection (groupingCollection);
+                       usingTasks = new UsingTaskCollection (this);
+                       itemGroups = new BuildItemGroupCollection (groupingCollection);
+                       propertyGroups = new BuildPropertyGroupCollection (groupingCollection);
                        targets = new TargetCollection (this);
-                       usingTaskElements = new ArrayList ();
+                       
                        taskDatabase = new TaskDatabase ();
+                       if (engine.DefaultTasksRegistered) {
+                               taskDatabase.CopyTasks (engine.DefaultTasks);
+                       }
+                       
+                       globalProperties = new BuildPropertyGroup ();
+                       fullFileName = String.Empty;
+
+                       foreach (BuildProperty bp in parentEngine.GlobalProperties) {
+                               GlobalProperties.AddProperty (bp.Clone (true));
+                       }
+
+                       // You can evaluate an empty project.
+                       Evaluate ();
                }
 
+               [MonoTODO]
                public void AddNewImport (string importLocation,
                                          string importCondition)
                {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public BuildItem AddNewItem (string itemName,
                                             string itemInclude)
                {
-                       // add it to rawitemgroups, maybe to evaluated items then?
-                       return null;
+                       return AddNewItem (itemName, itemInclude, false);
+               }
+               
+               [MonoTODO]
+               public BuildItem AddNewItem (string itemName,
+                                            string itemInclude,
+                                            bool treatItemIncludeAsLiteral)
+               {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public BuildItemGroup AddNewItemGroup ()
                {
-                       return null;
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public BuildPropertyGroup AddNewPropertyGroup (bool insertAtEndOfProject)
                {
-                       return null;
+                       throw new NotImplementedException ();
                }
-
-               public bool Build (string[] targetNamesToBuild,
-                                  IDictionary targetOutputs)
+               
+               [MonoTODO]
+               public void AddNewUsingTaskFromAssemblyFile (string taskName,
+                                                            string assemblyFile)
                {
-                       if (targetNamesToBuild.Length == 0) {
-                               if (defaultTargets.Length != 0) {
-                                       targetNamesToBuild = defaultTargets;
-                               }
-                               else if (firstTargetName != null) {
-                                       targetNamesToBuild = new string [1] { firstTargetName};
-                               }
-                               else
-                                       return false;
-                       }
-                       foreach (string target in targetNamesToBuild) {
-                               if (BuildTarget (target, targetOutputs) == false) {
-                                       return false;
-                               }
-                       }
-                       return true;
+                       throw new NotImplementedException ();
                }
-
-               public bool BuildTarget (string targetName,
-                                        IDictionary targetOutputs)
+               
+               [MonoTODO]
+               public void AddNewUsingTaskFromAssemblyName (string taskName,
+                                                            string assemblyName)
                {
-                       return BuildTargetWithFlags (targetName, targetOutputs, BuildSettings.None);
+                       throw new NotImplementedException ();
                }
-
-               public bool BuildTargetWithFlags (string targetName,
-                                                 IDictionary targetOutputs,
-                                                 BuildSettings buildFlags)
+               
+               [MonoTODO]
+               public bool Build ()
                {
-                       if (targets.Exists (targetName) == false)
-                               throw new Exception ("Target specified to build does not exist.");
-                       
-                       this.targets [targetName].Build ();
                        return true;
                }
                
-               public string[] GetConditionedPropertyValues (string propertyName)
+               [MonoTODO]
+               public bool Build (string targetName)
                {
-                       StringCollection sc = (StringCollection) conditionedProperties [propertyName];
-                       string[] propertyValues = new string [sc.Count];
-                       int i  = 0;
-                       foreach (string propertyValue in sc)
-                               propertyValues [i++] = propertyValue;
-                       return propertyValues;
+                       return Build (new string [1] { targetName });
                }
-
-               public string[] GetDirectlyImportedProjects ()
+               
+               [MonoTODO]
+               public bool Build (string[] targetNames)
                {
-                       string[] dip = new string [directlyImportedProjects.Count];
-                       int i = 0;
-                       foreach (string importedProject in directlyImportedProjects)
-                               dip [i++] = importedProject;
-                       return dip;
+                       return Build (targetNames, null);
                }
-
-               public BuildItemGroup GetEvaluatedItemsByName (string itemName)
+               
+               [MonoTODO]
+               public bool Build (string[] targetNames,
+                                  IDictionary targetOutputs)
                {
-                       return (BuildItemGroup) evaluatedItemsByName [itemName];
+                       return Build (targetNames, targetOutputs, BuildSettings.None);
                }
-
-               public BuildItemGroup GetEvaluatedItemsByNameIgnoringCondition (string itemName)
+               
+               [MonoTODO]
+               public bool Build (string[] targetNames,
+                                  IDictionary targetOutputs,
+                                  BuildSettings buildFlags)
+               
                {
-                       return (BuildItemGroup) evaluatedItemsByNameIgnoringCondition [itemName];
+                       CheckUnloaded ();
+                       
+                       if (targetNames.Length == 0) {
+                               if (defaultTargets != null && defaultTargets.Length != 0)
+                                       targetNames = defaultTargets;
+                               else if (firstTargetName != null)
+                                       targetNames = new string [1] { firstTargetName};
+                               else
+                                       return false;
+                       }
+                       
+                       foreach (string target in targetNames) {
+                               if (!targets.Exists (target))
+                                       // FIXME: test if it's logged
+                                       return false;
+                               
+                               if (!targets [target].Build ())
+                                       return false;
+                       }
+                               
+                       return true;
                }
 
-               public string GetEvaluatedProperty (string propertyName)
+               [MonoTODO]
+               public string[] GetConditionedPropertyValues (string propertyName)
                {
-                       return evaluatedProperties [propertyName];
+                       if (conditionedProperties.ContainsKey (propertyName))
+                               return conditionedProperties [propertyName].ToArray ();
+                       else
+                               return new string [0];
                }
 
-               public string[] GetNonImportedItemNames ()
+               public BuildItemGroup GetEvaluatedItemsByName (string itemName)
                {
-                       return null;
+                       if (evaluatedItemsByName.ContainsKey (itemName))
+                               return evaluatedItemsByName [itemName];
+                       else
+                               return new BuildItemGroup ();
                }
 
-               public string[] GetNonImportedPropertyNames ()
+               public BuildItemGroup GetEvaluatedItemsByNameIgnoringCondition (string itemName)
                {
-                       return null;
+                       if (evaluatedItemsByNameIgnoringCondition.ContainsKey (itemName))
+                               return evaluatedItemsByNameIgnoringCondition [itemName];
+                       else
+                               return new BuildItemGroup ();
                }
 
-               public string[] GetNonImportedTargetNames ()
+               public string GetEvaluatedProperty (string propertyName)
                {
-                       ArrayList temporaryNonImportedTargets = new ArrayList ();
-                       foreach (Target target in targets)
-                               if (target.IsImported == false)
-                                       temporaryNonImportedTargets.Add (target);
-                       string[] nonImportedTargetNames = new string [temporaryNonImportedTargets.Count];
-                       int i = 0;
-                       foreach (Target target in temporaryNonImportedTargets)
-                               nonImportedTargetNames [i++] = target.Name;
-                       return nonImportedTargetNames;
-               }
+                       if (propertyName == null)
+                               throw new ArgumentNullException ("propertyName");
 
-               public string[] GetNonImportedUsingTasks ()
-               {
-                       return null;
+                       BuildProperty bp = evaluatedProperties [propertyName];
+
+                       return bp == null ? null : (string) bp;
                }
 
                public string GetProjectExtensions (string id)
                {
-                       return null;
+                       if (id == null || id == String.Empty)
+                               return String.Empty;
+
+                       XmlNode node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
+
+                       if (node == null)
+                               return String.Empty;
+                       else
+                               return node.InnerXml;
                }
 
-               public void LoadFromFile (string projectFileName)
+
+               public void Load (string projectFileName)
                {
                        this.fullFileName = Path.GetFullPath (projectFileName);
-                       XmlSchemaCollection xmlSchemaCollection = null;
-                       XmlTextReader xmlTextReader = null;
-                       XmlValidatingReader xmlValidatingReader = null;
-                       
-                       if (this.schemaFile != null) {
-                               xmlSchemaCollection = new XmlSchemaCollection ();
-                               xmlSchemaCollection.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
-                               xmlSchemaCollection.Add (null, this.schemaFile);
-                               if (xmlSchemaCollection.Count > 0) {
-                                       xmlTextReader = new XmlTextReader (projectFileName);
-                                       xmlValidatingReader = new XmlValidatingReader (xmlTextReader);
-                                       xmlValidatingReader.ValidationType = ValidationType.Schema;
-                                       xmlValidatingReader.Schemas.Add (xmlSchemaCollection);
-                                       xmlValidatingReader.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
-                               }
-                       } else {
-                               xmlTextReader = new XmlTextReader (projectFileName);
-                       }
-                       if (xmlValidatingReader != null)
-                               xmlDocument.Load (xmlValidatingReader);
-                       else if (xmlTextReader != null)
-                               xmlDocument.Load (xmlTextReader);
-                       else
-                               throw new Exception ();
-                       xmlElement = xmlDocument.DocumentElement;
-                       if (xmlElement.Name != "Project")
-                               throw new InvalidProjectFileException ("Invalid root element.");
-                       if (xmlElement.GetAttributeNode ("DefaultTargets") != null)
-                               defaultTargets = xmlElement.GetAttribute ("DefaultTargets").Split (';');
-                       else
-                               defaultTargets = new string [0];
-                       
-                       ProcessElements (xmlElement, null);
-                       
-                       isDirty = false;
+                       DoLoad (new StreamReader (projectFileName));
+               }
+               
+               [MonoTODO]
+               public void Load (TextReader textReader)
+               {
+                       fullFileName = String.Empty;
+                       DoLoad (textReader);
                }
 
-               public void LoadFromXml (XmlDocument projectXml)
+               public void LoadXml (string projectXml)
                {
-                       fullFileName = "";
-                       xmlDocument = projectXml;
-                       xmlElement = xmlDocument.DocumentElement;
-                       if (xmlElement.Name != "Project")
-                               throw new InvalidProjectFileException ("Invalid root element.");
-                       if (xmlElement.GetAttributeNode ("DefaultTargets") != null)
-                               defaultTargets = xmlElement.GetAttribute ("DefaultTargets").Split (';');
-                       else
-                               defaultTargets = new string [0];
-                       
-                       ProcessElements (xmlElement, null);
-                       
-                       isDirty = false;
+                       fullFileName = String.Empty;
+                       DoLoad (new StringReader (projectXml));
+                       MarkProjectAsDirty ();
                }
 
+
                public void MarkProjectAsDirty ()
                {
                        isDirty = true;
+                       timeOfLastDirty = DateTime.Now;
                }
 
+               [MonoTODO]
                public void RemoveAllItemGroups ()
                {
+                       throw new NotImplementedException ();
                }
 
-               public void RemoveAllItemsGroupsByCondition (string condition)
-               {
-               }
-
+               [MonoTODO]
                public void RemoveAllPropertyGroups ()
                {
+                       throw new NotImplementedException ();
                }
 
-               public void RemoveAllPropertyGroupsByCondition (string condition)
-               {
-               }
-
+               [MonoTODO]
                public void RemoveItem (BuildItem itemToRemove)
                {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public void RemoveItemGroup (BuildItemGroup itemGroupToRemove)
                {
+                       throw new NotImplementedException ();
+               }
+               
+               [MonoTODO]
+               // NOTE: does not modify imported projects
+               public void RemoveItemGroupsWithMatchingCondition (string matchingCondition)
+               {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public void RemoveItemsByName (string itemName)
                {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public void RemovePropertyGroup (BuildPropertyGroup propertyGroupToRemove)
                {
-                       
+                       throw new NotImplementedException ();
+               }
+               
+               [MonoTODO]
+               // NOTE: does not modify imported projects
+               public void RemovePropertyGroupsWithMatchingCondition (string matchCondition)
+               {
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public void ResetBuildStatus ()
                {
+                       throw new NotImplementedException ();
                }
 
-               public void SaveToFile (string projectFileName)
+               public void Save (string projectFileName)
                {
-                       xmlDocument.Save (projectFileName);
+                       Save (projectFileName, Encoding.Default);
                }
 
-               public void SaveToFile (string projectFileName,
-                                       ProjectFileEncoding encoding)
+               public void Save (string projectFileName, Encoding encoding)
                {
-                       SaveToFile (projectFileName);
+                       xmlDocument.Save (projectFileName);
                }
 
-               public void SaveToTextWriter (TextWriter outTextWriter)
+               public void Save (TextWriter outTextWriter)
                {
                        xmlDocument.Save (outTextWriter);
                }
@@ -339,38 +359,164 @@ namespace Microsoft.Build.BuildEngine {
                                                 string condition,
                                                 Project importProject)
                {
+                       SetImportedProperty (propertyName, propertyValue, condition, importProject,
+                               PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup);
                }
 
-               public void SetImportedPropertyAt (string propertyName,
-                                                  string propertyValue,
-                                                  string condition,
-                                                  Project importedProject,
-                                                  PropertyPosition position)
+               public void SetImportedProperty (string propertyName,
+                                                string propertyValue,
+                                                string condition,
+                                                Project importedProject,
+                                                PropertyPosition position)
+               {
+                       SetImportedProperty (propertyName, propertyValue, condition, importedProject,
+                               PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
+               }
+
+               [MonoTODO]
+               public void SetImportedProperty (string propertyName,
+                                                string propertyValue,
+                                                string condition,
+                                                Project importedProject,
+                                                PropertyPosition position,
+                                                bool treatPropertyValueAsLiteral)
                {
+                       throw new NotImplementedException ();
                }
 
                public void SetProjectExtensions (string id, string xmlText)
                {
+                       XmlNode projectExtensions, node;
+
+                       if (id == null || id == String.Empty || xmlText == null)
+                               return;
+
+                       projectExtensions = xmlDocument.SelectSingleNode ("/tns:Project/tns:ProjectExtensions", XmlNamespaceManager);
+                       
+                       
+                       if (projectExtensions == null) {
+                               projectExtensions = xmlDocument.CreateElement ("ProjectExtensions", XmlNamespace);
+                               xmlDocument.DocumentElement.AppendChild (projectExtensions);
+
+                               node = xmlDocument.CreateElement (id, XmlNamespace);
+                               node.InnerXml = xmlText;
+                               projectExtensions.AppendChild (node);
+                       } else {
+                               node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
+
+                               if (node == null) {
+                                       node = xmlDocument.CreateElement (id, XmlNamespace);
+                                       projectExtensions.AppendChild (node);
+                               }
+                               
+                               node.InnerXml = xmlText;
+                               
+                       }
+
+                       MarkProjectAsDirty ();
+               }
+               
+               [MonoTODO]
+               public void SetProperty (string propertyName,
+                                        string propertyValue)
+               {
+                       SetProperty (propertyName, propertyValue, "true",
+                               PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
                }
 
+               [MonoTODO]
                public void SetProperty (string propertyName,
                                         string propertyValue,
                                         string condition)
                {
+                       SetProperty (propertyName, propertyValue, condition,
+                               PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup);
+               }
+
+               [MonoTODO]
+               public void SetProperty (string propertyName,
+                                        string propertyValue,
+                                        string condition,
+                                        PropertyPosition position)
+               {
+                       SetProperty (propertyName, propertyValue, condition,
+                               PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup, false);
                }
 
-               public void SetPropertyAt (string propertyName,
-                                          string propertyValue,
-                                          string condition,
-                                          PropertyPosition position)
+               [MonoTODO]
+               public void SetProperty (string propertyName,
+                                        string propertyValue,
+                                        string condition,
+                                        PropertyPosition position,
+                                        bool treatPropertyValueAsLiteral)
                {
+                       throw new NotImplementedException ();
                }
 
-               public void Unload ()
+               internal void Unload ()
+               {
+                       unloaded = true;
+               }
+
+               internal void CheckUnloaded ()
+               {
+                       if (unloaded)
+                               throw new InvalidOperationException ("This project object has been unloaded from the MSBuild engine and is no longer valid.");
+               }
+                               
+               // Does the actual loading.
+               void DoLoad (TextReader textReader)
                {
+                       try {
+                               ParentEngine.RemoveLoadedProject (this);
+       
+                               XmlReaderSettings settings = new XmlReaderSettings ();
+       
+                               if (SchemaFile != null) {
+                                       settings.Schemas.Add (null, SchemaFile);
+                                       settings.ValidationType = ValidationType.Schema;
+                                       settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
+                               }
+       
+                               XmlReader xmlReader = XmlReader.Create (textReader, settings);
+                               xmlDocument.Load (xmlReader);
+
+                               if (xmlDocument.DocumentElement.Name != "Project") {
+                                       throw new InvalidProjectFileException (String.Format (
+                                               "The element <{0}> is unrecognized, or not supported in this context.", xmlDocument.DocumentElement.Name));
+                               }
+       
+                               if (xmlDocument.DocumentElement.GetAttribute ("xmlns") != ns) {
+                                       throw new InvalidProjectFileException (
+                                               @"The default XML namespace of the project must be the MSBuild XML namespace." + 
+                                               " If the project is authored in the MSBuild 2003 format, please add " +
+                                               "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
+                                               "If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format.  ");
+                               }
+                               ProcessXml ();
+                               ParentEngine.AddLoadedProject (this);
+                       } catch (Exception e) {
+                               throw new InvalidProjectFileException (e.Message, e);
+                       }
+               }
+
+               void ProcessXml ()
+               {
+                       XmlElement xmlElement = xmlDocument.DocumentElement;
+                       if (xmlElement.Name != "Project")
+                               throw new InvalidProjectFileException ("Invalid root element.");
+                       if (xmlElement.GetAttributeNode ("DefaultTargets") != null)
+                               defaultTargets = xmlElement.GetAttribute ("DefaultTargets").Split (';');
+                       else
+                               defaultTargets = new string [0];
+                       
+                       ProcessElements (xmlElement, null);
+                       
+                       isDirty = false;
+                       Evaluate ();
                }
                
-               private void ProcessElements (XmlElement rootElement, ImportedProject ip)
+               internal void ProcessElements (XmlElement rootElement, ImportedProject ip)
                {
                        foreach (XmlNode xn in rootElement.ChildNodes) {
                                if (xn is XmlElement) {
@@ -394,10 +540,10 @@ namespace Microsoft.Build.BuildEngine {
                                                AddImport (xe, ip);
                                                break;
                                        case "ItemGroup":
-                                               AddItemGroup (xe);
+                                               AddItemGroup (xe, ip);
                                                break;
                                        case "PropertyGroup":
-                                               AddPropertyGroup (xe);
+                                               AddPropertyGroup (xe, ip);
                                                break;
                                        case  "Choose":
                                                AddChoose (xe);
@@ -409,122 +555,94 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
                
-               private void AddProjectExtensions (XmlElement xmlElement)
+               internal void Evaluate ()
+               {
+                       evaluatedItems = new BuildItemGroup (null, this, null);
+                       evaluatedItemsIgnoringCondition = new BuildItemGroup (null, this, null);
+                       evaluatedItemsByName = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
+                       evaluatedItemsByNameIgnoringCondition = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
+                       evaluatedProperties = new BuildPropertyGroup ();
+
+                       InitializeProperties ();
+
+                       groupingCollection.Evaluate ();
+
+                       //FIXME: UsingTasks aren't really evaluated. (shouldn't use expressions or anything)
+                       foreach (UsingTask usingTask in UsingTasks)
+                               usingTask.Evaluate ();
+               }
+
+               private void InitializeProperties ()
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
+                       BuildProperty bp;
+
+                       foreach (BuildProperty gp in GlobalProperties) {
+                               bp = new BuildProperty (gp.Name, gp.Value, PropertyType.Global);
+                               EvaluatedProperties.AddProperty (bp);
+                       }
+                       
+                       foreach (DictionaryEntry de in Environment.GetEnvironmentVariables ()) {
+                               bp = new BuildProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
+                               EvaluatedProperties.AddProperty (bp);
+                       }
+
+                       bp = new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved);
+                       EvaluatedProperties.AddProperty (bp);
                }
                
-               private void AddMessage (XmlElement xmlElement)
+               void AddProjectExtensions (XmlElement xmlElement)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
                }
                
-               private void AddTarget (XmlElement xmlElement, ImportedProject importedProject)
+               void AddMessage (XmlElement xmlElement)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
-                       Target target = targets.AddNewTarget (xmlElement.GetAttribute ("Name"));
-                       target.BindToXml (xmlElement);
-                       if (importedProject == null) {
-                               target.IsImported = false;
-                               if (firstTargetName == null)
-                                       firstTargetName = target.Name;
-                       } else
-                               target.IsImported = true;
                }
                
-               private void AddUsingTask (XmlElement xmlElement, ImportedProject importedProject)
+               void AddTarget (XmlElement xmlElement, ImportedProject importedProject)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
-                               
-                       if (xmlElement.GetAttribute ("TaskName") == String.Empty)
-                               throw new InvalidProjectFileException ("TaskName attribute must be specified.");
-
-                       usingTaskElements.Add (xmlElement);
-
-                       AssemblyLoadInfo loadInfo = null;
-                       string filename = null;
-                       string name = null;
-                       string taskName = xmlElement.GetAttribute ("TaskName");
+                       Target target = new Target (xmlElement, this, importedProject);
+                       targets.AddTarget (target);
                        
-                       if (xmlElement.GetAttribute ("AssemblyName") != String.Empty) {
-                               name  = xmlElement.GetAttribute ("AssemblyName");
-                               loadInfo  = new AssemblyLoadInfo (name, taskName);
-                               taskDatabase.RegisterTask (taskName, loadInfo);
-                       } else if (xmlElement.GetAttribute ("AssemblyFile") != String.Empty) {
-                               filename = xmlElement.GetAttribute ("AssemblyFile");
-                               if (Path.IsPathRooted (filename) == false) {
-                                       if (importedProject == null)
-                                               filename = Path.Combine (Path.GetDirectoryName (fullFileName), filename);
-                                       else
-                                               filename = Path.Combine (Path.GetDirectoryName (importedProject.FullFileName), filename);
-                               }
-                               loadInfo  = new AssemblyLoadInfo (LoadInfoType.AssemblyFilename, filename, null, null, null, null, taskName);
-                               taskDatabase.RegisterTask (taskName, loadInfo);
-                       } else
-                               throw new InvalidProjectFileException ("AssemblyName or AssemblyFile attribute must be specified.");
+                       if (firstTargetName == null)
+                               firstTargetName = target.Name;
                }
                
-               private void AddImport (XmlElement xmlElement, ImportedProject importingProject)
+               void AddUsingTask (XmlElement xmlElement, ImportedProject importedProject)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
-                       
-                       string importedFile;
-                       Expression importedFileExpr;
-                       ImportedProject ImportedProject;
+                       UsingTask usingTask;
 
-                       importedFileExpr = new Expression (this, xmlElement.GetAttribute ("Project"));
-                       importedFile = (string) importedFileExpr.ToNonArray (typeof (string));
-                       
-                       if (importedFile == String.Empty)
-                               throw new InvalidProjectFileException ("Project attribute must be specified.");
-                       
-                       if (Path.IsPathRooted (importedFile) == false) {
-                               if (importingProject == null)
-                                       importedFile = Path.Combine (Path.GetDirectoryName (fullFileName), importedFile);
-                               else
-                                       importedFile = Path.Combine (Path.GetDirectoryName (importingProject.FullFileName), importedFile);
-                       }
+                       usingTask = new UsingTask (xmlElement, this, importedProject);
+                       UsingTasks.Add (usingTask);
+               }
+               
+               void AddImport (XmlElement xmlElement, ImportedProject importingProject)
+               {
+                       Import import;
                        
-                       ImportedProject importedProject = new ImportedProject ();
-                       try {
-                               importedProject.Load (importedFile);
-                               ProcessElements (importedProject.XmlDocument.DocumentElement, importedProject);
-                       }
-                       catch (Exception ex) {
-                               Console.WriteLine (ex);
-                       }
+                       import = new Import (xmlElement, this, importingProject);
+                       Imports.Add (import);
                }
                
-               private void AddItemGroup (XmlElement xmlElement)
+               void AddItemGroup (XmlElement xmlElement, ImportedProject importedProject)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
-                       BuildItemGroup big = new BuildItemGroup (this);
-                       big.BindToXml (xmlElement);
-                       itemGroups.Add (big);
+                       BuildItemGroup big = new BuildItemGroup (xmlElement, this, importedProject);
+                       ItemGroups.Add (big);
                }
                
-               private void AddPropertyGroup (XmlElement xmlElement)
+               void AddPropertyGroup (XmlElement xmlElement, ImportedProject importedProject)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
-                       BuildPropertyGroup bpg = new BuildPropertyGroup (true, this);
-                       bpg.BindToXml (xmlElement);
-                       propertyGroups.Add (bpg);
+                       BuildPropertyGroup bpg = new BuildPropertyGroup (xmlElement, this, importedProject);
+                       PropertyGroups.Add (bpg);
                }
                
-               private void AddChoose (XmlElement xmlElement)
+               void AddChoose (XmlElement xmlElement)
                {
-                       if (xmlElement == null)
-                               throw new ArgumentNullException ("xmlElement");
+                       BuildChoose bc = new BuildChoose (xmlElement, this);
+                       groupingCollection.Add (bc);
+                       
                }
                
-               private static void ValidationCallBack (object sender, ValidationEventArgs e)
+               static void ValidationCallBack (object sender, ValidationEventArgs e)
                {
                        Console.WriteLine ("Validation Error: {0}", e.Message);
                }
@@ -538,22 +656,16 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
 
-               public ProjectFileEncoding CurrentProjectFileEncoding {
-                       get {
-                               if (currentEncoding == Encoding.UTF8)
-                                       return ProjectFileEncoding.Utf8;
-                               if (currentEncoding == Encoding.Unicode)
-                                       return ProjectFileEncoding.Unicode;
-                               if (currentEncoding == Encoding.GetEncoding ("ANSI"))
-                                       return ProjectFileEncoding.Ansi;
-                               throw new Exception ();
-                       }
+               public Encoding Encoding {
+                       get { return encoding; }
                }
 
                public string DefaultTargets {
-                       get { return xmlElement.GetAttribute ("DefaultTargets"); }
+                       get {
+                               return xmlDocument.DocumentElement.GetAttribute ("DefaultTargets");
+                       }
                        set {
-                               xmlElement.SetAttribute ("DefaultTargets",value);
+                               xmlDocument.DocumentElement.SetAttribute ("DefaultTargets", value);
                                defaultTargets = value.Split (';');
                        }
                }
@@ -566,11 +678,11 @@ namespace Microsoft.Build.BuildEngine {
                        get { return evaluatedItemsIgnoringCondition; }
                }
                
-               internal IDictionary EvaluatedItemsByName {
+               internal IDictionary <string, BuildItemGroup> EvaluatedItemsByName {
                        get { return evaluatedItemsByName; }
                }
                
-               internal IDictionary EvaluatedItemsByNameIgnoringCondition {
+               internal IDictionary <string, BuildItemGroup> EvaluatedItemsByNameIgnoringCondition {
                        get { return evaluatedItemsByNameIgnoringCondition; }
                }
 
@@ -586,9 +698,13 @@ namespace Microsoft.Build.BuildEngine {
                public BuildPropertyGroup GlobalProperties {
                        get { return globalProperties; }
                        set {
+                               if (value == null) {
+                                       throw new ArgumentNullException ("value");
+                               }
+                               if (value.FromXml) {
+                                       throw new InvalidOperationException ("Can't do that.");
+                               }
                                globalProperties = value;
-                               foreach (BuildProperty bp in globalProperties)
-                                       evaluatedProperties.AddFromExistingProperty (bp);
                        }
                }
 
@@ -604,6 +720,15 @@ namespace Microsoft.Build.BuildEngine {
                public BuildItemGroupCollection ItemGroups {
                        get { return itemGroups; }
                }
+               
+               public ImportCollection Imports {
+                       get { return imports; }
+               }
+               
+               public string InitialTargets {
+                       get { return initialTargets; }
+                       set { initialTargets = value; }
+               }
 
                public Engine ParentEngine {
                        get { return parentEngine; }
@@ -625,29 +750,39 @@ namespace Microsoft.Build.BuildEngine {
                public DateTime TimeOfLastDirty {
                        get { return timeOfLastDirty; }
                }
+               
+               public UsingTaskCollection UsingTasks {
+                       get { return usingTasks; }
+               }
 
-               public XmlDocument Xml {
-                       get { return xmlDocument; }
+               [MonoTODO]
+               public string Xml {
+                       get { return xmlDocument.InnerXml; }
+               }
+               
+               internal static XmlNamespaceManager XmlNamespaceManager {
+                       get {
+                               if (manager == null) {
+                                       manager = new XmlNamespaceManager (new NameTable ());
+                                       manager.AddNamespace ("tns", ns);
+                               }
+                               
+                               return manager;
+                       }
                }
                
                internal TaskDatabase TaskDatabase {
                        get { return taskDatabase; }
                }
                
-               internal BuildPropertyGroup EnvironmentProperties {
-                       set {
-                               environmentProperties = value;
-                               foreach (BuildProperty bp in environmentProperties)
-                                       evaluatedProperties.AddFromExistingProperty (bp);
-                       }
+               internal XmlDocument XmlDocument {
+                       get { return xmlDocument; }
                }
                
-               internal BuildPropertyGroup ReservedProperties {
-                       set {
-                               reservedProperties = value;
-                               foreach (BuildProperty bp in reservedProperties)
-                                       evaluatedProperties.AddFromExistingProperty (bp);
-                       }
+               internal static string XmlNamespace {
+                       get { return ns; }
                }
        }
 }
+
+#endif