← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/debugger_client into lp:zorba

 

Gabriel Petrovay has proposed merging lp:~zorba-coders/zorba/debugger_client into lp:zorba.

Requested reviews:
  Markos Zaharioudakis (markos-za)
  Juan Zacarias (juan457)
Related bugs:
  Bug #867377 in Zorba: "Add debugger client command line execution support"
  https://bugs.launchpad.net/zorba/+bug/867377
  Bug #898093 in Zorba: "Debugger: print source code of current line in debugger client"
  https://bugs.launchpad.net/zorba/+bug/898093
  Bug #898575 in Zorba: "Debugger: crash when breakpoint remove"
  https://bugs.launchpad.net/zorba/+bug/898575
  Bug #898578 in Zorba: "Debugger: breakpoint not removed from runtime during execution"
  https://bugs.launchpad.net/zorba/+bug/898578
  Bug #898580 in Zorba: "Debugger: starting query with "over" blocks the debugger client"
  https://bugs.launchpad.net/zorba/+bug/898580
  Bug #898593 in Zorba: "Debugger: query body not always breakable"
  https://bugs.launchpad.net/zorba/+bug/898593
  Bug #901676 in Zorba: "Clean the URIHelper decodeFileURI & encodeFileURI mess iin debugger_runtime.cpp"
  https://bugs.launchpad.net/zorba/+bug/901676

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/debugger_client/+merge/85471

The mature debugger client.
-- 
https://code.launchpad.net/~zorba-coders/zorba/debugger_client/+merge/85471
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'CMakeConfiguration.txt'
--- CMakeConfiguration.txt	2011-09-16 19:55:59 +0000
+++ CMakeConfiguration.txt	2011-12-13 11:51:46 +0000
@@ -70,10 +70,6 @@
 SET(ZORBA_FOR_ONE_THREAD_ONLY OFF CACHE BOOL "compile zorba for single threaded use")
 MESSAGE(STATUS "ZORBA_FOR_ONE_THREAD_ONLY:            " ${ZORBA_FOR_ONE_THREAD_ONLY})
 
-# by default the zorba command line client is deactivated until it gets to a more stable and userfriendly state
-SET(ZORBA_WITH_DEBUGGER_CLIENT OFF CACHE BOOL "build and install zorbas command line debugger client")
-MESSAGE(STATUS "ZORBA_WITH_DEBUGGER_CLIENT:           " ${ZORBA_WITH_DEBUGGER_CLIENT})
-
 IF (DEFINED UNIX)
   IF (NOT DEFINED ZORBA_HAVE_PTHREAD_H AND NOT DEFINED ZORBA_FOR_ONE_THREAD_ONLY)
     MESSAGE(FATAL_ERROR "pthread is not available")

=== modified file 'bin/CMakeLists.txt'
--- bin/CMakeLists.txt	2011-11-04 11:40:20 +0000
+++ bin/CMakeLists.txt	2011-12-13 11:51:46 +0000
@@ -15,26 +15,15 @@
 INCLUDE_DIRECTORIES(AFTER ${CMAKE_SOURCE_DIR}/src/)
 INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR})
 
-IF(ZORBA_WITH_DEBUGGER_CLIENT)
-  CONFIGURE_FILE (debug_client/event_handler_init.cpp.in debug_client/event_handler_init.cpp)
-  
-  SET(DEBUG_CLIENT_SRCS
-      debug_client/tuple.h
-      debug_client/main.cpp
-      debug_client/debug_command.h
-      debug_client/debug_command.cpp
-      debug_client/command_line_handler.h
-      debug_client/command_line_handler.cpp
-      debug_client/lock_free_queue.h
-      debug_client/event_handler.h
-      debug_client/event_handler.cpp
-      ${CMAKE_CURRENT_BINARY_DIR}/debug_client/event_handler_init.cpp
+IF (ZORBA_WITH_DEBUGGER)
+  SET (DEBUG_CLIENT_SRCS
+    debugger/main.cpp
+    debugger/command_prompt.cpp
+    debugger/command_line_handler.cpp
+    debugger/event_handler.cpp
   )
-  
-  CONFIGURE_FILE (debug_client/message-handler.xq message-handler.xq)
-  
-  ZORBA_GENERATE_EXE("debuggercmd" "${DEBUG_CLIENT_SRCS}" "" "debugger" "bin")
-ENDIF(ZORBA_WITH_DEBUGGER_CLIENT)
+  ZORBA_GENERATE_EXE ("xqdb" "${DEBUG_CLIENT_SRCS}" "" "xqdb" "bin")
+ENDIF (ZORBA_WITH_DEBUGGER)
 
 SET(SRCS
   zorbacmd.cpp

=== removed file 'bin/debug_client/debug_command.cpp'
--- bin/debug_client/debug_command.cpp	2011-07-01 01:53:24 +0000
+++ bin/debug_client/debug_command.cpp	1970-01-01 00:00:00 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <iostream>
-#include "debug_client/debug_command.h"
-
-namespace zorba { namespace debugclient {
-  
-  
-  void CommandLine::execute()
-  {
-    for (;;) {
-      std::cout << "zdb>> ";
-      std::string command;
-      std::getline(std::cin, command);
-      std::vector<std::string> args;
-      args << command;
-      std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.find(args[0]);
-      if (lIter == theCommands.end()) {
-        std::cout << args[0] << ": Command not found" << std::endl;
-        continue;
-      }
-      if (!lIter->second->execute(args))
-        continue;
-      return;
-    }
-  }
-  
-  
-  CommandLine::~CommandLine()
-  {
-    for (std::map<std::string, UntypedCommand*>::iterator i = theCommands.begin();
-         i != theCommands.end(); ++i)
-    {
-      delete i->second;
-    }
-  }
-  
-  CommandLine& CommandLine::operator<<(UntypedCommand *aCommand)
-  {
-    theCommands.insert(std::make_pair(aCommand->get_name(), aCommand));
-    return *this;
-  }
-}}
-
-namespace std {
-  vector<string>& operator<< (vector<string>& vec, const string& str)
-  {
-    string::size_type before = 0;
-    string::size_type pos = str.find(" ", 0);
-    while (pos != str.npos) {
-      std::string lSub = str.substr(before, pos - before);
-      if (lSub[0] == '"') {
-        std::string::size_type lBeforeCopy = before;
-        do {
-          lBeforeCopy = str.find("\"", lBeforeCopy + 1);
-        } while (pos != str.npos && str.size() > pos + 1 && str[pos + 1] == '\\');
-        pos = lBeforeCopy;
-        lSub = str.substr(before + 1, pos - before - 1);
-      }
-      vec.push_back(lSub);
-      before = pos + 1;
-      pos = str.find(" ", before);
-    }
-    std::string lSub = str.substr(before);
-    if (lSub[0] == '"') {
-      pos = str.find("\"", before + 1);
-      lSub = str.substr(before + 1, pos - before - 1);
-    }
-    vec.push_back(lSub);
-    return vec;
-  }
-  
-  set<string>& operator<< (set<string>& vec, const string& str)
-  {
-    string::size_type before = 0;
-    string::size_type pos = str.find(" ", 0);
-    while (pos != str.npos) {
-      vec.insert(str.substr(before, pos));
-      before = pos + 1;
-      pos = str.find(" ", before);
-    }
-    vec.insert(str.substr(before));
-    return vec;
-  }
-
-}

=== removed file 'bin/debug_client/event_handler_init.cpp.in'
--- bin/debug_client/event_handler_init.cpp.in	2011-07-01 01:53:24 +0000
+++ bin/debug_client/event_handler_init.cpp.in	1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <fstream>
-#include "debug_client/event_handler.h"
-
-namespace zorba { namespace debugclient {
-
-  std::istream* EventHandler::getCurrentDirectory() {
-    const char* build_dir = "@CMAKE_BINARY_DIR@/bin/message-handler.xq";
-    const char* install_dir = 
-#ifndef WIN32
-    "@CMAKE_INSTALL_PREFIX@/bin/";
-#else
-    "C:/Program Files/Zorba XQuery Processor @ZORBA_MAJOR_NUMBER@.@ZORBA_MINOR_NUMBER@.@ZORBA_PATCH_NUMBER@/bin/";
-#endif
-    std::auto_ptr<std::ifstream> stream(new std::ifstream(build_dir));
-    if (stream->good()) {
-      return stream.release();
-    }
-    stream.reset(new std::ifstream(install_dir));
-    if (stream->good()) {
-      return stream.release();
-    }
-    return 0;
-  }
-
-}} // end of namespace zorba::debugclient
-

=== removed file 'bin/debug_client/lock_free_queue.cpp'
--- bin/debug_client/lock_free_queue.cpp	2011-07-01 01:53:24 +0000
+++ bin/debug_client/lock_free_queue.cpp	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "lock_free_queue.h"

=== removed file 'bin/debug_client/message-handler.xq'
--- bin/debug_client/message-handler.xq	2011-08-26 23:36:24 +0000
+++ bin/debug_client/message-handler.xq	1970-01-01 00:00:00 +0000
@@ -1,165 +0,0 @@
-(:
- : Copyright 2006-2009 The FLWOR Foundation.
- :
- : Licensed under the Apache License, Version 2.0 (the "License");
- : you may not use this file except in compliance with the License.
- : You may obtain a copy of the License at
- :
- : http://www.apache.org/licenses/LICENSE-2.0
- :
- : Unless required by applicable law or agreed to in writing, software
- : distributed under the License is distributed on an "AS IS" BASIS,
- : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- : See the License for the specific language governing permissions and
- : limitations under the License.
-:)
-
-import module namespace refl = 'http://www.zorba-xquery.com/modules/reflection';
-import module namespace sctx = "http://www.zorba-xquery.com/modules/introspection/sctx";;
-import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64";;
-
-
-declare variable $local:localns as xs:string := 'http://www.w3.org/2005/xquery-local-functions';
-
-
-declare variable $local:endl as xs:string := '
-';
-
-declare function local:has-to-stop($resp as element())
-{
-  fn:not(($resp/@command/data(.) eq "stop" and $resp/@reason/data(.) eq "ok")
-    or ($resp/@status/data(.) eq "stopped")
-    or ($resp/@status/data(.) eq "stopping"))
-};
-
-declare function local:status($resp as element())
-{
-  fn:concat(
-    "Status: ", $resp/@status/data(.), $local:endl,
-    "Reason: ", $resp/@reason/data(.), $local:endl,
-    let $msg := $resp/text()
-    return
-      if (fn:empty($msg) or $msg eq "") then
-        ""
-      else
-        fn:concat($msg, $local:endl)
-  )
-};
-
-
-declare function local:run($resp as element()) {
-  if ($resp/@status/data(.) eq "starting") then
-    "Starting query"
-  else
-    local:status($resp)
-};
-
-declare function local:stop($resp as element())
-{
-  local:status($resp)
-};
-
-declare function local:breakpoint_set($resp as element())
-{
-  if ($resp/error) then
-    fn:concat("Error when setting a breakpoint: ", if ($resp/error/message) then $resp/error/message/text() else concat(" errcode: ", data($resp/error/@code)))
-  else
-    fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state))
-};
-
-declare function local:breakpoint_list($resp as element())
-{
-  string-join(
-    for $b in $resp/breakpoint
-    return concat("Breakpoint ", data($b/@id), " at ", data($b/@filename), ":", data($b/@lineno), " ", data($b/@state)),
-    $local:endl
-  )
-};
-
-declare function local:breakpoint_remove($resp as element())
-{
-  "Breakpoint removed"
-};
-
-declare function local:stack_depth($resp as element())
-{
-  concat("Depth: ", data($resp/@depth))
-};
-
-declare function local:stack_get($resp as element())
-{
-  string-join(
-    for $s in $resp/stack
-    return concat("Level ", data($s/@level), " at ", data($s/@filename), ":", data($s/@lineno)),
-    $local:endl
-  )
-};
-
-
-declare function local:context_names($resp as element())
-{
-  string-join(
-    for $c in $resp/context
-    return concat("Context: ", data($c/@name), " id: ", data($c/@id)),
-    $local:endl
-  )
-};
-
-declare function local:context_get($resp as element())
-{
-  string-join(
-    for $p in $resp/property
-    return concat(data($p/@fullname), ": [", data($p/@type), "]",
-                  if ($p/text() ne "") then concat(": ", base64:decode($p/text())) else ""),
-    $local:endl
-  )
-};
-
-declare function local:eval($resp as element())
-{
-  if (data($resp/@success) eq "1") then
-    local:context_get($resp)
-  else
-    concat("Eval failed", ":", $resp/error/message/text())
-};
-
-declare function local:process-response($resp as element())
-{
-  if (data($resp/@command) eq "") then
-    (fn:true(), $resp/@transaction_id/data(.), local:status($resp))
-  else
-    let $fun-cont-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.), "-cont"))
-    let $fun-msg-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.)))
-    return (
-      if (sctx:function-arguments-count($fun-cont-name) = 1) then
-        refl:invoke($fun-cont-name, $resp)
-      else
-        local:has-to-stop($resp),
-      $resp/@transaction_id/data(.),
-      if (sctx:function-arguments-count($fun-msg-name) = 1) then
-        refl:invoke($fun-msg-name, $resp)
-      else
-        "Recieved a message - command not implemented"
-    )
-};
-
-declare function local:process-init($init as element())
-{
-  fn:true(),
-  0,
-  fn:concat(fn:string-join(
-  ('Established connection with', $init/@language/data(.), 'client', $init/@appid/data(.)), ' '), '
-')
-};
-
-declare function local:main($response as element()) {
-  let $process-fun as xs:QName := fn:QName($local:localns, concat("local:process-", node-name($response)))
-  return
-    if (sctx:function-arguments-count($process-fun) = 1) then
-      refl:invoke($process-fun, $response)
-    else (
-          true(),
-          ($response/@transaction_id, 0)[1]/data(.),
-          "ERROR: Recieved unknown node from client"
-         )
-};

=== renamed directory 'bin/debug_client' => 'bin/debugger'
=== renamed file 'bin/debug_client/debug_command.h' => 'bin/debugger/command.h'
--- bin/debug_client/debug_command.h	2011-07-04 08:05:46 +0000
+++ bin/debugger/command.h	2011-12-13 11:51:46 +0000
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 #pragma once
-#include <zorba/config.h>
+#ifndef ZORBA_DEBUGGER_COMMAND_H
+#define ZORBA_DEBUGGER_COMMAND_H
+
 #include <string>
 #include <vector>
 #include <iostream>
@@ -23,151 +25,18 @@
 #include <sstream>
 #include <memory>
 #include <typeinfo>
-#include "debug_client/tuple.h"
-
-namespace zorba { namespace debugclient {
+
+#include <zorba/config.h>
+
+#include "command_arg.h"
+#include "tuple.h"
+
+
+namespace zorba { namespace debugger {
   
   class DebugClientParseException : public std::exception {
   };
   
-  template<typename Tuple>
-  class CommandArg;
-  
-  template<typename Tuple>
-  class CommandArgInstance {
-  public:
-    virtual int get_index() const = 0;
-    virtual const CommandArg<Tuple>* get_arg() const = 0;
-    virtual void insertValue(Tuple& t) = 0;
-    virtual bool isSet(Tuple& t) const = 0;
-  };
-  
-  template<typename T, int Idx, typename Tuple>
-  class TypedCommandArgInstance : public CommandArgInstance<Tuple>
-  {
-  public:
-    TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg)
-    : theValue(aValue), theArg(aArg) {}
-    virtual int get_index() const { return Idx; }
-    virtual const CommandArg<Tuple>* get_arg() const { return theArg; }
-    virtual void insertValue(Tuple& t)
-    {
-      ZORBA_TR1_NS::get<Idx>(t).first = true;
-      ZORBA_TR1_NS::get<Idx>(t).second = theValue;
-    }
-    virtual bool isSet(Tuple& t) const
-    {
-      return ZORBA_TR1_NS::get<Idx>(t).first;
-    }
-  private:
-    T theValue;
-    const CommandArg<Tuple>* theArg;
-  };
-  
-  template<typename Tuple>
-  class CommandArgType {
-  public:
-    virtual CommandArgInstance<Tuple>* parse(const std::string& str,
-                                             const CommandArg<Tuple>* arg) = 0;
-    virtual bool isVoid() const = 0;
-    virtual bool isSet(Tuple& t) const = 0;
-    virtual ~CommandArgType() {}
-  };
-  
-  template<typename T, int Idx, typename Tuple>
-  class TypedCommandArgType : public CommandArgType<Tuple> {
-  public:
-    typedef T Type;
-  public: // implementation
-    TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {}
-    TypedCommandArgType(const T& aValue,
-                        bool aIsVoid)
-    : theDefault(aValue), theIsVoid(aIsVoid) {}
-    virtual CommandArgInstance<Tuple>* parse(const std::string& str,
-                                             const CommandArg<Tuple>* arg)
-    {
-      T aValue;
-      std::stringstream stream(str);
-      stream >> aValue;
-      if (stream.fail()) {
-        std::cerr << "Could not parse argument of type "
-          << typeid(T).name()
-          << std::endl;
-        return 0;
-      }
-      return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg);
-    }
-    virtual bool isVoid() const { return theIsVoid; }
-    virtual bool isSet(Tuple& t) const
-    {
-      return ZORBA_TR1_NS::get<Idx>(t).first;
-    }
-  private:
-    TypedCommandArgType<T, Idx, Tuple>() {}
-    T theDefault;
-    bool theIsVoid;
-  };
-
-  template<typename Tuple>
-  class CommandArg {
-  public:
-    CommandArg(unsigned aId,
-               CommandArgType<Tuple>* aType,
-               const std::set<std::string>& aFlags,
-               const std::string& aDescription,
-               bool aIsRequired)
-    : theId(aId),
-    theType(aType),
-    theFlags(aFlags),
-    theDescription(aDescription),
-    theIsRequired(aIsRequired)
-    {
-    }
-    ~CommandArg() { delete theType; }
-    unsigned get_id() const { return theId; }
-    bool canHandle(const std::string& arg) const
-    {
-      if (theFlags.find(arg) != theFlags.end()) {
-        return true;
-      }
-      return false;
-    }
-    CommandArgInstance<Tuple>* parse(const std::string& str) const
-    {
-      return theType->parse(str, this);
-    }
-    bool isVoid() const {
-      return theType->isVoid();
-    }
-    bool isRequired() const { return theIsRequired; }
-    std::string get_name() const {
-      return *(theFlags.begin());
-    }
-    bool isSet(Tuple& t) const
-    {
-      return theType->isSet(t);
-    }
-  private:
-    unsigned theId;
-    CommandArgType<Tuple>* theType;
-    std::set<std::string> theFlags;
-    std::string theDescription;
-    bool theIsRequired;
-  };
-}} // end namespace zorba
-
-namespace std {
-  
-  /**
-   * This is a helper split function
-   */
-  vector<string>& operator<< (vector<string>& vec, const string& str);
-  
-  set<string>& operator<< (set<string>& vec, const string& str);
-} //end namespace std
-
-namespace zorba { namespace debugclient {
-
   template<typename Func, typename Tuple, int CommandIdx>
   class CommandInstance
   {
@@ -188,8 +57,10 @@
   
   class UntypedCommand {
   public:
-    virtual std::string get_name() const = 0;
-    virtual std::string get_description() const = 0;
+    virtual std::string getName() const = 0;
+    virtual std::set<std::string> getAliases() const = 0;
+    virtual std::string getDescription() const = 0;
+    virtual void printHelp() const = 0;
     virtual bool execute(const std::vector<std::string>& args) = 0;
   };
   
@@ -197,77 +68,141 @@
   class Command : public UntypedCommand {
   public:
     Command(const std::string& aName, Func& aFunction, const std::string& aDescription)
-      : theName(aName), theFunction(aFunction), theDescription(aDescription) {}
+      : theName(aName), theFunction(aFunction), theDescription(aDescription)
+    {}
+
+    Command(const std::string& aName, const std::set<std::string> aAliases, Func& aFunction, const std::string& aDescription)
+      : theName(aName), theAliases(aAliases), theFunction(aFunction), theDescription(aDescription)
+    {}
+
     ~Command();
+
   public:
-    Command& operator() (unsigned aId,
-                         const std::string& aFlags,
-                         CommandArgType<Tuple>* aType,
-                         const std::string& aDescription = "",
-                         bool isRequired = false);
-    virtual std::string get_name() const { return theName; }
-    virtual std::string get_description() const { return theDescription; }
+
+    void
+    addArgument(
+      unsigned aId,
+      const std::string& aFlags,
+      CommandArgType<Tuple>* aType,
+      const std::string& aDescription = "",
+      bool isRequired = false);
+
+    static void
+    splitNames(
+      const std::string& names,
+      std::set<std::string>& set);
+
+    virtual std::string
+    getName() const
+    {
+      return theName;
+    }
+
+    virtual std::set<std::string> getAliases() const
+    {
+      return theAliases;
+    }
+
+    virtual std::string
+    getDescription() const
+    {
+      return theDescription;
+    }
+
+    virtual void
+    printHelp() const;
+
     virtual bool execute(const std::vector<std::string>& args)
     {
       CommandInstance<Func, Tuple, CommandIdx> instance(theFunction, theTuple);
-      if (instance.parseArguments(args, theArgs))
+      if (instance.parseArguments(args, theArgs)) {
         instance.execute();
-      else
-        return false;
-      return true;
+        return true;
+      }
+      return false;
     }
   private:
     std::string theName;
+    std::set<std::string> theAliases;
     Func& theFunction;
     Tuple theTuple;
     std::string theDescription;
-    std::map<std::string, CommandArg<Tuple>* > theArgs;
-  };
-  
-  class CommandLine {
-  public:
-    ~CommandLine();
-  public:
-    void execute();
-    CommandLine& operator<< (UntypedCommand* aCommand);
-  private:
-    std::map<std::string, UntypedCommand*> theCommands;
-  };
-  
-  template<typename Func, typename Tuple, int CommandIdx>
-  Command<Func, Tuple, CommandIdx>::~Command()
-  {
-    typedef std::map<std::string, CommandArg<Tuple>* > ArgType;
-    for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) {
-      delete i->second;
-    }
-  }
-    
- 
-  template<typename Func, typename Tuple, int CommandIdx>
-  Command<Func, Tuple, CommandIdx>& 
-  Command<Func, Tuple, CommandIdx>::operator() (unsigned aId,
-                                    const std::string& aFlags,
-                                    CommandArgType<Tuple>* aType,
-                                    const std::string& aDescription,
-                                    bool isRequired)
-  {
-    std::set<std::string> args;
-    args << aFlags;
-    for (std::set<std::string>::iterator i = args.begin(); i != args.end(); ++i) {
-      std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i;
-      theArgs.insert(std::make_pair(toAdd,
-                                    new CommandArg<Tuple>(aId,
-                                                          aType,
-                                                          args,
-                                                          aDescription,
-                                                          isRequired)
-                                    )
-                     );
-    }
-    return *this;
-  }
-  
+    std::map<std::string, CommandArg<Tuple>*> theArgs;
+  };
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+template<typename Func, typename Tuple, int CommandIdx>
+Command<Func, Tuple, CommandIdx>::~Command()
+{
+  typedef std::map<std::string, CommandArg<Tuple>*> ArgType;
+  for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) {
+    delete i->second;
+  }
+}
+
+template<typename Func, typename Tuple, int CommandIdx>
+void
+Command<Func, Tuple, CommandIdx>::printHelp() const
+{
+  std::cout << "Purpose: " << getDescription() << std::endl;
+
+  typename std::map<std::string, CommandArg<Tuple>*>::const_iterator lIter = theArgs.begin();
+  if (lIter == theArgs.end()) {
+    std::cout << "This command has no arguments." << std::endl;
+    std::cout << std::endl;
+    return;
+  }
+  
+  std::cout << "Arguments:" << std::endl << std::endl;
+  for (; lIter != theArgs.end(); ++lIter) {
+    std::cout << "  " << lIter->first << "\t" << lIter->second->getDescription() << std::endl;
+  }
+  std::cout << std::endl;
+}
+
+template<typename Func, typename Tuple, int CommandIdx>
+void
+Command<Func, Tuple, CommandIdx>::splitNames(const std::string& aNames, std::set<std::string>& aSet)
+{
+  std::string::size_type before = 0;
+  std::string::size_type pos = aNames.find(" ", 0);
+  while (pos != aNames.npos) {
+    std::string lName = aNames.substr(before, pos);
+    if (lName != "") {
+      aSet.insert(lName);
+    }
+    before = pos + 1;
+    pos = aNames.find(" ", before);
+  }
+  std::string lName = aNames.substr(before);
+  if (lName != "") {
+    aSet.insert(lName);
+  }
+}
+
+template<typename Func, typename Tuple, int CommandIdx>
+void
+Command<Func, Tuple, CommandIdx>::addArgument(
+  unsigned aId,
+  const std::string& aFlags,
+  CommandArgType<Tuple>* aType,
+  const std::string& aDescription,
+  bool isRequired)
+{
+  std::set<std::string> lNames;
+  splitNames(aFlags, lNames);
+
+  for (std::set<std::string>::iterator i = lNames.begin(); i != lNames.end(); ++i) {
+    std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i;
+    CommandArg<Tuple>* lArg = new CommandArg<Tuple>(aId, aType, lNames, aDescription, isRequired);
+    theArgs.insert(std::make_pair(toAdd, lArg));
+  }
+}
+
+/*****************************************************************************/
+
   template<typename Tuple, typename T, int Idx>
   CommandArgType<Tuple>* createArgType(Tuple t)
   {
@@ -290,6 +225,16 @@
     return new Command<Func, Tuple, CommandIdx>(aName, aFunction, aDescription);
   }
   
+  template<int CommandIdx, typename Tuple, typename Func>
+  Command<Func, Tuple, CommandIdx>* createCommand(Tuple t,
+                                                  const std::string& aName,
+                                                  const std::set<std::string>& aAliases,
+                                                  Func& aFunction,
+                                                  const std::string& aDescription)
+  {
+    return new Command<Func, Tuple, CommandIdx>(aName, aAliases, aFunction, aDescription);
+  }
+  
   template<typename Func, typename Tuple, int CommandIdx>
   bool CommandInstance<Func, Tuple, CommandIdx>::
   parseArguments(const std::vector<std::string>& args,
@@ -301,29 +246,34 @@
     for (ArgType::size_type i = 1; i < size; ++i) {
       typename CArgType::const_iterator pos = aCommandArgs.find(args[i]);
       if (pos == aCommandArgs.end()) {
-        std::cerr << "Error: Unknown Argument " << args[i] << std::endl;
+        std::cerr << "Error: Unknown option " << args[i] << std::endl;
         parseError = true;
         return false;
       }
       const CommandArg<Tuple>& arg = *(pos->second);
-      if (!arg.isVoid() && args[++i][0] == '-') {
-        std::cerr << "Did not expect parameter for option " << args[i] << std::endl;
-        return false;
-      }
       std::auto_ptr<CommandArgInstance<Tuple> > instance;
       if (arg.isVoid()) {
         instance.reset(arg.parse("1"));
       } else {
+        ++i;
+        if (i >= size) {
+          std::cerr << "Error: Missing value for argument " << args[i - 1] << std::endl;
+          parseError = true;
+          allSet = false;
+          return false;
+        }
         instance.reset(arg.parse(args[i]));
       }
-      instance->insertValue(theTuple);
+      if (instance.get()) {
+        instance->insertValue(theTuple);
+      }
     }
     bool allSet = true;
     for (typename CArgType::const_iterator i = aCommandArgs.begin();
          i != aCommandArgs.end(); ++i)
     {
       if (i->second->isRequired() && !i->second->isSet(theTuple)) {
-        std::cerr << "Error: Argument " << i->second->get_name() << " not set" << std::endl;
+        std::cerr << "Error: Argument -" << i->second->getName() << " not set" << std::endl;
         allSet = false;
       }
     }
@@ -336,4 +286,7 @@
     theFunction.template handle<CommandIdx>(this->theTuple);
   }
 
-}} // end of namespace zorba::debugclient
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_COMMAND_H

