public override bool Execute()
        {
            List <ITaskItem> computed = new List <ITaskItem>();

            foreach (ITaskItem source in Sources)
            {
                bool skip = true;
                Log.LogMessage(MessageImportance.Low,
                               string.Format("Computing dependencies for {0}", source.GetMetadata("Identity")));
                var sourceInfo = new FileInfo(source.GetMetadata("FullPath"));
                if (!sourceInfo.Exists)
                {
                    Log.LogMessage(MessageImportance.Low,
                                   string.Format("Build required because source: {0} doesn't exists",
                                                 source.GetMetadata("Identity")));
                    skip = false;
                }

                var      generatedItems = GeneratedItems(source);
                FileInfo generatedInfo  = null;
                FileInfo dependInfo     = null;
                //
                // Check if the Slice compiler is older than the source file
                //
                var sliceCompiler = new FileInfo(Path.Combine(IceToolsPath, ToolName));
                if (skip)
                {
                    foreach (ITaskItem item in generatedItems)
                    {
                        generatedInfo = new FileInfo(item.GetMetadata("FullPath"));

                        if (generatedInfo.Exists &&
                            sliceCompiler.LastWriteTime.ToFileTime() > generatedInfo.LastWriteTime.ToFileTime())
                        {
                            Log.LogMessage(MessageImportance.Low,
                                           string.Format("Build required because target: {0} is older than Slice compiler: {1}",
                                                         TaskUtil.MakeRelative(WorkingDirectory, generatedInfo.FullName),
                                                         ToolName));
                            skip = false;
                            break;
                        }
                    }
                }

                XmlDocument dependsDoc = new XmlDocument();
                if (skip)
                {
                    dependInfo = new FileInfo(Path.Combine(WorkingDirectory, source.GetMetadata("OutputDir"),
                                                           string.Format("SliceCompile.{0}.d", Path.GetFileNameWithoutExtension(sourceInfo.Name))));
                    //
                    // Check that the depdend file exists
                    //
                    if (!dependInfo.Exists)
                    {
                        Log.LogMessage(MessageImportance.Low,
                                       string.Format("Build required because depend file: {0} doesn't exists",
                                                     TaskUtil.MakeRelative(WorkingDirectory, dependInfo.FullName)));
                        skip = false;
                    }
                    //
                    // Check that the depend file is older than the corresponding Slice source
                    //
                    else if (sourceInfo.LastWriteTime.ToFileTime() > dependInfo.LastWriteTime.ToFileTime())
                    {
                        Log.LogMessage(MessageImportance.Low,
                                       string.Format("Build required because source: {0} is older than depend file {1}",
                                                     source.GetMetadata("Identity"),
                                                     TaskUtil.MakeRelative(WorkingDirectory, dependInfo.FullName)));
                        skip = false;
                    }
                    else
                    {
                        try
                        {
                            dependsDoc.Load(dependInfo.FullName);
                        }
                        catch (XmlException)
                        {
                            try
                            {
                                File.Delete(dependInfo.FullName);
                            }
                            catch (IOException)
                            {
                            }
                            Log.LogMessage(MessageImportance.Low,
                                           string.Format("Build required because depend file: {0} has some invalid data",
                                                         TaskUtil.MakeRelative(WorkingDirectory, dependInfo.FullName)));
                            skip = false;
                        }
                    }
                }

                if (skip)
                {
                    foreach (ITaskItem item in generatedItems)
                    {
                        generatedInfo = new FileInfo(item.GetMetadata("FullPath"));
                        //
                        // Check that the generated file exists
                        //
                        if (!generatedInfo.Exists)
                        {
                            Log.LogMessage(MessageImportance.Low,
                                           string.Format("Build required because generated: {0} doesn't exists",
                                                         TaskUtil.MakeRelative(WorkingDirectory, generatedInfo.FullName)));
                            skip = false;
                            break;
                        }
                        //
                        // Check that the generated file is older than the corresponding Slice source
                        //
                        else if (sourceInfo.LastWriteTime.ToFileTime() > generatedInfo.LastWriteTime.ToFileTime())
                        {
                            Log.LogMessage(MessageImportance.Low,
                                           string.Format("Build required because source: {0} is older than target {1}",
                                                         source.GetMetadata("Identity"),
                                                         TaskUtil.MakeRelative(WorkingDirectory, generatedInfo.FullName)));
                            skip = false;
                            break;
                        }
                    }
                }

                if (skip)
                {
                    XmlNodeList options = dependsDoc.DocumentElement.SelectNodes(
                        string.Format("/dependencies/source[@name='{0}']/options/child::node()",
                                      source.GetMetadata("Identity")));
                    if (options != null)
                    {
                        var newOptions = GetOptions(source);
                        var oldOptions = options.Cast <XmlNode>().Select(node => new
                        {
                            node.Name,
                            node.InnerXml
                        }).ToDictionary(t => t.Name, t => t.InnerXml);

                        if (newOptions.Except(oldOptions).Any() || oldOptions.Except(newOptions).Any())
                        {
                            Log.LogMessage(MessageImportance.Low,
                                           string.Format("Build required because source: {0} build options change",
                                                         source.GetMetadata("Identity")));
                            skip = false;
                        }
                    }
                }

                if (skip)
                {
                    XmlNodeList depends = dependsDoc.DocumentElement.SelectNodes(
                        string.Format("/dependencies/source[@name='{0}']/dependsOn", source.GetMetadata("Identity")));

                    if (depends != null)
                    {
                        var inputs = new List <string>();
                        foreach (XmlNode depend in depends)
                        {
                            string   path           = depend.Attributes["name"].Value;
                            FileInfo dependencyInfo = new FileInfo(path);
                            if (!dependencyInfo.Exists)
                            {
                                Log.LogMessage(MessageImportance.Low,
                                               string.Format("Build required because dependency: {0} doesn't exists",
                                                             TaskUtil.MakeRelative(WorkingDirectory, dependencyInfo.FullName)));
                                skip = false;
                                break;
                            }
                            else if (dependencyInfo.LastWriteTime > generatedInfo.LastWriteTime)
                            {
                                Log.LogMessage(MessageImportance.Low,
                                               string.Format("Build required because source: {0} is older than target: {1}",
                                                             source.GetMetadata("Identity"),
                                                             TaskUtil.MakeRelative(WorkingDirectory, dependencyInfo.FullName)));
                                skip = false;
                                break;
                            }

                            inputs.Add(Path.GetFullPath(depend.Attributes["name"].Value).ToUpper());
                        }
                        inputs.Add(source.GetMetadata("FullPath").ToUpper());
                        inputs.Add(sliceCompiler.FullName.ToUpper());

                        var outputs = GeneratedItems(source).Select(item => item.GetMetadata("FullPath").ToUpper());
                        source.SetMetadata("Outputs", string.Join(";", outputs));
                        source.SetMetadata("Inputs", string.Join(";", inputs));
                    }
                }

                if (skip)
                {
                    string message = string.Format("Skipping {0} -> ", source.GetMetadata("Identity"));
                    message += generatedItems[0].GetMetadata("Identity");
                    if (generatedItems.Length > 1)
                    {
                        message += " and ";
                        message += generatedItems[1].GetMetadata("Identity");
                        message += " are ";
                    }
                    else
                    {
                        message += " is ";
                    }
                    message += "up to date";

                    Log.LogMessage(MessageImportance.Normal, message);
                }

                ITaskItem computedSource = new TaskItem(source.ItemSpec);
                source.CopyMetadataTo(computedSource);
                computedSource.SetMetadata("BuildRequired", skip ? "False" : "True");
                computedSource.SetMetadata("OutputDir", computedSource.GetMetadata("OutputDir").TrimEnd('\\'));
                computed.Add(computedSource);
            }
            ComputedSources = computed.ToArray();
            return(true);
        }
        protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
        {
            int status = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);

            if (status == 0)
            {
                TraceGenerated();

                //
                // Recompue dependencies
                //
                string output = "";
                string error  = "";
                status = TaskUtil.RunCommand(WorkingDirectory, pathToTool, commandLineCommands + " --depend-xml",
                                             ref output, ref error);
                if (status == 0)
                {
                    List <ITaskItem> computed   = new List <ITaskItem>();
                    XmlDocument      dependsDoc = new XmlDocument();
                    dependsDoc.LoadXml(output);

                    foreach (ITaskItem source in Sources)
                    {
                        var inputs  = new List <string>();
                        var depends = dependsDoc.DocumentElement.SelectNodes(
                            string.Format("/dependencies/source[@name='{0}']/dependsOn",
                                          source.GetMetadata("Identity")));
                        if (depends != null)
                        {
                            foreach (XmlNode depend in depends)
                            {
                                inputs.Add(depend.Attributes["name"].Value);
                            }
                        }

                        //
                        // Save the dependencies for each source to a dependency file
                        //
                        // Foo.ice -> $(OutputDir)/SliceCompile.Foo.d
                        //
                        var doc = new XDocument(
                            new XDeclaration("1.0", "utf-8", "yes"),
                            new XElement("dependencies",
                                         new XElement("source", new XAttribute("name", source.GetMetadata("Identity")),
                                                      inputs.Select(path => new XElement("dependsOn", new XAttribute("name", path))),
                                                      new XElement("options",
                                                                   GetOptions().Select(e => new XElement(e.Key, e.Value))))));

                        doc.Save(Path.Combine(OutputDir,
                                              string.Format("SliceCompile.{0}.d", source.GetMetadata("Filename"))));
                        //
                        // Update the Inputs and Outputs metadata of the output sources,
                        // these info will be use to write the TLog files
                        //
                        inputs = inputs.Select(path => Path.GetFullPath(path)).ToList();
                        inputs.Add(source.GetMetadata("FullPath").ToUpper());
                        inputs.Add(Path.GetFullPath(pathToTool).ToUpper());

                        ITaskItem computedSource = new TaskItem(source.ItemSpec);
                        source.CopyMetadataTo(computedSource);
                        var outputs = GeneratedItems(source).Select((item) => item.GetMetadata("FullPath").ToUpper());
                        computedSource.SetMetadata("Outputs", string.Join(";", outputs));
                        computedSource.SetMetadata("Inputs", string.Join(";", inputs));
                        computed.Add(computedSource);
                    }
                    ComputedSources = computed.ToArray();
                }
            }
            return(status);
        }