const char* ReDirTools::m_version = "2015.01.03";
 
+static const char* s_empty[] = { NULL };
+
 static const char* s_standardFilterUsage[] = {
     "-D<n> or --max-depth=<n> Default: 512",
     "   the depth of the subdirectory is lower or equal <n>",
     "   <v> is a date (e.g. 2015.02.17) or number followed by an unit",
     "   units: m(inutes) h(hours), d(days). Default: m(inutes)",
     "   examples: -o25 --older-than=30d -o24h -o2009.3.2/12:00 -o1999.01.01",
+    "-P<p> or --pathname-pattern=<p>",
+    "   a list of patterns for the path (without basename) separated by ';'",
+    "   Each pattern can contain '*' as wildcard",
+    "   If the first character is '^' the pattern is a 'not pattern':"
+    "   A directory will be entered if at least one of the positive patterns and none",
+    "   of the 'not patterns' matches",
+    "   examples: '*;^*/.git/' '*/cache/;*/temp/",
+    "-p<p> or --basename-pattern=<p>",
+    "   a list of patterns for the basename (filename without path) separated by ';'",
+    "   Each pattern can contain '*' as wildcard",
+    "   If the first character is '^' the pattern is a 'not pattern':"
+    "   A file will be found if at least one of the positive patterns and none",
+    "   of the 'not patterns' matches",
+    "   examples: '*.cpp;*.hpp;Make*' '*;^*.bak;^*~",
     "-t<l> or --type=<l>",
     "   the file type",
     "   <l> is a list of <v> values:",
     "   lists the metadata (size, modification date ...) of the selected files",
     NULL
 };
+const char* s_listExamples[] = {
+    "dirtool list --min-size=10M e:\\data",
+    "dirtool list --type=f -y7d --size=10M -p*.cpp;*.hpp;Makefile*;^*~ /home/data" ,
+    NULL
+};
+
+static const char* s_helpSummary[] = {
+    "dirtool or dt <command> <opts>",
+    "   Useful commands around a directry tree",
+    "   Type 'dirtool help <command>' for more help",
+    "<command>:",
+    "help          shows info about the arguments/options",
+    "list          shows the meta data of the selected files",
+    "statistic     shows statistics about a direcctory tree",
+    NULL
+};
+
+static const char* s_statisticUsage[] = {
+    "<command>:"
+    "st(atistic)  [<opts_stat>] <path> [<depth>]",
+    "          shows a statistic about a directory tree",
+    "<path>    a directory path: relative or absolute",
+    "<depth>   0: only the summary of <path> will be shown",
+    "          1: shows the summery of each subdir of <path> and the total",
+    "          n: shows the summery of each subdir until level <n> and the total",
+    "          default: 1",
+    "<opts_stat>:",
+    "-q or --quiet",
+    "   does not show additional information, e.g. runtime",
+    "-t<n> or --trace-interval=<n>",
+    "   trace the current path every <n> seconds.",
+    "   If n<=0: no trace. Default: 60",
+    "-k or --kbyte",
+    "   output is '<kbyte> path' (like du)",
+    NULL
+};
+const char* s_statisticExamples[] = {
+    "Examples:",
+    "dirtool st -q -t0 e:\\windows",  
+    "dirtool statistic --quiet --kbyte --trace-interval=60 ../mail 2",  
+    "dirtool stat -q --kbyte d:data 2",  
+    NULL
+};
 
 
 /**
  */
 ReDirOptions::ReDirOptions(const char* usage[], const char* examples[]) :
     m_programArgs(usage, examples),
