/// <summary>
        /// Introspects the current project and retrieves its
        /// properties and currently building targets.
        /// </summary>
        public override bool Execute()
        {
            var                  engine = BuildEngine.AsDynamicReflection();
            ProjectInstance      project;
            IEnumerable <object> targets;

            try
            {
                // TODO: when the oss msbuild is used more frequently
                // than the .NET one, swap these calls with the ones in the catch.
                var callback = engine.targetBuilderCallback;
                project = callback.projectInstance;
                targets = callback.targetsToBuild.target;
            }
            catch (RuntimeBinderException)
            {
                // Naming convention changed in the oss msbuild
                var callback = engine._targetBuilderCallback;
                project = callback._projectInstance;
                targets = callback._targetsToBuild.target;
            }

            var targetNames = ((IEnumerable <object>)targets)
                              .Select(entry => entry.AsDynamicReflection())
                              .Where(entry => !project.InitialTargets.Contains((string)entry.Name))
                              .Select(entry => new TaskItem((string)entry.Name, new Dictionary <string, string>
            {
                { "File", (string)entry.ReferenceLocation.File },
                { "Column", ((int)entry.ReferenceLocation.Column).ToString() },
                { "Line", ((int)entry.ReferenceLocation.Line).ToString() },
                { "Location", (string)entry.ReferenceLocation.LocationString },
            }))
                              .ToArray();

            Targets    = targetNames;
            Properties = new TaskItem(project.ProjectFileLocation.File, project.Properties.ToDictionary(
                                          prop => prop.Name, prop => prop.EvaluatedValue));

            return(true);
        }