diff -uBwNr nant-20030306.orig/src/NAnt.Core/Tasks/LoopTask.cs nant-20030306/src/NAnt.Core/Tasks/LoopTask.cs
--- nant-20030306.orig/src/NAnt.Core/Tasks/LoopTask.cs	Thu Mar 06 23:49:02 2003
+++ nant-20030306/src/NAnt.Core/Tasks/LoopTask.cs	Thu Mar 20 13:19:11 2003
@@ -62,6 +62,17 @@
     /// </foreach>
     ///     ]]>
     ///   </code>
+    ///   <para>Loops over the C# files in a fileset.</para>
+    ///   <code>
+    ///     <![CDATA[
+    /// <foreach item="File" property="filename">
+    ///     <fileset basedir=".">
+    ///         <includes name="*.cs"/>
+    ///     </fileset>
+    ///     <echo message="${filename}"/>
+    /// </foreach>    
+    ///     ]]>
+    ///   </code>
     /// </example>
     [TaskName("foreach")]
     public class LoopTask : TaskContainer {
@@ -85,6 +96,8 @@
         TrimTypes _trimType = TrimTypes.None;
         string _source = null;
         string _delim = null;
+        FileSet _fileset = new FileSet();
+        bool _filesetSet = false;
 
         /// <summary>The NAnt propperty name(s) that should be used for the current iterated item.</summary>
         /// <remarks>If specifying multiple properties, separate them with a comma.</remarks>
@@ -119,16 +132,34 @@
         /// <summary>
         /// The source of the iteration.
         /// </summary>
-        [TaskAttribute("in", Required=true)]
+        [TaskAttribute("in")]
         public string Source   { get { return _source;} set {_source = value; }}
 
         /// <summary>
+        /// The fileset source of the iteration. This can be used instead of &quot;in&quot; for &quot;File&quot; iterations.
+        /// </summary>
+        [FileSet("fileset")]
+        public FileSet SourceFileSet { 
+            get { 
+                _filesetSet = true;
+                return _fileset; 
+            } 
+            set {
+                _fileset = value; 
+                _filesetSet = true;
+            }
+        }
+
+        /// <summary>
         /// The deliminator char.
         /// </summary>
         [TaskAttribute("delim")]
         public string Delimiter { get { return _delim;} set {_delim = value; }}
 
         protected override void ExecuteTask() {
+            if ( (ItemType != ItemTypes.File) && (ItemType != ItemTypes.None) && (_source == null)) {
+                throw new BuildException(@"""in"" was not specified");
+            }
             string[] oldPropVals = new string[ _props.Length ];
             // Save all of the old property values
             for ( int nIndex = 0; nIndex < oldPropVals.Length; nIndex++ ) {
@@ -140,14 +171,20 @@
                     case ItemTypes.None:
                         throw new BuildException("Invalid itemtype", Location);
                     case ItemTypes.File: {
+                        if ((_source == null) && (_filesetSet == false)) {
+                            throw new BuildException(@"Either ""in"" or a fileset must be specified within a ""foreach"" task");
+                        }
+                        if ((_source != null) && (_filesetSet == false)) {
                         if(!Directory.Exists(Project.GetFullPath(_source)))
                             throw new BuildException("Invalid Source: " + _source, Location);
+                            _fileset = new FileSet();
+                            _fileset.BaseDirectory = _source;
+                            _fileset.Includes.Add("*.*");
+                        }
                         if(_props.Length != 1)
                             throw new BuildException(@"Only one property is valid for item=""File""");
-                        DirectoryInfo dirInfo = new DirectoryInfo(Project.GetFullPath(_source));
-                        FileInfo[] files = dirInfo.GetFiles();
-                        foreach(FileInfo file in files) {
-                            DoWork(file.FullName);
+                        foreach(string file in _fileset.FileNames) {
+                            DoWork(file);
                         }
                         break;
                     }
diff -uBwNr nant-20030306.orig/src/NAnt.Core.Tests/Tasks/LoopTest.cs nant-20030306/src/NAnt.Core.Tests/Tasks/LoopTest.cs
--- nant-20030306.orig/src/NAnt.Core.Tests/Tasks/LoopTest.cs	Wed Mar 05 08:35:24 2003
+++ nant-20030306/src/NAnt.Core.Tests/Tasks/LoopTest.cs	Thu Mar 20 12:52:55 2003
@@ -62,6 +62,22 @@
             Assertion.Assert(result.IndexOf("test.build") != -1);
         }
 
+        [Test]
+        public void Test_Loop_Fileset() {
+            string _xml = @"
+                    <project>
+                        <foreach item='File' property='file'>
+                            <fileset basedir='${nant.project.basedir}'>
+                                <includes name='*.*'/>
+                            </fileset>
+                            <echo message='File:${file}'/>
+                        </foreach>
+                    </project>";
+            string result = RunBuild(_xml);
+//           Log.WriteLine(result);
+            Assertion.Assert(result.IndexOf("test.build") != -1);
+        }
+
 		[Test]
         public void Test_Loop_Folders() {
             string _xml = @"
