diff --git a/doc/changes/inotify.txt b/doc/changes/inotify.txt
new file mode 100644
index 0000000000000000000000000000000000000000..85a5aa4349fe802bc5bb0ac373e21e6c70d672ad
--- /dev/null
+++ b/doc/changes/inotify.txt
@@ -0,0 +1,44 @@
+2010-05-28
+
+Using asynchronous file modification (using inotify) instead of timestamp
+checking.
+
+- all files (usually only IOdictionary) that need to be monitored
+should be registered using MUST_READ_IF_MODIFIED. The MUST_READ should
+be used for objects that do not need to be re-read (e.g. fields).
+In the old system it would actually monitor e.g. 0/U and constant/polyMesh
+files.
+I've temporarily added a warning in IOdictionary if constructed with MUST_READ.
+Same for IOList,IOField,IOMap if constructed with MUST_READ_IF_MODIFIED
+(or is rereading supported?). Please let me know if something does not work or
+you see this warning.
+
+- all file monitoring is done by an instance of 'fileMonitor' in the Time
+class. The fileMonitor class can be found in OSspecific. Default is
+to use the (linux-specific) 'inotify' system calls.
+If compiled with -DFOAM_USE_STAT it will revert to the current 'stat' system
+calls.
+
+- inotify does not need timestamps. There is no need for fileModificationSkew
+to allow for time differences. (there can still temporarily be a difference
+in modified status between different processors due to nfs lagging)
+
+- all reductions to synchronise status on different processors are done with
+a single reduction instead of one reduction per registered object. This could
+be quite a gain on large numbers of processors.
+
+- fileMonitor stores two hashtables per file so there is a small overhead
+adding and removing files from monitoring.
+
+- if runTimeModifiable is false at start of run no files will get monitored,
+however if runTimeModified gets set to false during the run and monitored files
+will still get monitored (though never reloaded). This is only a hypothetical
+problem in that the kernel still stores events for the monitored files. However
+inotify is very efficient - e.g. it gets used to track changes on file systems
+for desktop search engines.
+
+- any monitored and modified file will get reloaded from the exact path
+that was monitored. In the old system it would/could do a re-search through all
+times.
+
+
diff --git a/src/OSspecific/POSIX/Make/files b/src/OSspecific/POSIX/Make/files
index f6e7c2d55eda6f5ffbcc1f0de59451051b45d424..788a08105ae3f40dca14cb2ed15e7ec8af77b363 100644
--- a/src/OSspecific/POSIX/Make/files
+++ b/src/OSspecific/POSIX/Make/files
@@ -9,6 +9,12 @@ POSIX.C
 cpuTime/cpuTime.C
 clockTime/clockTime.C
 
+/*
+ * Note: fileMonitor assumes inotify by default. Compile with -DFOAM_USE_STAT
+ * to use stat (=timestamps) instead of inotify
+ */
+fileMonitor.C
+
 #ifdef SunOS64
 dummyPrintStack.C
 #else