=== added file 'bin/debugger/command_arg.h'
--- bin/debugger/command_arg.h	1970-01-01 00:00:00 +0000
+++ bin/debugger/command_arg.h	2011-12-13 11:51:46 +0000
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+#ifndef ZORBA_DEBUGGER_COMMAND_ARG_H
+#define ZORBA_DEBUGGER_COMMAND_ARG_H
+
+#include <string>
+#include <iostream>
+#include <set>
+#include <sstream>
+
+#include "tuple.h"
+
+
+namespace zorba { namespace debugger {
+
+template<typename Tuple>
+class CommandArg;
+
+template<typename Tuple>
+class CommandArgInstance {
+  public:
+    virtual int get_index() const = 0;
+    virtual const CommandArg<Tuple>* get_arg() const = 0;
+    virtual void insertValue(Tuple& t) = 0;
+    virtual bool isSet(Tuple& t) const = 0;
+};
+
+template<typename T, int Idx, typename Tuple>
+class TypedCommandArgInstance : public CommandArgInstance<Tuple>
+{
+  public:
+    TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg)
+      : theValue(aValue), theArg(aArg)
+    {
+    }
+
+    virtual int
+    get_index() const
+    {
+      return Idx;
+    }
+
+    virtual const CommandArg<Tuple>*
+    get_arg() const
+    {
+      return theArg;
+    }
+
+    virtual void
+    insertValue(Tuple& t)
+    {
+      ZORBA_TR1_NS::get<Idx>(t).first = true;
+      ZORBA_TR1_NS::get<Idx>(t).second = theValue;
+    }
+
+    virtual bool isSet(Tuple& t) const
+    {
+      return ZORBA_TR1_NS::get<Idx>(t).first;
+    }
+
+  private:
+
+    T theValue;
+    const CommandArg<Tuple>* theArg;
+};
+  
+template<typename Tuple>
+class CommandArgType
+{
+  public:
+    virtual CommandArgInstance<Tuple>*
+    parse(
+      const std::string& str,
+      const CommandArg<Tuple>* arg) = 0;
+
+    virtual bool
+    isVoid() const = 0;
+  
+    virtual bool
+    isSet(Tuple& t) const = 0;
+
+    virtual ~CommandArgType() {}
+};
+  
+  template<typename T, int Idx, typename Tuple>
+  class TypedCommandArgType : public CommandArgType<Tuple> {
+  public:
+    typedef T Type;
+  public: // implementation
+    TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {}
+    TypedCommandArgType(const T& aValue,
+                        bool aIsVoid)
+    : theDefault(aValue), theIsVoid(aIsVoid) {}
+    virtual CommandArgInstance<Tuple>* parse(const std::string& str,
+                                             const CommandArg<Tuple>* arg)
+    {
+      T aValue;
+
+      // special treatment for strings
+      // this is a double hack:
+      // - we check the type name if this starts with: class std::basic_string
+      // - we use void* in readEntireString to workaround the template type T
+      //   which would otherwise complain during compilation if types and
+      //   operators do not match
+      // TOSO: probably someone can find a more elegant solution
+      std::string lTypeName(typeid(T).name());
+      if (lTypeName.find("class std::basic_string") == 0) {
+        readEntireString(str, &aValue);
+      } else {
+        std::stringstream stream(str);
+        std::stringstream out;
+        stream >> aValue;
+        if (stream.fail()) {
+          std::cerr << "Error: Could not parse value \"" << str << "\" as type "
+            << typeid(T).name()
+            << std::endl;
+          return 0;
+        }
+      }
+
+      return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg);
+    }
+    virtual bool isVoid() const { return theIsVoid; }
+    virtual bool isSet(Tuple& t) const
+    {
+      return ZORBA_TR1_NS::get<Idx>(t).first;
+    }
+  private:
+    void readEntireString(std::string aIn, void* aValue)
+    {
+      *((std::string*)aValue) = aIn;
+    }
+
+    TypedCommandArgType<T, Idx, Tuple>() {}
+    T theDefault;
+    bool theIsVoid;
+  };
+
+  template<typename Tuple>
+  class CommandArg {
+  public:
+    CommandArg(unsigned aId,
+               CommandArgType<Tuple>* aType,
+               const std::set<std::string>& aNames,
+               const std::string& aDescription,
+               bool aIsRequired)
+    : theId(aId),
+    theType(aType),
+    theNames(aNames),
+    theDescription(aDescription),
+    theIsRequired(aIsRequired)
+    {
+    }
+
+    ~CommandArg()
+    { 
+      delete theType;
+    }
+
+    unsigned
+    get_id() const
+    {
+      return theId;
+    }
+
+    bool
+    canHandle(const std::string& arg) const
+    {
+      if (theNames.find(arg) != theNames.end()) {
+        return true;
+      }
+      return false;
+    }
+
+    CommandArgInstance<Tuple>*
+    parse(const std::string& str) const
+    {
+      return theType->parse(str, this);
+    }
+
+    bool
+    isVoid() const
+    {
+      return theType->isVoid();
+    }
+    
+    bool
+    isRequired() const
+    {
+      return theIsRequired;
+    }
+
+    std::string
+    getName() const
+    {
+      return *(theNames.begin());
+    }
+
+    std::string
+    getDescription() const
+    {
+      return theDescription;
+    }
+
+    bool
+    isSet(Tuple& t) const
+    {
+      return theType->isSet(t);
+    }
+
+  private:
+
+    unsigned theId;
+    CommandArgType<Tuple>* theType;
+    std::set<std::string> theNames;
+    std::string theDescription;
+    bool theIsRequired;
+  };
+
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_COMMAND_ARG_H

=== modified file 'bin/debugger/command_line_handler.cpp'
--- bin/debug_client/command_line_handler.cpp	2011-07-01 01:53:24 +0000
+++ bin/debugger/command_line_handler.cpp	2011-12-13 11:51:46 +0000
@@ -1,4 +1,4 @@
-/*
+  /*
  * Copyright 2006-2008 The FLWOR Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,225 +23,372 @@
 # define msleep Sleep
 #endif
 
-namespace zorba { namespace debugclient {
+namespace zorba { namespace debugger {
   
-  using namespace ::std;
   using namespace ::ZORBA_TR1_NS;
   
-  CommandLineHandler::CommandLineHandler(unsigned short port,
-                                         LockFreeConsumer<std::size_t>& aConsumer,
-                                         LockFreeConsumer<bool>& aContinueQueue,
-                                         EventHandler& aHandler,
-                                         CommandLine& aCommandLine)
+CommandLineHandler::CommandLineHandler(
+  unsigned short port,
+  LockFreeConsumer<std::size_t>& aConsumer,
+  LockFreeConsumer<bool>& aContinueQueue,
+  EventHandler& aHandler,
+  CommandPrompt& aCommandPrompt)
   : theConsumer(aConsumer),
     theContinueQueue(aContinueQueue),
     theClient(DebuggerClient::createDebuggerClient(&aHandler, port, "localhost")),
-    theCommandLine(aCommandLine),
-    theQuit(false), theContinue(false), theWaitFor(0)
+    theCommandLine(aCommandPrompt),
+    theQuit(false), theTerminated(true), theContinue(false), theWaitFor(0)
   {
     addCommands();
   }
   
-  CommandLineHandler::~CommandLineHandler()
-  {
-  }
+CommandLineHandler::~CommandLineHandler()
+{
+}
   
-  void CommandLineHandler::execute()
-  {
-    theClient->accept();
-    std::set<std::size_t> lIdList;
-    do {
+void
+CommandLineHandler::execute()
+{
+  theClient->accept();
+  std::set<std::size_t> lIdList;
+  do {
+    getNextId(lIdList);
+    while (lIdList.find(theWaitFor) == lIdList.end()) {
       getNextId(lIdList);
-      while (!theQuit && lIdList.find(theWaitFor) == lIdList.end()) {
-        getNextId(lIdList);
-        msleep(20);
-      }
-      while (!theContinueQueue.consume(theQuit)) {
-        msleep(20);
-      }
-      theQuit = !theQuit;
-      if (!theQuit) {
-        theCommandLine.execute();
-        while (theContinue) {
-          theContinue = false;
-          theCommandLine.execute();
-        }
-      }
-    } while (!theQuit);
-  }
-  
-  void CommandLineHandler::getNextId(std::set<std::size_t>& aIdList)
-  {
-    std::size_t result;
-    if (theConsumer.consume(result)) {
-      aIdList.insert(result);
-    }
-  }
-  
-  template<>
-  void CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t)
-  {
-    theWaitFor = theClient->status();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t)
-  {
+      msleep(20);
+    }
+    bool lCanQuit;
+    while (!theContinueQueue.consume(lCanQuit)) {
+      msleep(20);
+    }
+    if (lCanQuit) {
+      theTerminated = true;
+    }
+    theCommandLine.execute();
+    while (theContinue) {
+      theContinue = false;
+      theCommandLine.execute();
+    }
+  } while (!theQuit);
+}
+  
+void
+CommandLineHandler::getNextId(std::set<std::size_t>& aIdList)
+{
+  std::size_t result;
+  if (theConsumer.consume(result)) {
+    aIdList.insert(result);
+  }
+}
+
+template<>
+void
+CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theWaitFor = theClient->status();
+}
+
+template<>
+void
+CommandLineHandler::handle<Variables>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theWaitFor = theClient->variables();
+}
+
+template<>
+void
+CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t)
+{
+  if (!theTerminated) {
     bool answered = false;
     while (!answered) {
       std::cout << "Do you really want to stop debugging and exit? (y/n) ";
-      char answer;
-      std::cin >> answer;
-      std::cout << std::endl;
-      if (answer == 'y') {
+      std::string lAnswer;
+      std::getline(std::cin, lAnswer);
+      if (lAnswer == "y" || lAnswer == "yes") {
         answered = true;
-      } else if (answered == 'n') {
+      } else if (lAnswer == "n" || lAnswer == "no") {
         theContinue = true;
         return;
       }
     }
-    theWaitFor = theClient->stop();
-    theClient->quit();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t)
-  {
-    theWaitFor = theClient->run();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &t)
-  {
-    DebuggerClient::BreakpointType lType = DebuggerClient::Line;
-    bool lEnabled = true;
-    if (get<0>(t).first) {
-      if (get<0>(t).second == "disabled") {
-        lEnabled = false;
-      }
-    }
-    theWaitFor = theClient->breakpoint_set(lType,
-                                           lEnabled,
-                                           get<1>(t).second,
-                                           get<2>(t).second);
-  }
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple)
-  {
-    theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second);
-  }
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointDel>(tuple<bint> &aTuple)
-  {
-    theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second);
-  }
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointList>(tuple<> &t)
-  {
-    theWaitFor = theClient->breakpoint_list();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<StackDepth>(tuple<> &t)
-  {
-    theWaitFor = theClient->stack_depth();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple)
-  {
-    if (get<0>(aTuple).first) {
-      theWaitFor = theClient->stack_get(get<0>(aTuple).second);
-    } else {
-      theWaitFor = theClient->stack_get();
-    }
-  }
-  
-  template<>
-  void CommandLineHandler::handle<ContextNames>(tuple<>& aTuple)
-  {
-    theWaitFor = theClient->context_names();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<ContextGet>(tuple<bint> &aTuple)
-  {
-    if (get<0>(aTuple).first)
-      theWaitFor = theClient->context_get(get<0>(aTuple).second);
-    else
-      theWaitFor = theClient->context_get();
-  }
-  
-  template<>
-  void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple)
-  {
-    theWaitFor = theClient->eval(get<0>(aTuple).second);
-  }
-  
-  void CommandLineHandler::addCommands()
-  {
-    theCommandLine << createCommand<Status>(tuple<>(), "status", *this,
-                                            "Gets the status of the server");
-    theCommandLine << createCommand<Quit>(tuple<>(), "quit", *this,
-                                          "Stops debugging and quits the client");
-    theCommandLine << createCommand<Run>(tuple<>(), "run", *this, "Run the Query");
-    {
-      Command<CommandLineHandler, tuple<bstring, bstring, bint>, BreakpointSet>* lCommand =
-      createCommand<BreakpointSet>(tuple<bstring, bstring, bint>(), "break", *this, "Set a breakpoint");
-      (*lCommand)(0, "s", createArgType<tuple<bstring, bstring, bint>, std::string, 0>(tuple<bstring, bstring, bint>()),
-                  "breakpoint state (enabled or disabled - default: enabled)", false);
-      (*lCommand)(1, "f", createArgType<tuple<bstring, bstring, bint>, std::string, 1>(tuple<bstring, bstring, bint>()),
-                  "The name of the file where to stop", true);
-      (*lCommand)(2, "l", createArgType<tuple<bstring, bstring, bint>, int, 2>(tuple<bstring, bstring, bint>()),
-                  "The line number", true);
-      
-      theCommandLine << lCommand;
-    }
-    {
-      Command<CommandLineHandler, tuple<bint>, BreakpointGet>* lCommand
-      = createCommand<BreakpointGet>(tuple<bint>(), "binfo", *this, 
-                                   "Get information about a given breakpoint");
-      (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()),
-                  "The id of the breakpoint", true);
-      
-      theCommandLine << lCommand;
-    }
-    {
-      Command<CommandLineHandler, tuple<bint>, BreakpointDel>* lCommand
-      = createCommand<BreakpointDel>(tuple<bint>(), "bdel", *this, "Delete a breakpoint with a given id");
-      (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the breakpoint", true);
-      
-      theCommandLine << lCommand;
-    }
-    theCommandLine << createCommand<BreakpointList>(tuple<>(), "blist", *this, "List all set breakpoints");
-    theCommandLine << createCommand<StackDepth>(tuple<>(), "sdepth", *this, "Get the depth of the stack");
-    {
-      Command<CommandLineHandler, tuple<bint>, StackGet>* lCommand
-      = createCommand<StackGet>(tuple<bint>(), "sget", *this, "Get information about one or all stack frames");
-      (*lCommand)(0, "d", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The stack entry two show (show all if not provided)", false);
-      theCommandLine << lCommand;
-    }
-    theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts");
-    {
-      Command<CommandLineHandler, tuple<bint>, ContextGet>* lCommand
-      = createCommand<ContextGet>(tuple<bint>(), "cget", *this, "Get a context");
-      
-      (*lCommand)(0, "c", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the context", false);
-      
-      theCommandLine << lCommand;
-    }
-    {
-      Command<CommandLineHandler, tuple<bstring>, Eval>* lCommand
-      = createCommand<Eval>(tuple<bstring>(), "eval", *this, "Evaluate a function");
-      
-      (*lCommand)(0, "c", createArgType<tuple<bstring>, std::string, 0>(tuple<bstring>()), "The command to evaluate", true);
-      
-      theCommandLine << lCommand;
-    }
-  }
-  
-}} // namespace zorba::debugclient
-
+  }
+  theWaitFor = theClient->stop();
+  theClient->quit();
+  theQuit = true;
+}
+
+template<>
+void
+CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theTerminated = false;
+  theWaitFor = theClient->run();
+}
+
+template<>
+void
+CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &aTuple)
+{
+  DebuggerClient::BreakpointType lType = DebuggerClient::Line;
+  bool lEnabled = true;
+  if (get<0>(aTuple).first) {
+    if (get<0>(aTuple).second == "disabled") {
+      lEnabled = false;
+    }
+  }
+  theWaitFor = theClient->breakpoint_set(lType,
+                                          lEnabled,
+                                          get<1>(aTuple).second,
+                                          get<2>(aTuple).second);
+}
+  
+template<>
+void
+CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple)
+{
+  theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second);
+}
+  
+template<>
+void
+CommandLineHandler::handle<BreakpointRemove>(tuple<bint> &aTuple)
+{
+  theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second);
+}
+  
+template<>
+void
+CommandLineHandler::handle<BreakpointList>(tuple<> &aTuple)
+{
+  theWaitFor = theClient->breakpoint_list();
+}
+  
+template<>
+void
+CommandLineHandler::handle<StackDepth>(tuple<> &aTuple)
+{
+  theWaitFor = theClient->stack_depth();
+}
+  
+template<>
+void
+CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple)
+{
+  if (get<0>(aTuple).first) {
+    theWaitFor = theClient->stack_get(get<0>(aTuple).second);
+  } else {
+    theWaitFor = theClient->stack_get();
+  }
+}
+  
+template<>
+void
+CommandLineHandler::handle<ContextNames>(tuple<>& aTuple)
+{
+  theWaitFor = theClient->context_names();
+}
+  
+template<>
+void CommandLineHandler::handle<ContextGet>(tuple<bint, bint> &aTuple)
+{
+  int lDepth = -1;
+  int lContext = -1;
+
+  if (get<0>(aTuple).first) {
+    lDepth = get<0>(aTuple).second;
+  }
+  if (get<1>(aTuple).first) {
+    lContext  = get<1>(aTuple).second;
+  }
+  theWaitFor = theClient->context_get(lDepth, lContext);
+}
+
+template<>
+void CommandLineHandler::handle<Source>(tuple<bint, bint, bstring> &aTuple)
+{
+  theWaitFor = theClient->source(
+    get<2>(aTuple).second,
+    get<0>(aTuple).second,
+    get<1>(aTuple).second);
+}
+  
+template<>
+void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple)
+{
+  theWaitFor = theClient->eval(get<0>(aTuple).second);
+}
+
+template<>
+void
+CommandLineHandler::handle<StepIn>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theTerminated = false;
+  theWaitFor = theClient->step_into();
+}
+
+template<>
+void
+CommandLineHandler::handle<StepOut>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theWaitFor = theClient->step_out();
+}
+
+template<>
+void
+CommandLineHandler::handle<StepOver>(ZORBA_TR1_NS::tuple<> &t)
+{
+  theTerminated = false;
+  theWaitFor = theClient->step_over();
+}
+
+void
+CommandLineHandler::addCommands()
+{
+  typedef tuple<> TUPLE;
+  typedef tuple<bint> TUPLE_INT;
+  typedef tuple<bstring> TUPLE_STR;
+  typedef tuple<bint, bint> TUPLE_INT_INT;
+  typedef tuple<bstring, bstring, bint> TUPLE_STR_STR_INT;
+  typedef tuple<bint, bint, bstring> TUPLE_INT_INT_STR;
+
+  // DBGP: status
+  theCommandLine << createCommand<Status>(TUPLE(), "status", *this, "Gets the status of the server");
+
+  // ALIAS: variables (context_get -c -1)
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("vars");
+    theCommandLine << createCommand<Variables>(TUPLE(), "variables", lAliases, *this, "Gets the variables visible in the current scope");
+  }
+
+  // META: quit
+  theCommandLine << createCommand<Quit>(TUPLE(), "quit", *this, "Stops debugging and quits the client");
+
+  // DBGP: run
+  theCommandLine << createCommand<Run>(TUPLE(), "run", *this, "Run the query");
+
+  // DBGP: breakpoint_set
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("break");
+    Command<CommandLineHandler, TUPLE_STR_STR_INT, BreakpointSet>* lCommand =
+      createCommand<BreakpointSet>(TUPLE_STR_STR_INT(), "bset", lAliases, *this, "Set a breakpoint");
+
+    lCommand->addArgument(0, "s", createArgType<TUPLE_STR_STR_INT, std::string, 0>(TUPLE_STR_STR_INT()), "breakpoint state (optional, 'enabled' or 'disabled', default: enabled)", false);
+    lCommand->addArgument(1, "f", createArgType<TUPLE_STR_STR_INT, std::string, 1>(TUPLE_STR_STR_INT()), "name of the file where to stop", true);
+    lCommand->addArgument(2, "l", createArgType<TUPLE_STR_STR_INT, int, 2>(TUPLE_STR_STR_INT()), "line number", true);
+      
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: breakpoint_get
+  {
+    Command<CommandLineHandler, TUPLE_INT, BreakpointGet>* lCommand =
+      createCommand<BreakpointGet>(TUPLE_INT(), "bget", *this, "Get information about a given breakpoint");
+
+    lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true);
+      
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: breakpoint_remove
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("clear");
+    lAliases.insert("delete");
+    Command<CommandLineHandler, TUPLE_INT, BreakpointRemove>* lCommand = 
+      createCommand<BreakpointRemove>(TUPLE_INT(), "bremove", lAliases, *this, "Delete a breakpoint");
+
+    lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true);
+      
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: breakpoint_list
+  theCommandLine << createCommand<BreakpointList>(TUPLE(), "blist", *this, "List all set breakpoints");
+
+  // DBGP: stack_depth
+  theCommandLine << createCommand<StackDepth>(TUPLE(), "sdepth", *this, "Get the depth of the stack");
+
+  // DBGP: stack_get
+  {
+    Command<CommandLineHandler, TUPLE_INT, StackGet>* lCommand =
+      createCommand<StackGet>(TUPLE_INT(), "sget", *this, "Get information about one or all stack frames");
+
+    lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "stack frame to show: 0 for current stack frame, N for the main module (optional, all frames are shown if not provided)", false);
+
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: context_names
+  theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts");
+  // the DBGP -d arguments for this command is omitted since we always have/return: 0 - Local, 1 - Global
+
+  // DBGP: context_get
+  {
+    Command<CommandLineHandler, TUPLE_INT_INT, ContextGet>* lCommand =
+      createCommand<ContextGet>(TUPLE_INT_INT(), "cget", *this, "Get a context (list variables in this context)");
+
+    lCommand->addArgument(0, "d", createArgType<TUPLE_INT_INT, int, 0>(TUPLE_INT_INT()), "stack depth (optional, default: 0)", false);
+    lCommand->addArgument(0, "c", createArgType<TUPLE_INT_INT, int, 1>(TUPLE_INT_INT()), "context ID: 0 for Local, 1 for Global (optional, default: 0)", false);
+
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: source
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("list");
+    Command<CommandLineHandler, TUPLE_INT_INT_STR, Source>* lCommand =
+      createCommand<Source>(TUPLE_INT_INT_STR(), "source", lAliases, *this, "List source code");
+
+    lCommand->addArgument(0, "b", createArgType<TUPLE_INT_INT_STR, int, 0>(TUPLE_INT_INT_STR()), "begin line (optional, default: first line)", false);
+    lCommand->addArgument(1, "e", createArgType<TUPLE_INT_INT_STR, int, 1>(TUPLE_INT_INT_STR()), "end line (optional, default: last line)", false);
+    lCommand->addArgument(2, "f", createArgType<TUPLE_INT_INT_STR, std::string, 2>(TUPLE_INT_INT_STR()), "file URI (optional, default: the file in the top-most stack frame during execution, main module otherwise)", false);
+
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: eval
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("print");
+    Command<CommandLineHandler, TUPLE_STR, Eval>* lCommand =
+      createCommand<Eval>(TUPLE_STR(), "eval", lAliases, *this, "Evaluate an expression");
+
+    // TODO: this argument should not be here at all. Eval has the form: eval -i transaction_id -- {DATA}
+    // Eval should be called with a command like: eval 1 + 3
+    // - no need for an argument name
+    // - everything following the fist contiguous set of whitespaces are sent as string
+    lCommand->addArgument(0, "c", createArgType<TUPLE_STR, std::string, 0>(TUPLE_STR()), "expression to evaluate", true);
+      
+    theCommandLine << lCommand;
+  }
+
+  // DBGP: step_in
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("step");
+    lAliases.insert("s");
+    theCommandLine << createCommand<StepIn>(TUPLE(), "in", lAliases, *this, "Step in");
+  }
+
+  // DBGP: step_out
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("finish");
+    theCommandLine << createCommand<StepOut>(TUPLE(), "out", lAliases, *this, "Step out");
+  }
+
+  // DBGP: step_over
+  {
+    std::set<std::string> lAliases;
+    lAliases.insert("next");
+    lAliases.insert("n");
+    theCommandLine << createCommand<StepOver>(TUPLE(), "over", lAliases, *this, "Step over");
+  }
+}
+  
+} // namespace zorba
+} // namespace debugger

=== modified file 'bin/debugger/command_line_handler.h'
--- bin/debug_client/command_line_handler.h	2011-07-01 01:53:24 +0000
+++ bin/debugger/command_line_handler.h	2011-12-13 11:51:46 +0000
@@ -14,46 +14,69 @@
  * limitations under the License.
  */
 #pragma once
+#ifndef ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H
+#define ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H
 
 #include <set>
 #include <cassert>
+
 #include <zorba/debugger_client.h>
-#include "debug_command.h"
+
+#include "command.h"
+#include "command_prompt.h"
 #include "event_handler.h"
 
-namespace zorba { namespace debugclient {
-  
+
+namespace zorba { namespace debugger {
+
   enum Commands {
     Status,
+    Variables,
+    Quit,
     Run,
     BreakpointSet,
     BreakpointGet,
-    BreakpointDel,
+    BreakpointRemove,
     BreakpointList,
     StackDepth,
     StackGet,
     ContextNames,
     ContextGet,
+    Source,
     Eval,
-    Quit
+    StepIn,
+    StepOut,
+    StepOver
   };
   
-  class CommandLineHandler {
+class CommandLineHandler
+{
   private:
+
     typedef std::pair<bool, std::string> bstring;
     typedef std::pair<bool, int> bint;
+
   public:
-    CommandLineHandler(unsigned short port,
-                       LockFreeConsumer<std::size_t>& aConsumer,
-                       LockFreeConsumer<bool>& aContinueQueue,
-                       EventHandler& aHandler,
-                       CommandLine& aCommandLine);
+
+    CommandLineHandler(
+      unsigned short port,
+      LockFreeConsumer<std::size_t>& aConsumer,
+      LockFreeConsumer<bool>& aContinueQueue,
+      EventHandler& aHandler,
+      CommandPrompt& aCommandPrompt);
+
     ~CommandLineHandler();
+
   public:
     void execute();
+  
   public: // Handlers
+
     template<int>
-    void handle(ZORBA_TR1_NS::tuple<>& aTuple) { assert(false); }
+    void handle(ZORBA_TR1_NS::tuple<>& aTuple)
+    {
+      assert(false);
+    }
     
     template<int>
     void handle(ZORBA_TR1_NS::tuple<bstring, bstring, bint>& t)
@@ -62,63 +85,93 @@
     }
     
     template<int>
+    void handle(ZORBA_TR1_NS::tuple<bint, bint, bstring>& t)
+    {
+      assert(false);
+    }
+    
+    template<int>
     void handle(ZORBA_TR1_NS::tuple<bint>& aTuple)
     {
       assert(false);
     }
     
     template<int>
+    void handle(ZORBA_TR1_NS::tuple<bint, bint>& aTuple)
+    {
+      assert(false);
+    }
+    
+    template<int>
     void handle(ZORBA_TR1_NS::tuple<bstring>& aTuple)
     {
       assert(false);
     }
+
   private:
-    LockFreeConsumer<std::size_t>& theConsumer;
-    LockFreeConsumer<bool>& theContinueQueue;
-    DebuggerClient* theClient;
-    CommandLine& theCommandLine;
-    bool theQuit;
-    bool theContinue;
-    std::size_t theWaitFor;
+    LockFreeConsumer<std::size_t>&  theConsumer;
+    LockFreeConsumer<bool>&         theContinueQueue;
+    DebuggerClient*                 theClient;
+    CommandPrompt&                  theCommandLine;
+    bool                            theQuit;
+    bool                            theTerminated;
+    bool                            theContinue;
+    std::size_t                     theWaitFor;
+
   private:
     void getNextId(std::set<std::size_t>& aIdList);
     void addCommands();
-  };
-  
-  template<>
-  void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t);
-  
-  template<>
-  void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t);
-  
-  template<>
-  void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t);
-  
-  template<>
-  void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t);
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t);
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<BreakpointDel>(ZORBA_TR1_NS::tuple<bint> &aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint> &aTuple);
-  
-  template<>
-  void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple);
-  
-}} // close namespaces zorba::debugclient
+};
+
+template<>
+void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t);
+
+template<>
+void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t);
+
+template<>
+void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t);
+  
+template<>
+void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t);
+  
+template<>
+void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple);
+  
+template<>
+void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t);
+  
+template<>
+void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
+  
+template<>
+void CommandLineHandler::handle<BreakpointRemove>(ZORBA_TR1_NS::tuple<bint> &aTuple);
+  
+template<>
+void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
+  
+template<>
+void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple);
+  
+template<>
+void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint, bint> &aTuple);
+  
+template<>
+void CommandLineHandler::handle<Source>(ZORBA_TR1_NS::tuple<bint, bint, bstring> &aTuple);
+  
+template<>
+void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple);
+
+template<>
+void CommandLineHandler::handle<StepIn> (ZORBA_TR1_NS::tuple<> &t);
+
+template<>
+void CommandLineHandler::handle<StepOut> (ZORBA_TR1_NS::tuple<> &t);
+
+template<>
+void CommandLineHandler::handle<StepOver> (ZORBA_TR1_NS::tuple<> &t);
+
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H

=== added file 'bin/debugger/command_prompt.cpp'
--- bin/debugger/command_prompt.cpp	1970-01-01 00:00:00 +0000
+++ bin/debugger/command_prompt.cpp	2011-12-13 11:51:46 +0000
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "command_prompt.h"
+
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+
+#include "command.h"
+
+
+namespace zorba { namespace debugger {
+
+CommandPrompt::~CommandPrompt()
+{
+  std::map<std::string, UntypedCommand*>::iterator lIter;
+  for (lIter = theCommands.begin(); lIter != theCommands.end(); ++lIter) {
+    delete lIter->second;
+  }
+}
+
+void
+CommandPrompt::printHelp(UntypedCommand* aCommand)
+{
+  // if no command is provided, print all the available commands
+  if (!aCommand) {
+    std::cout << "Available commands:" << std::endl;
+
+    // print the names of all commands
+    std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin();
+    while (lIter != theCommands.end()) {
+      std::cout << "  " << (*lIter).first;
+      std::set<std::string> lAliases = (*lIter).second->getAliases();
+      std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
+      while (lAliasIter != lAliases.end()) {
+        std::cout << ", " << *lAliasIter;
+        lAliasIter++;
+      }
+      std::cout << std::endl;
+      lIter++;
+    }
+
+    // some hints for detailed help
+    std::cout << std::endl;
+    std::cout << "Type help <command> to get more information about one command." << std::endl;
+    std::cout << std::endl;
+  } else {
+    // ok, so we have a command; then print the help
+    aCommand->printHelp();
+  }
+}
+
+void
+CommandPrompt::execute()
+{
+  for (;;) {
+    std::cout << "(xqdb) ";
+    std::string lCommandLine;
+    std::getline(std::cin, lCommandLine);
+    std::vector<std::string> lArgs;
+
+    // split the command into arguments
+    parseLine(lCommandLine, lArgs);
+    std::string::size_type lSize = lArgs.size();
+
+    // empty command? do nothing!
+    if (lSize == 0) {
+      lArgs = theLastArgs;
+      if (lArgs.size() == 0) {
+        continue;
+      }
+    }
+    theLastArgs = lArgs;
+
+    UntypedCommand* lCommand = NULL;
+
+    // help is not a command but a hook here
+    if (lArgs.at(0) == "h" || lArgs.at(0) == "help") {
+      std::string lCmd = "";
+
+      // if the user needs the help for a specific command
+      if (lSize > 1) {
+        // do nothing if we don't have a command starting with this prefix?
+        // findCommand will print the appropriate errors
+        if (!findCommand(lArgs[1], lCommand)) {
+          continue;
+        }
+      }
+      printHelp(lCommand);
+      continue;
+    }
+    if (findCommand(lArgs[0], lCommand) && lCommand->execute(lArgs)) {
+      return;
+    }
+    continue;
+  }
+}
+  
+CommandPrompt&
+CommandPrompt::operator<<(UntypedCommand *aCommand)
+{
+  theCommands.insert(std::make_pair(aCommand->getName(), aCommand));
+  return *this;
+}
+
+bool
+CommandPrompt::findCommand(const std::string& aPrefix, UntypedCommand*& aCommand)
+{
+  std::vector<UntypedCommand*> lFoundCommands;
+
+  std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin();
+  while (lIter != theCommands.end()) {
+    // if a command name is equal with the prefix, this is the command we want
+    if ((*lIter).first == aPrefix) {
+      aCommand = (*lIter).second;
+      return true;
+    }
+
+    bool lIsCandidate = false;
+
+    // add this command to candidate commands if the prefix matches
+    if ((*lIter).first.find(aPrefix) == 0) {
+      lFoundCommands.push_back((*lIter).second);
+      lIsCandidate = true;
+    }
+
+    // now process the aliases
+    std::set<std::string> lAliases = (*lIter).second->getAliases();
+    std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
+    while (lAliasIter != lAliases.end()) {
+      // if a command alias is equal with the prefix, this is the command we want
+      if (*lAliasIter == aPrefix) {
+        aCommand = (*lIter).second;
+        return true;
+      }
+
+      // add this command to candidate commands if the prefix matches one alias
+      // and if the command is not already added 
+      if (!lIsCandidate && (*lAliasIter).find(aPrefix) == 0) {
+        lFoundCommands.push_back((*lIter).second);
+        break;
+      }
+      lAliasIter++;
+    }
+
+    lIter++;
+  }
+
+  if (lFoundCommands.empty()) {
+    std::cout << "Command not found: " << aPrefix << std::endl;
+    return false;
+  }
+
+  if (lFoundCommands.size() > 1) {
+    std::cout << "Ambigous command: " << aPrefix << std::endl;
+    // show all possible commands that start with this prefix
+    for (std::string::size_type i = 0; i < lFoundCommands.size(); i++) {
+      UntypedCommand* lCommand = lFoundCommands.at(i);
+
+      // commands
+      if (lCommand->getName().find(aPrefix) == 0) {
+        std::cout << "  " << lCommand->getName() << std::endl;
+      }
+
+      // and aliases
+      std::set<std::string> lAliases = lCommand->getAliases();
+      std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
+      while (lAliasIter != lAliases.end()) {
+        if ((*lAliasIter).find(aPrefix) == 0) {
+          std::cout << "  " << *lAliasIter << std::endl;
+        }
+        lAliasIter++;
+      }
+    }
+    return false;
+  }
+
+  aCommand = lFoundCommands[0];
+  return true;
+}
+
+void
+CommandPrompt::parseLine(const std::string& aLine, std::vector<std::string>& aVector)
+{
+  std::string::size_type lBefore = 0;
+  std::string::size_type lPos = aLine.find_first_of(" \t", 0);
+
+  while (lPos != aLine.npos) {
+    std::string lSub = aLine.substr(lBefore, lPos - lBefore);
+
+    // if two consecutive spaces, you get an empty string here
+    if (lSub != "") {
+      if (lSub[0] == '"') {
+        std::string::size_type lBeforeCopy = lBefore;
+        do {
+          lBeforeCopy = aLine.find("\"", lBeforeCopy + 1);
+        } while (lPos != aLine.npos && aLine.size() > lPos + 1 && aLine[lPos + 1] == '\\');
+        lPos = lBeforeCopy;
+        lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1);
+      }
+      aVector.push_back(lSub);
+    }
+
+    lBefore = lPos + 1;
+    lPos = aLine.find_first_of(" \t", lBefore);
+  }
+  std::string lSub = aLine.substr(lBefore);
+
+  // catching the case when the command ends with a space
+  if (lSub == "") {
+    return;
+  }
+
+  if (lSub[0] == '"') {
+    lPos = aLine.find("\"", lBefore + 1);
+    lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1);
+  }
+  aVector.push_back(lSub);
+}
+  
+} // namespace zorba
+} // namespace debugger

=== added file 'bin/debugger/command_prompt.h'
--- bin/debugger/command_prompt.h	1970-01-01 00:00:00 +0000
+++ bin/debugger/command_prompt.h	2011-12-13 11:51:46 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+#ifndef ZORBA_DEBUGGER_COMMAND_PROMPT_H
+#define ZORBA_DEBUGGER_COMMAND_PROMPT_H
+
+#include <string>
+#include <map>
+#include <vector>
+
+
+namespace zorba { namespace debugger {
+
+class UntypedCommand;
+
+class CommandPrompt
+{
+  public:
+    ~CommandPrompt();
+
+  public:
+
+    void execute();
+
+    CommandPrompt& operator<< (UntypedCommand* command);
+
+  private:
+
+    void
+    printHelp(UntypedCommand* command);
+
+    bool
+    findCommand(const std::string& prefix, UntypedCommand*& command);
+
+    void
+    parseLine(const std::string& line, std::vector<std::string>& vector);
+
+  private:
+    std::map<std::string, UntypedCommand*>  theCommands;
+    std::vector<std::string>                theLastArgs;
+};  
+
+  
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_COMMAND_PROMPT_H

=== modified file 'bin/debugger/event_handler.cpp'
--- bin/debug_client/event_handler.cpp	2011-07-01 01:53:24 +0000
+++ bin/debugger/event_handler.cpp	2011-12-13 11:51:46 +0000
@@ -13,88 +13,94 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include "event_handler.h"
+
+#include <sstream>
+
 #include <zorba/zorba.h>
 #include <zorba/store_manager.h>
 #include <zorba/iterator.h>
-#include <sstream>
-#include "debug_client/event_handler.h"
 
-namespace zorba { namespace debugclient {
+namespace zorba { namespace debugger {
   
-  EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer)
+EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer)
   : theIdQueue(aQueue), theContinueProducer(aContProducer),
     theStore(StoreManager::getStore()),
     theZorbaInstance(Zorba::getInstance(theStore)),
     theStaticContext(theZorbaInstance->createStaticContext())
-    
-  {
-    try {
-      Zorba_CompilerHints_t lHints;
-      lHints.opt_level = ZORBA_OPT_LEVEL_O1;
-      std::auto_ptr<std::istream> stream(getCurrentDirectory());
-      zorba::String query;
-      char buffer[1024];
-      std::string::size_type s;
-      while ((s = stream->readsome(buffer, 1024))) {
-        query.append(std::string(buffer, s));
-      }
-      theStaticContext->loadProlog(query, lHints);
-    } catch (zorba::ZorbaException& e) {
-      std::cerr << "Exception: I was not able to load the query file:" << std::endl;
-      std::cerr << e.what() << std::endl;
-      throw;
-    }
-  }
-  
-  EventHandler::~EventHandler()
-  {
-    theStaticContext = 0;
-    theZorbaInstance->shutdown();
-    StoreManager::shutdownStore(theStore);
-  }
-  
-  void EventHandler::parseMessage(const std::string &aMessage)
-  {
-    try {
-      zorba::String queryString = "local:main(";
-      queryString += aMessage + ")";
-      XQuery_t query = theZorbaInstance->compileQuery(queryString, theStaticContext);
-      Iterator_t lIter = query->iterator();
-      Item item;
-      lIter->open();
-      bool doContinue = false;
-      lIter->next(item);
-      {
-        const std::string& continueString = item.getStringValue().str();
-        if (continueString == "true") {
-          doContinue = true;
-        } else if (continueString == "false") {
-          doContinue = false;
-        } else {
-          std::stringstream stream(continueString);
-          stream >> doContinue;
-        }
-      }
-      lIter->next(item);
-      std::size_t lId;
-      {
-        std::stringstream stream(item.getStringValue().c_str());
-        stream >> lId;
-      }
-      lIter->next(item);
-      std::cout << item.getStringValue() << std::endl;
-      theContinueProducer.produce(doContinue);
-      theIdQueue.produce(lId);
-    } catch (ZorbaException& e) {
-      std::cerr << "FATAL: could not execute query: " << std::endl;
-      std::cerr << e << std::endl;
-      std::cerr << "This is a bug, please report to zorba-users@xxxxxxxxxxxxxxxxxxxxx" << std::endl;
-      theContinueProducer.produce(false);
-    }
-  }
-  
-  void EventHandler::error(unsigned int errcode, const std::string &msg)
-  {
-    std::cerr << "Error " << errcode << ": " << msg << std::endl;
-  }
-}}
+{
+}
+
+EventHandler::~EventHandler()
+{
+  theStaticContext = 0;
+  theZorbaInstance->shutdown();
+  StoreManager::shutdownStore(theStore);
+}
+
+void
+EventHandler::init()
+{
+  try {
+    Zorba_CompilerHints_t lHints;
+    lHints.opt_level = ZORBA_OPT_LEVEL_O1;
+    zorba::String lProlog("import module namespace dmh = 'http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler';");
+    theStaticContext->loadProlog(lProlog, lHints);
+  } catch (zorba::ZorbaException& e) {
+    std::cerr << "Exception: I was not able to load the query file:" << std::endl;
+    std::cerr << e.what() << std::endl;
+    throw;
+  }
+}
+
+void
+EventHandler::parseMessage(const std::string &aMessage)
+{
+  try {
+#ifndef NDEBUG
+    // uncomment this to see the raw messages received by the event handler
+    //std::cout << "Processing response: " << aMessage << std::endl;
+#endif
+    // the query to process the response
+    std::stringstream lQueryStream;
+    lQueryStream << "dmh:process(" << aMessage << ")";
+    XQuery_t lQuery = theZorbaInstance->compileQuery(lQueryStream.str(), theStaticContext);
+
+    // get the query result sequrence:
+    //   1. a message
+    Iterator_t lIter = lQuery->iterator();
+    Item lItem;
+    lIter->open();
+    lIter->next(lItem);
+    std::size_t lId;
+    std::stringstream lStream(lItem.getStringValue().c_str());
+    lStream >> lId;
+
+    //   2. an "idle" flag (to disable quit confirmation)
+    bool lCanQuit = false;
+    if (lIter->next(lItem)) {
+      String lMessage = lItem.getStringValue();
+      lCanQuit = lMessage == "idle";
+      std::cout << std::endl << lItem.getStringValue() << std::endl;
+    }
+    theContinueProducer.produce(lCanQuit);
+
+    // go and solve the event with this id
+    theIdQueue.produce(lId);
+  } catch (ZorbaException& e) {
+    std::cerr << "FATAL: could not execute query: " << std::endl;
+    std::cerr << e << std::endl;
+    std::cerr << "This is a bug, please report to zorba-users@xxxxxxxxxxxxxxxxxxxxx" << std::endl;
+    //theContinueProducer.produce(false);
+  }
+}
+  
+void
+EventHandler::error(unsigned int errcode, const std::string &msg)
+{
+  std::cerr << "Error " << errcode << ": " << msg << std::endl;
+}
+
+} // namespace zorba
+} // namespace debugger

=== modified file 'bin/debugger/event_handler.h'
--- bin/debug_client/event_handler.h	2011-07-01 01:53:24 +0000
+++ bin/debugger/event_handler.h	2011-12-13 11:51:46 +0000
@@ -14,33 +14,46 @@
  * limitations under the License.
  */
 #pragma once
+#ifndef ZORBA_DEBUGGER_EVENT_HANDLER_H
+#define ZORBA_DEBUGGER_EVENT_HANDLER_H
+
 #include <string>
 #include <iostream>
+
 #include <zorba/debugger_event_handler.h>
 #include <zorba/static_context.h>
+
 #include "lock_free_queue.h"
 
-namespace zorba {
-  class Zorba;
-}
-
-namespace zorba { namespace debugclient {
-  
-  class EventHandler : public zorba::DebuggerEventHandler
-  {
+
+namespace zorba { namespace debugger {
+
+class EventHandler : public zorba::DebuggerEventHandler
+{
   public:
-    EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContQueue);
+    EventHandler(
+      LockFreeProducer<std::size_t>& aQueue,
+      LockFreeProducer<bool>& aContQueue);
+
     ~EventHandler();
+
   public:
     virtual void parseMessage(const std::string& aMessage);
+
     virtual void error(unsigned int errcode, const std::string& msg);
+
+    virtual void init();
+
   private:
-    static std::istream* getCurrentDirectory();
     LockFreeProducer<std::size_t>& theIdQueue;
     LockFreeProducer<bool>& theContinueProducer;
     void* theStore;
     Zorba* theZorbaInstance;
     StaticContext_t theStaticContext;
-  };
+
+};
   
-}} // end of namespace zorba::debugclient
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_EVENT_HANDLER_H

=== modified file 'bin/debugger/lock_free_queue.h'
--- bin/debug_client/lock_free_queue.h	2011-07-01 01:53:24 +0000
+++ bin/debugger/lock_free_queue.h	2011-12-13 11:51:46 +0000
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 #pragma once
+#ifndef ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H
+#define ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H
+
 #include <iostream>
 #include <list>
 
-namespace zorba { namespace debugclient {
+
+namespace zorba { namespace debugger {
 
 template<typename T>
 class LockFreeProducer
@@ -80,4 +84,8 @@
   }
   return false;
 }
-}} // namespace zorba::debugclient
+
+} // namespace zorba
+} // namespace debugger
+
+#endif // ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H

=== modified file 'bin/debugger/main.cpp'
--- bin/debug_client/main.cpp	2011-07-01 01:53:24 +0000
+++ bin/debugger/main.cpp	2011-12-13 11:51:46 +0000
@@ -13,12 +13,244 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#ifdef WIN32
+# include <windows.h>
+# include <string.h>
+# include <strsafe.h>
+#endif
+
+#include <vector>
+
 #include <zorba/config.h>
-#include "debug_command.h"
+
+#include "command_prompt.h"
 #include "command_line_handler.h"
 
 using namespace zorba;
-using namespace zorba::debugclient;
+using namespace zorba::debugger;
+
+int
+startZorba(std::string& aExec, std::vector<std::string>& aArgs) 
+{
+#ifdef WIN32
+  // **************************
+  // start a process on Windows
+
+  DWORD iReturnVal = 0;
+  DWORD dwExitCode = 0;
+
+  std::wstring lExec;
+  std::wstring lArgs;
+
+  lExec.assign(aExec.begin(), aExec.end());
+
+  // the executable must be the first in the list of arguments
+  lArgs.append(L"\"");
+  lArgs.append(lExec);
+  lArgs.append(L"\"");
+
+  for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) {
+    std::string lArg(aArgs.at(j));
+    std::wstring lArgW;
+    lArgW.assign(lArg.begin(), lArg.end());
+    lArgs.append(L" ");
+    lArgs.append(lArgW);
+  }
+
+  // CreateProcessW can modify Parameters thus we allocate needed memory
+  wchar_t * pwszParam = new wchar_t[lArgs.size() + 1];
+  if (pwszParam == 0) {
+    return 1;
+  }
+  const wchar_t* pchrTemp = lArgs.c_str();
+  wcscpy_s(pwszParam, lArgs.size() + 1, pchrTemp); 
+
+  // CreateProcess API initialization
+  STARTUPINFOW siStartupInfo;
+  PROCESS_INFORMATION piProcessInfo;
+  memset(&siStartupInfo, 0, sizeof(siStartupInfo));
+  memset(&piProcessInfo, 0, sizeof(piProcessInfo));
+  siStartupInfo.cb = sizeof(siStartupInfo);
+
+  BOOL lResult = CreateProcessW(
+    const_cast<LPCWSTR>(lExec.c_str()),
+    pwszParam, 0, 0, false,
+    CREATE_DEFAULT_ERROR_MODE, 0, 0,
+    &siStartupInfo, &piProcessInfo);
+
+  if (lResult) {
+    // Watch the process
+    dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, 0);
+  }
+  else {
+    // CreateProcess failed
+    iReturnVal = GetLastError();
+    LPVOID lpMsgBuf;
+    LPVOID lpDisplayBuf;
+
+    FormatMessage(
+      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+      NULL,
+      iReturnVal,
+      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+      (LPTSTR) &lpMsgBuf,
+      0, NULL);
+
+    // Display the error message and exit the process
+
+    lpDisplayBuf = (LPVOID)LocalAlloc(
+      LMEM_ZEROINIT,
+      (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
+
+    StringCchPrintf(
+      (LPTSTR)lpDisplayBuf,
+      LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+      TEXT("Error (%d) when starting zorba: %s"),
+      iReturnVal,
+      lpMsgBuf);
+
+    std::wstring lErrorW((wchar_t*)lpDisplayBuf);
+    std::string lError;
+    lError.assign(lErrorW.begin(), lErrorW.end());
+    std::cout << lError << std::endl;
+
+    LocalFree(lpMsgBuf);
+    LocalFree(lpDisplayBuf);
+  }
+
+  // Free memory
+  delete[]pwszParam;
+  pwszParam = 0;
+
+  // Release handles
+  CloseHandle(piProcessInfo.hProcess);
+  CloseHandle(piProcessInfo.hThread);
+
+  return iReturnVal; 
+
+#else
+  // ************************
+  // start a process on Linux
+
+  pid_t pID = fork();
+  if (pID == 0) {
+    // Code only executed by child process
+    std::stringstream lCommand;
+    lCommand << aExec;
+    for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) {
+      lCommand << " " << aArgs.at(j);
+    }
+
+    int lRes = system(lCommand.str().c_str());
+    exit(lRes);
+  }
+  else {
+    // Code only executed by parent process
+    if (pID < 0) {
+      std::cerr << "Failed to fork Zorba" << std::endl;
+      return pID;
+    } else {
+      return 0;
+    }
+  }
+#endif
+}
+
+void printUsage(std::string& aProgram)
+{
+  std::cerr << "Usage:" << std::endl
+    << "    " << aProgram << " <zorba_arguments>" << std::endl
+    << "        this will start a debugger command line and a zorba process with the given arguments" << std::endl;
+}
+
+bool
+processArguments(
+  int argc,
+  char* argv[],
+  std::string& aProgram,
+  bool& aStandalone,
+  std::string& aZorba,
+  unsigned int& aPort,
+  std::vector<std::string>& aZorbaArgs)
+{
+  aPort = 28028;
+
+  // find the path to Zorba and this executable name
+  aProgram = argv[0];
+
+#ifdef WIN32
+  char lSep = '\\';
+#else
+  char lSep = '/';
+#endif
+  std::string::size_type lPos = aProgram.find_last_of(lSep);
+
+  std::stringstream lZs;
+
+  if (lPos == aProgram.npos) {
+    lZs << "." << lSep;
+  } else {
+    lZs << aProgram.substr(0, lPos + 1);
+    aProgram = aProgram.substr(lPos + 1);
+  }
+  lZs << "zorba";
+#ifdef WIN32
+  lZs << ".exe";
+#endif
+  aZorba = lZs.str();
+
+
+  bool lHasFileArg = false;
+  bool lHasQueryArg = false;
+  bool lHasQueryVal = false;
+
+  // find if the user asked for help or specified a specific port
+  for (int i = 1; i < argc; i++) {
+    std::string lArg = argv[i];
+    if (lArg == "-h" || lArg == "--help") {
+      return false;
+    }
+    else if (lArg == "-p" || lArg == "--debug-port") {
+      // if there is one more argument
+      if (i < argc - 1) {
+        // get the port value
+        int lPort;
+        std::stringstream lStream(argv[i + 1]);
+        lStream >> lPort;
+        if (!lStream.fail()) {
+          aPort = lPort;
+        }
+      }
+    }
+    else if (lArg == "-f") {
+      lHasFileArg = true;
+    }
+    else if (lArg == "-q") {
+      lHasQueryArg = true;
+      if (++i < argc) {
+        lHasQueryVal = true;
+      }
+    }
+  }
+
+  if (!lHasFileArg || !lHasQueryArg || !lHasQueryVal) {
+    std::cout << "Not enough arguments to start Zorba." << std::endl;
+    std::cout << "Running the standalone XQuery debugger client on port: " << aPort << std::endl;
+    return true;
+  }
+
+  // zorba will need the -d flag
+  aZorbaArgs.push_back("-d");
+
+  // gather all arguments (excepting the program name)
+  for (int i = 1; i < argc; i++) {
+    aZorbaArgs.push_back(argv[i]);
+  }
+
+  aStandalone = false;
+  return true;
+}
 
 #ifndef _WIN32_WCE
 int
@@ -28,24 +260,68 @@
 _tmain(int argc, _TCHAR* argv[])
 #endif
 {
-  int port = 28028;
-  if (argv[1]) {
-    std::stringstream stream(argv[1]);
-    stream >> port;
-    if (stream.fail() || argv[2]) {
-      std::cerr << "Unknown argument. USAGE: " << argv[0] << " [PORT]" << std::endl;
-      return 2;
+  // **************************************************************************
+  // processing arguments
+
+  std::string lProgram, lZorbaExec;
+  unsigned int lPort = 28028;
+  std::vector<std::string> lZorbaArgs;
+
+  bool lStandalone = true;
+  if (!processArguments(argc, argv, lProgram, lStandalone, lZorbaExec, lPort, lZorbaArgs)) {
+    printUsage(lProgram);
+    return 1;
+  }
+
+#ifndef NDEBUG
+  // **************************************************************************
+  // debug reporting
+
+  if (!lStandalone) {
+    std::cout << "Communication port: " << lPort << std::endl;
+    std::cout << "Zorba executable:   " << lZorbaExec << std::endl;
+    std::cout << "Zorba arguments:    ";
+    for (std::vector<std::string>::size_type j = 0; j < lZorbaArgs.size(); j++) {
+      std::cout << lZorbaArgs.at(j) << " ";
     }
+    std::cout << std::endl;
   }
+#endif
+
   try {
+    // **************************************************************************
+    // start a zorba
+
+    if (!lStandalone) {
+      int lResult = startZorba(lZorbaExec, lZorbaArgs);
+      if (lResult) {
+        return lResult;
+      }
+    } else {
+      std::cout << "Waiting for an incomming Zorba connection..." << std::endl;
+    }
+
+    // **************************************************************************
+    // start the debugger command line
+
     LockFreeQueue<std::size_t> lQueue;
     LockFreeQueue<bool> lContEvent;
-    EventHandler lHandler(lQueue, lContEvent);
-    CommandLine cli;
-    CommandLineHandler handler(port, lQueue, lContEvent, lHandler, cli);
-    handler.execute();
+    EventHandler lEventHandler(lQueue, lContEvent);
+    lEventHandler.init();
+
+    CommandPrompt lCommandPrompt;
+    CommandLineHandler lCommandLineHandler(lPort, lQueue, lContEvent, lEventHandler, lCommandPrompt);
+
+    lCommandLineHandler.execute();
+
+#ifndef WIN32
+    wait();
+#endif
+
   } catch (...) {
-    return 4;
+    return -1;
   }
+
   return 0;
 }
+

=== modified file 'bin/debugger/tuple.h'
--- bin/debug_client/tuple.h	2011-07-04 08:05:46 +0000
+++ bin/debugger/tuple.h	2011-12-13 11:51:46 +0000
@@ -14,9 +14,15 @@
  * limitations under the License.
  */
 #pragma once
+#ifndef ZORBA_DEBUGGER_TUPLE_H
+#define ZORBA_DEBUGGER_TUPLE_H
+
 #include <zorba/config.h>
+
 #if ZORBA_TR1_IN_TR1_SUBDIRECTORY
 # include <tr1/tuple>
 #else
 # include <tuple>
 #endif
+
+#endif // ZORBA_DEBUGGER_TUPLE_H

=== modified file 'bin/zorbacmd.cpp'
--- bin/zorbacmd.cpp	2011-11-08 03:11:02 +0000
+++ bin/zorbacmd.cpp	2011-12-13 11:51:46 +0000
@@ -925,17 +925,15 @@
           lHost = "127.0.0.1";
         }
 
-        if (lProperties.debug()) {
-          Zorba_SerializerOptions lSerOptions =
-              Zorba_SerializerOptions::SerializerOptionsFromStringParams(
-              lProperties.getSerializerParameters());
-          createSerializerOptions(lSerOptions, lProperties);
+        Zorba_SerializerOptions lSerOptions =
+            Zorba_SerializerOptions::SerializerOptionsFromStringParams(
+            lProperties.getSerializerParameters());
+        createSerializerOptions(lSerOptions, lProperties);
 
-          if (!lProperties.hasNoLogo() && !lProperties.debug()) {
-            std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl;
-          }
-          lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort());
+        if (!lProperties.hasNoLogo()) {
+          std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl;
         }
+        lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort());
       }
       catch (zorba::XQueryException const& qe)
       {

=== modified file 'include/zorba/debugger_client.h'
--- include/zorba/debugger_client.h	2011-07-24 22:28:31 +0000
+++ include/zorba/debugger_client.h	2011-12-13 11:51:46 +0000
@@ -162,6 +162,13 @@
      * @return The id of the request.
      */
     virtual std::size_t status() = 0;
+
+    /**
+     * @brief Get the variables in all the contexts in the topmost stack frame.
+     *
+     * @return The id of the request.
+     */
+    virtual std::size_t variables() = 0;
     
     /**
      * @brief Query the debug engine for supported features.
@@ -521,6 +528,7 @@
      */
     virtual void quit() = 0;
   };
+
 }//end of namespace
+
 #endif
-/* vim:set et sw=2 ts=2: */

=== modified file 'modules/com/zorba-xquery/www/modules/CMakeLists.txt'
--- modules/com/zorba-xquery/www/modules/CMakeLists.txt	2011-10-14 07:35:51 +0000
+++ modules/com/zorba-xquery/www/modules/CMakeLists.txt	2011-12-13 11:51:46 +0000
@@ -100,6 +100,13 @@
 DECLARE_ZORBA_MODULE(FILE store/static/integrity_constraints/dml.xq VERSION 2.0
   URI "http://www.zorba-xquery.com/modules/store/static/integrity_constraints/dml";)
 
+# debugger client DBGP message handler module
+IF (ZORBA_WITH_DEBUGGER)
+  DECLARE_ZORBA_MODULE (FILE debugger/dbgp-message-handler.xq VERSION 1.0
+    URI "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler";)
+ENDIF (ZORBA_WITH_DEBUGGER)
+
+
 # error and warning modules
 DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq
   URI "http://www.zorba-xquery.com/errors";

=== added directory 'modules/com/zorba-xquery/www/modules/debugger'
=== added file 'modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq'
--- modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq	1970-01-01 00:00:00 +0000
+++ modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq	2011-12-13 11:51:46 +0000
@@ -0,0 +1,272 @@
+(:
+ : Copyright 2006-2009 The FLWOR Foundation.
+ :
+ : Licensed under the Apache License, Version 2.0 (the "License");
+ : you may not use this file except in compliance with the License.
+ : You may obtain a copy of the License at
+ :
+ : http://www.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+:)
+module namespace dmh = "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler";;
+
+import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64";;
+
+
+declare variable $dmh:endl as xs:string := "
+";
+
+(:~
+ : Set this variale to true if you want to have mode debug information when
+ : an error occurs.
+ :)
+declare variable $dmh:debug as xs:boolean := fn:false();
+
+
+declare %private function dmh:status($resp as element(response))
+{
+  switch ($resp/@status)
+  case "starting"
+  case "stopping"
+    return "idle"
+  case "break"
+    return
+      let $status := $resp/@status
+      let $whyInfo :=
+        if ($resp/@reason ne "ok") then
+          fn:concat(" (", $resp/@reason, ")")
+        else
+          ""
+      let $whereInfo :=
+        if ($resp/text()[1] ne "") then
+          fn:concat(" in ", $resp/text()[1])
+        else
+          ""
+      return
+        fn:concat($status, $whyInfo, $whereInfo)
+  default
+    return $resp/@status
+};
+
+declare %private function dmh:source($resp as element(response))
+{
+  $resp/text()
+};
+
+declare %private function dmh:breakpoint-set($resp as element(response))
+{
+  fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state))
+};
+
+declare %private function dmh:breakpoint-get($resp as element(response))
+{
+  let $b := $resp/breakpoint
+  return
+    fn:concat(
+      "Breakpoint ", $b/@id, $dmh:endl,
+      "  type:  ", $b/@type, $dmh:endl,
+      "  file:  ", $b/@filename, $dmh:endl,
+      "  line:  ", $b/@lineno, $dmh:endl,
+      "  state: ", $b/@state
+    )
+};
+
+declare %private function dmh:breakpoint-list($resp as element(response))
+{
+  fn:string-join(
+    let $bs := $resp/breakpoint
+    return
+      if (fn:exists($bs)) then
+        fn:concat(
+          "--------------------------------------", $dmh:endl,
+          "|   ID   |   State   |  Line  | File", $dmh:endl,
+          "|--------|-----------|--------|-------", $dmh:endl,
+          fn:string-join(
+            for $b in $bs
+            return
+              fn:concat(
+                "| ", dmh:lpottl($b/@id, 6, " "), " ",
+                "| ", if ($b/@state eq "enabled") then "enabled  " else "disabled ", " ",
+                "| ", dmh:lpottl($b/@lineno, 6, " "), " ",
+                "| ", $b/@filename, $dmh:endl),
+            ""
+          ),
+          "--------------------------------------", $dmh:endl
+        )
+      else
+        "No breakpoints set"
+  )
+};
+
+(:~
+ : left-pad-or-trim-to-length
+ :)
+declare %private function dmh:lpottl($value as xs:string, $length as xs:integer, $padChar as xs:string)
+ as xs:string
+{
+  let $padChar := fn:substring($padChar, 1, 1)
+  let $len := fn:string-length($value)
+  return
+    if ($len < $length) then
+      let $pad :=
+        fn:string-join(
+          for $i in 1 to $length - $len
+          return $padChar,
+          ""
+        )
+      return
+        fn:concat($pad, $value)
+    else
+      fn:substring($value, $len - $length + 1)
+};
+
+declare %private function dmh:breakpoint-remove($resp as element(response))
+{
+  "Breakpoint removed"
+};
+
+declare %private function dmh:stack-depth($resp as element(response))
+{
+  fn:concat("depth: ", $resp/@depth)
+};
+
+declare %private function dmh:stack-get($resp as element(response))
+{
+  fn:string-join(
+    for $s in $resp/stack
+    return
+      fn:concat("#", $s/@level, " in ", $s/@where, " at ", $s/@filename, ":", $s/@lineno),
+    $dmh:endl
+  )
+};
+
+
+declare %private function dmh:context-names($resp as element(response))
+{
+  fn:string-join(
+    for $c in $resp/context
+    return
+      fn:concat("context ", $c/@id, ": ", $c/@name),
+    $dmh:endl
+  )
+};
+
+declare %private function dmh:context-get($resp as element(response))
+{
+  fn:string-join(
+    for $p in $resp/property
+    return
+      fn:concat($p/@fullname, " ", $p/@type,
+        if ($p/text() ne "") then
+          fn:concat(": ", base64:decode($p/text()))
+        else
+          ""
+      ),
+    $dmh:endl
+  )
+};
+
+declare %private function dmh:eval($resp as element(response))
+{
+  if ($resp/@success eq "1") then
+    dmh:context-get($resp)
+  else
+    dmh:report-error("An unknown error occured while evaluating expression.")
+};
+
+declare %private function dmh:report-error(
+  $message as xs:string)
+{
+  dmh:report-error($message, ())
+};
+
+declare %private function dmh:report-error(
+  $message as xs:string,
+  $debugMessage as xs:string*)
+{
+  fn:string-join(
+    (
+      (: the error message :)
+      fn:concat("Error: ", $message),
+
+      (: the debug info :)
+      if ($dmh:debug and fn:string-length($debugMessage) gt 0) then
+        $debugMessage
+      else
+        ()
+    ),
+    $dmh:endl
+  )
+};
+
+declare %private function dmh:process-response($resp as element(response))
+{
+  switch ($resp/@command)
+  case "eval"               return dmh:eval($resp)
+  case "context_get"        return dmh:context-get($resp)
+  case "context_names"      return dmh:context-names($resp)
+  case "stack_get"          return dmh:stack-get($resp)
+  case "stack_depth"        return dmh:stack-depth($resp)
+  case "breakpoint_remove"  return dmh:breakpoint-remove($resp)
+  case "breakpoint_list"    return dmh:breakpoint-list($resp)
+  case "breakpoint_get"     return dmh:breakpoint-get($resp)
+  case "breakpoint_set"     return dmh:breakpoint-set($resp)
+  case "source"             return dmh:source($resp)
+
+  (: continuation command only need to display/process the status :)
+  case "run"
+  case "step_into"
+  case "step_out"
+  case "step_over"
+  case "stop"
+  case "status"
+    return dmh:status($resp)
+
+  default
+    return dmh:report-error(fn:concat("Command not implemented: ", $resp/@command))
+};
+
+declare function dmh:process-init($init as element(init))
+{
+  fn:string-join(
+    ("Established connection with", $init/@language, "client", $init/@appid),
+    " "
+  )
+};
+
+declare function dmh:process($message as element())
+{
+  let $nodeName := fn:local-name($message)
+  let $id := fn:data($message/@transaction_id)
+  return
+    if ($nodeName eq "response") then
+      (: no transaction_id :)
+      if (fn:count($id) eq 0 or $id eq "") then
+        (0, dmh:report-error("Invalid response", "Missing or empty response transaction ID."))
+      (: wrong transaction_id :)
+      else if (xs:string(fn:number($id)) eq "NaN") then
+        (0, dmh:report-error("Invalid response", "Invalid value for response transaction ID."))
+      (: no or empty command :)
+      else if (fn:count($message/@command) eq 0 or $message/@command eq "") then
+        ($id, dmh:report-error("Invalid response", "Missing or empty response command attribute."))
+      (: error response :)
+      else if (fn:exists($message/error)) then
+        ($id, dmh:report-error(fn:data($message/error/message), fn:concat("Error code: ", fn:data($message/error/@code))))
+      else
+        ($id, dmh:process-response($message))
+    else if ($nodeName eq "init") then
+      (0, dmh:process-init($message))
+    else
+      (
+        if (fn:count($id) eq 0 or $id eq "" or xs:string(fn:number($id)) eq "NaN") then
+          0
+        else
+          $id,
+        dmh:report-error(fn:concat("Unknown message node: ", $nodeName))
+      )
+};

=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp	2011-12-13 03:38:23 +0000
+++ src/compiler/expression/expr.cpp	2011-12-13 11:51:46 +0000
@@ -1469,7 +1469,6 @@
   compute_scripting_kind();
 }
 
-
 void debugger_expr::serialize(::zorba::serialization::Archiver& ar)
 {
   serialize_baseclass(ar, (expr*)this);

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2011-12-13 03:38:23 +0000
+++ src/compiler/translator/translator.cpp	2011-12-13 11:51:46 +0000
@@ -1671,7 +1671,7 @@
 void wrap_in_debugger_expr(
   expr_t& aExpr,
   const QueryLoc& aLoc,
-  bool aAddBreakable = true,
+  bool aIsMainModuleBreakable = false,
   bool aIsVarDeclaration = false)
 {
 #ifdef ZORBA_WITH_DEBUGGER
@@ -1686,9 +1686,7 @@
     // add the breakable expression in the debugger commons as a possible
     // breakpoint location
     Breakable lBreakable(aLoc);
-    if (aAddBreakable) {
-      theCCB->theDebuggerCommons->addBreakable(lBreakable);
-    }
+    theCCB->theDebuggerCommons->addBreakable(lBreakable, aIsMainModuleBreakable);
 
     // retrieve all variables that are in the current scope
     typedef std::vector<var_expr_t> VarExprVector;
@@ -2246,7 +2244,7 @@
   // the main module debug iterator has no location otherwise
   // this would take precedence over a child debug iterator
   // starting in the same line
-  wrap_in_debugger_expr(program, program->get_loc(), false);
+  wrap_in_debugger_expr(program, program->get_loc(), true);
 
   program = wrap_in_globalvar_assign(program);
 
@@ -3725,7 +3723,7 @@
       QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),
                                                   initExpr->get_loc());
 
-      wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true);
+      wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
     }
 #endif
 
@@ -3747,7 +3745,7 @@
       QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),
                                                   initExpr->get_loc());
 
-      wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true);
+      wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
     }
 #endif
 

=== modified file 'src/debugger/debugger_client.cpp'
--- src/debugger/debugger_client.cpp	2011-06-14 17:26:33 +0000
+++ src/debugger/debugger_client.cpp	2011-12-13 11:51:46 +0000
@@ -38,5 +38,3 @@
 }
 
 }//end of namespace
-
-/* vim:set et sw=2 ts=2: */

=== modified file 'src/debugger/debugger_clientimpl.cpp'
--- src/debugger/debugger_clientimpl.cpp	2011-07-06 20:43:46 +0000
+++ src/debugger/debugger_clientimpl.cpp	2011-12-13 11:51:46 +0000
@@ -24,462 +24,549 @@
 
 namespace zorba {
   
-  DebuggerClient::~DebuggerClient()
-  {}
-  
-  DebuggerClient* DebuggerClient::createDebuggerClient(DebuggerEventHandler* aHandler,
-                                       unsigned short aPort,
-                                       const std::string& aHost)
-  {
-    return new DebuggerClientImpl(aHost, aPort, aHandler);
-  }
-  
-  DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient)
+DebuggerClient*
+DebuggerClient::createDebuggerClient(
+  DebuggerEventHandler* aHandler,
+  unsigned short aPort,
+  const std::string& aHost)
+{
+  return new DebuggerClientImpl(aHost, aPort, aHandler);
+}
+
+// ****************************************************************************
+
+DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient)
   : theClient(aClient), theStopLooping(false)
-  {
-  }
-  
-  void DebuggerListener::run()
-  {
-    while (!theStopLooping) {
-      std::string str;
-      std::getline(*(theClient->theStream), str, '\0');
-#ifndef NDEBUG
-      std::stringstream lStr(str);
-      std::size_t length;
-      lStr >> length;
-#endif
-      // we are not interested in the length, but only in the init
-      // message
-      std::getline(*(theClient->theStream), str, '\0');
-#ifndef NDEBUG
-      assert(str.size() == length);
-#endif
-      theClient->theHandler->parseMessage(str);
-      this->sleep_(1000);
-    }
-  }
-  
-  void DebuggerListener::finish()
-  {
-  }
-  
-  void DebuggerListener::stopLooping()
-  {
-    theStopLooping = true;
-  }
-  
-  DebuggerClientImpl::DebuggerClientImpl(const std::string& aHost,
-                                         unsigned short aPort,
-                                         DebuggerEventHandler* aHandler)
-  : theServerSocket(aHost, aPort), theSocket(0), theStreamBuffer(0), theStream(0),
-  theHandler(aHandler), theListener(this), theLastId(0)
-  {
-  }
-  
-  void DebuggerClientImpl::accept() {
-    theSocket = theServerSocket.accept();
-    theStreamBuffer = new socket_streambuf(*theSocket);
-    theStream = new std::iostream(theStreamBuffer);
-    theListener.start();
-  }
-  
-  std::size_t DebuggerClientImpl::status()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "status -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::feature_get(std::string const& aFeatureName)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "feature-get -i " << id << " -n " << aFeatureName << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::feature_set(std::string const &aFeatureName,
-                                              std::string const &aValue)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "feature-set -i " << id << " -n " << aFeatureName << " -v "
-               << aValue << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::run()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "run -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::step_into()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "step_into -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::step_over()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "step_over -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::step_out()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "step_out -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::stop()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "stop -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::detach()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "detach -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::breakpoint_set(BreakpointType aType,
-                                                 bool aEnabled,
-                                                 const std::string& aFilename,
-                                                 int aLinenumber,
-                                                 const std::string& aFunctionName,
-                                                 const std::string& aExceptionName,
-                                                 unsigned hit_value,
-                                                 HitCondition aCondition,
-                                                 bool aIsTemporary,
-                                                 const std::string& aExpression)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "breakpoint_set -i " << id
-               << " -t ";
-    switch (aType) {
-      case Line:
-        *theStream << "line";
-        break;
-      case Call:
-        *theStream << "call";
-        break;
-      case Return:
-        *theStream << "return";
-        break;
-      case Exception:
-        *theStream << "exception";
-        break;
-      case Conditional:
-        *theStream << "conditional";
-        break;
-      case Watch:
-        *theStream << "watch";
-        break;
-    }
-    if (!aEnabled)
-      *theStream << " -s disabled";
-    if (aFilename != "") {
-      *theStream << " -f " << aFilename;
-    }
-    if (aLinenumber != -1)
-      *theStream << " -n " << aLinenumber;
-    if (aFunctionName != "")
-      *theStream << " -m " << aFunctionName;
-    if (aExceptionName != "")
-      *theStream << " -x " << aExceptionName;
-    if (hit_value != 0)
-      *theStream << " -h " << hit_value;
-    switch (aCondition) {
-      case BiggerEqual:
-        break;
-      case Equal:
-        *theStream << " -o == ";
-        break;
-      case Multiple:
-        *theStream << " -o % ";
-    }
-    if (aIsTemporary)
-      *theStream << " -r 1 ";
-    if (aExpression != "")
-      *theStream << " -- " << aExpression;
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::breakpoint_update(std::size_t aBreakpointId,
-                                                    bool aEnabled,
-                                                    int aLinenumber,
-                                                    unsigned hit_value,
-                                                    HitCondition aCondition)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "breakpoint_update -i " << id
-               << " -d " << aBreakpointId;
-    if (aEnabled)
-      *theStream << " -s disabled";
-    if (aLinenumber != -1)
-      *theStream << " -n " << aLinenumber;
-    if (hit_value != 0)
-      *theStream << " -h " << hit_value;
-    switch (aCondition) {
-      case BiggerEqual:
-        break;
-      case Equal:
-        *theStream << " -o == ";
-        break;
-      case Multiple:
-        *theStream << " -o % ";
-    }
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::breakpoint_list()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "breakpoint_list -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::stack_depth()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "stack_depth -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::stack_get(int depth)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "stack_depth";
-    if (depth > 0)
-      *theStream << " -d " << depth;
-    *theStream << " -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::context_names(int depth)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "context_names";
-    if (depth > 0)
-      *theStream << " -d " << depth;
-    *theStream << " -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::context_get(int depth, int contextId)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "context_get";
-    if (depth > 0)
-      *theStream << " -d " << depth;
-    if (contextId > 0)
-      *theStream << " -c " << contextId;
-    *theStream << " -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::typemap_get()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "typemap_get -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::property_get(const std::string& aPropertyLongName,
-                                               int aStackDepth,
-                                               int aContextId,
-                                               std::size_t aMaxDataSize,
-                                               int aDatapage,
-                                               const std::string& aPropertyKey)
-  {
-    std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
-    if (aDatapage >= 0)
-      *theStream << " -p " << aDatapage;
-    if (aPropertyKey != "")
-      *theStream << " -k " << aPropertyKey;
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::property_set(const std::string& aPropertyLongName,
-                                               int aStackDepth,
-                                               int aContextId,
-                                               std::size_t aMaxDataSize,
-                                               const std::string& aPropertyAddress)
-  {
-    std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
-    if (aPropertyAddress != "")
-      *theStream << " -a " << aPropertyAddress;
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::property_value(const std::string& aPropertyLongName,
-                                                 int aStackDepth,
-                                                 int aContextId,
-                                                 std::size_t aMaxDataSize,
-                                                 int aDatapage,
-                                                 const std::string& aPropertyKey,
-                                                 const std::string& aPropertyAddress)
-  {
-    std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
-    if (aDatapage >= 0)
-      *theStream << " -p " << aDatapage;
-    if (aPropertyKey != "")
-      *theStream << " -k " << aPropertyKey;
-    if (aPropertyAddress != "")
-      *theStream << " -a " << aPropertyAddress;
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::property_x(const std::string& aCommand,
-                                             const std::string& aPropertyLongName,
-                                             int aStackDepth,
-                                             int aContextId,
-                                             std::size_t aMaxDataSize)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << aCommand << " -i " << id << " -n " << aPropertyLongName;
-    if (aStackDepth > 0)
-      *theStream << " -d " << aStackDepth;
-    if (aContextId > 0)
-      *theStream << " -c " << aContextId;
-    if (aMaxDataSize > 0)
-      *theStream << " -m " << aMaxDataSize;
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::source(std::string const &aFile,
-                                         unsigned int aBeginLine,
-                                         unsigned int aEndLine)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "source -i " << id << " -f " << aFile;
-    if (aBeginLine)
-      *theStream << " -b " << aBeginLine;
-    if (aEndLine)
-      *theStream << " -e " << aEndLine;
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour)
-  {
-    std::size_t id = ++theLastId;
-    switch (aStream) {
-      case Stdout:
-        *theStream << "stdout";
-        break;
-      case Stderr:
-        *theStream << "stderr";
-        break;
-      case Stdin:
-        *theStream << "stdin";
-        break;
-    }
-    *theStream << " -i " << id << " -c ";
-    switch (aBehaviour) {
-      case Disable:
-        *theStream << "0";
-        break;
-      case CopyData:
-        *theStream << "1";
-        break;
-      case Redirection:
-        *theStream << "2";
-        break;
-    }
-    *theStream << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::do_break()
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "break -i " << id << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  std::size_t DebuggerClientImpl::eval(std::string const &aExpr)
-  {
-    std::size_t id = ++theLastId;
-    *theStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0';
-    theStream->sync();
-    return id;
-  }
-  
-  void DebuggerClientImpl::quit() {
-    theListener.stopLooping();
-    theListener.join();
-  }
-  
-  
-  
-  DebuggerClientImpl::~DebuggerClientImpl()
-  {
-    if (theListener.status() == DebuggerListener::RUNNING) {
-      theListener.stopLooping();
-      theListener.join();
-    }
-    if (theSocket) {
-      theSocket->close();
-      theSocket->cleanUp();
-      delete theSocket;
-    }
-    if (theStream) {
-      theStream->sync();
-      delete theStream;
-      delete theStreamBuffer;
-    }
-  }
-}
+{
+}
+
+void
+DebuggerListener::run()
+{
+  while (!theStopLooping) {
+    std::string str;
+    std::getline(*(theClient->theInStream), str, '\0');
+
+#ifndef NDEBUG
+    std::stringstream lStr(str);
+    std::size_t length;
+    lStr >> length;
+#endif
+
+    // we are not interested in the length, but only in the init message
+    std::getline(*(theClient->theInStream), str, '\0');
+
+#ifndef NDEBUG
+    assert(str.size() == length);
+#endif
+
+    theClient->theHandler->parseMessage(str);
+
+    // TODO: this was the initial implementation. This will have to change
+    this->sleep_(1000);
+  }
+}
+  
+void
+DebuggerListener::finish()
+{
+}
+
+void
+DebuggerListener::stopLooping()
+{
+  theStopLooping = true;
+}
+
+// ****************************************************************************
+
+DebuggerClient::~DebuggerClient()
+{
+}
+
+DebuggerClientImpl::DebuggerClientImpl(
+  const std::string& aHost,
+  unsigned short aPort,
+  DebuggerEventHandler* aHandler)
+  : theServerSocket(aHost, aPort),
+    theSocket(0),
+    theInStreamBuffer(0),
+    theOutStreamBuffer(0),
+    theInStream(0),
+    theOutStream(0),
+    theHandler(aHandler),
+    theListener(0),
+    theLastId(0)
+{
+}
+
+DebuggerClientImpl::~DebuggerClientImpl()
+{
+  if (theListener) {
+    if (theListener->status() == DebuggerListener::RUNNING) {
+      theListener->stopLooping();
+      theListener->join();
+    }
+    delete theListener;
+  }
+  if (theSocket) {
+    theInStream->sync();
+    delete theInStream;
+
+    theOutStream->flush();
+    delete theInStream;
+
+    delete theOutStreamBuffer;
+    delete theInStreamBuffer;
+
+    theSocket->close();
+    theSocket->cleanUp();
+    delete theSocket;
+  }
+}
+  
+void
+DebuggerClientImpl::accept()
+{
+  theListener = new DebuggerListener(this);
+  theSocket = theServerSocket.accept();
+  theInStreamBuffer = new SocketStreambuf(*theSocket);
+  theOutStreamBuffer = new SocketStreambuf(*theSocket);
+  theInStream = new std::istream(theInStreamBuffer);
+  theOutStream = new std::ostream(theOutStreamBuffer);
+  theListener->start();
+}
+  
+std::size_t
+DebuggerClientImpl::status()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "status -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::variables()
+{
+  // we hack the protocol to return all properties if the context ID is -1
+  std::size_t id = ++theLastId;
+  *theOutStream << "context_get -c -1 -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::feature_get(std::string const& aFeatureName)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "feature_get -i " << id << " -n " << aFeatureName << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::feature_set(std::string const &aFeatureName,
+                                            std::string const &aValue)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "feature_set -i " << id << " -n " << aFeatureName << " -v "
+              << aValue << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::run()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "run -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::step_into()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "step_into -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::step_over()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "step_over -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::step_out()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "step_out -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::stop()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "stop -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::detach()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "detach -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+
+std::size_t
+DebuggerClientImpl::breakpoint_set(
+  BreakpointType aType,
+  bool aEnabled,
+  const std::string& aFilename,
+  int aLinenumber,
+  const std::string& aFunctionName,
+  const std::string& aExceptionName,
+  unsigned hit_value,
+  HitCondition aCondition,
+  bool aIsTemporary,
+  const std::string& aExpression)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "breakpoint_set -i " << id
+              << " -t ";
+  switch (aType) {
+    case Line:
+      *theOutStream << "line";
+      break;
+    case Call:
+      *theOutStream << "call";
+      break;
+    case Return:
+      *theOutStream << "return";
+      break;
+    case Exception:
+      *theOutStream << "exception";
+      break;
+    case Conditional:
+      *theOutStream << "conditional";
+      break;
+    case Watch:
+      *theOutStream << "watch";
+      break;
+  }
+  if (!aEnabled)
+    *theOutStream << " -s disabled";
+  if (aFilename != "") {
+    *theOutStream << " -f \"" << aFilename << "\"";
+  }
+  if (aLinenumber != -1)
+    *theOutStream << " -n " << aLinenumber;
+  if (aFunctionName != "")
+    *theOutStream << " -m " << aFunctionName;
+  if (aExceptionName != "")
+    *theOutStream << " -x " << aExceptionName;
+  if (hit_value != 0)
+    *theOutStream << " -h " << hit_value;
+  switch (aCondition) {
+    case BiggerEqual:
+      break;
+    case Equal:
+      *theOutStream << " -o == ";
+      break;
+    case Multiple:
+      *theOutStream << " -o % ";
+  }
+  if (aIsTemporary)
+    *theOutStream << " -r 1 ";
+  if (aExpression != "")
+    *theOutStream << " -- " << aExpression;
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::breakpoint_update(
+  std::size_t aBreakpointId,
+  bool aEnabled,
+  int aLinenumber,
+  unsigned hit_value,
+  HitCondition aCondition)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "breakpoint_update -i " << id
+              << " -d " << aBreakpointId;
+  if (aEnabled)
+    *theOutStream << " -s disabled";
+  if (aLinenumber != -1)
+    *theOutStream << " -n " << aLinenumber;
+  if (hit_value != 0)
+    *theOutStream << " -h " << hit_value;
+  switch (aCondition) {
+    case BiggerEqual:
+      break;
+    case Equal:
+      *theOutStream << " -o == ";
+      break;
+    case Multiple:
+      *theOutStream << " -o % ";
+  }
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::breakpoint_list()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "breakpoint_list -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::stack_depth()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "stack_depth -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::stack_get(int depth)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "stack_get";
+  if (depth >= 0) {
+    *theOutStream << " -d " << depth;
+  }
+  *theOutStream << " -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::context_names(int depth)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "context_names";
+  if (depth >= 0) {
+    *theOutStream << " -d " << depth;
+  }
+  *theOutStream << " -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+
+std::size_t
+DebuggerClientImpl::context_get(int depth, int contextId)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "context_get";
+  if (depth >= 0) {
+    *theOutStream << " -d " << depth;
+  }
+  if (contextId >= 0){
+    *theOutStream << " -c " << contextId;
+  }
+  *theOutStream << " -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+
+std::size_t
+DebuggerClientImpl::typemap_get()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "typemap_get -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::property_get(
+  const std::string& aPropertyLongName,
+  int aStackDepth,
+  int aContextId,
+  std::size_t aMaxDataSize,
+  int aDatapage,
+  const std::string& aPropertyKey)
+{
+  std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
+  if (aDatapage >= 0)
+    *theOutStream << " -p " << aDatapage;
+  if (aPropertyKey != "")
+    *theOutStream << " -k " << aPropertyKey;
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::property_set(
+  const std::string& aPropertyLongName,
+  int aStackDepth,
+  int aContextId,
+  std::size_t aMaxDataSize,
+  const std::string& aPropertyAddress)
+{
+  std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
+  if (aPropertyAddress != "")
+    *theOutStream << " -a " << aPropertyAddress;
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::property_value(
+  const std::string& aPropertyLongName,
+  int aStackDepth,
+  int aContextId,
+  std::size_t aMaxDataSize,
+  int aDatapage,
+  const std::string& aPropertyKey,
+  const std::string& aPropertyAddress)
+{
+  std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
+  if (aDatapage >= 0)
+    *theOutStream << " -p " << aDatapage;
+  if (aPropertyKey != "")
+    *theOutStream << " -k " << aPropertyKey;
+  if (aPropertyAddress != "")
+    *theOutStream << " -a " << aPropertyAddress;
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::property_x(
+  const std::string& aCommand,
+  const std::string& aPropertyLongName,
+  int aStackDepth,
+  int aContextId,
+  std::size_t aMaxDataSize)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << aCommand << " -i " << id << " -n " << aPropertyLongName;
+  if (aStackDepth > 0)
+    *theOutStream << " -d " << aStackDepth;
+  if (aContextId > 0)
+    *theOutStream << " -c " << aContextId;
+  if (aMaxDataSize > 0)
+    *theOutStream << " -m " << aMaxDataSize;
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::source(
+  std::string const &aFile,
+  unsigned int aBeginLine,
+  unsigned int aEndLine)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "source -i " << id;
+  // enable zorba extensions
+  *theOutStream << " -z 1";
+  *theOutStream << " -f \"" << aFile << "\"";
+  if (aBeginLine)
+    *theOutStream << " -b " << aBeginLine;
+  if (aEndLine)
+    *theOutStream << " -e " << aEndLine;
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour)
+{
+  std::size_t id = ++theLastId;
+  switch (aStream) {
+    case Stdout:
+      *theOutStream << "stdout";
+      break;
+    case Stderr:
+      *theOutStream << "stderr";
+      break;
+    case Stdin:
+      *theOutStream << "stdin";
+      break;
+  }
+  *theOutStream << " -i " << id << " -c ";
+  switch (aBehaviour) {
+    case Disable:
+      *theOutStream << "0";
+      break;
+    case CopyData:
+      *theOutStream << "1";
+      break;
+    case Redirection:
+      *theOutStream << "2";
+      break;
+  }
+  *theOutStream << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::do_break()
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "break -i " << id << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+std::size_t
+DebuggerClientImpl::eval(std::string const &aExpr)
+{
+  std::size_t id = ++theLastId;
+  *theOutStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0';
+  theOutStream->flush();
+  return id;
+}
+  
+void
+DebuggerClientImpl::quit()
+{
+  theListener->stopLooping();
+  theListener->join();
+}
+
+} // namespace zorba

=== modified file 'src/debugger/debugger_clientimpl.h'
--- src/debugger/debugger_clientimpl.h	2011-07-01 01:53:24 +0000
+++ src/debugger/debugger_clientimpl.h	2011-12-13 11:51:46 +0000
@@ -13,7 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#pragma once
+#ifndef ZORBA_DEBUGGER_CLIENTIMPL_H
+#define ZORBA_DEBUGGER_CLIENTIMPL_H
 
 #include <string>
 #include <zorba/debugger_client.h>
@@ -21,7 +22,7 @@
 #include "zorbautils/runnable.h"
 
 namespace zorba {
-  class socket_streambuf;
+  class SocketStreambuf;
   class DebuggerEventHandler;
   class DebuggerListener;
   class DebuggerClientImpl;
@@ -48,6 +49,7 @@
   public: // API
     virtual void accept();
     virtual std::size_t status();
+    virtual std::size_t variables();
     virtual std::size_t feature_get(const std::string& aFeatureName);
     virtual std::size_t feature_set(const std::string& aFeatureName,
                                     const std::string& aValue);
@@ -110,12 +112,17 @@
                            int aContextId = -1,
                            std::size_t aMaxDataSize = 0);
   private:
-    TCPServerSocket theServerSocket;
-    TCPSocket* theSocket;
-    socket_streambuf* theStreamBuffer;
-    std::iostream* theStream;
+    TCPServerSocket       theServerSocket;
+    TCPSocket*            theSocket;
+    SocketStreambuf*      theInStreamBuffer;
+    SocketStreambuf*      theOutStreamBuffer;
+    std::istream*         theInStream;
+    std::ostream*         theOutStream;
     DebuggerEventHandler* theHandler;
-    DebuggerListener theListener;
-    std::size_t theLastId;
+    DebuggerListener*     theListener;
+    std::size_t           theLastId;
   };
-}
+
+} // namespace zorba
+
+#endif // ZORBA_DEBUGGER_CLIENTIMPL_H

=== modified file 'src/debugger/debugger_common.h'
--- src/debugger/debugger_common.h	2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_common.h	2011-12-13 11:51:46 +0000
@@ -20,22 +20,15 @@
 #include "common/common.h"
 
 /* Type definitions */
-typedef unsigned char StepCommand;
 typedef unsigned char ExecutionStatus;
 typedef unsigned short SuspensionCause;
 
-/* Kind of step command */
-const StepCommand STEP_INTO   = 0x01;
-const StepCommand STEP_OUT    = 0x02;
-const StepCommand STEP_OVER   = 0x03;
-
 /* Status of the engine */
 const ExecutionStatus QUERY_IDLE       = 0x01;
 const ExecutionStatus QUERY_RUNNING    = 0x02;
-const ExecutionStatus QUERY_RESUMED    = 0x03;
-const ExecutionStatus QUERY_SUSPENDED  = 0x04;
-const ExecutionStatus QUERY_TERMINATED = 0x05;
-const ExecutionStatus QUERY_DETACHED   = 0x06;
+const ExecutionStatus QUERY_SUSPENDED  = 0x03;
+const ExecutionStatus QUERY_TERMINATED = 0x04;
+const ExecutionStatus QUERY_DETACHED   = 0x05;
 
 /* Cause of the suspension of the engine */
 const SuspensionCause CAUSE_USER               = 0x01;

=== modified file 'src/debugger/debugger_commons.cpp'
--- src/debugger/debugger_commons.cpp	2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_commons.cpp	2011-12-13 11:51:46 +0000
@@ -151,13 +151,11 @@
     theBreakCondition(0),
     theExecEval(false),
     theStepping(false)
-    
 {
   theRuntime = NULL;
   theCurrentStaticContext = NULL;
   theCurrentDynamicContext = NULL;
   thePlanState = NULL;
-  theDebugIteratorState = NULL;
 }
 
 DebuggerCommons::~DebuggerCommons()
@@ -185,8 +183,6 @@
 
   if(ar.is_serializing_out())
     thePlanState = NULL;
-  if(ar.is_serializing_out())
-    theDebugIteratorState = NULL;
   ar & theEvalItem;
   ar & theExecEval;
   ar & theStepping;
@@ -230,17 +226,98 @@
 }
 
 unsigned int
-DebuggerCommons::addBreakpoint(const QueryLoc& aLocation, bool aEnabled)
+DebuggerCommons::addBreakpoint(String& aFileName, int aLine, bool aEnabled)
 {
-  BreakableIdMap::iterator lIter = theBreakableIDs.find(aLocation);
+  QueryLoc lLocation;
+  lLocation.setLineBegin(aLine);
+  lLocation.setLineEnd(aLine);
+  lLocation.setFilename(aFileName.c_str());
+
+  // we make sure that the this location file name is aligned with the internal ones
+  // it must have a valid URI and a scheme (file://, http://, or https://)
+  adjustLocationFilePath(lLocation);
+
+  BreakableIdMap::iterator lIter = theBreakableIDs.find(lLocation);
+  unsigned int lId;
 
   if (lIter == theBreakableIDs.end()) {
+    String lFileName = aFileName;
+    // be prepared to throw an exception
     std::stringstream lSs;
-    lSs << "The breakpoint could not be set at line " << aLocation.getLineBegin()
-      << " in file: " << aLocation.getFilename();
-    throw lSs.str();
-  }
-  unsigned int lId = lIter->second;
+    lSs << "The breakpoint could not be set at line " << aLine
+      << " in file \"" << lFileName << "\"";
+
+    // let us then try some search before we fail, be good to the user and help him
+    // 1. first we check if he sent a file URI; in this case, sorry!
+    if (lFileName.find("file://") == 0) {
+      throw lSs.str();
+    }
+
+    // now we have to normalize if we hope to find something
+    lFileName = URIHelper::encodeFileURI(lFileName).str();
+    // remove the added file schema prefix
+    // TODO: maybe there is a better way to do this encoding
+    lFileName = lFileName.substr(8);
+
+    // 2. secondly we hope he gave us part of a path of a file
+    lIter = theBreakableIDs.begin();
+    String::size_type lFileNameSize = lFileName.size();
+    std::vector<std::pair<QueryLoc, int> > lFoundBreakables;
+    zorba::String lFirstBreakablePath;
+    while (lIter != theBreakableIDs.end()) {
+      // for now, only valid if on the breakable is on the same line as requested
+      // TODO: this could be improved if the user wants to add a breakpoint to a line
+      //       INSIDE a breakable that spans over multiple lines
+      if (lIter->second != theMainModuleBreakableId && lIter->first.getLineBegin() == aLine) {
+        zorba::String lBreakablePath = lIter->first.getFilename().str();
+
+        // dies the given string matche any part in the breakable file name?
+        if (lBreakablePath.find(lFileName) != String::npos) {
+          // we found the fist candidate path
+          if (lFirstBreakablePath == "") {
+            lFirstBreakablePath = lBreakablePath;
+          }
+          // but stop as soon as we are reaching a second different path (report ambiguity)
+          else if (lFirstBreakablePath != lBreakablePath){
+            lSs.str("");
+            lSs << "The file name \"" << aFileName << "\" is ambiguous. "
+              << "I already found two potential files to set a breakpoint in line " << aLine
+              << ":" << std::endl << "  " << lFirstBreakablePath << std::endl << "  " << lBreakablePath;
+            throw lSs.str();
+          }
+
+          // Yes! We found one!
+          lFoundBreakables.push_back(std::pair<QueryLoc, int>(lIter->first, lIter->second));
+        }
+      }
+      lIter++;
+    }
+
+    // what should I say, not a very successful search :(
+    if (lFoundBreakables.size() == 0) {
+      throw lSs.str();
+    }
+
+    // TODO: The best solution would be for the debugger to enable all the
+    // matched breakables but the protocol can send back only one ID of the
+    // breakpoint set.
+
+    // so we have multiple breakables, get the first in line
+    // TODO: this does not catch multiple breakables starting in the same line
+    // so only one will be picked (depending how the translator generated them)
+    unsigned int lMinCol = lFoundBreakables.at(0).first.getColumnBegin();
+    lId = lFoundBreakables.at(0).second;
+    for (std::size_t i = 1; i < lFoundBreakables.size(); i++) {
+      if (lMinCol > lFoundBreakables.at(i).first.getColumnBegin()) {
+        lId = lFoundBreakables.at(i).second;
+      }
+    }
+  }
+  else {
+    lId = lIter->second;
+  }
+
+  // now we have a breakable, so set it accordingly
   theBreakables[lId].setSet(true);
   theBreakables[lId].setEnabled(aEnabled);
   return lId;
@@ -253,6 +330,12 @@
   return theBreakables[aId];
 }
 
+BreakableVector
+DebuggerCommons::getBreakpoints()
+{
+  return theBreakables;
+}
+
 void
 DebuggerCommons::checkBreakpoint(unsigned int aId)
 {
@@ -338,6 +421,7 @@
 bool
 DebuggerCommons::hasToBreakAt(QueryLoc aLocation)
 {
+  // we make sure that this location file name is a valid URI and has a scheme (file://, http://, or https://)
   adjustLocationFilePath(aLocation);
 
   BreakableIdMap::const_iterator lIter = theBreakableIDs.find(aLocation);
@@ -449,14 +533,6 @@
   ZORBA_ASSERT(thePlanState == aPlanState);
 }
 
-void
-DebuggerCommons::setDebugIteratorState(DebugIteratorState* aState)
-{
-  theDebugIteratorState = aState;
-  //Check postconditions
-  ZORBA_ASSERT(theDebugIteratorState == aState);
-}
-
 std::list<std::pair<zstring, zstring> >
 DebuggerCommons::eval(const zstring& aExpr, Zorba_SerializerOptions& aSerOpts)
 {
@@ -511,11 +587,17 @@
 }
 
 void
-DebuggerCommons::addBreakable(Breakable& aBreakable)
+DebuggerCommons::addBreakable(
+  Breakable& aBreakable,
+  bool aIsMainModuleBreakable)
 {
+  // we make sure that this breakable file name is a valid URI and has a scheme (file://, http://, or https://)
   adjustLocationFilePath(aBreakable.getLocation());
 
   unsigned int lId = theBreakables.size();
+  if (aIsMainModuleBreakable) {
+    theMainModuleBreakableId = lId;
+  }
   theBreakables.push_back(aBreakable);
   theBreakableIDs[aBreakable.getLocation()] = lId;
 }
@@ -523,6 +605,9 @@
 void
 DebuggerCommons::pushStackFrame(QueryLoc aLocation, std::string& aFunctionName)
 {
+  // we make sure that the stack frame locations always have valid URIs and a scheme (file://, http://, or https://)
+  adjustLocationFilePath(aLocation);
+
   theStackTrace.push_back(std::pair<QueryLoc, std::string>(aLocation, aFunctionName));
 }
 
@@ -541,11 +626,24 @@
 void
 DebuggerCommons::adjustLocationFilePath(QueryLoc& aLocation)
 {
-  if (aLocation.getFilename().substr(0, 7) == "file://") {
-    // adjust the file paths by removing the schema and encoding
-    zstring lOldFilename(aLocation.getFilename());
+  zstring lOldFilename(aLocation.getFilename());
+  zstring lPrefix = lOldFilename.substr(0, 7);
+
+  if (lPrefix == "file://") {
+#ifdef WIN32
+    // decode and encode back to solve the driver column encoding: C:, D:, etc.
     const String lNewFilename = URIHelper::decodeFileURI(lOldFilename.str());
-    aLocation.setFilename(lNewFilename.str());
+    const String lNewURI = URIHelper::encodeFileURI(lNewFilename);
+    aLocation.setFilename(lNewURI.str());
+#endif
+    return;
+  }
+
+  // just encode and assume file for non-URI locations
+  if (lPrefix != "http://"; && lPrefix != "https:/") {
+    const String lNewURI = URIHelper::encodeFileURI(lOldFilename.str());
+    aLocation.setFilename(lNewURI.str());
+    return;
   }
 }
 

=== modified file 'src/debugger/debugger_commons.h'
--- src/debugger/debugger_commons.h	2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_commons.h	2011-12-13 11:51:46 +0000
@@ -19,14 +19,17 @@
 #include <map>
 #include <string>
 
+#include <zorba/util/uri.h>
+#include <zorba/zorba_string.h>
+
 #include "compiler/parser/query_loc.h"
 #include "runtime/core/item_iterator.h"
 
 #include "zorbaserialization/serialization_engine.h"
 #include "zorbatypes/zstring.h"
 
-#include "debugger/debugger_common.h"
-#include "debugger/query_locationimpl.h"
+#include "debugger_common.h"
+#include "query_locationimpl.h"
 
 
 struct Zorba_SerializerOptions;
@@ -208,16 +211,6 @@
     void setPlanState(PlanState* aPlanState);
 
     /**
-    * @brief Sets the current debugger state.
-    *
-    * When the debugger suspends, it saves its state.
-    *
-    * @param aState a pointer to the current debugger state.
-    * @post aState == theDebugIteratorState
-    */
-    void setDebugIteratorState(DebugIteratorState* aState);
-
-    /**
     * @brief Sets a setpoint according to the step out rules.
     *
     * This method sets a breakpoint according to the rules according to
@@ -245,11 +238,14 @@
   public:
 
     unsigned int
-    addBreakpoint(const QueryLoc& location, bool enabled);
+    addBreakpoint(String& fileName, int line, bool enabled);
 
     Breakable
     getBreakpoint(unsigned int id);
 
+    BreakableVector
+    getBreakpoints();
+
     void
     updateBreakpoint(unsigned int id, bool enabled);
 
@@ -336,7 +332,7 @@
     std::string getFilepathOfURI(const std::string& aUri) const;
 
     void
-    addBreakable(Breakable& location);
+    addBreakable(Breakable& location, bool isMainModuleBreakable = false);
 
     void
     pushStackFrame(QueryLoc location, std::string& functionName);
@@ -384,10 +380,10 @@
     std::vector<DebugIterator*>                     theIteratorStack;
     std::size_t                                     theBreakCondition;
     PlanState*                                      thePlanState;
-    DebugIteratorState*                             theDebugIteratorState;
     store::Item_t                                   theEvalItem;
     bool                                            theExecEval;
     bool                                            theStepping;
+    unsigned int                                    theMainModuleBreakableId;
   };
 
 }

=== modified file 'src/debugger/debugger_communicator.cpp'
--- src/debugger/debugger_communicator.cpp	2011-07-29 23:01:30 +0000
+++ src/debugger/debugger_communicator.cpp	2011-12-13 11:51:46 +0000
@@ -77,15 +77,15 @@
 void
 DebuggerCommunicator::connect()
 {
-	for (int i = 0; i < 3 && !theSocket; i++)
+	for (int i = 0; i < 5 && !theSocket; i++)
   {
 		try
     {
 			// Connect to the client on the given host and port
       std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort));
       theSocket = lSocket.release();
-      theSocketInStream = new socket_streambuf(*theSocket);
-      theSocketOutStream = new socket_streambuf(*theSocket);
+      theSocketInStream = new SocketStreambuf(*theSocket);
+      theSocketOutStream = new SocketStreambuf(*theSocket);
       theCommunicatorInStream = new std::istream(theSocketInStream);
       theCommunicatorOutStream = new std::ostream(theSocketOutStream);
       theResponseQueue = new ResponseQueue(theCommunicatorOutStream);

=== modified file 'src/debugger/debugger_communicator.h'
--- src/debugger/debugger_communicator.h	2011-07-01 16:07:54 +0000
+++ src/debugger/debugger_communicator.h	2011-12-13 11:51:46 +0000
@@ -28,7 +28,7 @@
 namespace zorba {
 
 class TCPSocket;
-class socket_streambuf;
+class SocketStreambuf;
 
 class DebuggerCommunicator {
 
@@ -96,13 +96,13 @@
     
 
     TCPSocket*        theSocket;
-    socket_streambuf* theSocketInStream;
-    socket_streambuf* theSocketOutStream;
+    SocketStreambuf*  theSocketInStream;
+    SocketStreambuf*  theSocketOutStream;
     std::istream*     theCommunicatorInStream;
     std::ostream*     theCommunicatorOutStream;
     ResponseQueue*    theResponseQueue;
 };
 
-}//end of namespace
+} //namespace zorba
 
 #endif // ZORBA_DEBUGGER_COMMUNICATOR_H

=== modified file 'src/debugger/debugger_protocol.cpp'
--- src/debugger/debugger_protocol.cpp	2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_protocol.cpp	2011-12-13 11:51:46 +0000
@@ -28,25 +28,17 @@
 DebuggerCommand::DebuggerCommand(std::string& aCommand)
   : theData()
 {
+  // this implements the DBGP command specification:
+  // http://xdebug.org/docs-dbgp.php#ide-to-debugger-engine-communications
+
+  // the debugger client should only send space delimited command
+  // and arguments, therefore we only check for space character
   std::size_t lNameEnd = aCommand.find(" ");
+
+  // first whitespace delimited token is the command name
   theName = aCommand.substr(0, lNameEnd);
-  std::size_t lDataBegin = aCommand.find("--", lNameEnd);
-  std::string lArgs = aCommand.substr(lNameEnd + 1, lDataBegin);
 
-  if (lDataBegin != std::string::npos) {
-    lDataBegin += 2;
-    while (lDataBegin < aCommand.size()) {
-      switch (aCommand.at(lDataBegin)) {
-      case ' ':
-      case '\t':
-        ++lDataBegin;
-        continue;
-      default:
-        theData = aCommand.substr(lDataBegin);
-        lDataBegin = aCommand.size();
-      }
-    }
-  }
+  std::string lArgs = aCommand.substr(lNameEnd + 1);
 
   bool lFollowsArg = true;
   bool lInArgName = false;
@@ -74,6 +66,26 @@
           lInArgName = true;
           continue;
         }
+        // we found the encoded data in this message
+        if (lArgName.str() == "") {
+          // DBGP is fuzzy here: can there be whitespaces between "--" and the encoded data?
+          // so, tollerate the whitespaces before data starts
+          std::string::size_type lDataBegin = i + 1;
+          while (++i < lArgs.size()) {
+            switch (lArgs.at(i)) {
+            case ' ':
+            case '\t':
+              continue;
+            default:
+              lDataBegin = i;
+              // force the while to terminate
+              i = lArgs.size();
+            }
+          }
+
+          theData = lArgs.substr(lDataBegin);
+        }
+
       default:
         if (!lInArgName) {
           throw "error reading command";

=== modified file 'src/debugger/debugger_runtime.cpp'
--- src/debugger/debugger_runtime.cpp	2011-08-03 02:26:53 +0000
+++ src/debugger/debugger_runtime.cpp	2011-12-13 11:51:46 +0000
@@ -21,6 +21,7 @@
 #include <memory>
 #include <vector>
 #include <sstream>
+#include <iomanip>
 #include <fstream>
 
 #include <zorba/util/uri.h>
@@ -70,7 +71,8 @@
     thePlanIsOpen(false),
     theSerializer(0),
     theItemHandler(aHandler),
-    theCallbackData(aCallBackData)
+    theCallbackData(aCallBackData),
+    theLastContinuationCommand()
 {
 }
 
@@ -122,7 +124,7 @@
 DebuggerRuntime::runQuery()
 {
   theLock.wlock();
-  theExecStatus = theExecStatus == QUERY_SUSPENDED ? QUERY_RESUMED : QUERY_RUNNING;
+  theExecStatus = QUERY_RUNNING;
 
   try {
     DebuggerCommons* lCommons = getDebbugerCommons();
@@ -144,33 +146,23 @@
     theOStream.flush();
   } catch (FlowCtlException&) {
     // Runtime correctly terminated by user interrupt
-  } catch (ZorbaException const& e){
-    // this does not rethrow but only print the error message
-    ZorbaImpl::notifyError(theQuery->theDiagnosticHandler, e);
+  } catch (ZorbaException const& e) {
+    std::cerr << e << std::endl;
   }
   theLock.wlock();
   theExecStatus = QUERY_TERMINATED;
   theLock.unlock();
 }
 
-
-void
-DebuggerRuntime::setQueryRunning()
-{
-  AutoLock lLock(theLock, Lock::WRITE);
-  assert(theExecStatus == QUERY_RESUMED);
-  theExecStatus = QUERY_RUNNING;
-}
-
 // ****************************************************************************
 // Breakpoints
 
 unsigned int
-DebuggerRuntime::addBreakpoint(const QueryLoc& aLocation, bool aEnabled)
+DebuggerRuntime::addBreakpoint(String& aFileName, int aLine, bool aEnabled)
 {
   AutoLock lLock(theLock, Lock::WRITE);
   DebuggerCommons* lCommons = getDebbugerCommons();
-  return lCommons->addBreakpoint(aLocation, aEnabled);
+  return lCommons->addBreakpoint(aFileName, aLine, aEnabled);
 }
 
 Breakable
@@ -181,6 +173,13 @@
   return lCommons->getBreakpoint(aId);
 }
 
+BreakableVector
+DebuggerRuntime::getBreakpoints()
+{
+  AutoLock lLock(theLock, Lock::WRITE);
+  return getDebbugerCommons()->getBreakpoints();
+}
+
 void
 DebuggerRuntime::updateBreakpoint(
   unsigned int aId,
@@ -219,6 +218,12 @@
 std::vector<StackFrameImpl>
 DebuggerRuntime::getStackFrames()
 {
+  // this is only working while execution is suspended
+  if (theExecStatus != QUERY_SUSPENDED) {
+    std::string lMessage("I can only show a stack if the execution is suspended.");
+    throw lMessage;
+  }
+
   std::vector<StackFrameImpl> lFrames;
 
   DebuggerCommons* lCommons = getDebbugerCommons();
@@ -230,10 +235,8 @@
   // add the frames for each function call
   for (std::size_t i = 0 ; i < lRawFrames.size(); i++) {
     lLocation = lRawFrames.at(i).first;
-
     StackFrameImpl lFrame(lSignature, lLocation);
     lFrames.push_back(lFrame);
-
     lSignature = lRawFrames.at(i).second;
   }
 
@@ -256,9 +259,35 @@
   theExecStatus = QUERY_SUSPENDED;
 
   std::stringstream lResponse;
-  lResponse << "<response command=\"" << "" << "\" transaction_id=\"" << theLastContinuationTransactionID << "\" ";
-  lResponse << "reason=\"ok\" status=\"break\" ";
-  lResponse << "/>";
+  lResponse << "<response "
+    << "command=\"" << theLastContinuationCommand.second << "\" "
+    << "transaction_id=\"" << theLastContinuationCommand.first << "\" "
+    << "reason=\"ok\" status=\"break\" "
+    << ">";
+
+  // if available, show the location where the execution is suspended
+  // this should be the top-most stack frame
+  std::vector<StackFrameImpl> lFrames = getStackFrames();
+  if (lFrames.size() > 0) {
+    // wrap in CDATA because xml elements might come along
+    lResponse << "<![CDATA[";
+
+    StackFrameImpl lFrame = lFrames[lFrames.size() - 1];
+    unsigned int lBeginLine = lFrame.getLocation().getLineBegin();
+    unsigned int lEndLine = lFrame.getLocation().getLineEnd();
+    String lFileName = lFrame.getLocation().getFileName();
+    lResponse  << lFrame.getSignature()
+      << " at " << lFileName
+      << ":" << lBeginLine;
+
+    // show also the current line
+    lResponse << std::endl << std::endl;
+    lResponse << listSource(lFileName, lBeginLine, lEndLine, true);
+
+    lResponse << "]]>";
+  }
+
+  lResponse << "</response>";
   theCommunicator->send(lResponse.str());
 
   theLock.unlock();
@@ -267,9 +296,24 @@
 
 
 void
+DebuggerRuntime::startRuntime()
+{
+  AutoLock lLock(theLock, Lock::WRITE);
+  if (theExecStatus == QUERY_RUNNING) {
+    return;
+  }
+  theExecStatus = QUERY_RUNNING;
+  start();
+}
+
+
+void
 DebuggerRuntime::resumeRuntime()
 {
   AutoLock lLock(theLock, Lock::WRITE);
+  if (theExecStatus != QUERY_SUSPENDED) {
+    return;
+  }
   theExecStatus = QUERY_RUNNING;
   resume();
 }
@@ -282,10 +326,10 @@
   theExecStatus = QUERY_TERMINATED;
 
   std::stringstream lResult;
-  lResult << "<response command=\"stop\" "
+  lResult << "<response command=\"" << theLastContinuationCommand.second << "\" "
     << "status=\"stopping\" "
     << "reason=\"ok\" "
-    << "transaction_id=\"" << theLastContinuationTransactionID << "\">"
+    << "transaction_id=\"" << theLastContinuationCommand.first << "\">"
     << "</response>";
   theCommunicator->send(lResult.str());
   // TODO: something more here?
@@ -302,6 +346,30 @@
 
 
 std::vector<std::pair<std::string, std::string> >
+DebuggerRuntime::getVariables()
+{
+  std::vector<std::pair<std::string, std::string> > lVarResult;
+
+  std::vector<std::pair<std::string, std::string> > lVarTmp;
+  std::vector<std::pair<std::string, std::string> >::iterator lIter;
+
+  // get the locals and add them to result
+  lVarTmp = getVariables(true);
+  for (lIter = lVarTmp.begin(); lIter != lVarTmp.end(); lIter++) {
+    lVarResult.push_back(*lIter);
+  }
+
+  // get the globals and add them to result
+  lVarTmp = getVariables(false);
+  for (lIter = lVarTmp.begin(); lIter != lVarTmp.end(); lIter++) {
+    lVarResult.push_back(*lIter);
+  }
+
+  return lVarResult;
+};
+
+
+std::vector<std::pair<std::string, std::string> >
 DebuggerRuntime::getVariables(bool aLocals)
 {
   DebuggerCommons* lCommons = getDebbugerCommons();
@@ -392,26 +460,46 @@
 
 
 void
-DebuggerRuntime::step(StepCommand aStepType)
-{
-  DebuggerCommons* lCommons = theWrapper->thePlanState->theDebuggerCommons;
-
-  switch (aStepType)
-  {
-  case STEP_INTO:
-    // Resume and then suspend as soon as the next iterator is reached.
-    lCommons->setBreak(true, CAUSE_STEP);
-    resumeRuntime();
-    break;
-  case STEP_OUT:
-    lCommons->makeStepOut();
-    resumeRuntime();
-    break;
-  case STEP_OVER:
-    lCommons->makeStepOver();
-    resumeRuntime();
-    break;
-  }
+DebuggerRuntime::stepIn()
+{
+  DebuggerCommons* lCommons = theWrapper->thePlanState->theDebuggerCommons;
+  // Resume and then suspend as soon as the next iterator is reached.
+  lCommons->setBreak(true, CAUSE_STEP);
+
+  if (theExecStatus == QUERY_SUSPENDED) {
+    resumeRuntime();
+  } else {
+    startRuntime();
+  }
+}
+
+
+void
+DebuggerRuntime::stepOver()
+{
+  DebuggerCommons* lCommons = theWrapper->thePlanState->theDebuggerCommons;
+  lCommons->makeStepOver();
+
+  if (theExecStatus == QUERY_SUSPENDED) {
+    resumeRuntime();
+  } else {
+    startRuntime();
+  }
+}
+
+
+void
+DebuggerRuntime::stepOut()
+{
+  // this combination doesn't make sense: to step out when the exeecution did not start yet
+  if (theExecStatus != QUERY_SUSPENDED) {
+    return;
+  }
+
+  DebuggerCommons* lCommons = theWrapper->thePlanState->theDebuggerCommons;
+  lCommons->makeStepOut();
+
+  resumeRuntime();
 }
 
 
@@ -425,6 +513,13 @@
 std::list<std::pair<zstring, zstring> >
 DebuggerRuntime::eval(zstring& aExpr)
 {
+  // must check if we actually CAN eval (only while in "break" status)
+  if (theExecStatus != QUERY_SUSPENDED) {
+    std::string lMessage("I can only eval expressions if the execution is suspended.");
+    throw lMessage;
+  }
+  
+
   // disable the xml declaration for evals/variables
   Zorba_omit_xml_declaration_t lOldOpt = theSerializerOptions.omit_xml_declaration;
   theSerializerOptions.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES;
@@ -446,55 +541,181 @@
 
 
 std::string
-DebuggerRuntime::listSource()
+DebuggerRuntime::listSource(
+  String& lFileName,
+  unsigned int aBeginLine,
+  unsigned int aEndLine,
+  bool aZorbaExtensions)
 {
-  //ZORBA_ASSERT(dynamic_cast<ListCommand*>(theCurrentMessage));
-  //ListCommand* lCommand = dynamic_cast<ListCommand*>(theCurrentMessage);
-  //std::string lFile;
-  //lFile = theWrapper->thePlanState->theDebuggerCommons->getFilepathOfURI(
-  //  lCommand->getFilename());
-
-  //std::string lCurrLine;
-  ////std::string::iterator lSIter;
-  ////for (lSIter = lFile.begin(); lSIter != lFile.end(); ++lSIter) {
-  ////  if (*lSIter == '\\' && *(lSIter+1) == '\\') {
-  ////    lFile.erase(lSIter);
-  ////    ++lSIter;
-  ////  }
-  ////}
-  //std::ifstream lStream(lFile.c_str());
-  //for (unsigned long i = 1; i < lCommand->getFirstline() && lStream.good(); ++i)
-  //{
-  //  std::getline(lStream, lCurrLine);
-  //}
-  //std::stringstream lOut;
-  //for (unsigned long i = lCommand->getFirstline();
-  //  i <= lCommand->getLastline() && lStream.good(); ++i) {
-  //  std::getline(lStream, lCurrLine);
-  //  lOut << lCurrLine;
-  //  if (lStream.good()) {
-  //    lOut << std::endl;
-  //  }
-  //}
-  //return new ListReply(
-  //  theCurrentMessage->getId(), DEBUGGER_NO_ERROR, lOut.str());
-
-  return "";
+  // these are needed if extensions are enabled
+  String lFileUri;
+  unsigned int lCurrentLine = 0;
+
+  // for unspecified files determine the file
+  if (lFileName == "") {
+    // if not started, than it's the main module
+    if (theExecStatus != QUERY_SUSPENDED) {
+#ifdef WIN32
+      lFileName = theQuery->getFileName();
+#else
+      // TODO: under Linux, when trying to get the file name of the query
+      //       the call fails because getFileName tries to get a lock that
+      //       is already taken. Therefore the assertion in mutex.cpp:63
+      //       terminates the execution 
+      lFileName = "";
+#endif
+    }
+    // else, the file pointed by the top-most stack frame
+    else {
+      std::vector<StackFrameImpl> lRawFrames = getStackFrames();
+      StackFrameImpl lFrame = lRawFrames.at(lRawFrames.size() - 1);
+      lFileName = lFrame.getLocation().getFileName();
+      // filter out the eval stack frames. They Start with "eval@"
+      // TODO: Unsafe if the stackframe changes notation.
+      //       Should use a constant taken from the stack frame logic.
+      if (lFileName.substr(0, 5) == "eval@") {
+        // TODO: can we get the eval iterator, get its source and surprize the user
+        //       with the source code of the eval code. That would be great!
+        std::stringstream lSs;
+        lSs << "Cannot list source code for stack frames inside an eval expression. "
+          << "(Yet! Try again in the next version!)";
+        throw lSs.str();
+      }
+      lCurrentLine = lFrame.getLocation().getLineBegin();
+    }
+  }
+
+#ifdef WIN32
+  // TODO: tolower all the file names/URIs on Windows
+  // This must be implemented also in the breakable/breakpoint logic
+#endif
+
+  // normalize file uri and file name
+  String lPrefix = lFileName.substr(0, 7);
+  if (lPrefix == "file://") {
+    lFileName = URIHelper::decodeFileURI(lFileName);
+    lFileUri = URIHelper::encodeFileURI(lFileName);
+  } else {
+    if (lPrefix != "http://"; && lPrefix != "https:/") {
+      lFileUri = URIHelper::encodeFileURI(lFileName);
+    } else {
+      lFileUri = lFileName;
+    }
+  }
+
+  // check if this file is actually one file where breakpoints are allowed
+  // this prevents the user opening random files in the system
+  BreakableVector lBkps = getBreakpoints();
+  bool lFoundFile = false;
+  for (BreakableVector::size_type j = 0; j < lBkps.size(); j++) {
+    Breakable lBkp = lBkps.at(j);
+    if (lBkp.getLocation().getFilename().str() == lFileUri.str()) {
+      lFoundFile = true;
+      break;
+    }
+  }
+
+  // TODO: if lZorbaExtensions and file not found add search capability like
+  // for breakpoints. This ways the useer can specify only a file name suffix
+
+  if (!lFoundFile) {
+    std::stringstream lSs;
+    lSs << "Cannot open file: " << lFileUri;
+    throw lSs.str();
+  }
+
+  // if a file is given check if this is the one in the top-most stack frame
+  if (lCurrentLine == 0 && aZorbaExtensions && theExecStatus == QUERY_SUSPENDED) {
+    std::vector<StackFrameImpl> lRawFrames = getStackFrames();
+    StackFrameImpl lFrame = lRawFrames.at(lRawFrames.size() - 1);
+    if (lFileUri == lFrame.getLocation().getFileName()) {
+      lCurrentLine = lFrame.getLocation().getLineBegin();
+    }
+  }
+
+
+  // read the entire file
+  std::ifstream lStream(lFileName.c_str());
+  std::string lCurrLine;
+  std::vector<std::string> lFileContent;
+
+  while (lStream.good()) {
+    std::getline(lStream, lCurrLine);
+    lFileContent.push_back(lCurrLine);
+  }
+  unsigned int lLineCount = lFileContent.size();
+
+  // ocmpute the begin and end lines depending on the current line:
+  // - 5 lines before and after the current line if available
+  // - all the file otherwise
+  unsigned int lLines = 5;
+  unsigned int lClBl = lCurrentLine == 0  || lCurrentLine <= lLines ? 1 : lCurrentLine - lLines;
+  unsigned int lClEl = lCurrentLine == 0  || lCurrentLine >= lLineCount - lLines ? lLineCount : lCurrentLine + lLines;
+  aBeginLine = std::min(lLineCount, (aBeginLine == 0 ? lClBl : aBeginLine));
+  aEndLine = std::min(lLineCount, (aEndLine == 0 ? lClEl : aEndLine));
+
+  // first, find the breakpoints in this file
+  std::map<int, bool> lBreakLines;
+  if (aBeginLine <= aEndLine) {
+    for (BreakableVector::size_type j = 0; j < lBkps.size(); j++) {
+      Breakable lBkp = lBkps.at(j);
+      if (lBkp.isSet() && lBkp.getLocation().getFilename().str() == lFileUri.str()) {
+        // TODO: one could also check if the line in in the range we want
+        lBreakLines[lBkp.getLocation().getLineBegin()] = lBkp.isEnabled();
+      }
+    }
+  }
+
+  // get only the needed lines
+  std::stringstream lOut;
+  for (unsigned int i = aBeginLine; i <= aEndLine; i++) {
+    if (aZorbaExtensions) {
+      // get the width of the line number column
+      std::stringstream lTmpSs;
+      lTmpSs << aEndLine;
+      int lWidth = lTmpSs.str().length();
+
+      // prepend line info column to the source
+      lOut << std::setw(lWidth) << i << " ";
+      std::map<int, bool>::iterator lIter = lBreakLines.find(i);
+      if (lIter != lBreakLines.end()) {
+        lOut << (lIter->second ? "o" : "x");
+      } else {
+        lOut << " ";
+      }
+      lOut << (lCurrentLine == i ? ">" : "|") << " ";
+    }
+    lOut << lFileContent.at(i - 1);
+    if (i != aEndLine) {
+      lOut << std::endl;
+    }
+  }
+
+  return lOut.str();
 }
 
 
 void
-DebuggerRuntime::setTheLastContinuationTransactionID(int aTID)
-{
-  theLastContinuationTransactionID = aTID;
-}
-
-
-int
-DebuggerRuntime::getTheLastContinuationTransactionID()
-{
-  return theLastContinuationTransactionID;
-}
+DebuggerRuntime::setLastContinuationCommand(int aTransactionID, std::string aCommandName)
+{
+  theLastContinuationCommand = std::pair<int, std::string>(aTransactionID, aCommandName);
+}
+
+DebuggerRuntime*
+DebuggerRuntime::clone()
+{
+  DebuggerRuntime* lNewRuntime = new DebuggerRuntime(
+    theQuery,
+    theOStream,
+    theSerializerOptions,
+    theCommunicator,
+    theItemHandler,
+    theCallbackData);
+
+  lNewRuntime->theBreakpoints = theBreakpoints;
+  return lNewRuntime;
+}
+
 
 // ****************************************************************************
 // Private functions

=== modified file 'src/debugger/debugger_runtime.h'
--- src/debugger/debugger_runtime.h	2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_runtime.h	2011-12-13 11:51:46 +0000
@@ -67,9 +67,6 @@
   public:
 
     void
-    setQueryRunning();
-
-    void
     setNotSendTerminateEvent();
 
     void
@@ -85,11 +82,14 @@
     // Breakpints
 
     unsigned int
-    addBreakpoint(const QueryLoc& location, bool enabled);
+    addBreakpoint(String& aFileName, int aLine, bool enabled);
 
     Breakable
     getBreakpoint(unsigned int id);
 
+    BreakableVector
+    getBreakpoints();
+
     void
     updateBreakpoint(
       unsigned int id,
@@ -113,13 +113,17 @@
     // Other
 
     void
-    setTheLastContinuationTransactionID(int transactionID);
-
-    int
-    getTheLastContinuationTransactionID();
+    setLastContinuationCommand(int transactionID, std::string commandName);
 
     std::string
-    listSource();
+    listSource(
+      String& fleName,
+      unsigned int beginLine,
+      unsigned int endLine,
+      bool zorbaExtensions);
+
+    std::vector<std::pair<std::string, std::string> >
+    getVariables();
 
     std::vector<std::pair<std::string, std::string> >
     getVariables(bool locals);
@@ -130,15 +134,28 @@
     void runQuery();
 
     void
+    startRuntime();
+
+    void
     resumeRuntime();
-    
+
     void
     terminateRuntime();
     
     void
     detachRuntime();
 
-    void step(StepCommand stepType);
+    void
+    stepIn();
+
+    void
+    stepOver();
+
+    void
+    stepOut();
+
+    DebuggerRuntime*
+    clone();
 
   private:
 
@@ -162,7 +179,7 @@
     itemHandler                       theItemHandler;
     void*                             theCallbackData;
 
-    int                               theLastContinuationTransactionID;
+    std::pair<int, std::string>       theLastContinuationCommand;
   };
 }
 

=== modified file 'src/debugger/debugger_server.cpp'
--- src/debugger/debugger_server.cpp	2011-07-01 16:07:54 +0000
+++ src/debugger/debugger_server.cpp	2011-12-13 11:51:46 +0000
@@ -42,11 +42,21 @@
   void*                     aCallbackData,
   const std::string&        aHost,
   unsigned short            aPort)
+  : theStopping(false)
 {
   theCommunicator = new DebuggerCommunicator(aHost, aPort);
   theRuntime = new DebuggerRuntime(
     aQuery, aOstream, aSerializerOptions,
     theCommunicator, aHandler, aCallbackData);
+#ifdef WIN32
+  theFileName = aQuery->getFileName().str();
+#else
+  // TODO: under Linux, when trying to get the file name of the query
+  //       the call fails because getFileName tries to get a lock that
+  //       is already taken. Therefore the assertion in mutex.cpp:63
+  //       terminates the execution 
+  theFileName = "";
+#endif
 }
 
 
@@ -56,7 +66,6 @@
   delete theCommunicator;
 }
 
-
 bool
 DebuggerServer::run()
 {
@@ -70,12 +79,27 @@
 
   std::string lCommand;
 
-  while (theRuntime->getExecutionStatus() != QUERY_TERMINATED &&
+  while (!theStopping &&
       theRuntime->getExecutionStatus() != QUERY_DETACHED) {
+
     // read next command
     theCommunicator->receive(lCommand);
     DebuggerCommand lCmd = DebuggerCommand(lCommand);
 
+    if (theRuntime->getExecutionStatus() == QUERY_TERMINATED) {
+      // clone the existing runtime
+      DebuggerRuntime* lNewRuntime = theRuntime->clone();
+
+      // reset and delete the existing runtime
+      theRuntime->terminate();
+      theRuntime->resetRuntime();
+      theRuntime->join();
+      delete theRuntime;
+
+      // and save the new runtime
+      theRuntime = lNewRuntime;
+    }
+
     // process the received command
     std::string lResponse = processCommand(lCmd);
     if (lResponse != "") {
@@ -102,8 +126,17 @@
   if (!getEnvVar("DBGP_SESSION", lSession)) {
     lSession = "";
   }
+  ThreadId tid = Runnable::self();
   std::stringstream lInitMsg;
-  lInitMsg << "<init appid=\"zorba\" idekey=\"" << lIdeKey << "\" session=\"" + lSession + "\" thread=\"6666\" parent=\"zorba\" language=\"xquery\" protocol_version=\"1.0\" fileuri=\"file://D:/mm.xq\"/>";
+  lInitMsg << "<init appid=\"zorba\" "
+    << "idekey=\"" << lIdeKey << "\" "
+    << "session=\"" + lSession + "\" "
+    << "thread=\"" << tid <<"\" "
+    << "parent=\"zorba\" "
+    << "language=\"XQuery\" "
+    << "protocol_version=\"1.0\" "
+    << "fileuri=\"" << URIHelper::encodeFileURI(theFileName).str() << "\"/>";
+  
   theCommunicator->send(lInitMsg.str());
 }
 
@@ -113,12 +146,20 @@
 {
   std::stringstream lResponse;
   int lTransactionID;
+  bool lZorbaExtensions = false;
   ExecutionStatus lStatus;
 
   if (aCommand.getArg("i", lTransactionID)) {
     lResponse << "<response command=\"" << aCommand.getName() << "\" transaction_id=\"" << lTransactionID << "\" ";
     lStatus = theRuntime->getExecutionStatus();
 
+    int lExtOpt;
+    if (aCommand.getArg("z", lExtOpt)) {
+      if (lExtOpt) {
+        lZorbaExtensions = true;
+      }
+    }
+
     std::string lCmdName = aCommand.getName();
 
     switch (lCmdName.at(0)) {
@@ -132,59 +173,52 @@
           if (aCommand.getArg("d", lBID)) {
             try {
               Breakable lBkp = theRuntime->getBreakpoint(lBID);
-              std::string lFilename = lBkp.getLocation().getFilename().str();
-              lFilename = URIHelper::encodeFileURI(lFilename).str();
-
-              lResponse << "<breakpoint "
-                << "id=\"" << lBID << "\" "
-                << "type=\"line\" "
-                << "state=\"" << (lBkp.isEnabled() ? "enabled" : "disabled") << "\" "
-                << "filename=\"" << lFilename << "\" "
-                << "lineno=\"" << lBkp.getLocation().getLineBegin() << "\" "
-//              << "function=\"FUNCTION\" "
-//              << "exception=\"EXCEPTION\" "
-//              << "hit_value=\"HIT_VALUE\" "
-//              << "hit_condition=\"HIT_CONDITION\" "
-//              << "hit_count=\"HIT_COUNT\" "
-                << ">"
-//              << "<expression>EXPRESSION</expression>"
-              << "</breakpoint>";
-
+              buildBreakpoint(lBkp, lBID, lResponse);
             } catch (std::string& lErr) {
-              return buildErrorResponse(lTransactionID, lCmdName, 4, lErr);
+              return buildErrorResponse(lTransactionID, lCmdName, 205, lErr);
             }
           } else {
             // error
           }
         } else {
           // breakpoint_list
+          BreakableVector lBkps = theRuntime->getBreakpoints();
+
+          BreakableVector::iterator lIter = lBkps.begin();
+          int lId = -1;
+          while (lIter != lBkps.end()) {
+            Breakable lBkp = *(lIter++);
+            lId++;
+
+            // this is only a location without a breakpoint set by the user
+            if (!lBkp.isSet()) {
+              continue;
+            }
+
+            buildBreakpoint(lBkp, lId, lResponse);
+          }
         }
       } else {
         if (aCommand.getName() == "breakpoint_set") {
 
           int lLineNo;
           aCommand.getArg("n", lLineNo);
-          std::string lFileName;
-          aCommand.getArg("f", lFileName);
+          std::string lFileNameTmp;
+          aCommand.getArg("f", lFileNameTmp);
+          String lFileName(lFileNameTmp);
+
           std::string lState;
+          bool lEnabled = true;
           if (!aCommand.getArg("s", lState)) {
             lState = "enabled";
           }
-
-          if (lFileName.substr(0, 7) == "file://") {
-            lFileName = URIHelper::decodeFileURI(lFileName).str();
-          }
-
-          QueryLoc lLocation;
-          lLocation.setLineBegin(lLineNo);
-          lLocation.setLineEnd(lLineNo);
-          lLocation.setFilename(lFileName);
+          lEnabled = (lState == "disabled" ? false : true);
+          lState = (lEnabled ? "enabled" : "disabled");
 
           try {
-            bool lEnabled = (lState == "disabled" ? false : true);
-            unsigned int lBID = theRuntime->addBreakpoint(lLocation, lEnabled);
-            lResponse << "state=\"enabled\" id=\"" << lBID << "\" ";
-          } catch (std::string lErr) {
+            unsigned int lBID = theRuntime->addBreakpoint(lFileName, lLineNo, lEnabled);
+            lResponse << "state=\"" << lState << "\" id=\"" << lBID << "\" ";
+          } catch (std::string& lErr) {
             return buildErrorResponse(lTransactionID, lCmdName, 200, lErr);
           }
  
@@ -196,11 +230,14 @@
           int lHitValue;
 //          bool lHasCondition = false;
 
-          // we can not change the line number of a breakpoint
-          // so we will never read the -n option
+          // since we can not change the line number of a breakpoint, we throw an error for that
+          if (aCommand.getArg("n", lBID)) {
+            return buildErrorResponse(lTransactionID, lCmdName, 208, "A breakpoint line number can not be changed. Omit the -n argument.");
+          }
 
+          // the breakpoint ID must be present or we throw an error
           if (!aCommand.getArg("d", lBID)) {
-            // TODO: throw exception
+            return buildErrorResponse(lTransactionID, lCmdName, 200, "No breakpoint could not be updated: missing breakpoint ID (-d) argument.");
           }
           if (!aCommand.getArg("s", lState)) {
             lState = "enabled";
@@ -216,14 +253,18 @@
           try {
             bool lEnabled = (lState == "disabled" ? false : true);
             theRuntime->updateBreakpoint(lBID, lEnabled, lCondition, lHitValue);
-          } catch (std::string lErr) {
-            // TODO: report error
+          } catch (std::string& lErr) {
+            return buildErrorResponse(lTransactionID, lCmdName, 205, lErr);
           }
 
         } else if (aCommand.getName() == "breakpoint_remove") {
           int lBID;
           if (aCommand.getArg("d", lBID)) {
-            theRuntime->removeBreakpoint(lBID);
+            try {
+              theRuntime->removeBreakpoint(lBID);
+            } catch (std::string& lErr) {
+              return buildErrorResponse(lTransactionID, lCmdName, 205, lErr);
+            }
           }
         }
 
@@ -253,13 +294,30 @@
         if (!aCommand.getArg("c", lContextID)) {
           lContextID = 0;
         }
+        // we allow -1 to return the properties (variables) in all contexts
+        if (lContextID < -1 || lContextID > 1) {
+          std::stringstream lErrMsg;
+          lErrMsg << "Context invalid (" << lContextID << ") invalid. Check the context list for a correct ID.";
+          return buildErrorResponse(lTransactionID, lCmdName, 302, lErrMsg.str());
+        }
 
         // currently we only support contexts for the topmost stack frame
         if (lContextDepth == 0) {
 
-          // get the variables either local or global depenging on the context ID
-          std::vector<std::pair<std::string, std::string> > lVariables =
-            theRuntime->getVariables(lContextID == 0 ? true : false);
+          // get the variables depenging on the context ID (all, local, global)
+          std::vector<std::pair<std::string, std::string> > lVariables;
+          switch (lContextID) {
+          case -1: 
+            lVariables = theRuntime->getVariables();
+            break;
+          case 0: 
+            lVariables = theRuntime->getVariables(true);
+            break;
+          case 1: 
+            lVariables = theRuntime->getVariables(false);
+            break;
+          }
+
           std::vector<std::pair<std::string, std::string> >::iterator lIter =
             lVariables.begin();
 
@@ -269,7 +327,17 @@
             std::string lName = getVariableName(lFullName);
             buildProperty(lFullName, lName, lIter->second, lResponse);
           }
+        } else {
+          std::stringstream lErrMsg;
+          if (lContextDepth < 0) {
+            lErrMsg << "Invalid stack depth: " << lContextDepth << "";
+            return buildErrorResponse(lTransactionID, lCmdName, 301, lErrMsg.str());
+          } else if (lContextDepth > 0) {
+            lErrMsg << "Invalid stack depth: " << lContextDepth << ". Currently we only support data commands for the top-most stack frame.";
+            return buildErrorResponse(lTransactionID, lCmdName, 301, lErrMsg.str());
+          }
         }
+
       }
 
       break;
@@ -290,6 +358,8 @@
           std::string lName = "";
           buildChildProperties(lName, lResults, lResponse);
 
+        } catch (std::string aMessage) {
+          return buildErrorResponse(lTransactionID, lCmdName, 206, aMessage);
         } catch (...) {
           return buildErrorResponse(lTransactionID, lCmdName, 206, "Error while evaluating expression.");
         }
@@ -358,9 +428,9 @@
     // run
     case 'r':
 
-      if (lStatus == QUERY_SUSPENDED || lStatus == QUERY_IDLE) {
-        theRuntime->setTheLastContinuationTransactionID(lTransactionID);
-        if (lStatus == QUERY_IDLE) {
+      if (lStatus == QUERY_SUSPENDED || lStatus == QUERY_IDLE || lStatus == QUERY_TERMINATED) {
+        theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
+        if (lStatus == QUERY_IDLE || lStatus == QUERY_TERMINATED) {
           theRuntime->start();
         } else if (lStatus == QUERY_SUSPENDED) {
           theRuntime->resumeRuntime();
@@ -374,9 +444,36 @@
     // stack_depth, stack_get, status, stop, step_into, step_over, step_out
     case 's':
 
-      if (aCommand.getName() == "stop") {
-
-        theRuntime->setTheLastContinuationTransactionID(lTransactionID);
+      if (aCommand.getName() == "source") {
+        lResponse << "success=\"1\" ";
+        lResponse << ">";
+
+        int lBeginLine;
+        if (!aCommand.getArg("b", lBeginLine)) {
+          lBeginLine = 0;
+        }
+        int lEndLine;
+        if (!aCommand.getArg("e", lEndLine)) {
+          lEndLine = 0;
+        }
+        std::string lTmp;
+        if (!aCommand.getArg("f", lTmp)) {
+          lTmp = "";
+        }
+        String lFileName(lTmp);
+
+        // we wrap the source code in CDATA to have it unparsed because it might contain XML
+        lResponse << "<![CDATA[";
+        try {
+          lResponse << theRuntime->listSource(lFileName, lBeginLine, lEndLine, lZorbaExtensions) << std::endl;
+        } catch (std::string& lErr) {
+          return buildErrorResponse(lTransactionID, lCmdName, 100, lErr);
+        }
+        lResponse << "]]>";
+
+      } else if (aCommand.getName() == "stop") {
+        theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
+        theStopping = true;
 
         lResponse << "reason=\"ok\" status=\"stopped\" ";
         lResponse << ">";
@@ -389,33 +486,18 @@
 
       } else if (aCommand.getName() == "stack_get") {
 
-        lResponse << ">";
-        std::vector<StackFrameImpl> lFrames = theRuntime->getStackFrames();
-
-        std::vector<StackFrameImpl>::reverse_iterator lRevIter;
-        int i = 0;
-        for (lRevIter = lFrames.rbegin(); lRevIter < lFrames.rend(); ++lRevIter, ++i) {
-          String lFileName(lRevIter->getLocation().getFileName());
-          lFileName = URIHelper::encodeFileURI(lFileName);
-          unsigned int lLB = lRevIter->getLocation().getLineBegin();
-          unsigned int lLE = lRevIter->getLocation().getLineEnd();
-
-          // for the client, the column numbers are 1-based
-          unsigned int lCB = lRevIter->getLocation().getColumnBegin() - 1;
-          // moreover, the column end points to the last character to be selected
-          unsigned int lCE = lRevIter->getLocation().getColumnEnd() - 2;
-
-          lResponse << "<stack "
-            << "level=\"" << i << "\" "
-            << "type=\"" << "file" << "\" "
-            << "filename=\"" << lFileName << "\" "
-            << "lineno=\"" << lLB << "\" "
-            << "where=\"" << lRevIter->getSignature() << "\" "
-            << "cmdbegin=\"" << lLB << ":" << lCB << "\" "
-            << "cmdend=\"" << lLE << ":" << lCE << "\" "
-            << "/>";
+        try {
+          lResponse << ">";
+          std::vector<StackFrameImpl> lFrames = theRuntime->getStackFrames();
+
+          std::vector<StackFrameImpl>::reverse_iterator lRevIter;
+          int i = 0;
+          for (lRevIter = lFrames.rbegin(); lRevIter < lFrames.rend(); ++lRevIter, ++i) {
+            buildStackFrame(*lRevIter, i, lResponse);
+          }
+        } catch (std::string& lErr) {
+          return buildErrorResponse(lTransactionID, lCmdName, 303, lErr);
         }
-
       } else if (aCommand.getName() == "status") {
 
         ExecutionStatus lStatus = theRuntime->getExecutionStatus();
@@ -425,7 +507,6 @@
           lStatusStr = "starting";
           break;
         case QUERY_RUNNING:
-        case QUERY_RESUMED:
           lStatusStr = "running";
           break;
         case QUERY_SUSPENDED:
@@ -442,16 +523,20 @@
           << ">";
 
       } else if (aCommand.getName() == "step_into") {
-        theRuntime->setTheLastContinuationTransactionID(lTransactionID);
-        theRuntime->step(STEP_INTO);
+        theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
+        theRuntime->stepIn();
         return "";
       } else if (aCommand.getName() == "step_over") {
-        theRuntime->setTheLastContinuationTransactionID(lTransactionID);
-        theRuntime->step(STEP_OVER);
+        theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
+        theRuntime->stepOver();
         return "";
       } else if (aCommand.getName() == "step_out") {
-        theRuntime->setTheLastContinuationTransactionID(lTransactionID);
-        theRuntime->step(STEP_OUT);
+        ExecutionStatus lStatus = theRuntime->getExecutionStatus();
+        if (lStatus != QUERY_SUSPENDED) {
+          return buildErrorResponse(lTransactionID, lCmdName, 6, "Can not step out since the execution is not started.");
+        }
+        theRuntime->setLastContinuationCommand(lTransactionID, aCommand.getName());
+        theRuntime->stepOut();
         return "";
       }
 
@@ -483,6 +568,65 @@
 }
 
 void
+DebuggerServer::buildStackFrame(
+  StackFrame& aFrame,
+  int aSNo,
+  std::ostream& aStream)
+{
+  // the file names in query locations always come as URIs, so decode it
+  String lFileName(aFrame.getLocation().getFileName());
+  if (lFileName.substr(0, 7) == "file://") {
+    lFileName = URIHelper::decodeFileURI(lFileName);
+  }
+
+  unsigned int lLB = aFrame.getLocation().getLineBegin();
+  unsigned int lLE = aFrame.getLocation().getLineEnd();
+
+  // for the client, the column numbers are 1-based
+  unsigned int lCB = aFrame.getLocation().getColumnBegin() - 1;
+  // moreover, the column end points to the last character to be selected
+  unsigned int lCE = aFrame.getLocation().getColumnEnd() - 2;
+
+  aStream << "<stack "
+    << "level=\"" << aSNo << "\" "
+    << "type=\"" << "file" << "\" "
+    << "filename=\"" << lFileName << "\" "
+    << "lineno=\"" << lLB << "\" "
+    << "where=\"" << aFrame.getSignature() << "\" "
+    << "cmdbegin=\"" << lLB << ":" << lCB << "\" "
+    << "cmdend=\"" << lLE << ":" << lCE << "\" "
+    << "/>";
+};
+
+void
+DebuggerServer::buildBreakpoint(
+  Breakable& aBreakpoint,
+  int aBID,
+  std::ostream& aStream)
+{
+  // the file names in query locations always come as URIs, so decode it
+  String lFileName(aBreakpoint.getLocation().getFilename().str());
+  if (lFileName.substr(0, 7) == "file://") {
+    lFileName = URIHelper::decodeFileURI(lFileName);
+  }
+
+  aStream << "<breakpoint "
+    << "id=\"" << aBID << "\" "
+    << "type=\"line\" "
+    << "state=\"" << (aBreakpoint.isEnabled() ? "enabled" : "disabled") << "\" "
+    << "filename=\"" << lFileName << "\" "
+    << "lineno=\"" << aBreakpoint.getLocation().getLineBegin() << "\" "
+//  << "function=\"FUNCTION\" "
+//  << "exception=\"EXCEPTION\" "
+//  << "hit_value=\"HIT_VALUE\" "
+//  << "hit_condition=\"HIT_CONDITION\" "
+//  << "hit_count=\"HIT_COUNT\" "
+    << ">"
+//  << "<expression>EXPRESSION</expression>"
+  << "</breakpoint>";
+};
+
+void
 DebuggerServer::buildProperty(
   std::string& aFullName,
   std::string& aName,

=== modified file 'src/debugger/debugger_server.h'
--- src/debugger/debugger_server.h	2011-07-01 16:07:54 +0000
+++ src/debugger/debugger_server.h	2011-12-13 11:51:46 +0000
@@ -23,6 +23,7 @@
 #include "zorbatypes/zstring.h"
 
 #include "debugger_common.h"
+#include "debugger_commons.h"
 #include "debugger_protocol.h"
 
 
@@ -72,6 +73,18 @@
     getVariableName(std::string& aFullName);
 
     void
+    buildStackFrame(
+      StackFrame& frame,
+      int stackFrameNumber,
+      std::ostream& stream);
+
+    void
+    buildBreakpoint(
+      Breakable& breakpoint,
+      int breakpointID,
+      std::ostream& stream);
+
+    void
     buildProperty(
       std::string& fullName,
       std::string& name,
@@ -94,7 +107,8 @@
 
     DebuggerCommunicator* theCommunicator;
     DebuggerRuntime*      theRuntime;
-
+    std::string           theFileName;
+    bool                  theStopping;
   };
 }
 

=== modified file 'src/debugger/socket_streambuf.cpp'
--- src/debugger/socket_streambuf.cpp	2011-07-01 01:53:24 +0000
+++ src/debugger/socket_streambuf.cpp	2011-12-13 11:51:46 +0000
@@ -14,66 +14,79 @@
  * limitations under the License.
  */
 #include "stdafx.h"
+
+#include "socket_streambuf.h"
+
 #include <sstream>
 #include <cstring>
 #include <iostream>
-#include "socket_streambuf.h"
+
 
 namespace zorba {
   
-  static const int BUF_SIZE = 1024;
+static const int BUF_SIZE = 1024;
   
-  socket_streambuf::socket_streambuf(TCPSocket& aSocket)
+SocketStreambuf::SocketStreambuf(TCPSocket& aSocket)
   : theSocket(aSocket)
-  {
-    theInputBuffer = new char_type[BUF_SIZE];
-    theOutputBuffer = new char_type[BUF_SIZE];
-    setg(theInputBuffer, theInputBuffer, theInputBuffer);
-    setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
-  }
-  
-  socket_streambuf::~socket_streambuf()
-  {
-    delete[] theInputBuffer;
-  }
-  
-  int socket_streambuf::sync()
-  {
-#if 0
-    std::cout << "sending:" << std::endl << std::string(pbase(), pptr() - pbase()) << std::endl;
-#endif
-    theSocket.send(pbase(), pptr() - pbase());
-    setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
-    return 0;
-  }
-  
-  int socket_streambuf::underflow() {
-    int size = theSocket.recv(theInputBuffer, BUF_SIZE);
-    if (size == 0)
-      return EOF;
-    setg(theInputBuffer, theInputBuffer, theInputBuffer + size);
-    return theInputBuffer[0];
-  }
-  
-  int socket_streambuf::overflow(int c)
-  {
-#if 0
-    std::cout << "sending:" << std::endl << std::string(pbase(), pptr() - pbase()) << std::endl;
-#endif
-    theSocket.send(pbase(), pptr() - pbase());
-    setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
-    sputc(c);
-    return 0;
-  }
-  
-  DebuggerResponse::DebuggerResponse(std::istream& aStream)
-  {
-  }
-  
-  bool DebuggerResponse::isInit() const {
-    std::string rootNodeName(reinterpret_cast<const char*>(theDoc->children->name));
-    if (rootNodeName == "init")
-      return true;
-    return false;
-  }
-}
+{
+  theInputBuffer = new char_type[BUF_SIZE];
+  theOutputBuffer = new char_type[BUF_SIZE];
+  setg(theInputBuffer, theInputBuffer, theInputBuffer);
+  setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
+}
+  
+SocketStreambuf::~SocketStreambuf()
+{
+  delete[] theInputBuffer;
+}
+  
+int
+SocketStreambuf::sync()
+{
+#if 0
+    std::cout << "sending:" << std::endl << std::string(pbase(), pptr() - pbase()) << std::endl;
+#endif
+  theSocket.send(pbase(), pptr() - pbase());
+  setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
+  return 0;
+}
+  
+int
+SocketStreambuf::underflow()
+{
+  int size = theSocket.recv(theInputBuffer, BUF_SIZE);
+  if (size == 0) {
+    return EOF;
+  }
+  setg(theInputBuffer, theInputBuffer, theInputBuffer + size);
+  return theInputBuffer[0];
+}
+  
+int
+SocketStreambuf::overflow(int c)
+{
+#if 0
+    std::cout << "sending:" << std::endl << std::string(pbase(), pptr() - pbase()) << std::endl;
+#endif
+  theSocket.send(pbase(), pptr() - pbase());
+  setp(theOutputBuffer, theOutputBuffer + BUF_SIZE);
+  sputc(c);
+  return 0;
+}
+
+
+DebuggerResponse::DebuggerResponse(std::istream& aStream)
+{
+}
+  
+bool
+DebuggerResponse::isInit() const
+{
+  std::string rootNodeName(reinterpret_cast<const char*>(theDoc->children->name));
+  if (rootNodeName == "init") {
+    return true;
+  }
+  return false;
+}
+
+} // namespace zorba

=== modified file 'src/debugger/socket_streambuf.h'
--- src/debugger/socket_streambuf.h	2011-06-22 11:19:07 +0000
+++ src/debugger/socket_streambuf.h	2011-12-13 11:51:46 +0000
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#pragma once
+#ifndef ZORBA_SOCKET_STREAMBUF_H
+#define ZORBA_SOCKET_STREAMBUF_H
+
+#include <streambuf>
 
 #include <libxml/parser.h>
 #include <libxml/xmlstring.h>
@@ -22,27 +25,35 @@
 
 namespace zorba {
   
-  class socket_streambuf : public std::streambuf {
+class SocketStreambuf : public std::streambuf {
   public:
-    socket_streambuf(TCPSocket& aSocket);
-    virtual ~socket_streambuf();
+    SocketStreambuf(TCPSocket& aSocket);
+    virtual ~SocketStreambuf();
+
   protected:
     virtual int sync();
     virtual int underflow();
     virtual int overflow(int c = EOF);
+
   private:
     TCPSocket& theSocket;
     char_type* theInputBuffer;
     char_type* theOutputBuffer;
-  };
+};
   
-  class DebuggerResponse {
-    friend class DebuggerClientImpl;
+class DebuggerResponse {
+  friend class DebuggerClientImpl;
+
   private:
     DebuggerResponse(std::istream& aStream);
+
   public: // API
     bool isInit() const;
+
   private:
     xmlDocPtr theDoc;
-  };
-}
+};
+
+} // namespace zorba
+
+#endif // ZORBA_SOCKET_STREAMBUF_H