-    m_patternList(),
+    m_nodePatterns(),
+    m_pathPatterns(),
     m_compoundUsage(NULL),
     m_countCompoundUsage(0)
 {
  * Adds a usage component to the compound usage message list.
  * @param usage     a string vector containing a part of the usage message
  */
-void ReDirOptions::addCompundUsage(const char** usage){
+void ReDirOptions::addCompoundUsage(const char** usage){
     int start = 0;
     while(m_compoundUsage[start] != NULL)
         assert(++start < m_countCompoundUsage);
     m_programArgs.addString("younger", "younger than", 'y', "younger-than", false, NULL);
     m_programArgs.addString("maxsize", "maximal filesize", 'Z', "max-size", false, NULL);
     m_programArgs.addString("minsize", "minimal filesize", 'z', "min-size", false, NULL);
+    m_programArgs.addString("nodepattern", "pattern list for the basename", 'p', "basename-pattern", false, NULL);
+    m_programArgs.addString("pathpattern", "pattern list for the path", 'P', "path-pattern", false, NULL);
 }
 
 /**
  *
  * @param filter    OUT: the filter to set
  */
-void ReDirOptions::setFilterFromProgramArgs(DirEntryFilter_t& filter){
+void ReDirOptions::setFilterFromProgramArgs(ReDirEntryFilter_t& filter){
     ReByteBuffer buffer;
-    if (m_programArgs.getString("younger", buffer) != NULL)
-        filter.m_maxAge = checkDate(m_programArgs.getString("younger", buffer));
-    if (m_programArgs.getString("older", buffer) != NULL)
-        filter.m_minAge = checkDate(m_programArgs.getString("older", buffer));
-    if (m_programArgs.getString("maxsize", buffer) != NULL)
-        filter.m_maxSize = checkSize(m_programArgs.getString("maxsize", buffer));
-    if (m_programArgs.getString("minsize", buffer) != NULL)
-        filter.m_minSize = checkSize(m_programArgs.getString("minsize", buffer));
+    if (m_programArgs.getString("younger", buffer)[0] != '\0')
+        filter.m_maxAge = checkDate(buffer.str());
+    if (m_programArgs.getString("older", buffer)[0] != '\0')
+        filter.m_minAge = checkDate(buffer.str());
+    if (m_programArgs.getString("maxsize", buffer)[0] != '\0')
+        filter.m_maxSize = checkSize(buffer.str());
+    if (m_programArgs.getString("minsize", buffer)[0] != '\0')
+        filter.m_minSize = checkSize(buffer.str());
     filter.m_minDepth = m_programArgs.getInt("mindepth");
     filter.m_maxDepth = m_programArgs.getInt("maxdepth");
-    if (m_programArgs.getArgCount() > 0)
-    {
-        m_patternList.set(m_programArgs.getArg(0));
-        filter.m_nodePatterns = &m_patternList;
+    if (m_programArgs.getString("nodepattern", buffer) != NULL){
+        m_nodePatterns.set(buffer.str());
+        filter.m_nodePatterns = &m_nodePatterns;
+    }
+    if (m_programArgs.getString("pathpattern", buffer) != NULL){
+        m_pathPatterns.set(buffer.str());
+        filter.m_pathPatterns = &m_nodePatterns;
     }
 }
+/**
+ * Prints a help message, the error message and exits.
+ *
+ * @param errorMessage  the error message.
+ * @param message2      an additional message
+ */
+
+void ReDirOptions::help(const char* errorMessage, const char* message2 ){
+    ReByteBuffer msg(errorMessage, -1);
+    if (message2 != NULL)
+        msg.append(message2, -1);
+    m_programArgs.help(msg.str(), false, stdout);
+    exit(1);
+}
 /**
  * Checks the correctness of the standard filter options.
  * 
     exit(1);
 }
 
-static const char* statisticCall[] = {
-    "<command>:"
-    "st(atistic)  [<opts_stat>] <path> [<depth>]",
-    "          shows a statistic about a directory tree",
-    "<path>    a directory path: relative or absolute",
-    "<depth>   0: only the summary of <path> will be shown",
-    "          1: shows the summery of each subdir of <path> and the total",
-    "          n: shows the summery of each subdir until level <n> and the total",
-    "          default: 1",
-    "<opts_stat>:",
-    "-q or --quiet",
-    "   does not show additional information, e.g. runtime",
-    "-t<n> or --trace-interval=<n>",
-    "   trace the current path every <n> seconds.",
-    "   If n<=0: no trace. Default: 60",
-    "-k or --kbyte",
-    "   output is '<kbyte> path' (like du)",
-    NULL
-};
-const char* statisticExamples[] = {
-    "Examples:",
-    "dirtool st -q -t0 e:\\windows",  
-    "dirtool statistic --quiet --kbyte --trace-interval=60 ../mail 2",  
-    "dirtool stat -q --kbyte d:data 2",  
-    NULL
-};
-
+/**
+ * Prints a vector of lines.
+ * 
+ * @param lines     a vector of lines without newline ('\n')
+ */
 static void printField(const char** lines){
     for (int ix = 0; lines[ix] != NULL; ix++){
         printf("%s\n", lines[ix]);
  * Prints an message how to use the statistic module and exits.
  */
 void ReDirTools::statisticUsage(){
-    printField(statisticCall); 
-    printField(statisticExamples); 
+    printField(s_statisticUsage); 
+    printField(s_statisticExamples); 
+}
+
+/**
+ * Constructor.
+ */
+ReDirList::ReDirList() :
+    ReDirOptions(s_empty, s_listExamples)
+{
+    addStandardFilterOptions();
+    initCompoundUsage(sizeof s_listUsage + sizeof s_standardFilterUsage);
+    addCompoundUsage(s_listUsage);
+    addCompoundUsage(s_standardFilterUsage);
+    m_programArgs.setUsage(m_compoundUsage);
+}
+
+/**
+ * Gets the arguments for the "list" command and execute this.
+ *
+ * @param argc      the number of arguments
+ * @param argav     the argument vector
+ */
+void ReDirList::list(int argc, char* argv[]){
+    ReDirEntryFilter_t filter;
+    try {
+        m_programArgs.init(argc, argv);
+        setFilterFromProgramArgs(filter);
+        if (m_programArgs.getArgCount() == 0)
+            help(i18n("no arguments given (missing path)"));
+        ReByteBuffer bufferRights;
+        ReByteBuffer bufferTime;
+        for (int ix = 0; ix < m_programArgs.getArgCount(); ix++){
+            ReTraverser traverser(m_programArgs.getArg(ix));
+            traverser.setMinLevel(filter.m_maxDepth);
+            traverser.setMaxLevel(filter.m_maxDepth);
+            int level;
+            ReDirStatus_t* entry;
+            while( (entry = traverser.nextFile(level, &filter)) != NULL){
+                if (! printOneFile(entry))
+                    printf("%s %12lld %s %s%s\n",
+                    entry->rightsAsString(bufferRights), entry->fileSize(), 
+                    entry->filetimeAsString(bufferTime), 
+                    entry->m_path.str(), entry->node());
+            }
+        }
+    } catch(ReOptionException& exc){
+        help(exc.getMessage());
+    }
 }
 
 /**
  * @param argav     the argument vector
  */
 void ReDirTools::list(int argc, char* argv[]){
+    ReDirList lister;
+    lister.list(argc, argv);
 }
 
 
  */
 void ReDirTools::statistic(int argc, char* argv[]){
     time_t start = time(NULL);
-       ReProgramArgs args(statisticCall, statisticExamples);
+       ReProgramArgs args(s_statisticUsage, s_statisticExamples);
     args.addBool("quiet", "no additional information", 'q', "quiet", false);
     args.addBool("kbyte", "output is '<kbyte> <path>'", 'k', "kbyte", false);
     args.addInt("trace", "trace each <n> seconds the current path", 't', "trace-interval", 60);
     bool rc = fullArg.startsWith(part, -1);
     return rc;
 }
-static const char* helpSummary[] = {
-    "dirtool or dt <command> <opts>",
-    "<command>:",
-    "help          shows info about the arguments/options",
-    "list          shows info about selected files",
-    "statistic     shows statistics about a direcctory tree",
-    NULL
-};
 /**
  * Gets the arguments for any command and execute this.
  *
     ReDirTools tools;
     if (argc < 2)
         tools.usage("missing arguments");
-    if (isArg("list", argv[1]))
-        tools.list(argc - 1, argv + 1);
-    else if (isArg("help", argv[1]))
-        printField(helpSummary);
-    else if (isArg("statistic", argv[1]))
-        tools.statistic(argc - 1, argv + 1);
-    else if (isArg("test", argv[1])){
+    argc--;
+    argv++;
+    const char* arg0 = argv[0];
+    if (isArg("list", arg0))
+        tools.list(argc, argv);
+    else if (isArg("help", arg0))
+        printField(s_helpSummary);
+    else if (isArg("statistic", arg0))
+        tools.statistic(argc, argv);
+    else if (isArg("test", arg0)){
         void testAll();
         testAll();
     }else