diff --git a/src/OSspecific/POSIX/Make/options b/src/OSspecific/POSIX/Make/options
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b7e9d7211b0d99053035f413a747854a47144187 100644
--- a/src/OSspecific/POSIX/Make/options
+++ b/src/OSspecific/POSIX/Make/options
@@ -0,0 +1,3 @@
+#ifdef SunOS64
+EXE_INC = -DFOAM_USE_STAT
+#endif
diff --git a/src/OSspecific/POSIX/fileMonitor.C b/src/OSspecific/POSIX/fileMonitor.C
new file mode 100644
index 0000000000000000000000000000000000000000..2103aa242d8f84142ef91581488d1635d816dd00
--- /dev/null
+++ b/src/OSspecific/POSIX/fileMonitor.C
@@ -0,0 +1,372 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    fileMonitor
+
+\*----------------------------------------------------------------------------*/
+
+#include "fileMonitor.H"
+#include "IOstreams.H"
+#include "Pstream.H"
+#include "PackedList.H"
+
+#ifdef FOAM_USE_STAT
+#   include "OSspecific.H"
+#   include "regIOobject.H"     // for fileModificationSkew symbol
+#else
+#   include <sys/inotify.h>
+#   include <stropts.h>
+#   include <sys/ioctl.h>
+#endif
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(Foam::fileMonitor, 0);
+
+template<>
+const char* Foam::NamedEnum<Foam::fileMonitor::fileState, 3>::names[] =
+{
+    "unmodified",
+    "deleted",
+    "modified"
+};
+const Foam::NamedEnum<Foam::fileMonitor::fileState, 3>
+    Foam::fileMonitor::fileStateNames_;
+
+
+namespace Foam
+{
+    class fileStateEqOp
+    {
+        public:
+        void operator()(unsigned int& x, const unsigned int& y) const
+        {
+            // x,y are list of 2bits representing fileState
+
+            unsigned int mask = 3u;
+            unsigned int shift = 0;
+            unsigned int result = 0;
+
+            while (mask)
+            {
+                // Combine state
+                unsigned int xState = (x & mask) >> shift;
+                unsigned int yState = (y & mask) >> shift;
+
+                // Combine and add to result. Combine is such that UNMODIFIED
+                // wins.
+                unsigned int state = min(xState, yState);
+                result |= (state << shift);
+
+                shift += 2;
+                mask <<= 2;
+            }
+            x = result;
+        }
+    };
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+#ifdef FOAM_USE_STAT
+void Foam::fileMonitor::checkFiles() const
+{
+    for
+    (
+        HashTable<label, time_t>::iterator iter = lastModified_.begin();
+        iter != lastModified_.end();
+        ++iter
+    )
+    {
+        label watchFd = iter.key();
+        const fileName& fName = watchFile_[watchFd];
+        time_t newTime = lastModified(fName);
+
+        if (newTime == 0)
+        {
+            state_.set(watchFd, DELETED);
+        }
+        else
+        {
+            time_t oldTime = iter();
+            if (newTime > (oldTime + regIOobject::fileModificationSkew))
+            {
+                iter() = newTime;
+                state_.set(watchFd, MODIFIED);
+            }
+            else
+            {
+                state_.set(watchFd, UNMODIFIED);
+            }
+        }
+    }
+}
+#else
+void Foam::fileMonitor::checkFiles() const
+{
+    while (true)
+    {
+        struct timeval zeroTimeout = {0, 0};
+
+        int ready = select
+        (
+            inotifyFd_+1,       // num filedescriptors in watchSet_
+            &watchSet_,         // watchSet_ with only inotifyFd
+            NULL,
+            NULL,
+            &zeroTimeout
+        );
+
+        if (ready < 0)
+        {
+            FatalErrorIn("fileMonitor::updateStates()")
+                << "Problem in issuing select."
+                << abort(FatalError);
+        }
+        else if (FD_ISSET(inotifyFd_, &watchSet_))
+        {
+            struct inotify_event inotifyEvent;
+
+            // Read first event
+            ssize_t nBytes = read
+            (
+                inotifyFd_,
+                &inotifyEvent,
+                sizeof(inotifyEvent)
+            );
+
+            if (nBytes != sizeof(inotifyEvent))
+            {
+                FatalErrorIn("fileMonitor::updateStates(const fileName&)")
+                    << "Read " << label(nBytes) << " ; expected "
+                    << label(sizeof(inotifyEvent))
+                    << abort(FatalError);
+            }
+
+            //Pout<< "mask:" << inotifyEvent.mask << endl;
+            //Pout<< "watchFd:" << inotifyEvent.wd << endl;
+            //Pout<< "watchName:" << watchFile_[inotifyEvent.wd] << endl;
+
+            switch (inotifyEvent.mask)
+            {
+                case IN_DELETE_SELF:
+                {
+                    Map<fileState>::iterator iter =
+                        state_.find(label(inotifyEvent.wd));
+                    iter() = DELETED;
+                }
+                break;
+
+                case IN_MODIFY:
+                case IN_CLOSE_WRITE:
+                {
+                    Map<fileState>::iterator iter =
+                        state_.find(label(inotifyEvent.wd));
+                    iter() = MODIFIED;
+                }
+                break;
+            }
+        }
+        else
+        {
+            // No data. Reset watchSet_
+            FD_SET(inotifyFd_, &watchSet_);
+            return;
+        }
+    }
+}
+#endif
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+// Null constructor
+#ifdef FOAM_USE_STAT
+
+Foam::fileMonitor::fileMonitor()
+:
+    state_(20),
+    watchFile_(20),
+    lastModified_(20)
+{}
+
+#else
+
+Foam::fileMonitor::fileMonitor()
+:
+    state_(20),
+    watchFile_(20),
+    inotifyFd_(inotify_init())
+{
+    //- Add notify descriptor to select set
+    FD_ZERO(&watchSet_);
+    FD_SET(inotifyFd_, &watchSet_);
+}
+
+#endif
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fileMonitor::~fileMonitor()
+{
+    // Remove any remaining files
+    List<label> watchFds(state_.toc());
+    forAll(watchFds, i)
+    {
+        removeWatch(watchFds[i]);
+    }
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::fileMonitor::addWatch(const fileName& fName)
+{
+#ifdef FOAM_USE_STAT
+    label watchFd = lastModified_.size();
+    lastModified_.insert(watchFd, lastModified(fName));
+#else
+    label watchFd = inotify_add_watch
+    (
+        inotifyFd_,
+        fName.c_str(),
+        //IN_ALL_EVENTS
+        IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MODIFY
+    );
+#endif
+
+    if (debug)
+    {
+        Pout<< "fileMonitor : added watch " << watchFd << " on file "
+            << fName << endl;
+    }
+
+    if (watchFd < 0)
+    {
+        WarningIn("fileMonitor::addWatch(const fileName&)")
+            << "could not add watch for file " << fName << endl;
+    }
+    else
+    {
+        state_.insert(watchFd, UNMODIFIED);
+        watchFile_.insert(watchFd, fName);
+    }
+    return watchFd;
+}
+
+
+bool Foam::fileMonitor::removeWatch(const label watchFd)
+{
+    if (debug)
+    {
+        Pout<< "fileMonitor : removing watch " << watchFd << " on file "
+            << watchFile_[watchFd] << endl;
+    }
+
+    state_.erase(watchFd);
+    watchFile_.erase(watchFd);
+#ifdef FOAM_USE_STAT
+    return lastModified_.erase(watchFd);
+#else
+    return inotify_rm_watch(inotifyFd_, int(watchFd)) == 0;
+#endif
+}
+
+
+const Foam::fileName& Foam::fileMonitor::getFile(const label watchFd) const
+{
+    return watchFile_[watchFd];
+}
+
+
+Foam::fileMonitor::fileState Foam::fileMonitor::getState(const label watchFd)
+const
+{
+    return state_[watchFd];
+}
+
+
+void Foam::fileMonitor::updateStates(const bool syncPar) const
+{
+    checkFiles();
+
+    if (syncPar)
+    {
+        PackedList<2> stats(state_.size());
+        label i = 0;
+        forAllConstIter(Map<fileState>, state_, iter)
+        {
+            stats[i++] = (unsigned int)(iter());
+        }
+        // Save local state for warning message below
+        PackedList<2> thisProcStats(stats);
+
+        Pstream::listCombineGather(stats.storage(), fileStateEqOp());
+
+        i = 0;
+        forAllIter(Map<fileState>, state_, iter)
+        {
+            if (thisProcStats[i] != UNMODIFIED)
+            {
+                if (stats[i] == UNMODIFIED)
+                {
+                    WarningIn("fileMonitor::updateStates(const bool) const")
+                        << "Delaying reading " << watchFile_[iter.key()]
+                        << " due to inconsistent "
+                           "file time-stamps between processors"
+                        << endl;
+                }
+                else
+                {
+                    unsigned int stat = stats[i];
+                    iter() = fileState(stat);
+                }
+            }
+            i++;
+        }
+    }
+}
+
+
+void Foam::fileMonitor::setUnmodified(const label watchFd)
+{
+#ifdef FOAM_USE_STAT
+    lastModified_[watchFd] = lastModified(watchFile_[watchFd]);
+#endif
+
+    Map<fileState>::iterator iter = state_.find(watchFd);
+
+    if (iter == state_.end())
+    {
+        FatalErrorIn("fileMonitor::setUnmodified(const label)")
+            << "Illegal watchFd " << watchFd
+            << abort(FatalError);
+    }
+
+    iter() = UNMODIFIED;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OSspecific/POSIX/fileMonitor.H b/src/OSspecific/POSIX/fileMonitor.H
new file mode 100644
index 0000000000000000000000000000000000000000..b9922eb3e2a45a69f9dba7963ddda640206dd4f3
--- /dev/null
+++ b/src/OSspecific/POSIX/fileMonitor.H
@@ -0,0 +1,159 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    fileMonitor
+
+Description
+    Checking for changes to files.
+
+!!!!!!!NOTE:
+    Default is to use inotify (Linux specific, since 2.6.13)
+
+    Compile with FOAM_USE_STAT to use the stat function call.
+
+
+    - works fine except for if file gets deleted and recreated
+    it stops monitoring the file!
+    (does work though if the file gets moved)
+
+SourceFiles
+    fileMonitor.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fileMonitor_H
+#define fileMonitor_H
+
+#include <sys/types.h>
+#include "Map.H"
+#include "NamedEnum.H"
+#include "labelList.H"
+#include "className.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class fileMonitor;
+
+/*---------------------------------------------------------------------------*\
+                           Class fileMonitor Declaration
+\*---------------------------------------------------------------------------*/
+
+class fileMonitor
+{
+
+public:
+
+    // Public data types
+
+        //- Enumeration defining the file state.
+        enum fileState
+        {
+            UNMODIFIED = 0,
+            DELETED = 1,
+            MODIFIED = 2
+        };
+
+        static const NamedEnum<fileState, 3> fileStateNames_;
+
+private:
+    // Private data
+
+        //- State for all watchFds
+        mutable Map<fileState> state_;
+        
+        //- From watch descriptor to filename
+        HashTable<fileName, label> watchFile_;
+
+#ifdef FOAM_USE_STAT
+
+        //- From watch descriptor to modified time
+        mutable HashTable<label, time_t> lastModified_;
+#else
+        //- File descriptor for the inotify instance
+        int inotifyFd_;
+
+        //- Pre-allocated structure containing file descriptors
+        mutable fd_set watchSet_;
+
+#endif
+        //- Update state_ from any events.
+        void checkFiles() const;
+
+        //- Disallow default bitwise copy construct
+        fileMonitor(const fileMonitor&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const fileMonitor&);
+
+
+public:
+
+    // Declare name of the class and its debug switch
+    ClassName("fileMonitor");
+
+    // Constructors
+
+        //- Construct null
+        fileMonitor();
+
+
+    // Destructor
+
+        ~fileMonitor();
+
+
+    // Member Functions
+
+        //- Add file to watch. Returns watch descriptor
+        label addWatch(const fileName&);
+
+        //- Remove file to watch. Return true if successful
+        bool removeWatch(const label watchFd);
+
+        //- Get name of file being watched
+        const fileName& getFile(const label watchFd) const;
+
+        //- Check state using handle
+        fileState getState(const label watchFd) const;
+
+        //- Check state of all files. Updates state_.
+        void updateStates(const bool syncPar) const;
+
+        //- Reset state (e.g. after having read it) using handle
+        void setUnmodified(const label watchFd);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //