diff --git a/pcl_expect.py b/pcl_expect.py
new file mode 100644
index 0000000000000000000000000000000000000000..4265bf55718fb42d31891d216695b9ae4cc39437
--- /dev/null
+++ b/pcl_expect.py
@@ -0,0 +1,166 @@
+import sets
+import select
+import os
+
+#
+# Global variables.  The user are supposed to change these.
+#
+
+# Default timeout, in seconds, as a floating point number.
+timeout = 10.0
+
+# If a timeout occurs and no timeout handler is specified, should an
+# exception be raised, or should the code just continue (TCL-style)?
+# Default is to raise an exception.
+timeout_raises_exception = True
+
+#
+# Internal code
+#
+
+class Timeout(Exception): pass
+
+class expectable:
+    def __init__(self):
+        self.__eof_seen = False
+
+    def fileno(self):
+        return self.__fileno
+
+    def fill_buffer(self):
+        s = os.read(self.fileno(), 8192)
+        if s == "":
+            self.__eof_seen = True
+        else:
+            self.__buffer = self.__buffer + s
+
+    def eof(self):
+        """Return True if end-of-file has been seen.
+
+        There might still be pending data in the buffer, though.
+        """
+
+    def buffer(self):
+        return self.__buffer
+
+    def remove_first(self, n):
+        self.__buffer = self.__buffer[n:]
+
+class impl:
+    def __init__(self, timeout = None):
+        self.__first = True
+        self.__inputs = sets.Set()
+        self.__readable = sets.Set()
+        self.__done = False
+        self.__timeout = timeout
+        self.__timeout_active = False
+        self.__acted = False
+        self.__all_inputs_seen = False
+
+    def loop(self):
+        if self.__done:
+            return False
+
+        if self.__first:
+            self.__first = False
+            if __expect_before():
+                return False
+            return True
+        elif not self.__acted:
+            self.__all_inputs_seen = True
+            if __expect_after():
+                return False
+
+        # Nothing handled the timeout event.
+        if self.__timeout_active:
+            debug("Unhandled timeout")
+            if timeout_raises_exception:
+                raise Timeout()
+            else:
+                return False
+
+        if not self.__all_inputs_seen:
+            t = 0
+        elif self.__timeout == None:
+            t = timeout
+        else:
+            t = self.__timeout
+        if t > 0:
+            debug("Waiting for input")
+        (r, w, e) = select.select([x for x in self.__inputs], [], [], t)
+        self.__readable = sets.Set(r)
+        if len(self.__readable) == 0:
+            if self.__all_inputs_seen:
+                debug("Processing timeout event")
+                self.__timeout_active = True
+        else:
+            debug("Input available")
+        if __expect_before():
+            return False
+        return True
+
+
+    def re(self, exp, regexp):
+        """Implement "when re foo, foo_re".
+
+        EXP is an event source that adheres to the expectable API.
+        REGEXP is a regular expression to match.  This can be a string
+        (that will be compiled using re.compile) or a compiled regexp
+        object.
+
+        Return true if a match was found.  The match attribute of EXP
+        will be set to the result of the match.  The matching string
+        will have been removed from the buffer of EXP upon return.
+        """
+
+        if self.__acted:
+            return False
+
+        if self.__done:
+            raise "foo! me bad!"
+
+        if exp in self.__readable:
+            self.__readable.remove(exp)
+            exp.fill_buffer()
+
+        # Doing this compilation again and again could be a problem.
+        # I rely on the cache in module re.  I hope it exists...
+        if isinstance(regexp, types.StringTypes):
+            regexp = re.compile(regexp)
+
+        match = regexp.search(exp.buffer())
+        if match != None:
+            exp.match = match
+            exp.remove_first(match.end())
+            self.__done = True
+            self.__acted = True
+            return True
+        else:
+            if not exp.eof():
+                self.__inputs.add(exp)
+            return False
+
+    def timeout(self):
+        """Implement "when timeout".
+
+        Return true if a timeout has occured.
+        """
+
+        if self.__acted:
+            return False
+        
+        if self.__done:
+            raise "foo! me bad!"
+
+        if self.__timeout_active:
+            self.__timeout_active = False
+            self.__done = True
+            self.__acted = True
+            return True
+        else:
+            return False
+
+    def cont(self):
+        self.__done = False
+        self.__first = True
+        # Don't touch self.__acted