=== modified file 'src/unit_tests/CMakeLists.txt'
--- src/unit_tests/CMakeLists.txt	2011-06-01 13:16:28 +0000
+++ src/unit_tests/CMakeLists.txt	2011-12-13 11:51:46 +0000
@@ -17,9 +17,3 @@
   unit_tests.cpp
   test_uri.cpp
 )
-
-IF(ZORBA_WITH_DEBUGGER)
-  LIST(APPEND UNIT_TEST_SRCS
-#    test_debugger_protocol.cpp
-  )
-ENDIF(ZORBA_WITH_DEBUGGER)

=== removed file 'src/unit_tests/test_debugger_protocol.cpp'
--- src/unit_tests/test_debugger_protocol.cpp	2011-08-27 14:57:52 +0000
+++ src/unit_tests/test_debugger_protocol.cpp	1970-01-01 00:00:00 +0000
@@ -1,414 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-
-#include <zorba/internal/unique_ptr.h>
-
-#include "unit_test_list.h"
-
-#include "debugger/message_factory.h"
-#include "zorbatypes/zstring.h"
-
-namespace zorba
-{
-
-
-template<class T>
-bool test_packet( AbstractMessage * aMessage ) 
-{
-  //Cast to the concrete Message Type
-  T * lMessage1 = dynamic_cast<T *> ( aMessage );
-  //Ensure that the cast is correct
-  if(lMessage1 == 0){ return false; }
-  //Serialize and unserialize the message
-  Length length;
-  Byte * msg = lMessage1->serialize( length );
-  AbstractMessage * lAbstractMessage = MessageFactory::buildMessage( msg, length );
-  delete[] msg;
-  T * lMessage2 = dynamic_cast<T *> ( lAbstractMessage );
-  if(lMessage2 == 0) { return false; }
-  //Ensure that both message are identical
-  bool lResult = (*lMessage1) == (*lMessage2);
-  if(lResult == 0) { return false; }
-  delete lAbstractMessage;
-  return true;
-}
-
-
-bool msgcmp( Byte * aMsg1, const char * aMsg2, unsigned int aLength )
-{
-  Byte * lMsg2 = reinterpret_cast<Byte *>( const_cast< char * >( aMsg2 ) );
-  return memcmp( aMsg1, lMsg2, aLength ) == 0;
-}
-
-  
-class TestDebuggerSerialization
-{
-public:
-  bool testReplyMessageOk();
-  
-  bool testReplyMessage();
-      
-  bool testRunMessage();
-
-  bool testResumeMessage();
-  
-  bool testSuspendMessage();
-    
-  bool testTerminateMessage();
-
-  bool testStepIntoMessage();
-    
-  bool testStepOutMessage();
-    
-  bool testStepOverMessage();
-
-  bool testStartedEvent();
-
-  bool testTerminatedEvent();
-
-  bool testSuspendedEvent();
-
-  bool testResumedEvent();
-
-  bool testClearMessage();
-
-  bool testSetMessage();
-
-  bool testEvalMessage();
-
-  bool testEvalEvent();
-
-  bool testVariableMessage();
-};
-
-
-bool TestDebuggerSerialization::testReplyMessage()
-{
-  std::cerr << "Test reply message" << std::endl;
-  ReplyMessage msg( 1, DEBUGGER_ERROR_INVALID_MESSAGE_FORMAT );
-  bool lResult = test_packet<ReplyMessage>( &msg );
-  if(!lResult) return false;
-  const char * lBinary = "\0\0\0\xb\0\0\0\1\200\0\xb";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-
-bool TestDebuggerSerialization::testReplyMessageOk()
-{
-  std::cerr << "Test reply message Ok" << std::endl;
-  ReplyMessage msg( 1, DEBUGGER_NO_ERROR );
-  bool lResult = test_packet<ReplyMessage>( &msg );
-  if(!lResult) return false;
-  test_packet<ReplyMessage>( &msg );
-  const char * lBinary = "\0\0\0\xb\0\0\0\1\200\0\0";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-
-bool TestDebuggerSerialization::testRunMessage()
-{
-  std::cerr << "Test run message" << std::endl;
-  RunMessage msg;
-  bool lResult = test_packet<RunMessage>( &msg );
-  if(!lResult) return false;
-  const char * lBinary =  "\0\0\0\xb\0\0\0\1\0\xf1\1";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-
-bool TestDebuggerSerialization::testSuspendMessage()
-{
-  std::cerr << "Test suspend message" << std::endl;
-  SuspendMessage msg;
-  bool lResult = test_packet<SuspendMessage>( &msg );
-  if(!lResult) return false;
-  const char * lBinary =  "\0\0\0\xb\0\0\0\2\0\xf1\2"; 
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-
-bool TestDebuggerSerialization::testResumeMessage()
-{
-  std::cerr << "Test resume message" << std::endl;
-  ResumeMessage msg;
-  bool lResult = test_packet<ResumeMessage>(&msg);
-  if(!lResult) return false;
-  const char * lBinary =  "\0\0\0\xb\0\0\0\3\0\xf1\3"; 
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-
-bool TestDebuggerSerialization::testTerminateMessage()
-{
-  std::cerr << "Test terminate message" << std::endl;
-  TerminateMessage msg;
-  bool lResult = test_packet<TerminateMessage>( &msg );
-  if(!lResult) return false;
-  const char * lBinary =  "\0\0\0\xb\0\0\0\4\0\xf1\4"; 
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp(lBmsg.get(), lBinary, length);
-}
-  
-  
-bool TestDebuggerSerialization::testStepIntoMessage()
-{
-  std::cerr << "Test step into message" << std::endl;
-  StepMessage msg(STEP_INTO);
-  bool lResult = test_packet<StepMessage>( &msg );
-  if (!lResult) return false;
-  const char* lBinary =  "\0\0\0\x19\0\0\0\5\0\xf1\5{\"stepType\":1}"; 
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-  
-bool TestDebuggerSerialization::testStepOutMessage()
-{
-  std::cerr << "Test step out message" << std::endl;
-  StepMessage msg(STEP_OUT);
-  bool lResult = test_packet<StepMessage>( &msg );
-  if (!lResult) return false;
-  const char* lBinary =  "\0\0\0\x19\0\0\0\6\0\xf1\5{\"stepType\":2}";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-  
-bool TestDebuggerSerialization::testStepOverMessage()
-{
-  std::cerr << "Test step over message" << std::endl;
-  StepMessage msg(STEP_OVER);
-  bool lResult = test_packet<StepMessage>( &msg );
-  if (!lResult) return false;
-  const char* lBinary =  "\0\0\0\x19\0\0\0\7\0\xf1\5{\"stepType\":3}";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize( length ));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-  
-  
-bool TestDebuggerSerialization::testStartedEvent()
-{
-  std::cerr << "Test started event message" << std::endl;
-  StartedEvent msg;
-  bool lResult = test_packet<StartedEvent>( &msg );
-  if(!lResult) return false;
-  const char * lBinary = "\0\0\0\xb\0\0\0\x8\0\xf8\1";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-  
-bool TestDebuggerSerialization::testTerminatedEvent()
-{
-  std::cerr << "Test terminated event message" << std::endl;
-  TerminatedEvent msg;
-  bool lResult = test_packet<TerminatedEvent>( &msg );
-  if(!lResult) return false;
-  const char * lBinary = "\0\0\0\xb\0\0\0\x9\0\xf8\2";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-  
-bool TestDebuggerSerialization::testSuspendedEvent()
-{
-  std::cerr << "Test suspended event message" << std::endl;
-
-  QueryLoc loc;
-  loc.setFilename( "data.xq" );
-  loc.setLineBegin( 1 );
-  loc.setColumnBegin( 1 );
-  loc.setLineEnd( 1 );
-  loc.setColumnEnd( 1 );
-  
-  SuspendedEvent msg( loc, CAUSE_USER );
-  bool lResult =test_packet< SuspendedEvent >( &msg );
-  if(!lResult) return false;
-
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  std::unique_ptr<char[]> lBinary(new char[length]);
-  memcpy( lBinary.get(), "\0\0\0\x070\0\0\0\xa\0\xf8\3", MESSAGE_HEADER_SIZE );
-  const char * lJSONString = "{\"cause\":1,\"location\":{\"fileName\":\"data.xq\",\"lineBegin\":1,\"columnBegin\":1,\"lineEnd\":1,\"columnEnd\":1}}";
-  memcpy( lBinary.get() + MESSAGE_HEADER_SIZE, lJSONString, length - MESSAGE_HEADER_SIZE );
-  return  msgcmp( lBmsg.get(), lBinary.get(), length );
-}
-
-  
-bool TestDebuggerSerialization::testResumedEvent()
-{
-  std::cerr << "Test resumed event message" << std::endl;
-  ResumedEvent msg;
-  bool lResult = test_packet<ResumedEvent>( &msg );
-  if(!lResult) return false;
-  const char * lBinary = "\0\0\0\xb\0\0\0\xb\0\xf8\4";
-  Length length;
-  std::unique_ptr<Byte[]> lBmsg(msg.serialize(length));
-  return msgcmp( lBmsg.get(), lBinary, length );
-}
-
-  
-bool TestDebuggerSerialization::testClearMessage()
-{
-  std::cerr << "Test clear message" << std::endl;
-  ClearMessage msg;
-  msg.addId( 1 );
-  msg.addId( 2 );
-  msg.addId( 3 );
-  msg.addId( 4 );
-  bool lResult = test_packet<ClearMessage>( &msg );
-  if(!lResult) return false;
-  return true;
-}
-
-  
-bool TestDebuggerSerialization::testSetMessage()
-{
-  std::cerr << "Test set message" << std::endl;
-  QueryLoc loc;
-  loc.setFilename( "data.xq" );
-  loc.setLineBegin( 1 );
-  loc.setColumnBegin( 1 );
-  loc.setLineEnd( 1 );
-  loc.setColumnEnd( 1 );
-  SetMessage msg;
-  msg.addLocation( 1, loc );
-  zstring lExpr("$i=1");
-  msg.addExpr( 2, lExpr);
-  bool lResult = test_packet<SetMessage>( &msg );
-  if(!lResult) return false;
-  return true;
-}
-  
-  
-bool TestDebuggerSerialization::testEvalMessage()
-{
-  std::cerr << "Test eval message" << std::endl;
-  EvalMessage msg( "$i/foo" );
-  bool lResult = test_packet<EvalMessage>( &msg );
-  if(!lResult) return false;
-  return true;
-}
-
-  
-bool TestDebuggerSerialization::testEvalEvent()
-{
-  std::cerr << "Test eval event" << std::endl;
-  std::list<std::pair<zstring, zstring> > lList;
-  EvaluatedEvent evt(0, "()", lList);
-  evt.setId(5);
-  bool lResult = test_packet<EvaluatedEvent>(&evt);
-  if (!lResult) return false;
-  zstring lData = evt.getData();
-  zstring::size_type lPos = lData.find("id");
-  if (lPos == zstring::npos) {
-    return false;
-  }
-  lPos = lData.find("5", lPos);
-  if (lPos == zstring::npos) {
-    return false;
-  }
-  if (evt.getId() != 5) {
-    return false;
-  }
-  return true;
-}
-
-
-bool TestDebuggerSerialization::testVariableMessage()
-{
-  std::cerr << "Test variable message" << std::endl;
-  {
-    VariableMessage msg;
-    bool lResult = test_packet<VariableMessage>( &msg );
-    if(!lResult) return false;
-  }
-  {
-    VariableReply msg( 1, DEBUGGER_NO_ERROR );
-    msg.addGlobal( "$i", "xs:integer" );
-    msg.addGlobal( "$j", "xs:integer" );
-    msg.addLocal("$foo", "xs:string" );
-    msg.addLocal("$bar", "xs:string" );
-    bool lResult = test_packet<VariableReply>( &msg );
-    if(!lResult) return false;
-  }
-  return true;
-}
-
-  
-
-int UnitTests::runDebuggerProtocolTest(int argc, char* argv[])
-{
-  bool lResult;
-  zorba::TestDebuggerSerialization * test = new zorba::TestDebuggerSerialization();
-  lResult = test->testReplyMessage();
-  if(!lResult) return 1;
-  lResult = test->testReplyMessageOk();
-  if(!lResult) return 1;
-  lResult = test->testRunMessage();
-  if(!lResult) return 1;
-  lResult = test->testSuspendMessage();
-  if(!lResult) return 1;
-  lResult = test->testResumeMessage();
-  if(!lResult) return 1;
-  lResult = test->testTerminateMessage();
-  if(!lResult) return 1;
-  lResult = test->testStepIntoMessage();
-  if(!lResult) return 1;
-  lResult = test->testStepOutMessage();
-  if(!lResult) return 1;
-  lResult = test->testStepOverMessage();
-  if(!lResult) return 1;
-  lResult = test->testStartedEvent();
-  if(!lResult) return 1;
-  lResult = test->testTerminatedEvent();
-  if(!lResult) return 1;
-  lResult = test->testSuspendedEvent();
-  if(!lResult) return 1;
-  lResult = test->testResumedEvent();
-  if(!lResult) return 1;
-  lResult = test->testClearMessage();
-  if(!lResult) return 1;
-  lResult = test->testSetMessage();
-  if(!lResult) return 1;
-  lResult = test->testEvalMessage();
-  if(!lResult) return 1;
-  lResult = test->testVariableMessage();
-  if(!lResult) return 1;
-  delete test;
-  return 0;
-}
-
-} // namespace zorba
-/* vim:set et sw=2 ts=2: */

=== added directory 'test/rbkt/ExpQueryResults/zorba/debugger'
=== added directory 'test/rbkt/ExpQueryResults/zorba/debugger/dmh'
=== added file 'test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response.xml.res'
--- test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response.xml.res	2011-12-13 11:51:46 +0000
@@ -0,0 +1,1 @@
+5 break in dmh:process#1 at file.xq:10
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response_no_info.xml.res'
--- test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response_no_info.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response_no_info.xml.res	2011-12-13 11:51:46 +0000
@@ -0,0 +1,1 @@
+5 break
\ No newline at end of file

=== added directory 'test/rbkt/Queries/zorba/debugger'
=== added directory 'test/rbkt/Queries/zorba/debugger/dmh'
=== added file 'test/rbkt/Queries/zorba/debugger/dmh/break_response.xq'
--- test/rbkt/Queries/zorba/debugger/dmh/break_response.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/debugger/dmh/break_response.xq	2011-12-13 11:51:46 +0000
@@ -0,0 +1,5 @@
+import module namespace dmh = "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler";;
+
+let $e := <response command="status" status="break" reason="ok" transaction_id="5">dmh:process#1 at file.xq:10</response>
+return
+  dmh:process($e)

=== added file 'test/rbkt/Queries/zorba/debugger/dmh/break_response_no_info.xq'
--- test/rbkt/Queries/zorba/debugger/dmh/break_response_no_info.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/debugger/dmh/break_response_no_info.xq	2011-12-13 11:51:46 +0000
@@ -0,0 +1,7 @@
+import module namespace dmh = "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler";;
+
+let $e :=
+  <response command="status" status="break" reason="ok" transaction_id="5">
+  </response>
+return
+  dmh:process($e)