diff --git a/bootstrap b/bootstrap
old mode 100755
new mode 100644
diff --git a/i18n/ko_KR/pgadmin3.po b/i18n/ko_KR/pgadmin3.po
old mode 100755
new mode 100644
diff --git a/pgadmin/ctl/ctlSQLResult.cpp b/pgadmin/ctl/ctlSQLResult.cpp
index 73e3d67..34df194 100644
--- a/pgadmin/ctl/ctlSQLResult.cpp
+++ b/pgadmin/ctl/ctlSQLResult.cpp
@@ -141,7 +141,9 @@ int ctlSQLResult::Abort()
 	{
 		((sqlResultTable *)GetTable())->SetThread(0);
 
-		thread->Delete();
+		thread->CancelExecution();
+		thread->Wait();
+
 		delete thread;
 	}
 	thread = 0;
diff --git a/pgadmin/db/pgConn.cpp b/pgadmin/db/pgConn.cpp
index 6aebc21..b0d2a9a 100644
--- a/pgadmin/db/pgConn.cpp
+++ b/pgadmin/db/pgConn.cpp
@@ -52,7 +52,7 @@ static void pgNoticeProcessor(void *arg, const char *message)
 pgConn::pgConn(const wxString &server, const wxString &service, const wxString &hostaddr, const wxString &database, const wxString &username, const wxString &password,
                int port, const wxString &rolename, int sslmode, OID oid, const wxString &applicationname,
                const wxString &sslcert, const wxString &sslkey, const wxString &sslrootcert, const wxString &sslcrl,
-               const bool sslcompression)
+               const bool sslcompression) : m_cancelConn(NULL)
 {
 	wxString msg;
 
@@ -324,7 +324,10 @@ bool pgConn::DoConnect()
 void pgConn::Close()
 {
 	if (conn)
+	{
+		CancelExecution();
 		PQfinish(conn);
+	}
 	conn = 0;
 	connStatus = PGCONN_BAD;
 }
@@ -350,11 +353,26 @@ bool pgConn::Reconnect()
 }
 
 
-pgConn *pgConn::Duplicate()
+pgConn *pgConn::Duplicate(const wxString &_appName)
 {
-	return new pgConn(wxString(save_server), wxString(save_service), wxString(save_hostaddr), wxString(save_database), wxString(save_username), wxString(save_password),
-	                  save_port, save_rolename, save_sslmode, save_oid,
-	                  save_applicationname, save_sslcert, save_sslkey, save_sslrootcert, save_sslcrl, save_sslcompression);
+	pgConn *res = new pgConn(wxString(save_server), wxString(save_service),
+	                         wxString(save_hostaddr), wxString(save_database), wxString(save_username),
+	                         wxString(save_password), save_port, save_rolename, save_sslmode, save_oid,
+	                         _appName.IsEmpty() ? save_applicationname : _appName, save_sslcert, save_sslkey,
+	                         save_sslrootcert, save_sslcrl, save_sslcompression);
+
+	// Save the version and features information from the existing connection
+	res->majorVersion = majorVersion;
+	res->minorVersion = minorVersion;
+	res->patchVersion = patchVersion;
+	res->isEdb = isEdb;
+	res->isGreenplum = isGreenplum;
+	res->reservedNamespaces = reservedNamespaces;
+
+	for (size_t index = FEATURE_INITIALIZED; index < FEATURE_LAST; index++)
+		res->features[index] = features[index];
+
+	return res;
 }
 
 
@@ -714,7 +732,11 @@ bool pgConn::ExecuteVoid(const wxString &sql, bool reportError)
 	PGresult *qryRes;
 
 	wxLogSql(wxT("Void query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str());
+
+	SetConnCancel();
 	qryRes = PQexec(conn, sql.mb_str(*conv));
+	ResetConnCancel();
+
 	lastResultStatus = PQresultStatus(qryRes);
 	SetLastResultError(qryRes);
 
@@ -734,7 +756,7 @@ bool pgConn::ExecuteVoid(const wxString &sql, bool reportError)
 
 
 
-wxString pgConn::ExecuteScalar(const wxString &sql)
+wxString pgConn::ExecuteScalar(const wxString &sql, bool reportError)
 {
 	wxString result;
 
@@ -743,14 +765,18 @@ wxString pgConn::ExecuteScalar(const wxString &sql)
 		// Execute the query and get the status.
 		PGresult *qryRes;
 		wxLogSql(wxT("Scalar query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str());
+
+		SetConnCancel();
 		qryRes = PQexec(conn, sql.mb_str(*conv));
+		ResetConnCancel();
+
 		lastResultStatus = PQresultStatus(qryRes);
 		SetLastResultError(qryRes);
 
 		// Check for errors
 		if (lastResultStatus != PGRES_TUPLES_OK && lastResultStatus != PGRES_COMMAND_OK)
 		{
-			LogError();
+			LogError(!reportError);
 			PQclear(qryRes);
 			return wxEmptyString;
 		}
@@ -775,14 +801,17 @@ wxString pgConn::ExecuteScalar(const wxString &sql)
 	return result;
 }
 
-pgSet *pgConn::ExecuteSet(const wxString &sql)
+pgSet *pgConn::ExecuteSet(const wxString &sql, bool reportError)
 {
 	// Execute the query and get the status.
 	if (GetStatus() == PGCONN_OK)
 	{
 		PGresult *qryRes;
 		wxLogSql(wxT("Set query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str());
+
+		SetConnCancel();
 		qryRes = PQexec(conn, sql.mb_str(*conv));
+		ResetConnCancel();
 
 		lastResultStatus = PQresultStatus(qryRes);
 		SetLastResultError(qryRes);
@@ -792,14 +821,17 @@ pgSet *pgConn::ExecuteSet(const wxString &sql)
 			pgSet *set = new pgSet(qryRes, this, *conv, needColQuoting);
 			if (!set)
 			{
-				wxLogError(__("Couldn't create a pgSet object!"));
+				if (reportError)
+					wxLogError(_("Couldn't create a pgSet object!"));
+				else
+					wxLogQuietError(_("Couldn't create a pgSet object!"));
 				PQclear(qryRes);
 			}
 			return set;
 		}
 		else
 		{
-			LogError();
+			LogError(!reportError);
 			PQclear(qryRes);
 		}
 	}
@@ -924,7 +956,15 @@ void pgConn::LogError(const bool quiet)
 bool pgConn::IsAlive()
 {
 	if (GetStatus() != PGCONN_OK)
+	{
+		if (conn)
+		{
+			PQfinish(conn);
+			conn = 0;
+			connStatus = PGCONN_BROKEN;
+		}
 		return false;
+	}
 
 	PGresult *qryRes = PQexec(conn, "SELECT 1;");
 	lastResultStatus = PQresultStatus(qryRes);
@@ -968,6 +1008,59 @@ void pgConn::Reset()
 }
 
 
+void pgConn::SetConnCancel(void)
+{
+	wxMutexLocker  lock(m_cancelConnMutex);
+	PGcancel      *oldCancelConn = m_cancelConn;
+
+	m_cancelConn = NULL;
+
+	if (oldCancelConn != NULL)
+		PQfreeCancel(oldCancelConn);
+
+	if (!conn)
+		return;
+
+	m_cancelConn = PQgetCancel(conn);
+
+}
+
+
+void pgConn::ResetConnCancel(void)
+{
+	wxMutexLocker  lock(m_cancelConnMutex);
+	PGcancel      *oldCancelConn = m_cancelConn;
+
+	m_cancelConn = NULL;
+
+	if (oldCancelConn != NULL)
+		PQfreeCancel(oldCancelConn);
+}
+
+
+void pgConn::CancelExecution(void)
+{
+	char           errbuf[256];
+	wxMutexLocker  lock(m_cancelConnMutex);
+
+	if (m_cancelConn)
+	{
+		PGcancel *cancelConn = m_cancelConn;
+		m_cancelConn = NULL;
+
+		if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
+		{
+			SetLastResultError(NULL, wxT("Cancel request sent"));
+		}
+		else
+		{
+			SetLastResultError(NULL, wxString::Format(wxT("Could not send cancel request:\n%s"), errbuf));
+		}
+		PQfreeCancel(cancelConn);
+	}
+}
+
+
 wxString pgConn::GetVersionString()
 {
 	return ExecuteScalar(wxT("SELECT version();"));
@@ -1101,14 +1194,14 @@ bool pgConn::TableHasColumn(wxString schemaname, wxString tblname, const wxStrin
 		schemaname.Replace(wxT("'"), wxT("''"));
 
 		wxString sql
-		    = wxT("SELECT a.attname AS colname FROM pg_catalog.pg_attribute a ") \
-		      wxT("WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c ") \
-		      wxT("                    LEFT JOIN pg_catalog.pg_namespace n ON ") \
-		      wxT("                                    n.oid = c.relnamespace ") \
-		      wxT("                    WHERE c.relname ~ '^(") + tblname + wxT(")$' AND ") \
-		      wxT("                          n.nspname ~ '^(") + schemaname + wxT(")$') AND ") \
-		      wxT("      a.attnum > 0 AND NOT a.attisdropped ") \
-		      wxT("ORDER BY a.attnum");
+		= wxT("SELECT a.attname AS colname FROM pg_catalog.pg_attribute a ") \
+		  wxT("WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c ") \
+		  wxT("                    LEFT JOIN pg_catalog.pg_namespace n ON ") \
+		  wxT("                                    n.oid = c.relnamespace ") \
+		  wxT("                    WHERE c.relname ~ '^(") + tblname + wxT(")$' AND ") \
+		  wxT("                          n.nspname ~ '^(") + schemaname + wxT(")$') AND ") \
+		  wxT("      a.attnum > 0 AND NOT a.attisdropped ") \
+		  wxT("ORDER BY a.attnum");
 
 		pgSet *set = ExecuteSet(sql);
 		if (set)
@@ -1129,3 +1222,88 @@ bool pgConn::TableHasColumn(wxString schemaname, wxString tblname, const wxStrin
 	return false;
 }
 
+void pgError::SetError(PGresult *_res, wxMBConv *_conv)
+{
+	if (!_conv)
+	{
+		_conv = &wxConvLibc;
+	}
+	if (_res)
+	{
+		msg_primary = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_PRIMARY), *_conv);
+		severity = wxString(PQresultErrorField(_res, PG_DIAG_SEVERITY), *_conv);
+		sql_state = wxString(PQresultErrorField(_res, PG_DIAG_SQLSTATE), *_conv);
+		msg_detail = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_DETAIL), *_conv);
+		msg_hint = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_HINT), *_conv);
+		statement_pos = wxString(PQresultErrorField(_res, PG_DIAG_STATEMENT_POSITION), *_conv);
+		internal_pos = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_POSITION), *_conv);
+		internal_query = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_QUERY), *_conv);
+		context = wxString(PQresultErrorField(_res, PG_DIAG_CONTEXT), *_conv);
+		source_file = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FILE), *_conv);
+		source_line = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_LINE), *_conv);
+		source_function = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FUNCTION), *_conv);
+	}
+	else
+	{
+		msg_primary = wxEmptyString;
+		severity = wxEmptyString;
+		sql_state = wxEmptyString;
+		msg_detail = wxEmptyString;
+		msg_hint = wxEmptyString;
+		statement_pos = wxEmptyString;
+		internal_pos = wxEmptyString;
+		internal_query = wxEmptyString;
+		context = wxEmptyString;
+		source_file = wxEmptyString;
+		source_line = wxEmptyString;
+		source_function = wxEmptyString;
+	}
+
+	wxString errMsg;
+
+	if (severity != wxEmptyString && msg_primary != wxEmptyString)
+		errMsg = severity + wxT(": ") + msg_primary;
+	else if (msg_primary != wxEmptyString)
+		errMsg = msg_primary;
+
+	if (!sql_state.IsEmpty())
+	{
+		if (!errMsg.EndsWith(wxT("\n")))
+			errMsg += wxT("\n");
+		errMsg += _("SQL state: ");
+		errMsg += sql_state;
+	}
+
+	if (!msg_detail.IsEmpty())
+	{
+		if (!errMsg.EndsWith(wxT("\n")))
+			errMsg += wxT("\n");
+		errMsg += _("Detail: ");
+		errMsg += msg_detail;
+	}
+
+	if (!msg_hint.IsEmpty())
+	{
+		if (!errMsg.EndsWith(wxT("\n")))
+			errMsg += wxT("\n");
+		errMsg += _("Hint: ");
+		errMsg += msg_hint;
+	}
+
+	if (!statement_pos.IsEmpty())
+	{
+		if (!errMsg.EndsWith(wxT("\n")))
+			errMsg += wxT("\n");
+		errMsg += _("Character: ");
+		errMsg += statement_pos;
+	}
+
+	if (!context.IsEmpty())
+	{
+		if (!errMsg.EndsWith(wxT("\n")))
+			errMsg += wxT("\n");
+		errMsg += _("Context: ");
+		errMsg += context;
+	}
+	formatted_msg = errMsg;
+}
diff --git a/pgadmin/db/pgQueryThread.cpp b/pgadmin/db/pgQueryThread.cpp
index 77b361c..f697a6a 100644
--- a/pgadmin/db/pgQueryThread.cpp
+++ b/pgadmin/db/pgQueryThread.cpp
@@ -21,176 +21,512 @@
 #include "db/pgSet.h"
 #include "db/pgConn.h"
 #include "db/pgQueryThread.h"
+#include "db/pgQueryResultEvent.h"
+#include "utils/pgDefs.h"
 #include "utils/sysLogger.h"
 
-static void pgNoticeProcessor(void *arg, const char *message)
+const wxEventType PGQueryResultEvent = wxNewEventType();
+
+// default notice processor for the pgQueryThread
+// we do assume that the argument passed will be always the
+// object of pgQueryThread
+void pgNoticeProcessor(void *_arg, const char *_message)
 {
-	wxString str(message, wxConvUTF8);
+	wxString str(_message, wxConvUTF8);
 
 	wxLogNotice(wxT("%s"), str.Trim().c_str());
-	((pgQueryThread *)arg)->appendMessage(str);
+	if (_arg)
+	{
+		((pgQueryThread *)_arg)->AppendMessage(str);
+	}
 }
 
-pgQueryThread::pgQueryThread(pgConn *_conn, const wxString &qry, int _resultToRetrieve, wxWindow *_caller, long _eventId, void *_data)
-	: wxThread(wxTHREAD_JOINABLE)
+
+// support for multiple queries support
+pgQueryThread::pgQueryThread(pgConn *_conn, wxEvtHandler *_caller,
+                             PQnoticeProcessor _processor, void *_noticeHandler) :
+	wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn),
+	m_cancelled(false), m_multiQueries(true), m_useCallable(false),
+	m_caller(_caller), m_processor(pgNoticeProcessor), m_noticeHandler(NULL)
 {
-	query = qry;
-	conn = _conn;
-	dataSet = 0;
-	result = 0;
-	resultToRetrieve = _resultToRetrieve;
-	rc = -1;
-	insertedOid = (OID) - 1;
-	caller = _caller;
-	eventId = _eventId;
-	data = _data;
-
-	wxLogSql(wxT("Thread query (%s:%d): %s"), conn->GetHost().c_str(), conn->GetPort(), qry.c_str());
-
-	conn->RegisterNoticeProcessor(pgNoticeProcessor, this);
-	if (conn->conn)
-		PQsetnonblocking(conn->conn, 1);
+	// check if we can really use the enterprisedb callable statement and
+	// required
+#ifdef __WXMSW__
+	if (PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut)
+	{
+		// we do not need all of pqi stuff as90 onwards
+		if (m_conn && m_conn->conn && m_conn->GetIsEdb()
+		        && !m_conn->EdbMinimumVersion(9, 0))
+		{
+			m_useCallable = true;
+		}
+	}
+#else // __WXMSW__
+#ifdef EDB_LIBPQ
+	// use callable statement only with enterprisedb advanced servers
+	// we do not need all of pqi stuff as90 onwards
+	if (m_conn && m_conn->conn && m_conn->GetIsEdb()
+	        && !m_conn->EdbMinimumVersion(9, 0))
+	{
+		m_useCallable = true;
+	}
+#endif // EDB_LIBPQ
+#endif // __WXMSW__
+
+	if (m_conn && m_conn->conn)
+	{
+		PQsetnonblocking(m_conn->conn, 1);
+	}
+
+	if (_processor != NULL)
+	{
+		m_processor = _processor;
+		if (_noticeHandler)
+			m_noticeHandler = _noticeHandler;
+		else
+			m_noticeHandler = (void *)this;
+	}
+	else
+	{
+		m_noticeHandler = (void *)this;
+	}
 }
 
+pgQueryThread::pgQueryThread(pgConn *_conn, const wxString &_qry,
+                             int _resultToRetrieve, wxWindow *_caller, long _eventId, void *_data)
+	: wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn),
+	  m_cancelled(false), m_multiQueries(false), m_useCallable(false),
+	  m_caller(NULL), m_processor(pgNoticeProcessor), m_noticeHandler(NULL)
+{
+	if (m_conn && m_conn->conn)
+	{
+		PQsetnonblocking(m_conn->conn, 1);
+	}
+	m_queries.Add(
+	    new pgBatchQuery(_qry, (pgParamsArray *)NULL, _eventId, _data, false,
+	                     _resultToRetrieve));
+
+	wxLogInfo(wxT("queueing : %s"), _qry.c_str());
+	m_noticeHandler = (void *)this;
+
+	if (_caller)
+	{
+		m_caller = _caller->GetEventHandler();
+	}
+}
+
+
+void pgQueryThread::AddQuery(const wxString &_qry, pgParamsArray *_params,
+                             long _eventId, void *_data, bool _useCallable, int _resultToRetrieve)
+{
+	m_queries.Add(
+	    new pgBatchQuery(_qry, _params, _eventId, _data,
+	                     // use callable statement only if supported
+	                     m_useCallable && _useCallable, _resultToRetrieve));
+
+	wxLogInfo(wxT("queueing (%ld): %s"), GetId(), _qry.c_str());
+}
+
+
 pgQueryThread::~pgQueryThread()
 {
-	conn->RegisterNoticeProcessor(0, 0);
-	if (dataSet)
-		delete dataSet;
+	m_conn->RegisterNoticeProcessor(0, 0);
+	WX_CLEAR_ARRAY(m_queries);
 }
 
 
-wxString pgQueryThread::GetMessagesAndClear()
+wxString pgQueryThread::GetMessagesAndClear(int idx)
 {
 	wxString msg;
 
+	if (idx == -1)
+		idx = m_currIndex;
+
+	if (idx >= 0 && idx <= m_currIndex)
 	{
-		wxCriticalSectionLocker cs(criticalSection);
-		msg = messages;
-		messages.Empty();
+		wxCriticalSectionLocker lock(m_criticalSection);
+		msg = m_queries[idx]->m_message;
+		m_queries[idx]->m_message.empty();
 	}
 
 	return msg;
 }
 
 
-void pgQueryThread::appendMessage(const wxString &str)
+void pgQueryThread::AppendMessage(const wxString &str)
 {
-	if (messages.IsEmpty())
+	if (m_queries[m_currIndex]->m_message.IsEmpty())
 	{
+		wxCriticalSectionLocker lock(m_criticalSection);
 		if (str != wxT("\n"))
-			appendMessageRaw(str);
+			m_queries[m_currIndex]->m_message.Append(str);
 	}
 	else
-		appendMessageRaw(wxT("\n") + str);
-}
-
-void pgQueryThread::appendMessageRaw(const wxString &str)
-{
-	wxCriticalSectionLocker cs(criticalSection);
-	messages.Append(str);
+	{
+		wxCriticalSectionLocker lock(m_criticalSection);
+		m_queries[m_currIndex]->m_message.Append(wxT("\n")).Append(str);
+	}
 }
 
 
-int pgQueryThread::execute()
+int pgQueryThread::Execute()
 {
-	rowsInserted = -1L;
+	wxMutexLocker lock(m_queriesLock);
+
+	PGresult       *result           = NULL;
+	wxMBConv       &conv             = *(m_conn->conv);
+
+	wxString       &query            = m_queries[m_currIndex]->m_query;
+	int            &resultToRetrieve = m_queries[m_currIndex]->m_resToRetrieve;
+	long           &rowsInserted     = m_queries[m_currIndex]->m_rowsInserted;
+	Oid            &insertedOid      = m_queries[m_currIndex]->m_insertedOid;
+	// using the alias for the pointer here, in order to save the result back
+	// in the pgBatchQuery object
+	pgSet         *&dataSet          = m_queries[m_currIndex]->m_resultSet;
+	int            &rc               = m_queries[m_currIndex]->m_returnCode;
+	pgParamsArray  *params           = m_queries[m_currIndex]->m_params;
+	bool            useCallable      = m_queries[m_currIndex]->m_useCallable;
+	pgError        &err              = m_queries[m_currIndex]->m_err;
+
+	wxCharBuffer queryBuf = query.mb_str(conv);
+
+	if (PQstatus(m_conn->conn) != CONNECTION_OK)
+	{
+		rc = pgQueryResultEvent::PGQ_CONN_LOST;
+		err.msg_primary = _("Connection to the database server lost");
 
-	if (!conn->conn)
-		return(raiseEvent(0));
+		return(RaiseEvent(rc));
+	}
 
-	wxCharBuffer queryBuf = query.mb_str(*conn->conv);
 	if (!queryBuf && !query.IsEmpty())
 	{
-		conn->SetLastResultError(NULL, _("The query could not be converted to the required encoding."));
-		return(raiseEvent(0));
+		rc = pgQueryResultEvent::PGQ_STRING_INVALID;
+		m_conn->SetLastResultError(NULL, _("the query could not be converted to the required encoding."));
+		err.msg_primary = _("Query string is empty");
+
+		return(RaiseEvent(rc));
 	}
 
-	if (!PQsendQuery(conn->conn, queryBuf))
+	// Honour the parameters (if any)
+	if (params && params->GetCount() > 0)
 	{
-		conn->SetLastResultError(NULL);
-		conn->IsAlive();
-		return(raiseEvent(0));
+		int    pCount = params->GetCount();
+		int    ret    = 0,
+		       idx    = 0;
+
+		Oid         *pOids    = (Oid *)malloc(pCount * sizeof(Oid));
+		const char **pParams  = (const char **)malloc(pCount * sizeof(const char *));
+		int         *pLens    = (int *)malloc(pCount * sizeof(int));
+		int         *pFormats = (int *)malloc(pCount * sizeof(int));
+		// modes are used only by enterprisedb callable statement
+#if defined (__WXMSW__) || (EDB_LIBPQ)
+		int         *pModes   = (int *)malloc(pCount * sizeof(int));
+#endif
+
+		for (; idx < pCount; idx++)
+		{
+			pgParam *param = (*params)[idx];
+
+			pOids[idx] = param->m_type;
+			pParams[idx] = (const char *)param->m_val;
+			pLens[idx] = param->m_len;
+			pFormats[idx] = param->GetFormat();
+#if defined (__WXMSW__) || (EDB_LIBPQ)
+			pModes[idx] = param->m_mode;
+#endif
+		}
+
+		if (useCallable)
+		{
+#if defined (__WXMSW__) || (EDB_LIBPQ)
+			wxLogInfo(wxString::Format(
+			              _("using an enterprisedb callable statement (queryid:%ld, threadid:%ld)"),
+			              (long)m_currIndex, (long)GetId()));
+			wxString stmt = wxString::Format(wxT("pgQueryThread-%ld-%ld"), this->GetId(), m_currIndex);
+			PGresult *res = PQiPrepareOut(m_conn->conn, stmt.mb_str(wxConvUTF8),
+			                              queryBuf, pCount, pOids, pModes);
+
+			if( PQresultStatus(res) != PGRES_COMMAND_OK)
+			{
+				rc = pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE;
+				err.SetError(res, &conv);
+
+				PQclear(res);
+
+				goto return_with_error;
+			}
+
+			ret = PQiSendQueryPreparedOut(m_conn->conn, stmt.mb_str(wxConvUTF8),
+			                              pCount, pParams, pLens, pFormats, 1);
+
+			if (ret != 1)
+			{
+				rc = pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE;
+
+				m_conn->SetLastResultError(NULL, _("Failed to run PQsendQuery in pgQueryThread"));
+				err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv);
+
+				PQclear(res);
+				res = NULL;
+
+				goto return_with_error;
+			}
+
+			PQclear(res);
+			res = NULL;
+#else
+			rc = -1;
+			wxASSERT_MSG(false,
+			             _("the program execution flow must not reach to this point in pgQueryThread"));
+
+			goto return_with_error;
+#endif
+		}
+		else
+		{
+			// assumptions: we will need the results in text format only
+			ret = PQsendQueryParams(m_conn->conn, queryBuf, pCount, pOids, pParams, pLens, pFormats, 0);
+
+			if (ret != 1)
+			{
+				rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY;
+
+				m_conn->SetLastResultError(NULL,
+				                           _("Failed to run PQsendQueryParams in pgQueryThread"));
+
+				err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") +
+				                  wxString(PQerrorMessage(m_conn->conn), conv);
+
+				goto return_with_error;
+			}
+		}
+		goto continue_without_error;
+
+return_with_error:
+		{
+			free(pOids);
+			free(pParams);
+			free(pLens);
+			free(pFormats);
+#if defined (__WXMSW__) || (EDB_LIBPQ)
+			free(pModes);
+#endif
+			return (RaiseEvent(rc));
+		}
 	}
+	else
+	{
+		// use the PQsendQuery api in case, we don't have any parameters to
+		// pass to the server
+		if (!PQsendQuery(m_conn->conn, queryBuf))
+		{
+			rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY;
+
+			err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") +
+			                  wxString(PQerrorMessage(m_conn->conn), conv);
+
+			return(RaiseEvent(rc));
+		}
+	}
+
+continue_without_error:
 	int resultsRetrieved = 0;
 	PGresult *lastResult = 0;
+
 	while (true)
 	{
-		if (TestDestroy())
+		// This is a 'joinable' thread, it is not advisable to call 'delete'
+		// function on this.
+		// Hence - it does not make sense to use the function 'testdestroy' here.
+		// We introduced the 'CancelExecution' function for the same purpose.
+		//
+		// Also, do not raise event when the query execution is cancelled to
+		// avoid the bugs introduced to handle events by the event handler,
+		// which is missing or being deleted.
+		//
+		// It will be responsibility of the compononent, using the object of
+		// pgQueryThread, to take the required actions to take care of the
+		// issue.
+		if (m_cancelled)
 		{
-			if (rc != -3)
+			m_conn->CancelExecution();
+			rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED;
+
+			err.msg_primary = _("Execution Cancelled");
+
+			if (lastResult)
 			{
-				if (!PQrequestCancel(conn->conn)) // could not abort; abort failed.
-					return(raiseEvent(-1));
+				PQclear(lastResult);
+				lastResult = NULL;
+			}
+			AppendMessage(_("Query-thread execution cancelled...\nthe query is:"));
+			AppendMessage(query);
+
+			return rc;
+		}
 
-				rc = -3;
+		if ((rc = PQconsumeInput(m_conn->conn)) != 1)
+		{
+			if (rc == 0)
+			{
+				err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv);
+			}
+			if (PQstatus(m_conn->conn) == CONNECTION_BAD)
+			{
+				err.msg_primary = _("Connection to the database server lost");
+				rc = pgQueryResultEvent::PGQ_CONN_LOST;
+			}
+			else
+			{
+				rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT;
 			}
+
+			return(RaiseEvent(rc));
 		}
-		if (!PQconsumeInput(conn->conn))
-			return(raiseEvent(0));
-		if (PQisBusy(conn->conn))
+
+		if (PQisBusy(m_conn->conn))
 		{
 			Yield();
 			this->Sleep(10);
+
 			continue;
 		}
 
-		// If resultToRetrieve is given, the nth result will be returned,
+		// if resultToRetrieve is given, the nth result will be returned,
 		// otherwise the last result set will be returned.
 		// all others are discarded
-		PGresult *res = PQgetResult(conn->conn);
+		PGresult *res = PQgetResult(m_conn->conn);
 
 		if (!res)
 			break;
 
+		if((PQresultStatus(res) == PGRES_NONFATAL_ERROR) ||
+		        (PQresultStatus(res) == PGRES_FATAL_ERROR) ||
+		        (PQresultStatus(res) == PGRES_BAD_RESPONSE))
+		{
+			result = res;
+			err.SetError(res, &conv);
+
+			// Wait for the execution to be finished
+			// We need to fetch all the results, before sending the error
+			// message
+			do
+			{
+				if (PQconsumeInput(m_conn->conn) != 1)
+				{
+					if (m_cancelled)
+					{
+						rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED;
+
+						// Release the result as the query execution has been cancelled by the
+						// user
+						if (result)
+							PQclear(result);
+
+						return rc;
+					}
+					goto out_of_consume_input_loop;
+				}
+
+				if ((res = PQgetResult(m_conn->conn)) == NULL)
+				{
+					goto out_of_consume_input_loop;
+				}
+				// Release the temporary results
+				PQclear(res);
+				res = NULL;
+
+				if (PQisBusy(m_conn->conn))
+				{
+					Yield();
+					this->Sleep(10);
+				}
+			}
+			while (true);
+
+			break;
+		}
+
+#if defined (__WXMSW__) || (EDB_LIBPQ)
+		// there should be 2 results in the callable statement - the first is the
+		// dummy, the second contains our out params.
+		if (useCallable)
+		{
+			PQclear(res);
+			result = PQiGetOutResult(m_conn->conn);
+		}
+#endif
 		if (PQresultStatus(res) == PGRES_COPY_IN)
 		{
-			PQputCopyEnd(conn->conn, "not supported by pgAdmin");
+			rc = PGRES_COPY_IN;
+			PQputCopyEnd(m_conn->conn, "not supported by pgadmin");
 		}
+
 		if (PQresultStatus(res) == PGRES_COPY_OUT)
 		{
-			int copyrc;
+			int copyRc;
 			char *buf;
-			int copyrows = 0;
-			int lastcopyrc = 0;
+			int copyRows = 0;
+			int lastCopyRc = 0;
 
-			appendMessage(_("Query returned COPY data:\n"));
+			rc = PGRES_COPY_OUT;
 
-			while((copyrc = PQgetCopyData(conn->conn, &buf, 1)) >= 0)
+			AppendMessage(_("query returned copy data:\n"));
+
+			while((copyRc = PQgetCopyData(m_conn->conn, &buf, 1)) >= 0)
 			{
 				if (buf != NULL)
 				{
-					if (copyrows < 100)
+					if (copyRows < 100)
 					{
-						wxString str(buf, wxConvUTF8);
-						appendMessageRaw(str);
+						wxString str(buf, conv);
+						wxCriticalSectionLocker cs(m_criticalSection);
+						m_queries[m_currIndex]->m_message.Append(str);
+
 					}
-					else if (copyrows == 100)
-						appendMessage(_("Query returned more than 100 COPY rows, discarding the rest...\n"));
+					else if (copyRows == 100)
+						AppendMessage(_("Query returned more than 100 copy rows, discarding the rest...\n"));
 
 					PQfreemem(buf);
 				}
-				if (copyrc > 0)
-					copyrows++;
-				if (TestDestroy() && rc != -3)
+				if (copyRc > 0)
+					copyRows++;
+
+				if (m_cancelled)
 				{
-					if (!PQrequestCancel(conn->conn)) // could not abort; abort failed.
-						return(raiseEvent(-1));
-					rc = -3;
+					m_conn->CancelExecution();
+					rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED;
+
+					return -1;
 				}
-				if (lastcopyrc == 0 && copyrc == 0)
+				if (lastCopyRc == 0 && copyRc == 0)
 				{
 					Yield();
 					this->Sleep(10);
 				}
-				if (copyrc == 0)
+				if (copyRc == 0)
 				{
-					if (!PQconsumeInput(conn->conn))
-						return(raiseEvent(0));
+					if (!PQconsumeInput(m_conn->conn))
+					{
+						if (PQstatus(m_conn->conn) == CONNECTION_BAD)
+						{
+							err.msg_primary = _("Connection to the database server lost");
+							rc = pgQueryResultEvent::PGQ_CONN_LOST;
+						}
+						else
+						{
+							rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT;
+
+							err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv);
+						}
+						return(RaiseEvent(rc));
+					}
 				}
-				lastcopyrc = copyrc;
+				lastCopyRc = copyRc;
 			}
-			res = PQgetResult(conn->conn);
+
+			res = PQgetResult(m_conn->conn);
+
 			if (!res)
 				break;
 		}
@@ -200,37 +536,36 @@ int pgQueryThread::execute()
 		{
 			result = res;
 			insertedOid = PQoidValue(res);
-			if (insertedOid && insertedOid != (OID) - 1)
-				appendMessage(wxString::Format(_("Query inserted one row with OID %d.\n"), insertedOid));
+			if (insertedOid && insertedOid != (Oid) - 1)
+				AppendMessage(wxString::Format(_("query inserted one row with oid %d.\n"), insertedOid));
 			else
-				appendMessage(wxString::Format(wxPLURAL("Query result with %d row will be returned.\n", "Query result with %d rows will be returned.\n",
+				AppendMessage(wxString::Format(wxPLURAL("query result with %d row will be returned.\n", "query result with %d rows will be returned.\n",
 				                                        PQntuples(result)), PQntuples(result)));
 			continue;
 		}
+
 		if (lastResult)
 		{
 			if (PQntuples(lastResult))
-				appendMessage(wxString::Format(wxPLURAL("Query result with %d row discarded.\n", "Query result with %d rows discarded.\n",
+				AppendMessage(wxString::Format(wxPLURAL("query result with %d row discarded.\n", "query result with %d rows discarded.\n",
 				                                        PQntuples(lastResult)), PQntuples(lastResult)));
 			PQclear(lastResult);
 		}
 		lastResult = res;
 	}
+out_of_consume_input_loop:
 
 	if (!result)
 		result = lastResult;
 
-	conn->SetLastResultError(result);
+	err.SetError(result, &conv);
 
-	appendMessage(wxT("\n"));
-	rc = PQresultStatus(result);
-	insertedOid = PQoidValue(result);
-	if (insertedOid == (OID) - 1)
-		insertedOid = 0;
+	AppendMessage(wxT("\n"));
 
+	rc = PQresultStatus(result);
 	if (rc == PGRES_TUPLES_OK)
 	{
-		dataSet = new pgSet(result, conn, *conn->conv, conn->needColQuoting);
+		dataSet = new pgSet(result, m_conn, conv, m_conn->needColQuoting);
 		dataSet->MoveFirst();
 	}
 	else if (rc == PGRES_COMMAND_OK)
@@ -239,37 +574,238 @@ int pgQueryThread::execute()
 		if (*s)
 			rowsInserted = atol(s);
 	}
-	else if (rc == PGRES_FATAL_ERROR)
+	else if (rc == PGRES_FATAL_ERROR ||
+	         rc == PGRES_NONFATAL_ERROR ||
+	         rc == PGRES_BAD_RESPONSE)
 	{
-		appendMessage(conn->GetLastError() + wxT("\n"));
+		if (result)
+		{
+			AppendMessage(wxString(PQresultErrorMessage(result), conv));
+			PQclear(result);
+			result = NULL;
+		}
+		else
+		{
+			AppendMessage(wxString(PQerrorMessage(m_conn->conn), conv));
+		}
+
+		return(RaiseEvent(rc));
 	}
-	return(raiseEvent(1));
-}
 
+	insertedOid = PQoidValue(result);
+	if (insertedOid == (Oid) - 1)
+		insertedOid = 0;
+
+	return(RaiseEvent(1));
+}
 
-int pgQueryThread::raiseEvent(int retval)
+int pgQueryThread::RaiseEvent(int _retval)
 {
-	if (caller)
-	{
 #if !defined(PGSCLI)
-		wxCommandEvent resultEvent(wxEVT_COMMAND_MENU_SELECTED, eventId);
-		resultEvent.SetClientData(data);
-#if wxCHECK_VERSION(2, 9, 0)
-		caller->GetEventHandler()->AddPendingEvent(resultEvent);
-#else
-		caller->AddPendingEvent(resultEvent);
-#endif
+	if (m_caller)
+	{
+		pgQueryResultEvent resultEvent(GetId(), m_queries[m_currIndex], m_queries[m_currIndex]->m_eventID);
 
-#endif
+		// client data
+		resultEvent.SetClientData(m_queries[m_currIndex]->m_data);
+		resultEvent.SetInt(_retval);
+
+		m_caller->AddPendingEvent(resultEvent);
 	}
-	return retval;
+#endif
+	return _retval;
 }
 
 
 void *pgQueryThread::Entry()
 {
-	rc = -2;
-	execute();
+	do
+	{
+		if (m_currIndex < (((int)m_queries.GetCount()) - 1))
+		{
+			// Create the PGcancel object to enable cancelling the running
+			// query
+			m_conn->SetConnCancel();
+			m_currIndex++;
+
+			m_queries[m_currIndex]->m_returnCode = -2;
+			m_queries[m_currIndex]->m_rowsInserted = -1l;
+
+			wxLogSql(wxT("Thread executing query (%d:%s:%d): %s"),
+			         m_currIndex + 1, m_conn->GetHost().c_str(), m_conn->GetPort(),
+			         m_queries[m_currIndex]->m_query.c_str());
+
+			// register the notice processor for the current query
+			m_conn->RegisterNoticeProcessor(m_processor, m_noticeHandler);
+
+			// execute the current query now
+			Execute();
+
+			// remove the notice processor now
+			m_conn->RegisterNoticeProcessor(0, 0);
+
+			// reset the PGcancel object
+			m_conn->ResetConnCancel();
+		}
+
+		if (!m_multiQueries || m_cancelled)
+			break;
+
+		wxThread::Sleep(20);
+	}
+	while (true);
 
 	return(NULL);
 }
+
+int pgQueryThread::DeleteReleasedQueries()
+{
+	int res = 0,
+	    idx = 0;
+
+	if (m_queriesLock.TryLock() == wxMUTEX_BUSY)
+		return res;
+
+	for (; idx <= m_currIndex; idx++)
+	{
+		if (m_queries[idx]->m_resultSet != NULL)
+		{
+			pgSet *set = m_queries[idx]->m_resultSet;
+			m_queries[idx]->m_resultSet = NULL;
+			delete set;
+			set = NULL;
+
+			res++;
+		}
+	}
+	m_queriesLock.Unlock();
+
+	return res;
+}
+
+
+const wxString &pgBatchQuery::GetErrorMessage()
+{
+	return m_err.msg_primary;
+}
+
+pgBatchQuery::~pgBatchQuery()
+{
+	if (m_resultSet)
+	{
+		delete m_resultSet;
+		m_resultSet = NULL;
+	}
+
+	if (m_params)
+	{
+		WX_CLEAR_ARRAY((*m_params));
+		delete m_params;
+		m_params = NULL;
+	}
+}
+
+bool pgBatchQuery::Release()
+{
+	bool res = false;
+
+	if (m_resultSet != NULL)
+	{
+		res = true;
+
+		pgSet *set = m_resultSet;
+		m_resultSet = NULL;
+
+		if (set)
+			delete set;
+		set = NULL;
+	}
+
+	if (m_params)
+	{
+		res = true;
+
+		WX_CLEAR_ARRAY((*m_params));
+		delete m_params;
+		m_params = NULL;
+	}
+
+	return res;
+}
+
+pgQueryResultEvent::pgQueryResultEvent(
+    unsigned long _thrdId, pgBatchQuery *_qry, int _id) :
+	wxCommandEvent(PGQueryResultEvent, _id), m_thrdId(_thrdId),
+	m_query(_qry) { }
+
+pgQueryResultEvent::pgQueryResultEvent(const pgQueryResultEvent &_ev)
+	: wxCommandEvent(_ev), m_thrdId(_ev.m_thrdId), m_query(_ev.m_query) { }
+
+
+pgParam::pgParam(Oid _type, void *_val, int _len, short _mode)
+	: m_type(_type), m_val(_val), m_len(_len), m_mode(_mode)
+{
+	switch(m_type)
+	{
+		case PGOID_TYPE_CHAR:
+		case PGOID_TYPE_NAME:
+		case PGOID_TYPE_TEXT:
+		case PGOID_TYPE_VARCHAR:
+		case PGOID_TYPE_CSTRING:
+			m_format = 0;
+		default:
+			m_format = 1;
+	}
+}
+
+// wxString data
+pgParam::pgParam(Oid _oid, wxString *_val, wxMBConv *_conv, short _mode)
+	: m_mode(_mode)
+{
+	if (m_mode == PG_PARAM_OUT || !_val)
+	{
+		m_len = 0;
+	}
+	else
+	{
+		m_len = _val->Len();
+	}
+	if (_val)
+	{
+		char *str = (char *)malloc(m_len + 1);
+		if (!_val->IsEmpty() && _mode != PG_PARAM_OUT)
+		{
+			strncpy(str,
+			        (const char *)_val->mb_str(
+			            *(_conv != NULL ? _conv : &wxConvLocal)), m_len);
+			str[m_len] = '\0';
+		}
+		else
+		{
+			str[0] = '\0';
+		}
+		m_val = (void *)(str);
+	}
+	else
+	{
+		m_val = NULL;
+	}
+	m_type = _oid;
+
+	// text format
+	m_format = 0;
+}
+
+
+pgParam::~pgParam()
+{
+	if (m_val)
+		free(m_val);
+	m_val = NULL;
+}
+
+
+int pgParam::GetFormat()
+{
+	return m_format;
+}
diff --git a/pgadmin/db/pgSet.cpp b/pgadmin/db/pgSet.cpp
index adfb1e9..3ee195a 100644
--- a/pgadmin/db/pgSet.cpp
+++ b/pgadmin/db/pgSet.cpp
@@ -20,7 +20,6 @@
 // App headers
 #include "db/pgSet.h"
 #include "db/pgConn.h"
-#include "db/pgQueryThread.h"
 #include "utils/sysLogger.h"
 #include "utils/pgDefs.h"
 
diff --git a/pgadmin/debugger/ctlCodeWindow.cpp b/pgadmin/debugger/ctlCodeWindow.cpp
deleted file mode 100644
index a93c177..0000000
--- a/pgadmin/debugger/ctlCodeWindow.cpp
+++ /dev/null
@@ -1,1563 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// ctlCodeWindow.cpp - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include "pgAdmin3.h"
-
-// wxWindows headers
-#include <wx/wx.h>
-#include <wx/colour.h>
-#include <wx/tokenzr.h>
-#include <wx/progdlg.h>
-
-// App headers
-#include "debugger/ctlCodeWindow.h"
-#include "debugger/ctlVarWindow.h"
-#include "debugger/frmDebugger.h"
-#include "debugger/dlgDirectDbg.h"
-#include "debugger/dbgConst.h"
-#include "debugger/dbgPgConn.h"
-#include "debugger/dbgResultset.h"
-#include "debugger/dbgBreakPoint.h"
-#include "ctl/ctlMenuToolbar.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// NOTES:
-//
-//    1) In this class, we update the user interface in a lazy fashion. Instead of
-//  updating the variable list, call stack, and breakpoint markers every time
-//  the target pauses, we wait for an idle period and then query the proxy for
-//  the variable list, call stack, and breakpoint list. That way, the debugger
-//    doesn't bog down when you hit the 'step over' or 'step into' key repeatedly.
-//
-//    Lazy updating is a multi-step operation.  When the target pauses (which
-//  means that a call to pldbg_continue(), pldbg_step_over(), or pldbg_step_into()
-//    has just returned), we update the source code window and then set a flag
-//    (m_updateVars) that tells us to update the variable window during the next
-//    idle period.  As soon as OnIdle() is called, we update the variable window,
-//    turn off the m_updateVars flag, and turn on the next flag (m_updateStack)
-//  to force the stack window to update itself during the next idle period.
-//    After the stack window updates itself, it turns on m_updateBreakpoints() to
-//  force the breakpoint markers to refresh.
-//
-//    2) This class will issue a number of different queries to the proxy process.
-//    Each query executes (one at a time) in a separate thread so that the user
-//    interface remains responsive. When we queue up a query, we give an event
-//    ID to the queue - when the query completes, the dbgPgThread objects sends us
-//  an event that includes the event ID that we provided.
-//
-//  All of the result-set related event names start with 'RESULT_ID_' and each
-//  event is handled by an event handler function whose name starts with 'Result'.
-//  For example, when we queue a query to retrieve the source code for a function,
-//  we tell dbgPgThread to send us a RESULT_ID_GET_SOURCE event when the query
-//    completes and we handle that event in a function named ResultSource.
-
-IMPLEMENT_CLASS(ctlCodeWindow,  pgFrame)
-
-BEGIN_EVENT_TABLE(ctlCodeWindow , pgFrame)
-	EVT_MENU(MENU_ID_TOGGLE_BREAK,            ctlCodeWindow::OnCommand)
-	EVT_MENU(MENU_ID_CLEAR_ALL_BREAK,         ctlCodeWindow::OnCommand)
-
-	EVT_MENU(MENU_ID_CONTINUE,                ctlCodeWindow::OnCommand)
-	EVT_MENU(MENU_ID_STEP_OVER,               ctlCodeWindow::OnCommand)
-	EVT_MENU(MENU_ID_STEP_INTO,               ctlCodeWindow::OnCommand)
-	EVT_MENU(MENU_ID_STOP,                    ctlCodeWindow::OnCommand)
-
-	EVT_IDLE(ctlCodeWindow::OnIdle)
-
-	EVT_BUTTON(MENU_ID_NOTICE_RECEIVED,       ctlCodeWindow::OnNoticeReceived)
-
-	EVT_LISTBOX(wxID_ANY,                     ctlCodeWindow::OnSelectFrame)
-	EVT_GRID_CELL_CHANGE(                     ctlCodeWindow::OnVarChange)
-	EVT_STC_MARGINCLICK(wxID_ANY,             ctlCodeWindow::OnMarginClick)
-	EVT_STC_UPDATEUI(wxID_ANY,                ctlCodeWindow::OnPositionStc)
-
-	EVT_MENU(RESULT_ID_ATTACH_TO_PORT,        ctlCodeWindow::ResultPortAttach)
-	EVT_MENU(RESULT_ID_BREAKPOINT,            ctlCodeWindow::ResultBreakpoint)
-	EVT_MENU(RESULT_ID_GET_VARS,              ctlCodeWindow::ResultVarList)
-	EVT_MENU(RESULT_ID_GET_STACK,             ctlCodeWindow::ResultStack)
-	EVT_MENU(RESULT_ID_GET_BREAKPOINTS,       ctlCodeWindow::ResultBreakpoints)
-	EVT_MENU(RESULT_ID_GET_SOURCE,            ctlCodeWindow::ResultSource)
-	EVT_MENU(RESULT_ID_NEW_BREAKPOINT,        ctlCodeWindow::ResultNewBreakpoint)
-	EVT_MENU(RESULT_ID_NEW_BREAKPOINT_WAIT,   ctlCodeWindow::ResultNewBreakpointWait)
-	EVT_MENU(RESULT_ID_DEL_BREAKPOINT,        ctlCodeWindow::ResultDeletedBreakpoint)
-	EVT_MENU(RESULT_ID_DEPOSIT_VALUE,         ctlCodeWindow::ResultDepositValue)
-	EVT_MENU(RESULT_ID_ABORT_TARGET,          ctlCodeWindow::ResultAbortTarget)
-	EVT_MENU(RESULT_ID_ADD_BREAKPOINT,        ctlCodeWindow::ResultAddBreakpoint)
-	EVT_MENU(RESULT_ID_LAST_BREAKPOINT,       ctlCodeWindow::ResultLastBreakpoint)
-	EVT_MENU(RESULT_ID_LISTENER_CREATED,      ctlCodeWindow::ResultListenerCreated)
-	EVT_MENU(RESULT_ID_TARGET_READY,          ctlCodeWindow::ResultTargetReady)
-
-	EVT_TIMER(wxID_ANY,                       ctlCodeWindow::OnTimer)
-END_EVENT_TABLE()
-
-////////////////////////////////////////////////////////////////////////////////
-// Static data members
-////////////////////////////////////////////////////////////////////////////////
-wxString ctlCodeWindow::m_commandAttach(wxT("SELECT * FROM pldbg_attach_to_port(%s)"));
-wxString ctlCodeWindow::m_commandWaitForBreakpoint( wxT( "SELECT * FROM pldbg_wait_for_breakpoint(%s)"));
-wxString ctlCodeWindow::m_commandGetVars(wxT("SELECT name, varClass, value, pg_catalog.format_type( dtype, NULL ) as dtype, isconst FROM pldbg_get_variables(%s)"));
-wxString ctlCodeWindow::m_commandGetStack(wxT("SELECT targetName, args, linenumber FROM pldbg_get_stack(%s) ORDER BY level"));
-wxString ctlCodeWindow::m_commandGetBreakpoints(wxT("SELECT * FROM pldbg_get_breakpoints(%s)"));
-wxString ctlCodeWindow::m_commandGetSourceV1(wxT("SELECT %s AS pkg, %s AS func, pldbg_get_source(%s,%s,%s) AS source, targetName, args FROM pldbg_get_stack(%s) ORDER BY level LIMIT 1"));
-wxString ctlCodeWindow::m_commandGetSourceV2(wxT("SELECT %s AS func, pldbg_get_source(%s,%s) AS source, targetName, args FROM pldbg_get_stack(%s) ORDER BY level LIMIT 1"));
-wxString ctlCodeWindow::m_commandStepOver(wxT("SELECT * FROM pldbg_step_over(%s)"));
-wxString ctlCodeWindow::m_commandStepInto(wxT("SELECT * FROM pldbg_step_into(%s)"));
-wxString ctlCodeWindow::m_commandContinue(wxT("SELECT * FROM pldbg_continue(%s)"));
-wxString ctlCodeWindow::m_commandSetBreakpointV1(wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%s,%d)"));
-wxString ctlCodeWindow::m_commandSetBreakpointV2(wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%d)"));
-wxString ctlCodeWindow::m_commandClearBreakpointV1(wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%s,%d)"));
-wxString ctlCodeWindow::m_commandClearBreakpointV2(wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%d)"));
-wxString ctlCodeWindow::m_commandSelectFrame(wxT("SELECT * FROM pldbg_select_frame(%s,%d)"));
-wxString ctlCodeWindow::m_commandDepositValue(wxT("SELECT * FROM pldbg_deposit_value(%s,%s,%d,%s)"));
-wxString ctlCodeWindow::m_commandAbortTarget(wxT("SELECT * FROM pldbg_abort_target(%s)"));
-wxString ctlCodeWindow::m_commandAddBreakpointEDB(wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, %s, %s, %s)"));
-wxString ctlCodeWindow::m_commandAddBreakpointPG(wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, %s, %s)"));
-wxString ctlCodeWindow::m_commandGetTargetInfo(wxT("SELECT *, %s as pid FROM pldbg_get_target_info('%s', '%c')"));
-wxString ctlCodeWindow::m_commandCreateListener(wxT("SELECT * from pldbg_create_listener()"));
-wxString ctlCodeWindow::m_commandWaitForTarget(wxT("SELECT * FROM pldbg_wait_for_target(%s)"));
-
-////////////////////////////////////////////////////////////////////////////////
-// ctlCodeWindow constructor
-//
-//    This class implements the debugger window.  The constructor expects a string
-//  that contains a TCP port number - the constructor connects to the debugger
-//  server waiting at that port.
-//
-//  A ctlCodeWindow object creates (and manages) a toolbar and handles toolbar
-//  and keystroke messages. The input messages are treated as debugger commands.
-//
-//    The m_view member is a ctlSQLBox that displays the code for the PL
-//  function that you're debugging.  The m_currentLineNumber member tracks the current
-//  line (that is, the line about to execute).  We use hilight the current line.
-//  If m_currentLineNumber is -1, there is no current line.
-
-ctlCodeWindow::ctlCodeWindow( frmDebugger *parent, wxWindowID id, const dbgConnProp &connProps )
-	: pgFrame(NULL, wxEmptyString),
-	  m_debugPort(connProps.m_debugPort),
-	  m_parent(parent),
-	  m_currentLineNumber(-1),
-	  m_updateVars(false),
-	  m_updateStack(false),
-	  m_updateBreakpoints(false),
-	  m_progressBar(NULL),
-	  m_timer(this)
-{
-	m_targetComplete = false;
-	m_targetAborted = false;
-
-	clearSourceCache();
-
-	wxWindowBase::SetFont(settings->GetSystemFont());
-
-	m_stackWindow = new ctlStackWindow(parent , WINDOW_ID_STACK,  wxDefaultPosition, wxDefaultSize, 0);
-	m_tabWindow = new ctlTabWindow(parent, WINDOW_ID_TABS, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON);
-	m_view = new ctlSQLBox(parent, -1);
-
-	// Set up the markers that we use do indicate the current line and a breakpoint
-	m_view->MarkerDefine( MARKER_CURRENT, wxSTC_MARK_ARROW , *wxGREEN, *wxGREEN );
-	m_view->MarkerDefine( MARKER_CURRENT_BG, wxSTC_MARK_BACKGROUND, *wxGREEN, *wxGREEN );
-	m_view->MarkerDefine( MARKER_BREAKPOINT, wxSTC_MARK_CIRCLEPLUS, *wxRED, *wxRED );
-
-	m_view->SetMarginWidth(1, 16);
-	m_view->SetMarginType(1, wxSTC_MARGIN_SYMBOL);
-
-	// Make sure that the text control tells us when the user clicks in the left margin
-	m_view->SetMarginSensitive( 0, true );
-	m_view->SetMarginSensitive( 1, true );
-	m_view->SetMarginSensitive( 2, true );
-
-	// Make sure the user can't edit the source code for this function...
-	m_view->SetReadOnly( true );
-
-	// We create a ctlCodeWindow when a dbgPgThread intercepts a PLDBGBREAK NOTICE
-	// generated by the PostgreSQL server.   The NOTICE contains a TCP port number
-	// and we connect to that port here.
-	m_parent->manager.AddPane(m_view, wxAuiPaneInfo().Name(wxT("sourcePane")).Caption(_("Source pane")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(350, 200)));
-	m_parent->manager.AddPane(m_stackWindow, wxAuiPaneInfo().Name(wxT("stackPane")).Caption(_("Stack pane")).Right().MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200)));
-	m_parent->manager.AddPane(m_tabWindow, wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300)));
-
-	// Now (re)load the layout
-	wxString perspective;
-	settings->Read(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), &perspective, FRMDEBUGGER_DEFAULT_PERSPECTIVE);
-	m_parent->manager.LoadPerspective(perspective, true);
-
-	// And reset the captions
-	m_parent->manager.GetPane(wxT("sourcePane")).Caption(_("Source pane"));
-	m_parent->manager.GetPane(wxT("stackPane")).Caption(_("Stack pane"));
-	m_parent->manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
-
-	// Sync the View menu options
-	m_parent->m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, m_parent->manager.GetPane(wxT("stackPane")).IsShown());
-	m_parent->m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, m_parent->manager.GetPane(wxT("outputPane")).IsShown());
-
-	// Enable the options for these controls
-	m_parent->m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, true);
-	m_parent->m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE,  true);
-
-	m_parent->manager.Update();
-
-	// The wsDbgConn constructor connects to the given host+port and
-	// and sends events to us whenever a string arrives from the
-	// debugger server.
-
-	m_parent->getStatusBar()->SetStatusText( _( "Connecting to debugger" ), 1 );
-	m_dbgConn = new dbgPgConn(m_parent, connProps, (this != 0 ? true : false) );
-	m_parent->getStatusBar()->SetStatusText( _( "Connecting to debugger..." ), 1 );
-
-	// Our proxy API may throw (perfectly legitimate) errors at us (for example,
-	// if the target process ends while we are waiting for a breakpoint) - apparently
-	// those error messages scare the user when they show up in the log, so we'll
-	// just suppress logging for this session
-
-	PQclear( m_dbgConn->waitForCommand( wxT( "SET log_min_messages TO fatal" )));
-
-	m_sessionType = SESSION_TYPE_UNKNOWN;
-
-	// force
-	enableTools();
-}
-
-void ctlCodeWindow::OnClose(wxCloseEvent &event)
-{
-	if (event.CanVeto() && !m_targetAborted && !m_targetComplete)
-	{
-		if (wxMessageBox(_("Are you sure you wish to abort the debugging session?\nThis will abort the function currently being debugged."), _("Close debugger"), wxICON_QUESTION | wxYES_NO) != wxYES)
-		{
-			event.Veto();
-			return;
-		}
-	}
-	// If we're global debugging, we may be waiting for a
-	// breakpoint if we're waiting for the function to be
-	// called a second, third, fourth etc. time
-	if (!m_parent->m_standaloneDirectDbg)
-	{
-		m_targetAborted = true;
-		if (m_dbgConn)
-		{
-			m_dbgConn->Cancel();
-			stopDebugging();
-		}
-	}
-	else
-	{
-		// If we haven't completed or aborted, stop debugging.
-		if (!m_targetComplete && !m_targetAborted)
-			stopDebugging();
-	}
-
-	// Wait for the abort to complete.
-	while (!m_targetComplete && !m_targetAborted)
-		wxTheApp->Yield(true);
-
-	closeConnection();
-	m_timer.Stop();
-
-#ifdef __WXGTK__
-	if (m_parent->m_standaloneDirectDbg && m_targetAborted && !m_targetComplete)
-		m_parent->m_standaloneDirectDbg->Close();
-#endif
-
-	event.Skip();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnMarginClick()
-//
-//  This event handler is called when the user clicks in the margin to the left
-//  of a line of source code. We use the margin to display breakpoint indicators
-//  so it makes sense that if you click on an breakpoint indicator, we will clear
-//  that breakpoint.  If you click on a spot that does not contain a breakpoint
-//  indicator (but it's still in the margin), we create a new breakpoint at that
-//  line.
-
-void ctlCodeWindow::OnMarginClick( wxStyledTextEvent &event )
-{
-	int lineNumber;
-
-	// Check that the user clicked on the line number or breakpoint margin.
-	// We don't want to set a breakpoint when the user folds/unfolds code.
-	if (!(event.GetMargin() == 0 || event.GetMargin() == 1))
-		return;
-
-	lineNumber = m_view->LineFromPosition(event.GetPosition());
-	if (!lineNumber)
-		return;
-
-	// If we already have a breakpoint at the clickpoint, disable it, otherwise
-	// create a new breakpoint.
-
-	if(m_view->MarkerGet(lineNumber) &MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))
-		clearBreakpoint(lineNumber, true);
-	else
-		setBreakpoint(lineNumber);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnPositionStc()
-//
-//  Update the current line number etc in the status bar.
-
-void ctlCodeWindow::OnPositionStc( wxStyledTextEvent &event )
-{
-	wxString pos;
-	pos.Printf(_("Ln %d Col %d Ch %d"), m_view->LineFromPosition(m_view->GetCurrentPos()) + 1, m_view->GetColumn(m_view->GetCurrentPos()) + 1, m_view->GetCurrentPos() + 1);
-	m_parent->getStatusBar()->SetStatusText(pos, 2);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// doDebug()
-//
-//  This function gets things started by asking the proxy process to attach
-//    to the given port (m_debugPort).
-
-void ctlCodeWindow::startLocalDebugging()
-{
-	m_sessionType = SESSION_TYPE_DIRECT;
-
-	m_dbgConn->startCommand( wxString::Format( m_commandAttach, m_debugPort.c_str()), GetEventHandler(), RESULT_ID_ATTACH_TO_PORT );
-}
-
-void ctlCodeWindow::resumeLocalDebugging()
-{
-	// The user has asked to resume local debugging after the previous target finished.
-	// We can find ourself in two different states here:
-	//
-	//    1) The previous target may have run to completion, in which case we are already
-	//       waiting for the target to hit a breakpoint
-	//
-	//    2) The user aborted the previous target, in which case we are NOT waiting for
-	//       a breakpoint and we'd better tell the proxy to wait
-	//
-	// We use the m_targetAborted flag to figure out which of the two states were are
-	// in. If m_targetAborted is false, our proxy is already waiting for the target
-	// to hit a breakpoint so we don't have to do anything here.  If m_targetAborted
-	// is true, the proxy is waiting for another command from us - send it a waitForBreakpoint
-	// request
-
-	// Clear the source cache in case someone updated the function in another session
-	clearSourceCache();
-	m_displayedFuncOid = wxT("-1");
-	m_displayedPackageOid = wxT("-1");
-
-	if( m_targetAborted )
-	{
-		m_targetAborted = false;
-		m_dbgConn->startCommand( wxString::Format( m_commandWaitForBreakpoint, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnActivate()
-//
-//     This event handler is called when this window is activated *or* deactivated.
-//     When we become active, we want to display the debugger toolbar.
-//     When we become inactive, we want to hide the debugger toolbar.
-
-void ctlCodeWindow::disableTools()
-{
-	setTools(false);
-}
-
-void ctlCodeWindow::enableTools()
-{
-	setTools(true);
-}
-
-void ctlCodeWindow::setTools(bool enable)
-{
-	// If we don't have a connection to the debugger proxy, disable all
-	// of the debugger controls
-	bool activateDebug = true;
-
-	if( m_dbgConn == NULL )
-		activateDebug = false;
-
-	if( enable == false )
-		activateDebug = false;
-
-	ctlMenuToolbar *t = m_parent->m_toolBar;
-	wxMenu *m = m_parent->m_debugMenu;
-
-	// We may find that our toolbar has disappeared during application shutdown -
-	// It seems a little strange that OnActivate() is called during shutdown, but
-	// that does seem to happen on Win32 hosts.
-
-	if (t)
-	{
-		t->EnableTool( MENU_ID_STEP_INTO,       activateDebug );
-		t->EnableTool( MENU_ID_STEP_OVER,       activateDebug );
-		t->EnableTool( MENU_ID_CONTINUE,        activateDebug );
-		t->EnableTool( MENU_ID_TOGGLE_BREAK,       activateDebug );
-		t->EnableTool( MENU_ID_CLEAR_ALL_BREAK, activateDebug );
-		t->EnableTool( MENU_ID_STOP,            activateDebug );
-	}
-
-	if (m)
-	{
-		m->Enable( MENU_ID_STEP_INTO,       activateDebug );
-		m->Enable( MENU_ID_STEP_OVER,       activateDebug );
-		m->Enable( MENU_ID_CONTINUE,        activateDebug );
-		m->Enable( MENU_ID_TOGGLE_BREAK,       activateDebug );
-		m->Enable( MENU_ID_CLEAR_ALL_BREAK, activateDebug );
-		m->Enable( MENU_ID_STOP,            activateDebug );
-	}
-
-	/* Activate hook */
-	m_parent->Show( true );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnIdle()
-//
-//    This event handler is called during 'idle time' (that is, when other events
-//  are not waiting in the queue).  We use the idle period to update most parts
-//  of the user interface in a lazy fashion.  That way, the debugger doesn't
-//  bog down when you hit the 'step over' or 'step into' key repeatedly - we
-//  don't bother updating the variable list, call stack, or breakpoint markers
-//  until the user pauses for a moment.
-
-void ctlCodeWindow::OnIdle( wxIdleEvent &event )
-{
-	if (m_targetAborted)
-		return;
-
-	if( m_updateVars )
-	{
-		m_updateVars = false;
-		m_dbgConn->startCommand( wxString::Format( m_commandGetVars, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_GET_VARS );
-		return;
-	}
-
-	if( m_updateStack )
-	{
-		m_updateStack = false;
-		m_dbgConn->startCommand( wxString::Format( m_commandGetStack, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_GET_STACK );
-		return;
-	}
-
-	if( m_updateBreakpoints )
-	{
-		m_updateBreakpoints = false;
-		m_dbgConn->startCommand( wxString::Format( m_commandGetBreakpoints, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_GET_BREAKPOINTS );
-		return;
-	}
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultPortAttach()
-//
-//    This event handler is called when the result set of an earlier query arrives
-//  from the proxy. In this case, the result set is generated by a call to
-//  pldbg_attach_to_port(). If the query succeeded, our proxy is connected to
-//  the debugger server running inside of the target process. At that point,
-//  we have to wait for the target process to wait for a breakpoint so we
-//  queue up another query (a call to pldbg_wait_for_breakpoint()).
-
-void ctlCodeWindow::ResultPortAttach( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( result.getCommandStatus() == PGRES_TUPLES_OK )
-	{
-		m_parent->getStatusBar()->SetStatusText( _( "Connected to debugger" ), 1 );
-
-		m_sessionHandle = result.getString( 0 );
-
-		m_dbgConn->startCommand( wxString::Format( m_commandWaitForBreakpoint, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-	}
-	else
-	{
-		wxLogError( result.getErrorMessage(), _( "Connection Error" ));
-		closeConnection();
-	}
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultBreakpoint()
-//
-//    This event handler is called when the target process pauses.  The target
-//  may have reached a breakpoint or it may have just completed a step/over or
-//    step/into.
-//
-//    In any case, we schedule an update of the user interface for the next idle
-//  period by calling updateUI().
-
-void ctlCodeWindow::ResultBreakpoint( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getCommandStatus() == PGRES_TUPLES_OK )
-		{
-			// Change our focus
-			if (result.columnExists(wxT("pkg")))
-				m_focusPackageOid = result.getString(wxT( "pkg"));
-			else
-				m_focusPackageOid = wxT("0");
-
-			m_focusFuncOid    = result.getString(wxT("func"));
-
-			// The result set contains one tuple:
-			//    packageOID, functionOID, linenumber
-			m_parent->getStatusBar()->SetStatusText(wxString::Format(_( "Paused at line %d"), atoi(result.getString(wxT("linenumber")).ToAscii()) - 1), 1);
-			updateUI(result);
-
-			/* break point markup line number */
-			unhilightCurrentLine();
-
-			int current_line = atoi(result.getString( wxT("linenumber")).ToAscii()) - 1;
-			if ( current_line < 0)
-				current_line = 1;
-			m_currentLineNumber = current_line;
-
-			m_view->SetAnchor(m_view->PositionFromLine(!current_line ? 0 : current_line - 1));
-			m_view->SetCurrentPos(m_view->PositionFromLine(!current_line ? 0 : current_line - 1));
-			m_view->MarkerAdd(current_line - 1, MARKER_CURRENT);
-			m_view->MarkerAdd(current_line - 1, MARKER_CURRENT_BG);
-			m_view->EnsureCaretVisible();
-			enableTools();
-
-		}
-		else if(result.getCommandStatus() == PGRES_FATAL_ERROR)
-		{
-			if (!m_targetAborted)
-			{
-				// We were waiting for a breakpoint (because we just sent a step into, step over, or continue request) and
-				// the proxy sent us an error instead.  Presumably, the target process exited before reaching a breakpoint.
-				//
-				// If we have any global breakpoints, we must have a listener in the proxy... wait for the next target process.
-
-				if( m_breakpoints.GetCount())
-				{
-					m_dbgConn->startCommand( wxString::Format(m_commandWaitForTarget, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_TARGET_READY);
-
-					m_parent->getStatusBar()->SetStatusText(_("Waiting for a target"), 1 );
-					m_parent->getStatusBar()->SetStatusText(wxT(""), 2 );
-
-					launchWaitingDialog();
-				}
-			}
-		}
-	}
-}
-
-
-void ctlCodeWindow::launchWaitingDialog()
-{
-	m_parent->getStatusBar()->SetStatusText(wxString::Format( _( "Waiting for another session to invoke %s" ), m_targetName.c_str()), 1 );
-
-	// NOTE: the waiting-dialog takes forever to appear running a remote X session so you can disable it by defining the following env. variable
-	if( getenv( "SUPPRESS_WAIT_DIALOG" ))
-		m_progressBar = NULL;
-	else
-	{
-		m_progressBar = new wxProgressDialog(_( "Waiting for target" ), wxString::Format( _( "Waiting for breakpoint in %s" ), m_targetName.c_str()), 100, m_parent, wxPD_SMOOTH | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
-
-		m_timer.Start( 100 );    // 10 clock ticks per second
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultVarList()
-//
-//    This event handler is called when the proxy finishes sending us a list of
-//  variables (in response to an earlier call to pldbg_get_variables()).
-//
-//    We extract the variable names, types, and values from the result set and
-//    add them to the variable (and parameter) windows.
-
-void ctlCodeWindow::ResultVarList( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getCommandStatus() == PGRES_TUPLES_OK )
-		{
-			// The result set contains one tuple per variable
-			for( int row = 0; row < result.getRowCount(); ++row )
-			{
-				wxString    varName = result.getString( wxT( "name" ), row );
-				char        varClass = result.getString( wxT( "varclass" ), row )[0];
-
-				if( varClass == 'A' )
-				{
-					getParamWindow( true )->addVar( varName, result.getString( wxT( "value" ), row ), result.getString( wxT( "dtype" ), row ), result.getBool( wxT( "isconst" ), row ));
-				}
-				else if( varClass == 'P' )
-				{
-					getPkgVarWindow( true )->addVar( varName, result.getString( wxT( "value" ), row ), result.getString( wxT( "dtype" ), row ), result.getBool( wxT( "isconst" ), row ));
-				}
-				else
-				{
-					getVarWindow( true )->addVar( varName, result.getString( wxT( "value" ), row ), result.getString( wxT( "dtype" ), row ), result.getBool( wxT( "isconst" ), row ));
-				}
-			}
-		}
-
-		// Update the next part of the user interface
-		m_updateStack = true;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultStack()
-//
-//    This event handler is called when the proxy finishes sending us a stack
-//    trace (in response to an earlier call to pldbg_get_stack()).
-//
-//    We extract each frame from the result set and add it to the stack window.
-//    For each frame, the proxy sends us the function name, line number, and
-//  a string that holds the name and value of each argument.
-
-void ctlCodeWindow::ResultStack( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getCommandStatus() == PGRES_TUPLES_OK )
-		{
-			// The result set contains one tuple per frame:
-			//        package, function, linenumber, args
-
-			wxArrayString    stack;
-
-			for(int row = 0; row < result.getRowCount(); ++row)
-				stack.Add(wxString::Format(wxT( "%s(%s)@%s" ), result.getString(wxT("targetName"), row ).c_str(), result.getString(wxT("args"), row).c_str(), result.getString(wxT("linenumber"), row).c_str()));
-
-			getStackWindow()->clear();
-			getStackWindow()->setStack( stack );
-
-		}
-
-		m_updateBreakpoints = true;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultBreakpoints()
-//
-//    This event handler is called when the proxy finishes sending us a list of
-//  breakpoints (in response to an earlier SHOW BREAKPOINTS command).
-//
-//    We clear out the old breakpoint markers and then display a new marker
-//    for each breakpoint defined in the current function.
-
-void ctlCodeWindow::ResultBreakpoints(wxCommandEvent &event)
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost(result))
-		closeConnection();
-	else
-	{
-		if(result.getCommandStatus() == PGRES_TUPLES_OK)
-		{
-			clearBreakpointMarkers();
-
-			// The result set contains one tuple per breakpoint:
-			//        packageOID, functionOID, linenumber
-
-			for(int row = 0; row < result.getRowCount(); ++row)
-			{
-				m_view->MarkerAdd(result.getLong(wxT("linenumber"), row) - 1, MARKER_BREAKPOINT);
-			}
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultSource()
-//
-//    This event handler is called when the proxy finishes sending us the source
-//    code for a function (in response to an earlier call to pldbg_get_source()).
-//
-//    We keep a client-side cache of source code listings to avoid an extra
-//  round trip for each step. In this function, we add the source code to
-//  the cache and then display the source code in the source window.
-
-void ctlCodeWindow::ResultSource(wxCommandEvent &event)
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if(connectionLost(result))
-		closeConnection();
-	else
-	{
-		wxString pkg = wxT("0");
-		if (result.columnExists(wxT("pkg")))
-			pkg = result.getString(wxT("pkg"));
-
-		cacheSource(pkg, result.getString(wxT("func")), result.getString(wxT("source")), wxString::Format(wxT("%s(%s)"), result.getString(wxT("targetName")).c_str(), result.getString(wxT("args")).c_str()));
-		displaySource(pkg, result.getString(wxT("func")));
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultDeletedBreakpoint()
-//
-//    This event handler is called when the proxy finishes executing a DROP
-//    BREAKPOINT command on our behalf.
-//
-//    If the DROP BREAKPOINT command succeeded, we display a mesasge in the
-//  status bar.
-
-void ctlCodeWindow::ResultDeletedBreakpoint( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getBool( 0 ))
-		{
-			m_updateBreakpoints = true;
-			m_parent->getStatusBar()->SetStatusText( _( "Breakpoint dropped" ), 1 );
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultNewBreakpoint()
-//
-//    This event handler is called when the proxy finishes executing a CREATE
-//    BREAKPOINT command on our behalf.
-//
-//    We schedule a refresh of our breakpoint markers for the next idle period.
-
-void ctlCodeWindow::ResultNewBreakpoint( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else if( gotFatalError( result ))
-		popupError(result);
-	else
-	{
-	}
-}
-
-void ctlCodeWindow::ResultNewBreakpointWait( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else if( gotFatalError( result ))
-		popupError(result);
-	else
-	{
-		setTools(false);
-		m_dbgConn->startCommand( wxString::Format( m_commandWaitForTarget, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_TARGET_READY );
-
-		launchWaitingDialog();
-	}
-}
-////////////////////////////////////////////////////////////////////////////////
-// ResultDepositValue()
-//
-//    This event handler is called when the proxy completes a 'deposit' operation
-//    (in response to an earlier call to pldbg_deposit_value()).
-//
-//    We schedule a refresh of our variable window(s) for the next idle period.
-
-void ctlCodeWindow::ResultDepositValue( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getBool( 0 ))
-		{
-			m_parent->getStatusBar()->SetStatusText( _( "Value changed" ), 1 );
-			m_updateVars = true;
-		}
-		else
-		{
-			wxLogError(wxT( "Could not deposit the new value." ));
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultAbortTarget()
-//
-//    This event handler is called when the proxy completes an 'abort target'
-//  operation (in response to an earlier call to pldbg_abort_target()).
-//
-
-void ctlCodeWindow::ResultAbortTarget( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		if( result.getBool( 0 ))
-		{
-			// Make a note of the fact that we've aborted the target, that way we
-			// can know (should we start debugging again) that we are *not* waiting
-			// for a breakpoint.
-			m_targetAborted = true;
-
-			m_parent->getStatusBar()->SetStatusText( _( "Execution Canceled" ), 1 );
-
-			// Remove the current-line indicator
-			unhilightCurrentLine();
-
-			// And force the toolbar to refresh itself (to disable the debugger-related tools)
-			setTools(false);
-		}
-		else
-		{
-			// FIXME: display error message here...
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// connectionLost()
-//
-//    This function checks the given result set to determine whether the connection
-//  to the debugger proxy is still viable.  For the moment, we assume that any
-//  fatal error is... fatal.  We should probably PQstatus() if we get a fatal
-//    error.
-
-bool ctlCodeWindow::connectionLost( dbgResultset &resultSet )
-{
-	if (!m_dbgConn)
-		return true;
-
-	if( m_dbgConn->isConnected())
-		return false;
-	else
-		return true;
-}
-
-bool ctlCodeWindow::gotFatalError( dbgResultset &resultSet )
-{
-	if( resultSet.getCommandStatus() == PGRES_FATAL_ERROR )
-		return( true );
-	else
-		return( false );
-}
-
-void ctlCodeWindow::popupError(dbgResultset &resultSet)
-{
-	wxLogError(wxT("%s"), resultSet.getErrorMessage().c_str());
-	m_timer.Stop();
-	m_parent->getStatusBar()->SetStatusText(_( "Done." ), 1 );
-	setTools(false);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// closeConnection()
-//
-//    This member function closes the connection to the debugger and changes the
-//  user interface to let the user know what just happened. In particular, we
-//    remove the breakpoint markers (they may be obsolete) and disable the
-//    debugger-related tools on the toolbar.
-
-void ctlCodeWindow::closeConnection()
-{
-	// Close the debugger (proxy) connection
-	if (m_dbgConn)
-		m_dbgConn->Close();
-	m_dbgConn = NULL;
-
-	// Let the user know what happened
-	m_parent->getStatusBar()->SetStatusText( _( "Debugger connection terminated (session complete)" ), 1 );
-
-	// Remove the current-line indicator
-	unhilightCurrentLine();
-
-	// And force the toolbar to refresh itself (to disable the debugger-related tools)
-	setTools(false);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// updateSourceCode()
-//
-//    This function is invoked whenever the target process pauses (either because
-//    it reached a breakpoint or because it just completed a step over/into).  In
-//  this function, we update the source code window.
-//
-//    The caller gives us a result set (that had better contain a breakpoint tuple)
-//    that gives us the OID of the function that we're paused in.  We search our
-//    cache for the source code for that function. If we don't already have the
-//    source code for the function, we send a request for the code to the proxy and
-//    (asynchronously) wait for the result set (ResultSource() is called when the
-//    result set arrives). If we have the required source code (in the cache), we
-//  display the code in the source window (if not already displayed).
-
-void ctlCodeWindow::updateSourceCode(dbgResultset &breakpoint)
-{
-	wxString packageOID, funcOID, lineNumber;
-
-	if (breakpoint.columnExists(wxT("pkg")))
-		packageOID = breakpoint.getString( wxT("pkg"));
-	else
-		packageOID = wxT("0");
-
-	funcOID = breakpoint.getString(wxT("func"));
-	lineNumber = breakpoint.getString(wxT("linenumber"));
-
-	m_currentLineNumber = atoi((const char *)lineNumber.c_str());
-
-	if(!findSourceInCache(packageOID, funcOID))
-	{
-		getSource(packageOID, funcOID);
-	}
-	else
-	{
-		displaySource(packageOID, funcOID);
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// updateUI()
-//
-//    This function is called each time the target pauses (either because it reached
-//  a breakpoint or because it just completed a step over/into). We update some
-//    parts of the user interface in a lazy fashion so that we remain responsive if
-//  the user repeatedly hits the step over/into key.  updateUI() turns off the lazy
-//  update flags and the updates the source code window - when the source code
-//  refresh completes, we schedule a variable refresh for the next idle period.
-//    When the variable refresh completes, it schedules a stack refresh...
-
-void ctlCodeWindow::updateUI(dbgResultset &breakpoint)
-{
-	// Arrange for the lazy parts of our UI to be updated
-	// during the next IDLE time
-	m_updateVars    = false;
-	m_updateStack    = false;
-	m_updateBreakpoints = false;
-
-	updateSourceCode(breakpoint);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// clearBreakpointMarkers()
-//
-//    This is a helper function that clears all of the breakpoint markers currently
-//    displayed in the source code window (m_view).
-
-void ctlCodeWindow::clearBreakpointMarkers()
-{
-	int    lineNo = 0;
-
-	while(( lineNo = m_view->MarkerNext( lineNo, MARKERINDEX_TO_MARKERMASK( MARKER_BREAKPOINT ))) != -1 )
-		m_view->MarkerDelete( lineNo++, MARKER_BREAKPOINT );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// findSourceInCache()
-//
-//    A ctlCodeWindow can display the source code for many different functions (if
-//  you step from one function into another function, the same ctlCodeWindow will
-//  display the source code for each function).
-//
-//    To avoid constantly re-sending the source code for each function over the
-//  network we keep a cache (m_sourceCodeMap) of the source code for each
-//  function that we've seen. The cache is indexed by function OID.  We keep
-//  track of the transaction and command ID for each function too so we know
-//  when our cached copy becomes stale.
-//
-//  This function searches the cache for an entry that matches the given
-//  function ID.  Note that we simply return true or false to indicate
-//  whether the function exists in the cache - to retreive the actual source
-//  code for a function, call getSource()
-
-bool ctlCodeWindow::findSourceInCache(const wxString &packageOID, const wxString &funcOID)
-{
-	sourceHash::iterator match = m_sourceCodeMap.find(funcOID);
-
-	if (match == m_sourceCodeMap.end())
-		return(false);
-	else
-	{
-		// FIXME: compare the xid and cid here, throw out out the cached copy (and return false) if they don't match
-		return(true);
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// clearSourceCache()
-//
-// (Re-)initializes the source cache.
-
-void ctlCodeWindow::clearSourceCache()
-{
-	m_sourceCodeMap.clear();
-
-	// Put a dummy entry for invalid function OID to the cache. This is
-	// displayed at least for inline code blocks, as we currently have
-	// no way to fetch the source for those.
-	m_sourceCodeMap[wxT("0")] = wsCodeCache(wxT("0"), wxT("0"), wxT("<source not available>"), wxT(""));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// cacheSource()
-//
-//    This function adds the source code for a given function to the cache.  See
-//  findSourceInCache() for more details.
-
-void ctlCodeWindow::cacheSource(const wxString &packageOID, const wxString &funcOID, const wxString &sourceCode, const wxString &signature)
-{
-	// Throw out any stale version
-	m_sourceCodeMap.erase(funcOID);
-
-	// And add the new version to the cache.
-	m_sourceCodeMap[funcOID] = wsCodeCache(packageOID, funcOID, sourceCode, signature);
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getSource()
-//
-//    This function retrieves the source code for a given function from the
-//  PostgreSQL server. We don't actually wait for completionm, we just
-//  schedule the request.
-
-void ctlCodeWindow::getSource(const wxString &packageOID, const wxString &funcOID)
-{
-	if (m_dbgConn->DebuggerApiVersion() <= DEBUGGER_V2_API)
-		m_dbgConn->startCommand(wxString::Format(m_commandGetSourceV1, packageOID.c_str(), funcOID.c_str(), m_sessionHandle.c_str(), packageOID.c_str(), funcOID.c_str(), m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_GET_SOURCE);
-	else
-		m_dbgConn->startCommand(wxString::Format(m_commandGetSourceV2, funcOID.c_str(), m_sessionHandle.c_str(), funcOID.c_str(), m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_GET_SOURCE);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// displaySource()
-//
-//    This function loads the source code for the given funcID into the view.
-//  If the requested function is already loaded, we just return without doing
-//  any extra work.
-
-void ctlCodeWindow::displaySource(const wxString &packageOID, const wxString &funcOID)
-{
-
-	// We're about to display the source code for the target, give the keyboard
-	// focus to the view (so that function keys will work).  This seems like a
-	// reasonable point in time to grab the focus since we're just doing something
-	// rather visual.
-	m_view->SetFocus();
-
-	// If we've already loaded the source code for this function, just update the current-line marker
-	if( m_displayedFuncOid != funcOID || m_displayedPackageOid != packageOID )
-	{
-		// We're looking at a different target now, delete all of the local, package, and parameter variables
-		// so we can add the variables defined by the new target.
-		if( getVarWindow( false ))
-			getVarWindow( false )->delVar();
-
-		if( getParamWindow( false ))
-			getParamWindow( false )->delVar();
-
-		if( getPkgVarWindow( false ))
-			getPkgVarWindow( false )->delVar();
-
-		m_displayedFuncOid       = funcOID;
-		m_displayedPackageOid = packageOID;
-
-		wsCodeCache &codeCache = m_sourceCodeMap[funcOID];
-
-		// Now erase any old code and write out the new listing
-		m_view->SetReadOnly( false );
-
-		// Get the source. Ignore any CRs.
-		wxString src = codeCache.getSource();
-		src.Replace(wxT("\r"), wxT(""));
-
-		// Before PostgreSQL 9.1, the server ignored an initial newline
-		// when calculating line numbers. The line numbers of what we display
-		// has to match the server's numbering, or all the highlighting and
-		// breakpoints are off, so if we're connected to a server older than
-		// 9.1, strip the initial newline from the display.
-		if (src.StartsWith(wxT("\n")))
-		{
-			if (!m_dbgConn->BackendMinimumVersion(9, 1))
-				src = src.AfterFirst('\n');
-		}
-
-		m_view->SetText(src);
-
-		m_view->Colourise(0, src.Length());
-		m_view->SetReadOnly(true);
-	}
-
-	// Clear the current-line indicator
-	int lineNo = m_view->MarkerNext(0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT));
-	int current_line = m_currentLineNumber;
-
-	if (lineNo != -1)
-	{
-		m_view->MarkerDelete(lineNo, MARKER_CURRENT);
-		m_view->MarkerDelete(lineNo, MARKER_CURRENT_BG);
-	}
-
-	// Adjustment of the next position
-	if (current_line >= 1)
-		current_line--;
-
-	// Add the current-line indicator to the current line of code
-	m_view->MarkerAdd(current_line, MARKER_CURRENT);
-	m_view->MarkerAdd(current_line, MARKER_CURRENT_BG);
-
-	// Scroll the source code listing (if required) to make sure
-	// that this line of code is visible
-	//
-	// (note: we set the anchor and the caret to the same position to avoid
-	// creating a selection region)
-	m_view->SetAnchor(m_view->PositionFromLine(current_line));
-	m_view->SetCurrentPos(m_view->PositionFromLine(current_line));
-	m_view->EnsureCaretVisible();
-
-	// Update the next lazy part of the user interface (the variable list)
-	m_updateVars = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getLineNo()
-//
-//     Figure out which line (in the source code listing) contains the cursor
-//    (actually, the insertion point)
-
-int ctlCodeWindow::getLineNo( )
-{
-	return(m_view->LineFromPosition( m_view->GetCurrentPos( )));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnCommand()
-//
-//     This event handler is called when the user clicks a button in the debugger
-//    toolbar.
-
-void ctlCodeWindow::OnCommand( wxCommandEvent &event )
-{
-
-	switch( event.GetId())
-	{
-		case MENU_ID_TOGGLE_BREAK:
-		{
-			// The user wants to set or clear a breakpoint at the line that
-			// contains the insertion point (the caret)
-			if (isBreakpoint(getLineNo()))
-				clearBreakpoint(getLineNo(), true);
-			else
-				setBreakpoint(getLineNo());
-			break;
-		}
-
-		case MENU_ID_CLEAR_ALL_BREAK:
-		{
-			// The user wants to clear all the breakpoint
-			clearAllBreakpoints();
-			break;
-		}
-
-		case MENU_ID_CONTINUE:
-		{
-			// The user wants to continue execution (as opposed to
-			// single-stepping through the code).  Unhilite all
-			// variables and tell the debugger server to continue.
-			m_dbgConn->startCommand( wxString::Format( m_commandContinue, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-			m_parent->getStatusBar()->SetStatusText( _( "Waiting for target (continue)..." ), 1 );
-			unhilightCurrentLine();
-			disableTools();
-			break;
-		}
-
-		case MENU_ID_STEP_OVER:
-		{
-			// The user wants to step-over a function invocation (or
-			// just single-step). Unhilite all variables and tell the
-			// debugger server to step-over
-			m_dbgConn->startCommand( wxString::Format( m_commandStepOver, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-			m_parent->getStatusBar()->SetStatusText( _( "Waiting for target (step over)..." ), 1 );
-			unhilightCurrentLine();
-			disableTools();
-			break;
-		}
-
-		case MENU_ID_STEP_INTO:
-		{
-			// The user wants to step-into a function invocation (or
-			// just single-step). Unhilite all variables and tell the
-			// debugger server to step-into
-			m_dbgConn->startCommand( wxString::Format( m_commandStepInto, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-			m_parent->getStatusBar()->SetStatusText( _( "Waiting for target (step into)..." ), 1 );
-			unhilightCurrentLine();
-			disableTools();
-			break;
-		}
-
-		case MENU_ID_STOP:
-		{
-			stopDebugging();
-			if (!m_parent->m_standaloneDirectDbg)
-				closeConnection();
-			unhilightCurrentLine();
-			break;
-		}
-
-		default:
-			break;
-	}
-}
-
-void ctlCodeWindow::OnNoticeReceived( wxCommandEvent &event )
-{
-	getMessageWindow()->AppendText( event.GetString());
-	m_tabWindow->selectTab( ID_MSG_PAGE );
-}
-
-void ctlCodeWindow::OnResultSet( PGresult *result )
-{
-	getResultWindow()->fillGrid( result );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// setBreakpoint()
-//
-//    This function creates a breakpoint at the given line number (actually, it
-//  sends a request to the debugger server to create the breakpoint - the server
-//  will send back a reply if everything worked).
-
-void ctlCodeWindow::setBreakpoint(int lineNumber)
-{
-	if (m_dbgConn->DebuggerApiVersion() <= DEBUGGER_V2_API)
-		m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-	else
-		m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-
-	m_updateBreakpoints = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// clearBreakpoint()
-//
-//    This function clears a breakpoint at the given line number (actually, it
-//  sends a request to the debugger server to clear the breakpoint)
-
-void ctlCodeWindow::clearBreakpoint( int lineNumber, bool requestUpdate )
-{
-	if (m_dbgConn->DebuggerApiVersion() <= DEBUGGER_V2_API)
-		m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-	else
-		m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-
-	if (requestUpdate)
-		m_updateBreakpoints = true;
-}
-
-void ctlCodeWindow::clearAllBreakpoints()
-{
-	int    lineNo = 0;
-
-	if (m_view)
-	{
-		while(( lineNo = m_view->MarkerNext( lineNo, MARKERINDEX_TO_MARKERMASK( MARKER_BREAKPOINT ))) != -1 )
-			clearBreakpoint( lineNo++, false );
-
-		m_updateBreakpoints = true;
-	}
-}
-
-void ctlCodeWindow::stopDebugging()
-{
-	m_dbgConn->startCommand( wxString::Format( m_commandAbortTarget, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_ABORT_TARGET );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnSelectFrame()
-//
-//  This event handler is called when the user clicks on a frame in the stack-
-//  trace window.  We ask the debugger server to switch to that frame, update
-//  the breakpoint markers, and send a list of variables that are in-scope in
-//  the selected frame.
-//
-//  Note: when the debugger server sees a '^' command, it automatically sends
-//        is a "current-statement-location" message and we'll update the source
-//        code listing when we receive that message.
-//
-
-void ctlCodeWindow::OnSelectFrame( wxCommandEvent &event )
-{
-	if( event.GetSelection() != -1 )
-	{
-		if (!m_targetComplete && !m_targetAborted)
-			m_dbgConn->startCommand( wxString::Format( m_commandSelectFrame, m_sessionHandle.c_str(), event.GetSelection()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-	}
-}
-
-void ctlCodeWindow::OnVarChange( wxGridEvent &event )
-{
-	ctlVarWindow        *window;
-
-	if( event.GetId() == ID_PARAMGRID )
-		window = getParamWindow( false );
-	else if( event.GetId() == ID_VARGRID )
-		window = getVarWindow( false );
-	else
-		window = getPkgVarWindow( false );
-
-	wxString varName  = window->getVarName( event.GetRow());
-	wxString varValue = window->getVarValue( event.GetRow());
-
-	if( event.GetId() == ID_PKGVARGRID )
-		varName.Prepend( wxT( "@" ));
-
-	m_dbgConn->startCommand( wxString::Format( m_commandDepositValue, m_sessionHandle.c_str(), m_dbgConn->qtDbString(varName).c_str(), -1, m_dbgConn->qtDbString(varValue).c_str()), GetEventHandler(), RESULT_ID_DEPOSIT_VALUE );
-
-
-}
-
-void ctlCodeWindow::startGlobalDebugging( )
-{
-	m_sessionType = SESSION_TYPE_INCONTEXT;
-
-	m_dbgConn->startCommand(m_commandCreateListener, GetEventHandler(), RESULT_ID_LISTENER_CREATED);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ResultListenerCreated()
-//
-//    This event handler is called when the result set of an earlier query arrives
-//  from the proxy. In this case, the result set is generated by a call to
-//  pldbg_create_listener(). If the query succeeded, our proxy has created a
-//  global listener that's listening for a debugger target.  At this point, the
-//  listener is *not* waiting for a target, it's just created the socket.
-//  Now we'll issue another query (to the proxy) that will force it to wait
-//  for a debugger target.
-
-void ctlCodeWindow::ResultListenerCreated( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		// We now have a global listener and a session handle.
-		// Grab the session handle (we'll need it for just about
-		// everything else).
-
-		m_sessionHandle = result.getString( 0 );
-
-		// Now create any global breakpoints that the user requested.
-		// We start by asking the server to resolve the breakpoint name
-		// into an OID (or a pair of OID's if the target is defined in a
-		// package).  As each (targetInfo) result arrives, we add a
-		// breakpoint at the resulting OID.
-
-		unsigned int    index = 1;
-
-		for( dbgBreakPointList::Node *node = m_breakpoints.GetFirst(); node; node = node->GetNext(), ++index )
-		{
-			dbgBreakPoint *breakpoint = node->GetData();
-
-			if( index < m_breakpoints.GetCount())
-				addBreakpoint( breakpoint, RESULT_ID_ADD_BREAKPOINT );
-			else
-				addBreakpoint( breakpoint, RESULT_ID_LAST_BREAKPOINT );
-		}
-	}
-}
-
-void ctlCodeWindow::ResultTargetReady(  wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if(m_progressBar)
-	{
-		m_progressBar->Close();
-		delete m_progressBar;
-		m_progressBar = NULL;
-	}
-
-	if( connectionLost( result ))
-		closeConnection();
-	else
-	{
-		setTools(true);
-		m_dbgConn->startCommand( wxString::Format( m_commandWaitForBreakpoint, m_sessionHandle.c_str()), GetEventHandler(), RESULT_ID_BREAKPOINT );
-	}
-}
-
-void ctlCodeWindow::addBreakpoint( dbgBreakPoint *breakpoint, wxEventType nextStep )
-{
-	// The user want's to add a (global) breakpoint on a function, procedure, oid, or trigger
-	//
-	// First, ask the proxy to resolve the target name into an OID (or two OID's if the
-	// target happens to reside in a package).  When the target info arrives, we'll get a
-	// RESULT_ID_ADD_BREAKPOINT message.
-
-	char    targetType = 0;
-
-	switch( breakpoint->getTargetType())
-	{
-		case dbgBreakPoint::FUNCTION:
-			targetType = 'f';
-			break;
-		case dbgBreakPoint::PROCEDURE:
-			targetType = 'p';
-			break;
-		case dbgBreakPoint::OID:
-			targetType = 'o';
-			break;
-		case dbgBreakPoint::TRIGGER:
-			targetType = 't';
-			break;
-	}
-
-	m_dbgConn->startCommand( wxString::Format( m_commandGetTargetInfo, breakpoint->getTargetProcess().c_str(), breakpoint->getTarget().c_str(), targetType ), GetEventHandler(), nextStep );
-}
-
-void ctlCodeWindow::ResultAddBreakpoint( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else if( gotFatalError( result ))
-		popupError(result);
-	else
-	{
-		/*
-		 * In EnterpriseDB versions <= 9.1 the
-		 * pldbg_set_global_breakpoint function took five arguments,
-		 * the 2nd argument being the package's OID, if any. Starting
-		 * with 9.2, the package OID argument is gone, and the function
-		 * takes four arguments like the community version has always
-		 * done.
-		 */
-		if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2))
-			m_dbgConn->startCommand(wxString::Format(m_commandAddBreakpointEDB, m_sessionHandle.c_str(), result.getString(wxT("pkg")).c_str(), result.getString(wxT("target")).c_str(), wxT("NULL"), result.getString(wxT( "pid")).c_str()), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-		else
-			m_dbgConn->startCommand(wxString::Format(m_commandAddBreakpointPG, m_sessionHandle.c_str(), result.getString(wxT("target")).c_str(), wxT("NULL"), result.getString(wxT( "pid")).c_str()), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
-
-		if( m_targetName.IsEmpty() == false )
-			m_targetName.Append( wxT( ", " ));
-
-		m_targetName.Append( result.getString( wxT( "fqname" )));
-	}
-}
-
-void ctlCodeWindow::ResultLastBreakpoint( wxCommandEvent &event )
-{
-	dbgResultset  result((PGresult *)event.GetClientData());
-
-	if( connectionLost( result ))
-		closeConnection();
-	else if( gotFatalError( result ))
-		popupError(result);
-	else
-	{
-		/*
-		 * In EnterpriseDB versions <= 9.1 the
-		 * pldbg_set_global_breakpoint function took five arguments,
-		 * the 2nd argument being the package's OID, if any. Starting
-		 * with 9.2, the package OID argument is gone, and the function
-		 * takes four arguments like the community version has always
-		 * done.
-		 */
-		if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2))
-			m_dbgConn->startCommand(wxString::Format(m_commandAddBreakpointEDB, m_sessionHandle.c_str(), result.getString(wxT("pkg")).c_str(), result.getString(wxT("target")).c_str(), wxT("NULL"), result.getString(wxT("pid")).c_str()), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT_WAIT);
-		else
-			m_dbgConn->startCommand(wxString::Format(m_commandAddBreakpointPG, m_sessionHandle.c_str(), result.getString(wxT("target")).c_str(), wxT("NULL"), result.getString(wxT("pid")).c_str()), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT_WAIT);
-
-		if( m_targetName.IsEmpty() == false )
-			m_targetName.Append( wxT( ", " ));
-
-		m_targetName.Append( result.getString( wxT( "fqname" )));
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getBreakpointList()
-//
-//    This function returns a non-const reference to our breakpoint list.  The
-//  caller typically populates this list before calling startDebugging() - we
-//  set a breakpoint for each member of the list
-
-dbgBreakPointList &ctlCodeWindow::getBreakpointList()
-{
-	return( m_breakpoints );
-}
-
-void ctlCodeWindow::unhilightCurrentLine()
-{
-
-	int    lineNo = m_view->MarkerNext( 0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT ));
-
-	if( lineNo != -1 )
-	{
-		m_view->MarkerDelete( lineNo, MARKER_CURRENT );
-		m_view->MarkerDelete( lineNo, MARKER_CURRENT_BG );
-	}
-
-}
-
-void ctlCodeWindow::OnTimer( wxTimerEvent &event )
-{
-	if( m_progressBar )
-	{
-		if( m_progressBar->Pulse() == false )
-		{
-			closeConnection();
-			m_targetAborted = true;
-			m_parent->Close();
-		}
-	}
-	else
-	{
-		// If we're indirect debugging from the query tool, the query thread
-		// might be preventing Idle events being fired, so we do it
-		// manually here.
-		if (!m_parent->m_standaloneDirectDbg)
-		{
-			wxIdleEvent evt;
-			OnIdle(evt);
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// wsCodeCache constructor
-//
-//    Each entry in our code cache (ctlCodeWindow::m_sourceCodeMap) is an object
-//  of class wsCodeCache.
-
-wsCodeCache::wsCodeCache(const wxString &packageOID, const wxString &funcOID, const wxString &source, const wxString &signature)
-	: m_packageOID(packageOID), m_funcOID(funcOID), m_sourceCode(source), m_signature(signature)
-{
-}
-
-
diff --git a/pgadmin/debugger/ctlMessageWindow.cpp b/pgadmin/debugger/ctlMessageWindow.cpp
index 3069645..c7316d2 100644
--- a/pgadmin/debugger/ctlMessageWindow.cpp
+++ b/pgadmin/debugger/ctlMessageWindow.cpp
@@ -17,7 +17,7 @@
 // App headers
 #include "debugger/ctlMessageWindow.h"
 
-IMPLEMENT_CLASS( ctlMessageWindow, wxTextCtrl )
+IMPLEMENT_CLASS(ctlMessageWindow, wxTextCtrl)
 
 ////////////////////////////////////////////////////////////////////////////////
 // ctlMessageWindow constructor
@@ -25,20 +25,20 @@ IMPLEMENT_CLASS( ctlMessageWindow, wxTextCtrl )
 //  Initialize the grid control and clear it out....
 //
 
-ctlMessageWindow::ctlMessageWindow( wxWindow *parent, wxWindowID id )
-	: wxTextCtrl( parent, wxID_ANY, wxT(""), wxPoint(0, 0), wxSize(0, 0),
-	              wxTE_MULTILINE | wxTE_READONLY)
+ctlMessageWindow::ctlMessageWindow(wxWindow *parent, wxWindowID id)
+	: wxTextCtrl(parent, wxID_ANY, wxT(""), wxPoint(0, 0), wxSize(0, 0),
+	             wxTE_MULTILINE | wxTE_READONLY)
 {
 	SetFont(settings->GetSQLFont());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// addMessage()
+// AddMessage()
 //
 //    Adds the message in the 'DBMS Messages' window.
 //
 
-void ctlMessageWindow::addMessage( wxString message )
+void ctlMessageWindow::AddMessage(wxString message)
 {
 	AppendText(message + wxT("\n"));
 }
@@ -49,13 +49,13 @@ void ctlMessageWindow::addMessage( wxString message )
 //    Removes the given message from the 'DBMS Messages' window.
 //
 
-void ctlMessageWindow::delMessage( const char *name )
+void ctlMessageWindow::DelMessage(const char *name)
 {
 	SetValue(wxT(""));
 }
 
 
-wxString ctlMessageWindow::getMessage( int row )
+wxString ctlMessageWindow::GetMessage(int row)
 {
-	return( GetValue());
+	return(GetValue());
 }
diff --git a/pgadmin/debugger/ctlResultGrid.cpp b/pgadmin/debugger/ctlResultGrid.cpp
index 3a47b1e..65d98e8 100644
--- a/pgadmin/debugger/ctlResultGrid.cpp
+++ b/pgadmin/debugger/ctlResultGrid.cpp
@@ -39,15 +39,24 @@ ctlResultGrid::ctlResultGrid( wxWindow *parent, wxWindowID id )
 //    Given a result set handle, this function copies the values in that result
 //  set into the grid.
 
-void ctlResultGrid::fillGrid( PGresult *result )
+void ctlResultGrid::FillResult(pgSet *set)
 {
-	int    rowCount = PQntuples( result );
-	int    colCount = PQnfields( result );
+	// Clear out the old results (if any) and resize
+	// grid to match the result set
+	if( GetNumberRows())
+		DeleteRows( 0, GetNumberRows());
+	if( GetNumberCols())
+		DeleteCols( 0, GetNumberCols());
+
+	if (!set)
+		return;
+
+	int rowCount = set->NumRows();
+	int colCount = set->NumCols();
 
 	// If this PGresult represents a non-query command
 	// (like an INSERT), there won't be any columns in
 	// the result set - just return
-
 	if( colCount == 0 )
 		return;
 
@@ -55,42 +64,34 @@ void ctlResultGrid::fillGrid( PGresult *result )
 
 	BeginBatch();
 
-	// Clear out the old results (if any) and resize
-	// grid to match the result set
-
-	if( GetNumberRows())
-		DeleteRows( 0, GetNumberRows());
-	if( GetNumberCols())
-		DeleteCols( 0, GetNumberCols());
+	AppendRows(rowCount);
+	AppendCols(colCount);
 
-	AppendRows( rowCount );
-	AppendCols( colCount );
-
-	EnableEditing( false );
+	EnableEditing(false);
 
 	// Copy the column names from the result set into the column headers
-
-	for( int col = 0; col < colCount; ++col )
-		SetColLabelValue( col, wxString( PQfname( result, col ), wxConvUTF8 ));
+	int row = 0,
+	    col;
+	for(col = 0; col < colCount; ++col)
+		SetColLabelValue(col, set->ColName(col));
 
 	// Now copy each value from the result set into the grid
-
-	for( int row = 0; row < rowCount; ++row )
+	while(!set->Eof())
 	{
-		for( int col = 0; col < colCount; ++col )
+		for(col = 0; col < colCount; ++col)
 		{
-			if( PQgetisnull( result, row, col ))
-				SetCellValue( row, col, wxT( "" ));
+			if(set->IsNull(col))
+				SetCellValue(row, col, wxT(""));
 			else
-				SetCellValue( row, col, wxString( PQgetvalue( result, row, col ), wxConvUTF8 ));
+				SetCellValue(row, col, set->GetVal(col));
 		}
+		row++;
+		set->MoveNext();
 	}
 
 	// Resize each column to fit its content
-
-	AutoSizeColumns( false );
+	AutoSizeColumns(false);
 
 	// Enable repaints
-
 	EndBatch();
 }
diff --git a/pgadmin/debugger/ctlStackWindow.cpp b/pgadmin/debugger/ctlStackWindow.cpp
index 1156425..a39631b 100644
--- a/pgadmin/debugger/ctlStackWindow.cpp
+++ b/pgadmin/debugger/ctlStackWindow.cpp
@@ -33,24 +33,21 @@ ctlStackWindow::ctlStackWindow(wxWindow *parent, wxWindowID id, const wxPoint &p
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// clear()
+// ClearStack()
 //
 //    Remove all stack frames from the display
 //
-
-void ctlStackWindow::clear()
+void ctlStackWindow::ClearStack()
 {
 	Set(0, NULL);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// setStack()
+// SetStack()
 //
 //    Add an array of stack frames to the display
 //
-
-
-void ctlStackWindow::setStack(const wxArrayString &stack )
+void ctlStackWindow::SetStack(const wxArrayString &stack )
 {
 	for(size_t i = 0; i < stack.GetCount(); ++i)
 	{
diff --git a/pgadmin/debugger/ctlTabWindow.cpp b/pgadmin/debugger/ctlTabWindow.cpp
index 17c4f6d..e2ec306 100644
--- a/pgadmin/debugger/ctlTabWindow.cpp
+++ b/pgadmin/debugger/ctlTabWindow.cpp
@@ -21,7 +21,7 @@
 #include "debugger/dbgConst.h"
 
 
-IMPLEMENT_CLASS( ctlTabWindow, wxWindow )
+IMPLEMENT_CLASS(ctlTabWindow, wxWindow)
 
 ////////////////////////////////////////////////////////////////////////////////
 // ctlTabWindow constructor
@@ -29,153 +29,147 @@ IMPLEMENT_CLASS( ctlTabWindow, wxWindow )
 //    This constructor creates a new notebook (a tab control) and clears out the
 //  rest of the data members.
 //
-
-ctlTabWindow::ctlTabWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name )
-	: ctlAuiNotebook( parent, id, pos, size, style ),
-	  m_resultWindow( 0 ),
-	  m_varWindow( 0 ),
-	  m_pkgVarWindow( 0 ),
-	  m_stackWindow( 0 ),
-	  m_paramWindow( 0 ),
-	  m_messageWindow( 0 )
+ctlTabWindow::ctlTabWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos,
+                           const wxSize &size, long style, const wxString &name)
+	: ctlAuiNotebook(parent, id, pos, size, style),
+	  m_resultWindow(NULL),
+	  m_varWindow(NULL),
+	  m_pkgVarWindow(NULL),
+	  m_stackWindow(NULL),
+	  m_paramWindow(NULL),
+	  m_messageWindow(NULL)
 {
 	wxWindowBase::SetFont(settings->GetSystemFont());
 	m_tabMap   = new wsTabHash();
 }
 
-void ctlTabWindow::selectTab( wxWindowID id )
+void ctlTabWindow::SelectTab(wxWindowID id)
 {
-	wsTabHash::iterator result = m_tabMap->find( id );
+	wsTabHash::iterator result = m_tabMap->find(id);
 
-	if( result != m_tabMap->end())
+	if (result != m_tabMap->end())
 	{
-		SetSelection( result->second );
+		SetSelection(result->second);
 	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getResultWindow()
+// GetResultWindow()
 //
 //    This function returns a pointer to our child result window (m_resultWindow)
 //  and creates that window when we first need it.
 //
-
-ctlResultGrid *ctlTabWindow::getResultWindow( void )
+ctlResultGrid *ctlTabWindow::GetResultWindow()
 {
-	if( m_resultWindow == 0 )
+	if (m_resultWindow == 0)
 	{
 		// We don't have a result window yet - go ahead and create one
 
-		m_resultWindow = new ctlResultGrid( this, -1 );
-		AddPage( m_resultWindow, _( "Results" ), true );
+		m_resultWindow = new ctlResultGrid(this, -1);
+		AddPage(m_resultWindow, _("Results"), true);
 	}
 
-	return( m_resultWindow );
+	return m_resultWindow;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getVarWindow()
+// GetVarWindow()
 //
 //    This function returns a pointer to our child 'local-variables' window
 //  (m_varWindow) and creates that window when we first need it.
 //
-
-ctlVarWindow *ctlTabWindow::getVarWindow( bool create )
+ctlVarWindow *ctlTabWindow::GetVarWindow(bool _create)
 {
-	if(( m_varWindow == NULL ) && create )
+	if ((m_varWindow == NULL) && _create)
 	{
 		// We don't have a variable window yet - go ahead and create one
 
 		(*m_tabMap)[ID_VARGRID] = GetPageCount();
 
-		m_varWindow = new ctlVarWindow( this, ID_VARGRID );
-		AddPage( m_varWindow, _( "Local Variables" ), true );
+		m_varWindow = new ctlVarWindow(this, ID_VARGRID);
+		AddPage(m_varWindow, _("Local Variables"), true);
 	}
 
-	return( m_varWindow );
+	return m_varWindow;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getPkgVarWindow()
+// GetPkgVarWindow()
 //
 //  This function returns a pointer to our child 'package-variables' window
 //  (m_varWindow) and creates that window when we first need it.
 //
-
-ctlVarWindow *ctlTabWindow::getPkgVarWindow( bool create )
+ctlVarWindow *ctlTabWindow::GetPkgVarWindow(bool create)
 {
-	if(( m_pkgVarWindow == NULL ) && create )
+	if ((m_pkgVarWindow == NULL) && create)
 	{
 		// We don't have a variable window yet - go ahead and create one
 
 		(*m_tabMap)[ID_PKGVARGRID] = GetPageCount();
 
-		m_pkgVarWindow = new ctlVarWindow( this, ID_PKGVARGRID );
-		AddPage( m_pkgVarWindow, _( "Package Variables" ), true );
+		m_pkgVarWindow = new ctlVarWindow(this, ID_PKGVARGRID);
+		AddPage(m_pkgVarWindow, _("Package Variables"), true);
 	}
 
-	return( m_pkgVarWindow );
+	return m_pkgVarWindow;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getParamWindow()
+// GetParamWindow()
 //
 //    This function returns a pointer to our child 'parameters' window
 //  (m_paramWindow) and creates that window when we first need it.
 //
-
-ctlVarWindow *ctlTabWindow::getParamWindow( bool create )
+ctlVarWindow *ctlTabWindow::GetParamWindow(bool create)
 {
-	if(( m_paramWindow == NULL ) && create )
+	if ((m_paramWindow == NULL) && create)
 	{
 		// We don't have a variable window yet - go ahead and create one
 
 		(*m_tabMap)[ID_PARAMGRID] = GetPageCount();
 
-		m_paramWindow = new ctlVarWindow( this, ID_PARAMGRID );
-		AddPage( m_paramWindow, _( "Parameters" ), true );
+		m_paramWindow = new ctlVarWindow(this, ID_PARAMGRID);
+		AddPage(m_paramWindow, _("Parameters"), true);
 	}
 
-	return( m_paramWindow );
+	return m_paramWindow;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getMessageWindow()
+// GetMessageWindow()
 //
 //    This function returns a pointer to our child 'messages' window
 //  (m_messageWindow) and creates that window when we first need it.
 //
-
-ctlMessageWindow *ctlTabWindow::getMessageWindow( void )
+ctlMessageWindow *ctlTabWindow::GetMessageWindow()
 {
-	if( m_messageWindow == 0 )
+	if (m_messageWindow == 0)
 	{
 		// We don't have a variable window yet - go ahead and create one
 
 		(*m_tabMap)[ID_MSG_PAGE] = GetPageCount();
 
-		m_messageWindow = new ctlMessageWindow( this, ID_MSG_PAGE );
-		AddPage( m_messageWindow, _( "DBMS Messages" ), true );
+		m_messageWindow = new ctlMessageWindow(this, ID_MSG_PAGE);
+		AddPage(m_messageWindow, _("DBMS Messages"), true);
 	}
-	return( m_messageWindow );
+	return m_messageWindow;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// getStackWindow()
+// GetStackWindow()
 //
 //    This function returns a pointer to our child stack-trace window
 //  (m_stackWindow) and creates that window when we first need it.
 //
-
-ctlStackWindow *ctlTabWindow::getStackWindow( )
+ctlStackWindow *ctlTabWindow::GetStackWindow()
 {
-	if( m_stackWindow == 0 )
+	if (m_stackWindow == 0)
 	{
 		// We don't have a stack-trace window yet - go ahead and create one
-		m_stackWindow = new ctlStackWindow( this, -1 );
-		AddPage( m_stackWindow, _( "Stack" ), true );
+		m_stackWindow = new ctlStackWindow(this, -1);
+		AddPage(m_stackWindow, _("Stack"), true);
 	}
 
-	return( m_stackWindow );
+	return m_stackWindow;
 }
 
diff --git a/pgadmin/debugger/ctlVarWindow.cpp b/pgadmin/debugger/ctlVarWindow.cpp
index 155bc31..8ec6849 100644
--- a/pgadmin/debugger/ctlVarWindow.cpp
+++ b/pgadmin/debugger/ctlVarWindow.cpp
@@ -18,7 +18,7 @@
 // App headers
 #include "debugger/ctlVarWindow.h"
 
-IMPLEMENT_CLASS( ctlVarWindow, wxGrid )
+IMPLEMENT_CLASS(ctlVarWindow, wxGrid)
 
 ////////////////////////////////////////////////////////////////////////////////
 // ctlVarWindow constructor
@@ -26,58 +26,57 @@ IMPLEMENT_CLASS( ctlVarWindow, wxGrid )
 //  Initialize the grid control and clear it out....
 //
 
-ctlVarWindow::ctlVarWindow( wxWindow *parent, wxWindowID id )
-	: wxGrid( parent, id ),
-	  m_cells( NULL ),
-	  m_nameFont( GetDefaultCellFont())
+ctlVarWindow::ctlVarWindow(wxWindow *parent, wxWindowID id)
+: wxGrid(parent, id),
+	  m_cells(NULL),
+	  m_nameFont(GetDefaultCellFont())
 {
 	wxWindowBase::SetFont(settings->GetSystemFont());
 
 	// Create the grid control
-	CreateGrid( 0, 0 );
-	SetRowLabelSize( 0 );	// Turn off the row labels
+	CreateGrid(0,0);
+	SetRowLabelSize(0);	// Turn off the row labels
 
 	// Set up three columns: name, value, and data type
-	AppendCols( 3 );
-	SetColLabelValue( COL_NAME,  _( "Name" ));
-	SetColLabelValue( COL_TYPE,  _( "Type" ));
-	SetColLabelValue( COL_VALUE, _( "Value" ));
+	AppendCols(3);
+	SetColLabelValue(COL_NAME,  _("Name"));
+	SetColLabelValue(COL_TYPE,  _("Type"));
+	SetColLabelValue(COL_VALUE, _("Value"));
 
-	EnableDragGridSize( true );
+	EnableDragGridSize(true);
 
 	// EDB wants to hide certain PL variables.  To do that, we
 	// keep a hash of hidden names and a hash of hidden types...
-	m_hiddenNames.insert( wxT( "found" ));
-	m_hiddenNames.insert( wxT( "rowcount" ));
-	m_hiddenNames.insert( wxT( "sqlcode" ));
-	m_hiddenNames.insert( wxT( "sqlerrm" ));
-	m_hiddenNames.insert( wxT( "_found" ));
-	m_hiddenNames.insert( wxT( "_rowcount" ));
-	m_hiddenNames.insert( wxT( "sqlstate" ));
+	m_hiddenNames.insert(wxT("found"));
+	m_hiddenNames.insert(wxT("rowcount"));
+	m_hiddenNames.insert(wxT("sqlcode"));
+	m_hiddenNames.insert(wxT("sqlerrm"));
+	m_hiddenNames.insert(wxT("_found"));
+	m_hiddenNames.insert(wxT("_rowcount"));
+	m_hiddenNames.insert(wxT("sqlstate"));
 
-	m_hiddenTypes.insert( wxT( "refcursor" ));
+	m_hiddenTypes.insert(wxT("refcursor"));
 
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// addVar()
+// AddVar()
 //
 //    Adds (or updates) the given variable in the 'local variables' window.  If
 //  we find a variabled named 'name' in the window, we simply update the value,
 //  otherwise, we create a new entry in the grid
 //
-
-void ctlVarWindow::addVar( wxString name, wxString value, wxString type, bool readOnly )
+void ctlVarWindow::AddVar(wxString name, wxString value, wxString type, bool readOnly)
 {
 	// If this is a 'hidden' variable, just ignore it
 
-	if( m_hiddenNames.find( name ) != m_hiddenNames.end())
+	if (m_hiddenNames.find(name) != m_hiddenNames.end())
 		return;
 
-	if( m_hiddenTypes.find( type ) != m_hiddenTypes.end())
+	if (m_hiddenTypes.find(type) != m_hiddenTypes.end())
 		return;
 
-	if( m_cells == NULL )
+	if (m_cells == NULL)
 	{
 		// This is the first variable we're adding to this grid,
 		// layout the grid and set the column headers.
@@ -86,11 +85,11 @@ void ctlVarWindow::addVar( wxString name, wxString value, wxString type, bool re
 	}
 
 	// Try to find an existing grid cell for this variable...
-	wxString	key( name );
+	wxString	key(name);
 
-	wsCellHash::iterator cell = m_cells->find( key );
+	wsCellHash::iterator cell = m_cells->find(key);
 
-	if( cell == m_cells->end())
+	if (cell == m_cells->end())
 	{
 		// Can't find this variable in the grid, go ahead and add it
 
@@ -100,19 +99,19 @@ void ctlVarWindow::addVar( wxString name, wxString value, wxString type, bool re
 		newCell.m_type  = type;
 		newCell.m_value = value;
 
-		AppendRows( 1 );
+		AppendRows(1);
 
-		SetRowLabelValue( newCell.m_row, key );
+		SetRowLabelValue(newCell.m_row, key);
 
-		SetCellValue( newCell.m_row, COL_NAME,  key );
-		SetCellValue( newCell.m_row, COL_TYPE,  type );
-		SetCellValue( newCell.m_row, COL_VALUE, value );
+		SetCellValue(newCell.m_row, COL_NAME,  key);
+		SetCellValue(newCell.m_row, COL_TYPE,  type);
+		SetCellValue(newCell.m_row, COL_VALUE, value);
 
-		SetCellFont( newCell.m_row, COL_NAME, m_nameFont );
+		SetCellFont(newCell.m_row, COL_NAME, m_nameFont);
 
-		SetReadOnly( newCell.m_row, COL_NAME,  true );
-		SetReadOnly( newCell.m_row, COL_TYPE,  true );
-		SetReadOnly( newCell.m_row, COL_VALUE, readOnly );
+		SetReadOnly(newCell.m_row, COL_NAME,  true);
+		SetReadOnly(newCell.m_row, COL_TYPE,  true);
+		SetReadOnly(newCell.m_row, COL_VALUE, readOnly);
 
 		(*m_cells)[key] = newCell;
 	}
@@ -123,23 +122,23 @@ void ctlVarWindow::addVar( wxString name, wxString value, wxString type, bool re
 
 		cell->second.m_value = value;
 
-		if( GetCellValue( cell->second.m_row, COL_VALUE ).IsSameAs( value ))
-			SetCellTextColour( cell->second.m_row, COL_VALUE, *wxBLACK );
+		if (GetCellValue(cell->second.m_row, COL_VALUE).IsSameAs(value))
+			SetCellTextColour(cell->second.m_row, COL_VALUE, *wxBLACK);
 		else
-			SetCellTextColour( cell->second.m_row, COL_VALUE, *wxRED );
+			SetCellTextColour(cell->second.m_row, COL_VALUE, *wxRED);
 
-		SetCellValue( cell->second.m_row, COL_VALUE, value );
+		SetCellValue(cell->second.m_row, COL_VALUE, value);
 
 		// FIXME: why is this part conditional?
 		// FIXME: why do we need this code? can the type ever change?
 
-		if( GetCellValue( cell->second.m_row, COL_TYPE) == wxT( "" ))
+		if (GetCellValue(cell->second.m_row, COL_TYPE) == wxT(""))
 		{
-			SetCellValue( cell->second.m_row, COL_TYPE, type );
+			SetCellValue(cell->second.m_row, COL_TYPE, type);
 		}
 	}
 
-	// AutoSizeColumns( false );
+	// AutoSizeColumns(false);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -148,30 +147,37 @@ void ctlVarWindow::addVar( wxString name, wxString value, wxString type, bool re
 //    Removes the given variable from the 'local variables' window.
 //
 
-void ctlVarWindow::delVar( wxString name )
+void ctlVarWindow::DelVar(wxString name)
 {
-	if( name.IsEmpty())
+	if (name.IsEmpty())
 	{
 		delete m_cells;
 		m_cells = NULL;
 
-		if( GetNumberRows())
-			DeleteRows( 0, GetNumberRows());
+		if (GetNumberRows())
+			DeleteRows(0, GetNumberRows());
 	}
 	else
 	{
-
+		for (int row = 0; row < GetNumberRows(); row++)
+		{
+			if (GetCellValue(row, COL_NAME) == name)
+			{
+				DeleteRows(row, 1);
+				break;
+			}
+		}
 	}
 }
 
 
-wxString ctlVarWindow::getVarName( int row )
+wxString ctlVarWindow::GetVarName(int row)
 {
-	return( GetCellValue( row, COL_NAME ));
+	return(GetCellValue(row, COL_NAME));
 
 }
 
-wxString ctlVarWindow::getVarValue( int row )
+wxString ctlVarWindow::GetVarValue(int row)
 {
-	return( GetCellValue( row, COL_VALUE ));
+	return(GetCellValue(row, COL_VALUE));
 }
diff --git a/pgadmin/debugger/dbgDbResult.cpp b/pgadmin/debugger/dbgDbResult.cpp
deleted file mode 100644
index 2843ba4..0000000
--- a/pgadmin/debugger/dbgDbResult.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgDbResult.cpp - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include "pgAdmin3.h"
-
-// wxWindows headers
-#include <wx/wx.h>
-
-// App headers
-#include "debugger/dbgDbResult.h"
-
-DEFINE_EVENT_TYPE( dbgDbResult )
-
diff --git a/pgadmin/debugger/dbgPgConn.cpp b/pgadmin/debugger/dbgPgConn.cpp
deleted file mode 100644
index dd666db..0000000
--- a/pgadmin/debugger/dbgPgConn.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgPgConn.cpp - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include "pgAdmin3.h"
-
-// wxWindows headers
-#include <wx/wx.h>
-
-// App headers
-#include "debugger/dbgPgConn.h"
-#include "utils/sysLogger.h"
-
-#include <stdexcept>
-
-#ifdef __WXMSW__
-#include <winsock.h>
-typedef u_long in_addr_t;
-#else
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
-#ifndef INADDR_NONE
-#define INADDR_NONE (-1)
-#endif
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// dbgPgConn constructors
-//
-//    A dbgPgConn object encapsulates the connection to a PostgreSQL server.  This
-//  class is a wrapper around a Pgconn that provides a convenient constructor
-//  and a few member functions.
-//
-//    The constructor creates a new thread and connects to the specified server
-
-dbgPgConn::dbgPgConn(frmDebugger *frame, const wxString &server, const wxString &database, const wxString &userName, const wxString &password, const wxString &port, int sslmode, const wxString &applicationname)
-	: m_frame(frame)
-{
-	Init( server, database, userName, password, port, sslmode, applicationname, true );
-}
-
-dbgPgConn::dbgPgConn(frmDebugger *frame, const dbgConnProp &props, bool startThread )
-	: m_frame(frame)
-{
-	Init(  props.m_host, props.m_database, props.m_userName, props.m_password, props.m_port, props.m_sslMode, props.m_applicationName, startThread );
-}
-
-void dbgPgConn::Init( const wxString &server, const wxString &database, const wxString &username, const wxString &password, const wxString &port, int sslmode, const wxString &applicationname, bool startThread )
-{
-	bool utfConnectString = false;
-	bool libcConnectString = false;
-
-	m_pgConn       = NULL;
-	m_majorVersion = 0;
-	m_minorVersion = 0;
-	m_debuggerApiVersion = DEBUGGER_UNKNOWN_API;
-	m_isEdb = false;
-
-	if( startThread )
-		m_workerThread = new dbgPgThread( *this );
-	else
-		m_workerThread = NULL;
-
-	wxString 	msg;
-	wxString	delimiter;
-
-	// To keep the user interface thread responsive while we're waiting for the
-	// PostgreSQL server, we create a separate thread to interact with the
-	// database - the worker thread sleeps until the GUI thread signals that it
-	// has some work to do.  When the result set arrives from the server, the
-	// worker thread creates a DBResult event and posts it to the GUI thread's
-	// event queue.
-
-	if( m_workerThread )
-	{
-		m_workerThread->Create();
-		m_workerThread->Run();
-	}
-
-	// Figure out the hostname/IP address
-	struct hostent *host;
-	in_addr_t addr;
-	wxString hostip, hostname;
-
-#ifdef __WXMSW__
-	struct in_addr ipaddr;
-#else
-	unsigned long ipaddr;
-#endif
-
-#ifndef __WXMSW__
-	if (!(server.IsEmpty() || server.StartsWith(wxT("/"))))
-	{
-#endif
-		addr = inet_addr(server.ToAscii());
-		if (addr == INADDR_NONE) // szServer is not an IP address
-		{
-			host = gethostbyname(server.ToAscii());
-			if (host == NULL)
-			{
-				wxLogError(__("Could not resolve hostname %s"), server.c_str());
-				return;
-			}
-
-			memcpy(&(ipaddr), host->h_addr, host->h_length);
-			hostip = wxString::FromAscii(inet_ntoa(*((struct in_addr *) host->h_addr_list[0])));
-			hostname = server;
-		}
-		else
-		{
-			hostip = server;
-			hostname = server;
-		}
-#ifndef __WXMSW__
-	}
-	else
-		hostname = server;
-#endif
-
-	// Build up a connection string
-	wxString connectParams;
-
-	if(hostname.Length())
-	{
-		connectParams.Append(wxT( "host="));
-		connectParams.Append(hostname);
-
-		msg += delimiter + server;
-		delimiter = _(":");
-	}
-
-	if (hostip.Length())
-	{
-		connectParams.Append(wxT(" hostaddr="));
-		connectParams.Append(hostip);
-	}
-
-	if(port.Length())
-	{
-		connectParams += wxT(" port=");
-		connectParams += port;
-
-		msg += delimiter + port;
-		delimiter = _(":");
-	}
-
-
-	if(database.Length())
-	{
-		connectParams.Append(wxT(" dbname="));
-		connectParams.Append(qtConnString(database));
-
-		msg += delimiter + database;
-		delimiter = _(":");
-	}
-
-	if(username.Length())
-	{
-		connectParams.Append(wxT(" user="));
-		connectParams.Append(username );
-
-		msg += delimiter + username;
-		delimiter =  _(":");
-	}
-
-	if(password.Length())
-	{
-		connectParams.Append(wxT(" password="));
-		connectParams.Append(password);
-	}
-
-	switch (sslmode)
-	{
-		case 1:
-			connectParams.Append(wxT(" sslmode=require"));
-			break;
-
-		case 2:
-			connectParams.Append(wxT(" sslmode=prefer"));
-			break;
-
-		case 3:
-			connectParams.Append(wxT(" sslmode=allow"));
-			break;
-
-		case 4:
-			connectParams.Append(wxT(" sslmode=disable"));
-			break;
-
-		case 5:
-			connectParams.Append(wxT(" sslmode=verify-ca"));
-			break;
-
-		case 6:
-			connectParams.Append(wxT(" sslmode=verify-full"));
-			break;
-
-		default:
-			break;
-	}
-
-	connectParams.Trim(true);
-	connectParams.Trim(false);
-
-#ifdef HAVE_CONNINFO_PARSE
-	if (!applicationname.IsEmpty())
-	{
-		// Check connection string with application_name
-		char *errmsg;
-		wxString connectParams_with_applicationname = connectParams + wxT(" application_name='") + applicationname + wxT("'");
-		if (PQconninfoParse(connectParams_with_applicationname.mb_str(wxConvUTF8), &errmsg))
-		{
-			utfConnectString = true;
-			connectParams = connectParams_with_applicationname;
-		}
-		else if (PQconninfoParse(connectParams_with_applicationname.mb_str(wxConvLibc), &errmsg))
-		{
-			libcConnectString = true;
-			connectParams = connectParams_with_applicationname;
-		}
-	}
-#endif
-
-	m_frame->getStatusBar()->SetStatusText( wxString::Format(_( "Connecting to %s" ), msg.c_str()), 1 );
-	wxCharBuffer cstrUTF = connectParams.mb_str(wxConvUTF8);
-	wxCharBuffer cstrLibc = connectParams.mb_str(wxConvLibc);
-
-	if (!libcConnectString)
-		m_pgConn = PQconnectdb(cstrUTF);
-	else
-		m_pgConn = PQconnectdb(cstrLibc);
-
-	if (PQstatus(m_pgConn) != CONNECTION_OK)
-	{
-		PQfinish(m_pgConn);
-		m_pgConn = PQconnectdb(cstrLibc);
-	}
-
-	if( PQstatus( m_pgConn ) == CONNECTION_OK )
-	{
-		m_frame->getStatusBar()->SetStatusText( wxString::Format(_( "Connected to %s" ), msg.c_str()), 1 );
-		PQsetClientEncoding( m_pgConn, "UNICODE" );
-	}
-	else
-	{
-		throw( std::runtime_error( PQerrorMessage( m_pgConn )));
-	}
-}
-
-dbgPgConn::~dbgPgConn()
-{
-	Close();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// isConnected()
-//
-//    Returns true if the connection to the PostgreSQL server is alive and well,
-//  otherwise, returns false.
-
-bool dbgPgConn::isConnected( void ) const
-{
-	if( m_pgConn && PQstatus( m_pgConn ) == CONNECTION_OK )
-		return( true );
-	else
-		return( false );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getName()
-//
-//     This function returns a user-friendly descriptive name for this connection.
-//     The result is "hostname/database".
-
-const wxString dbgPgConn::getName() const
-{
-	wxString 	result = wxString( PQhost( m_pgConn ), wxConvUTF8 );
-
-	result += wxT( "/" );
-	result.Append( wxString( PQdb( m_pgConn ), wxConvUTF8 ));
-
-	return( result );
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getHost()
-//
-//    Returns the name of the host (or the IP address) that we're connected to.
-
-const wxString dbgPgConn::getHost() const
-{
-	return( wxString( PQhost( m_pgConn ), wxConvUTF8 ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getDatabase()
-//
-//    Returns the name of the database that we're connected to
-
-const wxString dbgPgConn::getDatabase() const
-{
-	return( wxString( PQdb( m_pgConn ), wxConvUTF8 ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getConnection()
-//
-//    Returns the libpq connection handle for this dbgPgConn
-
-PGconn *dbgPgConn::getConnection()
-{
-	return( m_pgConn );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// startCommand()
-//
-//     The GUI thread invokes startCommand() when the user asks us to execute a
-//    command.  We pass off the real work to the worker thread.
-
-void dbgPgConn::startCommand( const wxString &command, wxEvtHandler *caller, wxEventType eventType, dbgPgParams *params )
-{
-	wxLogSql(wxT("%s"), command.c_str());
-
-	m_workerThread->startCommand(command, caller, eventType, params);
-}
-
-PGresult *dbgPgConn::waitForCommand( const wxString &command )
-{
-	wxLogSql(wxT("%s"), command.c_str());
-
-	PGresult *result = PQexec( m_pgConn, command.mb_str( wxConvUTF8 ));
-
-	return( result );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// setNoticeHandler()
-//
-//     Register a NOTICE handler with the libpq library - libpq will invoke the
-//  given handler whenever a NOTICE arrives on this connection. libpq will
-//    pass 'arg' to the handler. 'handler' is typically a static function and
-//    'arg' is often a pointer to an object.  That lets you use a regular member
-//    function as a callback (because 'arg' is mapped into a 'this' pointer by the
-//     callback function).
-
-void dbgPgConn::setNoticeHandler( PQnoticeProcessor handler, void *arg )
-{
-	PQnoticeProcessor p = NULL;
-	p = PQsetNoticeProcessor( m_pgConn, handler, arg );
-}
-
-void dbgPgConn::Close()
-{
-	// Attempt to cancel any ongoing query
-	Cancel();
-
-	// Wait a tenth of a second or so for things to sort themselves out.
-	// Otherwise on Windows things can get funky here ...
-	wxMilliSleep(100);
-
-	if (m_workerThread)
-	{
-		m_workerThread->Die();
-		m_workerThread->Wait();
-
-		delete m_workerThread;
-		m_workerThread = NULL;
-	}
-
-	if (m_pgConn)
-		PQfinish(m_pgConn);
-
-	m_pgConn = NULL;
-}
-
-void dbgPgConn::Cancel()
-{
-	// Attempt to cancel any ongoing query
-	if (m_pgConn)
-	{
-		PGcancel *cancel = PQgetCancel(m_pgConn);
-		char errbuf[256];
-		PQcancel(cancel, errbuf, sizeof(errbuf));
-		PQfreeCancel(cancel);
-	}
-}
-
-// Check the backend version
-bool dbgPgConn::BackendMinimumVersion(int major, int minor)
-{
-	if (!m_majorVersion)
-	{
-		wxString version = GetVersionString();
-		sscanf(version.ToAscii(), "%*s %d.%d", &m_majorVersion, &m_minorVersion);
-		m_isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*"));
-
-		// EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style
-		// catalogs. This is expected to change either before GA, but in the meantime we
-		// need to check the catalogue version in more detail, and if we don't see what looks
-		// like a 8.3 catalog, force the version number back to 8.2. Yuck.
-		if (m_isEdb && m_majorVersion == 8 && m_minorVersion == 3)
-		{
-			PGresult *res;
-			wxString result;
-
-			res = waitForCommand(wxT( "SELECT count(*) FROM pg_attribute WHERE attname = 'proconfig' AND attrelid = 'pg_proc'::regclass"));
-
-			if (PQresultStatus(res) == PGRES_TUPLES_OK)
-			{
-				// Retrieve the query result and return it.
-				result = wxString(PQgetvalue(res, 0, 0), wxConvUTF8);
-
-				// Cleanup & exit
-				PQclear(res);
-			}
-			if (result == wxT("0"))
-				m_minorVersion = 2;
-		}
-		else
-			m_isGreenplum = version.Upper().Matches(wxT("*GREENPLUM DATABASE*"));
-	}
-
-	return m_majorVersion > major || (m_majorVersion == major && m_minorVersion >= minor);
-}
-
-// Check the EDB backend version
-bool dbgPgConn::EdbMinimumVersion(int major, int minor)
-{
-	return BackendMinimumVersion(major, minor) && GetIsEdb();
-}
-
-// Get the debugger API version
-DebuggerApiVersions dbgPgConn::DebuggerApiVersion()
-{
-	if (m_debuggerApiVersion > 0)
-		return m_debuggerApiVersion;
-
-	// The v1 protocol didn't have pldbg_get_proxy_info()
-	wxString result;
-
-	PGresult *res = waitForCommand(wxT( "SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_proxy_info';"));
-
-	if (PQresultStatus(res) == PGRES_TUPLES_OK)
-	{
-		// Retrieve the query result and return it.
-		if (wxString(PQgetvalue(res, 0, 0), wxConvUTF8) == wxT("0"))
-		{
-			PQclear(res);
-			m_debuggerApiVersion = DEBUGGER_V1_API;
-			return DEBUGGER_V1_API;
-		}
-
-		PQclear(res);
-	}
-	else
-	{
-		wxLogError(wxT("%s"), wxString(PQerrorMessage(m_pgConn), wxConvUTF8).c_str());
-		return DEBUGGER_UNKNOWN_API;
-	}
-
-	// We have pldbg_get_proxy_info, so use it to get the API version
-	res = waitForCommand(wxT( "SELECT proxyapiver FROM pldbg_get_proxy_info();"));
-
-	if (PQresultStatus(res) == PGRES_TUPLES_OK)
-	{
-		// Retrieve the query result and return it.
-		m_debuggerApiVersion = (DebuggerApiVersions)atoi(wxString(PQgetvalue(res, 0, 0), wxConvUTF8).ToAscii());
-		PQclear(res);
-	}
-	else
-	{
-		wxLogError(wxT("%s"), wxString(PQerrorMessage(m_pgConn), wxConvUTF8).c_str());
-		return DEBUGGER_UNKNOWN_API;
-	}
-
-	return m_debuggerApiVersion;
-}
-
-
-wxString dbgPgConn::GetVersionString()
-{
-	PGresult *res;
-	wxString result;
-
-	res = waitForCommand(wxT( "SELECT version();"));
-
-	if (PQresultStatus(res) == PGRES_TUPLES_OK)
-	{
-		// Retrieve the query result and return it.
-		result = wxString(PQgetvalue(res, 0, 0), wxConvUTF8);
-
-		// Cleanup & exit
-		PQclear(res);
-	}
-
-	return result;
-}
-
-bool dbgPgConn::GetIsEdb()
-{
-	// to retrieve edb flag
-	BackendMinimumVersion(0, 0);
-	return m_isEdb;
-}
-
-bool dbgPgConn::GetIsGreenplum()
-{
-	// to retrieve edb flag
-	BackendMinimumVersion(0, 0);
-	return m_isGreenplum;
-}
-
-wxString dbgPgConn::qtDbString(const wxString &value)
-{
-	wxString result = value;
-
-	result.Replace(wxT("\\"), wxT("\\\\"));
-	result.Replace(wxT("'"), wxT("''"));
-	result.Append(wxT("'"));
-
-	if (BackendMinimumVersion(8, 1))
-	{
-		if (result.Contains(wxT("\\")))
-			result.Prepend(wxT("E'"));
-		else
-			result.Prepend(wxT("'"));
-	}
-	else
-		result.Prepend(wxT("'"));
-
-	return result;
-}
\ No newline at end of file
diff --git a/pgadmin/debugger/dbgPgThread.cpp b/pgadmin/debugger/dbgPgThread.cpp
deleted file mode 100644
index 9c80d8b..0000000
--- a/pgadmin/debugger/dbgPgThread.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgPgThread.cpp - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include "pgAdmin3.h"
-
-// wxWindows headers
-#include <wx/wx.h>
-#include <wx/app.h>
-#include <wx/tokenzr.h>
-#include <wx/listimpl.cpp>
-
-// App headers
-#include "debugger/dbgPgThread.h"
-#include "debugger/dbgDbResult.h"
-#include "debugger/frmDebugger.h"
-#include "debugger/dbgPgConn.h"
-
-#include <libpq-fe.h>
-
-WX_DEFINE_LIST( ThreadCommandList );
-
-////////////////////////////////////////////////////////////////////////////////
-// dbgPgThread constructor
-//
-//    A dbgPgThread object encapsulates a separate execution thread that interacts
-//  with a PostgreSQL server.  We use a separate thread to keep the main thread
-//  (and thus the user interface) responsive while we're waiting for the server.
-
-dbgPgThread::dbgPgThread( dbgPgConn &owner )
-	: wxThread(wxTHREAD_JOINABLE),
-	  m_owner( owner ),
-	  m_queueCounter(),
-	  m_queueMutex(),
-	  m_commandQueue(),
-	  m_currentCommand( NULL ),
-	  run( 0 ),
-	  die( false )
-{
-	conv = &wxConvLibc;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// startCommand()
-//
-//     This function is called by the GUI thread when the user decides to
-//     execute a command.  To keep the GUI thread responsive, we use a
-//     separate thread to interact with the PostgreSQL server. This function
-//  wakes up the worker thread.
-
-void dbgPgThread::startCommand( const wxString &command, wxEvtHandler *caller, wxEventType eventType, dbgPgParams *params )
-{
-	// Save the command text (and the event handler that we should
-	// notify on completion) in the command queue and then wake up the
-	// worker thread.  The worker thread sleeps until we increment
-	// m_queueCounter
-
-	m_queueMutex.Lock();
-	m_commandQueue.Append( new dbgPgThreadCommand( command, caller, eventType, params ));
-
-	wxLogInfo( wxT( "Queueing: %s" ), command.c_str());
-
-	m_queueMutex.Unlock();
-
-	m_queueCounter.Post();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Die()
-//
-//    Instruct the thread to kill itself.
-
-void dbgPgThread::Die()
-{
-	wxLogInfo( wxT( "Telling the query thread to die..." ));
-	die = true;
-
-	m_queueCounter.Post();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Entry()
-//
-//    This is the entry point (and main loop) for the worker thread.  It simply
-//  waits for a command from the GUI thread (see the startCommand() function)
-//  and then sends the command to the PostgreSQL server.  This function also
-//  waits for a result set from the server - when the result set arrives, we
-//  send an event to the GUI thread.
-
-void *dbgPgThread::Entry( void )
-{
-
-	wxLogInfo( wxT( "worker thread waiting for some work to do..." ));
-
-	// This thread should hang at the call to m_condition.Wait()
-	// When m_condition is signaled, we wake up, send a command
-	// to the PostgreSQL server, and wait for a result.
-
-	while( m_queueCounter.Wait() == wxSEMA_NO_ERROR && !die && !TestDestroy() )
-	{
-		m_owner.setNoticeHandler( noticeHandler, this );
-
-		m_currentCommand = getNextCommand();
-		wxString command = m_currentCommand->getCommand();
-
-		wxLogInfo( wxT( "Executing: %s" ), command.c_str());
-
-		// This call to PQexec() will hang until we've received
-		// a complete result set from the server.
-		PGresult *result = 0;
-
-#if defined (__WXMSW__) || (EDB_LIBPQ)
-		// If we have a set of params, and we have the required functions...
-		dbgPgParams *params = m_currentCommand->getParams();
-		bool use_callable = true;
-
-		// we do not need all of PQi stuff AS90 onwards
-		if (m_owner.EdbMinimumVersion(9, 0))
-			use_callable = false;
-
-#ifdef EDB_LIBPQ
-		if (params && use_callable)
-#else
-		if (PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut && params && use_callable)
-#endif
-		{
-			wxLogInfo(wxT("Using an EnterpriseDB callable statement"));
-			wxString stmt = wxString::Format(wxT("DebugStmt-%d-%d"), this->GetId(), ++run);
-			PGresult *res = PQiPrepareOut(m_owner.getConnection(),
-			                              stmt.mb_str(wxConvUTF8),
-			                              command.mb_str(wxConvUTF8),
-			                              params->nParams,
-			                              params->paramTypes,
-			                              params->paramModes);
-
-			if( PQresultStatus(res) != PGRES_COMMAND_OK)
-			{
-				wxLogError(_( "Could not prepare the callable statement: %s, error: %s" ), stmt.c_str(), wxString(PQresultErrorMessage(res), *conv).c_str());
-				PQclear(res);
-				return this;
-			}
-
-			int ret = PQiSendQueryPreparedOut(m_owner.getConnection(),
-			                                  stmt.mb_str(wxConvUTF8),
-			                                  params->nParams,
-			                                  params->paramValues,
-			                                  NULL, // Can be null - all params are text
-			                                  NULL, // Can be null - all params are text
-			                                  1);
-			if (ret != 1)
-			{
-				wxLogError(_( "Couldn't execute the callable statement: %s" ), stmt.c_str());
-				PQclear(res);
-				return this;
-			}
-
-			// We need to call PQgetResult before we can call PQgetOutResult
-			// Note that this is all async code as far as libpq is concerned to
-			// ensure we can always bail out when required, without leaving threads
-			// hanging around.
-			PGresult *dummy;
-			while(true)
-			{
-				if (die || TestDestroy())
-				{
-					PQrequestCancel(m_owner.getConnection());
-					return this;
-				}
-
-				PQconsumeInput(m_owner.getConnection());
-
-				if (PQisBusy(m_owner.getConnection()))
-				{
-					Yield();
-					wxMilliSleep(10);
-					continue;
-				}
-
-				dummy = PQgetResult(m_owner.getConnection());
-
-				// There should be 2 results - the first is the dummy, the second
-				// contains our out params.
-				if (dummy)
-					break;
-			}
-
-			if((PQresultStatus(dummy) == PGRES_NONFATAL_ERROR) || (PQresultStatus(dummy) == PGRES_FATAL_ERROR))
-				result = dummy;
-			else
-			{
-				PQclear(dummy);
-				result = PQiGetOutResult(m_owner.getConnection());
-			}
-		}
-		else
-		{
-#endif
-			// This is the normal case for a pl/pgsql function, or if we don't
-			// have access to PQgetOutResult.
-			// Note that this is all async code as far as libpq is concerned to
-			// ensure we can always bail out when required, without leaving threads
-			// hanging around.
-			int ret = PQsendQuery(m_owner.getConnection(), command.mb_str(wxConvUTF8));
-
-			if (ret != 1)
-			{
-				wxLogError(_( "Couldn't execute the query (%s): %s" ), command.c_str(), wxString(PQerrorMessage(m_owner.getConnection()), *conv).c_str());
-				return this;
-			}
-
-			PGresult *part;
-			while(true)
-			{
-				if (die || TestDestroy())
-				{
-					PQrequestCancel(m_owner.getConnection());
-					return this;
-				}
-
-				PQconsumeInput(m_owner.getConnection());
-
-				if (PQisBusy(m_owner.getConnection()))
-				{
-					Yield();
-					wxMilliSleep(10);
-					continue;
-				}
-
-				// In theory we should only get one result here, but we'll loop
-				// anyway until we get the last one.
-				part = PQgetResult(m_owner.getConnection());
-
-				if (!part)
-					break;
-
-				result = part;
-			}
-
-#if defined (__WXMSW__) || (EDB_LIBPQ)
-		}
-#endif
-
-		if(!result)
-		{
-			wxLogInfo(wxT( "NULL PGresult - user abort?" ));
-			return this;
-		}
-
-		wxLogInfo(wxT( "Complete: %s" ), wxString(PQresStatus(PQresultStatus(result)), *conv).c_str());
-
-		// Notify the GUI thread that a result set is ready for display
-
-		if( m_currentCommand->getEventType() == wxEVT_NULL )
-		{
-			wxCommandEvent resultEvent( wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_DIRECT_TARGET_COMPLETE );
-			resultEvent.SetClientData( result );
-			m_currentCommand->getCaller()->AddPendingEvent( resultEvent );
-		}
-		else
-		{
-			wxCommandEvent resultEvent( wxEVT_COMMAND_MENU_SELECTED, m_currentCommand->getEventType());
-			resultEvent.SetClientData( result );
-			m_currentCommand->getCaller()->AddPendingEvent( resultEvent );
-		}
-	}
-
-	return this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// noticeHandler()
-//
-//     This function is invoked when a NOTICE is received from the PostgreSQL
-//    server.  We watch for a specially-formatted NOTICE that the PL debugger
-//    raises when it reaches a breakpoint.
-
-void dbgPgThread::noticeHandler( void *arg, const char *message )
-{
-	// Remove the last char from the message as it'll be a \n
-	wxString msg = wxString(message, wxConvUTF8);
-
-	if (msg.EndsWith(wxT("\n")))
-		msg.RemoveLast();
-
-	wxLogInfo(wxT("%s"), msg.c_str());
-
-	dbgPgThread    *thread = (dbgPgThread *)arg;
-	wxEvtHandler *caller = thread->m_currentCommand->getCaller();
-
-	if( strstr( message, "PLDBGBREAK" ))
-	{
-		wxStringTokenizer    tokens( wxString( message, wxConvUTF8 ), wxT( ":\n" ));
-
-		wxString NOTICE     = tokens.GetNextToken();        // NOTICE:
-		wxString PLDBGBREAK = tokens.GetNextToken();        // PLDBGBREAK:
-		wxString PORT       = tokens.GetNextToken();        // port
-
-		PGconn *conn = thread->m_owner.getConnection();
-
-		// Create a dbgConnProp object that contains the same information in a
-		// more convenient format
-
-		dbgConnProp *debugProps = new dbgConnProp;
-
-		debugProps->m_host         = wxString( PQhost( conn ), wxConvUTF8 );
-		debugProps->m_database     = wxString( PQdb( conn ),   wxConvUTF8 );
-		debugProps->m_userName     = wxString( PQuser( conn ), wxConvUTF8 );
-		debugProps->m_debugPort = PORT;
-		debugProps->m_port         = wxString( PQport( conn ), wxConvUTF8 );
-		debugProps->m_password  = wxString( PQpass( conn ), wxConvUTF8 );
-
-		wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_SPAWN_DEBUGGER );
-		buttonEvent.SetClientData((wxClientData *)debugProps );
-		caller->AddPendingEvent( buttonEvent );
-	}
-	else if( strstr( message, "INFO" ))
-	{
-		if( strstr( message, "CONTEXT:" ) == NULL )
-		{
-			wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED );
-
-			wxString strippedMessage( wxString( message, wxConvUTF8 ));
-
-			strippedMessage.Replace( wxT( "INFO:  " ), wxT( "" ), false );
-
-			buttonEvent.SetString( strippedMessage );
-			caller->AddPendingEvent( buttonEvent );
-		}
-	}
-	else
-	{
-		wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED );
-
-		buttonEvent.SetString( wxString( message, wxConvUTF8 ) );
-		caller->AddPendingEvent( buttonEvent );
-	}
-}
-
-dbgPgThreadCommand *dbgPgThread::getNextCommand()
-{
-	dbgPgThreadCommand *result;
-
-	m_queueMutex.Lock();
-
-	wxLogInfo( wxT( "%d commands in queue" ), m_commandQueue.GetCount());
-
-	ThreadCommandList::Node *node = m_commandQueue.GetFirst();
-
-	result = node->GetData();
-
-	m_commandQueue.DeleteNode( node );
-
-	m_queueMutex.Unlock();
-
-	return( result );
-}
diff --git a/pgadmin/debugger/dbgResultset.cpp b/pgadmin/debugger/dbgResultset.cpp
deleted file mode 100644
index 9c5f231..0000000
--- a/pgadmin/debugger/dbgResultset.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgResultset.cpp - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include "pgAdmin3.h"
-
-// wxWindows headers
-#include <wx/wx.h>
-
-// App headers
-#include "debugger/dbgResultset.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// dbgResultset constructor
-//
-//    A dbgResultset object encapsulates a result set produced by executing a
-//  database command. This class is a wrapper around a PGresult handle that
-//    provides a few convenient member functions.
-//
-
-dbgResultset::dbgResultset( PGresult *handle )
-	: m_handle( handle )
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getString()
-//
-//    This function, given a column number and a row number, returns the value in
-//  that slot in the result set (in the form of a string).
-//
-//  Notice that row defaults to 0, which is handy if you have a single-row result
-//    set.
-
-const wxString dbgResultset::getString( int column, int row )
-{
-	return( wxString( PQgetvalue( m_handle, row, column ), wxConvUTF8 ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getString()
-//
-//    This function, given a column name and a row number, returns the value in
-//  that slot in the result set (in the form of a string).
-//
-//  Notice that row defaults to 0.
-
-const wxString dbgResultset::getString( const wxString &columnName, int row )
-{
-	return( getString( PQfnumber( m_handle, columnName.mb_str( wxConvUTF8 )), row ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getLong()
-//
-//    This function, given a column number and a row number, converts the value
-//  in that slot into a long and returns that long.
-//
-//  Notice that row defaults to 0.
-
-long dbgResultset::getLong( int column, int row )
-{
-	return( atoi( PQgetvalue( m_handle, row, column )));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getLong()
-//
-//    This function, given a column name and a row number, converts the value
-//  in that slot into a long and returns that long.
-//
-//  Notice that row defaults to 0.
-
-long dbgResultset::getLong( const wxString &columnName, int row )
-{
-	return( getLong( PQfnumber( m_handle, columnName.mb_str( wxConvUTF8 )), row ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getBool()
-//
-//    This function, given a column number and a row number, converts the value
-//  in that slot into a bool.
-//
-//  Notice that row defaults to 0.
-
-bool dbgResultset::getBool( int column, int row )
-{
-	return( PQgetvalue( m_handle, row, column )[0] == 't' ? true : false );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getBool()
-//
-//    This function, given a column name and a row number, converts the value
-//  in that slot into a bool.
-//
-//  Notice that row defaults to 0.
-
-bool dbgResultset::getBool( const wxString &columnName, int row )
-{
-	return( getBool( PQfnumber( m_handle, columnName.mb_str( wxConvUTF8 )), row ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getCommandStatus()
-//
-//    This function returns the command status contained in the result set. (The
-//  command status will be a value such as PGRES_TUPLES_OK or PGRES_FATAL_ERROR)
-
-ExecStatusType dbgResultset::getCommandStatus()
-{
-	return( PQresultStatus( m_handle ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getErrorMessage()
-//
-//    This function returns the error message (if any) contained in the result set
-
-const wxString dbgResultset::getErrorMessage()
-{
-	return( wxString( PQresultErrorMessage( m_handle ), wxConvUTF8 ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// getRawErrorMessage()
-//
-//    This function returns the error message (if any) contained in the result set
-//
-//    Use this variant (as opposed to getErrorMessage()) when you need the error
-//    message in the same character encoding provided by the server
-
-const char *dbgResultset::getRawErrorMessage()
-{
-	return( PQresultErrorMessage( m_handle ));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// columnExists()
-//
-//    Check if a column exists in the resultset
-
-bool dbgResultset::columnExists(const wxString &columnName)
-{
-	if(PQfnumber(m_handle, columnName.mb_str(wxConvUTF8)) != -1)
-		return(true);
-	else
-		return(false);
-}
diff --git a/pgadmin/debugger/dbgTargetInfo.cpp b/pgadmin/debugger/dbgTargetInfo.cpp
index 300cb82..9795b1f 100644
--- a/pgadmin/debugger/dbgTargetInfo.cpp
+++ b/pgadmin/debugger/dbgTargetInfo.cpp
@@ -14,33 +14,15 @@
 
 // wxWindows headers
 #include <wx/wx.h>
-#include <wx/tokenzr.h>
-#include <wx/arrimpl.cpp>
 
 // App headers
 #include "debugger/dbgTargetInfo.h"
-#include "debugger/dbgResultset.h"
-#include "debugger/dbgPgConn.h"
+#include "debugger/dbgConst.h"
+#include "utils/misc.h"
+#include "utils/pgfeatures.h"
 
 #include <stdexcept>
 
-WX_DEFINE_OBJARRAY( wsArgInfoArray );
-
-#define COL_TARGET_NAME    	"targetname"
-#define COL_SCHEMA_NAME    	"nspname"
-#define COL_LANGUAGE_NAME    "lanname"
-#define COL_ARG_NAMES    	"argnames"
-#define COL_ARG_MODES    	"argmodes"
-#define COL_ARG_TYPES    	"argtypenames"
-#define COL_ARG_TYPEOIDS    "argtypeoids"
-#define COL_ARG_DEFVALS     "argdefvals"
-#define COL_IS_FUNCTION    	"isfunc"
-#define COL_TARGET_OID    	"target"
-#define COL_PACKAGE_OID    	"pkg"
-#define COL_FQ_NAME    	    "fqname"		/* Fully qualified name	*/
-#define COL_RETURNS_SET    	"proretset"
-#define COL_RETURN_TYPE    	"rettype"
-
 ////////////////////////////////////////////////////////////////////////////////
 // dbgTargetInfo constructor
 //
@@ -61,234 +43,594 @@ WX_DEFINE_OBJARRAY( wsArgInfoArray );
 //    This class offers a number of (inline) member functions that you can call
 //  to extract the above information after it's been queried from the server.
 
-dbgTargetInfo::dbgTargetInfo( const wxString &target,  dbgPgConn *conn, char targetType )
+dbgTargetInfo::dbgTargetInfo(Oid _target, pgConn *_conn)
+	: m_args(NULL), m_inputParamCnt(0), m_hasVariadic(false)
 {
-	wxString query =
-	    wxT("select t.*, ")
-	    wxT("  pg_catalog.oidvectortypes( t.argtypes ) as argtypenames, t.argtypes as argtypeoids,")
-	    wxT("  l.lanname, n.nspname, p.proretset, y.typname AS rettype")
-	    wxT(" from")
-	    wxT("  pldbg_get_target_info( '%s', '%c' ) t , pg_namespace n, pg_language l, pg_proc p, pg_type y")
-	    wxT(" where")
-	    wxT("  n.oid = t.schema and ")
-	    wxT("  l.oid = t.targetlang and " )
-	    wxT("  p.oid = t.target and ")
-	    wxT("  y.oid = t.returntype");
-
-	dbgResultset *result = new dbgResultset(conn->waitForCommand(wxString::Format(query, target.c_str(), targetType)));
-
-	if(result->getCommandStatus() != PGRES_TUPLES_OK)
-		throw( std::runtime_error( result->getRawErrorMessage()));
-
-	m_name     	 = result->getString( wxString(COL_TARGET_NAME, wxConvUTF8));
-	m_schema   	 = result->getString( wxString(COL_SCHEMA_NAME, wxConvUTF8));
-	m_language 	 = result->getString( wxString(COL_LANGUAGE_NAME, wxConvUTF8));
-	m_argNames 	 = result->getString( wxString(COL_ARG_NAMES, wxConvUTF8));
-	m_argModes 	 = result->getString( wxString(COL_ARG_MODES, wxConvUTF8));
-	m_argTypes 	 = result->getString( wxString(COL_ARG_TYPES, wxConvUTF8));
-	m_argTypeOids = result->getString( wxString(COL_ARG_TYPEOIDS, wxConvUTF8));
-
-	// get arg defvals if they exist
-	if (result->columnExists(wxString(COL_ARG_DEFVALS, wxConvUTF8)))
-		m_argDefVals = result->getString( wxString(COL_ARG_DEFVALS, wxConvUTF8));
-
-	if (result->columnExists(wxString(COL_IS_FUNCTION, wxConvUTF8)))
-		m_isFunction = result->getBool( wxString(COL_IS_FUNCTION, wxConvUTF8));
+	wxMBConv *conv = _conn->GetConv();
+	wxString targetQuery =
+	    wxT("SELECT\n")
+	    wxT("	p.proname AS name, l.lanname, p.proretset, p.prorettype, y.typname AS rettype,\n")
+	    wxT("	CASE WHEN proallargtypes IS NOT NULL THEN\n")
+	    wxT("			pg_catalog.array_to_string(ARRAY(\n")
+	    wxT("				SELECT\n")
+	    wxT("					pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n")
+	    wxT("				FROM\n")
+	    wxT("					pg_catalog.generate_series(0, pg_catalog.array_upper(\n")
+	    wxT("						p.proallargtypes, 1)) AS s(i)), ',')\n")
+	    wxT("		ELSE\n")
+	    wxT("			pg_catalog.array_to_string(ARRAY(\n")
+	    wxT("				SELECT\n")
+	    wxT("					pg_catalog.format_type(p.proargtypes[s.i], NULL)\n")
+	    wxT("				FROM\n")
+	    wxT("					pg_catalog.generate_series(0, pg_catalog.array_upper(\n")
+	    wxT("						p.proargtypes, 1)) AS s(i)), ',')\n")
+	    wxT("	END AS proargtypenames,\n")
+	    wxT("	CASE WHEN proallargtypes IS NOT NULL THEN\n")
+	    wxT("			pg_catalog.array_to_string(ARRAY(\n")
+	    wxT("				SELECT proallargtypes[s.i] FROM\n")
+	    wxT("					pg_catalog.generate_series(0, pg_catalog.array_upper(proallargtypes, 1)) s(i)), ',')\n")
+	    wxT("		ELSE\n")
+	    wxT("			pg_catalog.array_to_string(ARRAY(\n")
+	    wxT("				SELECT proargtypes[s.i] FROM\n")
+	    wxT("					pg_catalog.generate_series(0, pg_catalog.array_upper(proargtypes, 1)) s(i)), ',')\n")
+	    wxT("	END AS proargtypes,\n")
+	    wxT("	pg_catalog.array_to_string(p.proargnames, ',') AS proargnames,\n")
+	    wxT("	pg_catalog.array_to_string(proargmodes, ',') AS proargmodes,\n");
+
+	if (_conn->GetIsEdb())
+	{
+		targetQuery +=
+		    wxT("	CASE WHEN n.nspparent <> 0 THEN n.oid ELSE 0 END AS pkg,\n")
+		    wxT("	CASE WHEN n.nspparent <> 0 THEN n.nspname ELSE '' END AS pkgname,\n")
+		    wxT("	CASE WHEN n.nspparent <> 0 THEN (SELECT oid FROM pg_proc WHERE pronamespace=n.oid AND proname='cons') ELSE 0 END AS pkgconsoid,\n")
+		    wxT("	CASE WHEN n.nspparent <> 0 THEN g.oid ELSE n.oid END AS schema,\n")
+		    wxT("	CASE WHEN n.nspparent <> 0 THEN g.nspname ELSE n.nspname END AS schemaname,\n")
+		    wxT("	NOT (l.lanname = 'edbspl' AND protype = '1') AS isfunc,\n");
+	}
 	else
-		m_isFunction = true;
-
-	m_oid      	 = result->getLong( wxString(COL_TARGET_OID, wxConvUTF8));
+	{
+		targetQuery +=
+		    wxT("	0 AS pkg,\n")
+		    wxT("	'' AS pkgname,\n")
+		    wxT("	0 AS pkgconsoid,\n")
+		    wxT("	n.oid     AS schema,\n")
+		    wxT("	n.nspname AS schemaname,\n")
+		    wxT("	true AS isfunc,\n");
+	}
+	if (_conn->BackendMinimumVersion(8, 4))
+	{
+		targetQuery += wxT("	pg_catalog.pg_get_function_identity_arguments(p.oid) AS signature,");
+	}
+	else if (_conn->BackendMinimumVersion(8, 1))
+	{
+		targetQuery +=
+		    wxT("	CASE\n")
+		    wxT("		WHEN proallargtypes IS NOT NULL THEN pg_catalog.array_to_string(ARRAY(\n")
+		    wxT("			SELECT\n")
+		    wxT("				CASE\n")
+		    wxT("					WHEN p.proargmodes[s.i] = 'i' THEN ''\n")
+		    wxT("					WHEN p.proargmodes[s.i] = 'o' THEN 'OUT '\n")
+		    wxT("					WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT '\n")
+		    wxT("					WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC '\n")
+		    wxT("				END ||\n")
+		    wxT("				CASE WHEN COALESCE(p.proargnames[s.i], '') = '' THEN ''\n")
+		    wxT("					ELSE p.proargnames[s.i] || ' '\n")
+		    wxT("				END ||\n")
+		    wxT("				pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n")
+		    wxT("			FROM\n")
+		    wxT("				pg_catalog.generate_series(1, pg_catalog.array_upper(p.proallargtypes, 1)) AS s(i)\n")
+		    wxT("			WHERE p.proargmodes[s.i] != 't'\n")
+		    wxT("			), ', ')\n")
+		    wxT("		ELSE\n")
+		    wxT("			pg_catalog.array_to_string(ARRAY(\n")
+		    wxT("				SELECT\n")
+		    wxT("					CASE\n")
+		    wxT("						WHEN COALESCE(p.proargnames[s.i+1], '') = '' THEN ''\n")
+		    wxT("						ELSE p.proargnames[s.i+1] || ' '\n")
+		    wxT("					END ||\n")
+		    wxT("					pg_catalog.format_type(p.proargtypes[s.i], NULL)\n")
+		    wxT("				FROM\n")
+		    wxT("					pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n")
+		    wxT("				), ', ')\n")
+		    wxT("	END AS signature,\n");
+	}
+	else
+	{
+		targetQuery += wxT("	'' AS signature,");
+	}
 
-	if (result->columnExists(wxString(COL_PACKAGE_OID, wxConvUTF8)))
-		m_pkgOid = result->getLong( wxString(COL_PACKAGE_OID, wxConvUTF8));
+	if (_conn->HasFeature(FEATURE_FUNCTION_DEFAULTS))
+	{
+		// EnterpriseDB 8.3R2
+		if(!_conn->BackendMinimumVersion(8, 4))
+		{
+			targetQuery +=
+			    wxT("	pg_catalog.array_to_string(ARRAY(\n")
+			    wxT("	SELECT\n")
+			    wxT("		CASE WHEN p.proargdefvals[x.j] != '-' THEN\n")
+			    wxT("			pg_catalog.pg_get_expr(p.proargdefvals[x.j], 'pg_catalog.pg_class'::regclass, true)\n")
+			    wxT("		ELSE '-' END\n")
+			    wxT("	FROM\n")
+			    wxT("		pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargdefvals, 1)) AS x(j)\n")
+			    wxT("	), ',') AS proargdefaults,\n")
+			    wxT("	CASE WHEN p.proargdefvals IS NULL THEN '0'\n")
+			    wxT("		ELSE pg_catalog.array_upper(p.proargdefvals, 1)::text END AS pronargdefaults\n");
+		}
+		else
+		{
+			targetQuery +=
+			    wxT("	pg_catalog.pg_get_expr(p.proargdefaults, 'pg_catalog.pg_class'::regclass, false) AS proargdefaults,\n")
+			    wxT("	p.pronargdefaults\n");
+		}
+	}
 	else
-		m_pkgOid = 0;
+	{
+		targetQuery +=
+		    wxT("	'' AS proargdefaults, 0 AS pronargdefaults\n");
+	}
+	targetQuery +=
+	    wxT("FROM\n")
+	    wxT("	pg_catalog.pg_proc p\n")
+	    wxT("	LEFT JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid\n")
+	    wxT("	LEFT JOIN pg_catalog.pg_language l ON p.prolang = l.oid\n")
+	    wxT("	LEFT JOIN pg_catalog.pg_type y ON p.prorettype = y.oid\n");
+	if(_conn->GetIsEdb())
+	{
+		targetQuery +=
+		    wxT("	LEFT JOIN pg_catalog.pg_namespace g ON n.nspparent = g.oid\n");
+	}
+	targetQuery +=
+	    wxString::Format(wxT("WHERE p.oid = %ld"), (long)_target);
+
+	pgSet *set = _conn->ExecuteSet(targetQuery);
+
+	if (conv == NULL)
+	{
+		conv = &wxConvLibc;
+	}
+
+	if (!set || _conn->GetLastResultStatus() != PGRES_TUPLES_OK)
+	{
+		if (set)
+			delete set;
+		wxLogError(_("Could not fetch information about the debugger target.\n") +
+		           _conn->GetLastError());
+
+		throw (std::runtime_error(
+		           (const char *)(_conn->GetLastError().c_str())));
+	}
+
+	if (set->NumRows() == 0)
+	{
+		delete set;
+
+		wxLogError(_("Can't find the debugging target"));
+		throw (std::runtime_error("Can't find target!"));
+	}
+
+	m_oid           = _target;
+	m_name          = set->GetVal(wxT("name"));
+	m_schema        = set->GetVal(wxT("schemaname"));
+	m_package       = set->GetVal(wxT("pkgname"));
+	m_language      = set->GetVal(wxT("lanname"));
+	m_returnType    = set->GetVal(wxT("rettype"));
+	m_funcSignature = set->GetVal(wxT("signature"));
+	m_isFunction    = set->GetBool(wxT("isfunc"));
+	m_returnsSet    = set->GetBool(wxT("proretset"));
+	m_pkgOid        = set->GetLong(wxT("pkg"));
+	m_pkgInitOid    = set->GetLong(wxT("pkgconsoid"));
+	m_schemaOid     = set->GetLong(wxT("schema"));
+	m_fqName        = m_schema + wxT(".") +
+	                  (m_pkgOid == 0 ? wxT("") : (m_package + wxT("."))) + m_name;
+
+	wxArrayString argModes, argNames, argTypes, argTypeOids, argDefVals,
+	              argBaseTypes;
+
+	// Fetch Argument Modes (if available)
+	if (!set->IsNull(set->ColNumber(wxT("proargmodes"))))
+	{
+		wxString tmp;
+		tmp = set->GetVal(wxT("proargmodes"));
+
+		if (!tmp.IsEmpty())
+			getArrayFromCommaSeparatedList(tmp, argModes);
+	}
+	// Fetch Argument Names (if available)
+	if (!set->IsNull(set->ColNumber(wxT("proargnames"))))
+	{
+		wxString tmp;
+		tmp = set->GetVal(wxT("proargnames"));
+
+		if (!tmp.IsEmpty())
+			getArrayFromCommaSeparatedList(tmp, argNames);
+	}
+	// Fetch Argument Type-Names (if available)
+	if (!set->IsNull(set->ColNumber(wxT("proargtypenames"))))
+	{
+		wxString tmp;
+		tmp = set->GetVal(wxT("proargtypenames"));
 
-	m_fqName	 = result->getString( wxString(COL_FQ_NAME, wxConvUTF8));
-	m_returnsSet = result->getBool( wxString(COL_RETURNS_SET, wxConvUTF8));
-	m_returnType = result->getString( wxString(COL_RETURN_TYPE, wxConvUTF8));
+		if (!tmp.IsEmpty())
+			getArrayFromCommaSeparatedList(tmp, argTypes);
+	}
+	// Fetch Argument Type-Names (if available)
+	if (!set->IsNull(set->ColNumber(wxT("proargtypes"))))
+	{
+		wxString tmp;
+		tmp = set->GetVal(wxT("proargtypes"));
+		if (!tmp.IsEmpty())
+			getArrayFromCommaSeparatedList(tmp, argTypeOids);
+	}
 
-	// Parse out the argument types, names, and modes
+	size_t nArgDefs = (size_t)set->GetLong(wxT("pronargdefaults"));
+	// Fetch Argument Default Values (if available)
+	if (!set->IsNull(set->ColNumber(wxT("proargdefaults"))) && nArgDefs != 0)
+	{
+		wxString tmp;
+		tmp = set->GetVal(wxT("proargdefaults"));
 
-	// By creating a tokenizer with wxTOKEN_STRTOK and a delimiter string
-	// that contains ",{}", we can parse out PostgreSQL array strings like:
-	//	 {int, varchar, numeric}
+		if (!tmp.IsEmpty())
+			getArrayFromCommaSeparatedList(tmp, argDefVals);
+	}
 
-	wxStringTokenizer names(m_argNames, wxT( ",{}" ), wxTOKEN_STRTOK);
-	wxStringTokenizer types(m_argTypes, wxT( ",{}" ), wxTOKEN_STRTOK);
-	wxStringTokenizer typeOids(m_argTypeOids, wxT( ",{}" ), wxTOKEN_STRTOK);
-	wxStringTokenizer modes(m_argModes, wxT( ",{}" ), wxTOKEN_STRTOK);
-	wxStringTokenizer defvals(m_argDefVals, wxT( ",{}" ), wxTOKEN_STRTOK);
+	wxString argName, argDefVal;
+	short    argMode;
+	Oid      argTypeOid;
+	size_t   argCnt = argTypes.Count();
 
-	// Create one wsArgInfo for each target argument
+	// This function/procedure does not take any arguments
+	if (argCnt == 0)
+	{
+		return;
+	}
 
-	m_argInCount = m_argOutCount = m_argInOutCount = 0;
-	int	argCount = 0;
+	size_t idx = 0;
+	m_args = new pgDbgArgs();
 
-	while( types.HasMoreTokens())
+	for (; idx < argCnt; idx++)
 	{
-		argCount++;
+		argTypeOid = (Oid)strtoul(argTypeOids[idx].mb_str(wxConvUTF8), 0, 10);
+		argDefVal  = wxEmptyString;
 
-		wxString	argName = names.GetNextToken();
-		wxString    defVal;
+		argName = wxEmptyString;
+		if (idx < argNames.Count())
+			argName = argNames[idx];
 
-		if( argName.IsEmpty())
-			argName.Printf( wxT( "$%d" ), argCount );
+		if (argName.IsEmpty())
+			argName.Printf( wxT( "dbgParam%d" ), (idx + 1));
+
+		if (idx < argModes.Count())
+		{
+			wxString tmp = argModes[idx];
+			switch ((tmp.c_str())[0])
+			{
+				case 'i':
+					argMode = pgParam::PG_PARAM_IN;
+					m_inputParamCnt++;
+					break;
+				case 'b':
+					m_inputParamCnt++;
+					argMode = pgParam::PG_PARAM_INOUT;
+					break;
+				case 'o':
+					argMode = pgParam::PG_PARAM_OUT;
+					break;
+				case 'v':
+					m_inputParamCnt++;
+					argMode = pgParam::PG_PARAM_VARIADIC;
+					m_hasVariadic = true;
+					break;
+				case 't':
+					continue;
+				default:
+					m_inputParamCnt++;
+					argMode = pgParam::PG_PARAM_IN;
+					break;
+			}
+		}
+		else
+		{
+			m_inputParamCnt++;
+			argMode = pgParam::PG_PARAM_IN;
+		}
 
 		// In EDBAS 90, if an SPL-function has both an OUT-parameter
 		// and a return value (which is not possible on PostgreSQL otherwise),
 		// the return value is transformed into an extra OUT-parameter
 		// named "_retval_"
-		if (argName == wxT("_retval_") && conn->EdbMinimumVersion(9, 0))
+		if (argName == wxT("_retval_") && _conn->EdbMinimumVersion(9, 0))
 		{
 			// this will be the return type for this object
-			m_returnType = types.GetNextToken();
-
-			// consume uniformly, mode will definitely be "OUT"
-			modes.GetNextToken();
+			m_returnType = argTypes[idx];
 
-			// ignore OID also..
-			typeOids.GetNextToken();
 			continue;
 		}
 
-		wsArgInfo	argInfo( argName, types.GetNextToken(), modes.GetNextToken(), typeOids.GetNextToken());
-
-		if( argInfo.getMode() == wxT( "i" ))
-			m_argInCount++;
-		else if( argInfo.getMode() == wxT( "o" ))
-			m_argOutCount++;
-		else if( argInfo.getMode() == wxT( "b" ))
-			m_argInOutCount++;
-
-		// see if this arg has a def value and add if so. If we see an empty
-		// string "", what should we do? Infact "" might be a valid default
-		// value in some cases, so for now store "" too. Note that we will
-		// store the "" only if this is stringlike type and nothing otherwise..
-		defVal = (defvals.GetNextToken()).Strip ( wxString::both );
-		if (argInfo.isValidDefVal(defVal))
-		{
-			// remove starting/trailing quotes
-			defVal.Replace( wxT( "\"" ), wxT( "" ));
-			argInfo.setValue(defVal);
-		}
-
-		m_argInfo.Add( argInfo );
+		m_args->Add(new dbgArgInfo(argName, argTypes[idx], argTypeOid, argMode));
 	}
 
-	// Get the package initializer function OID. On 8.1 or below, this is
-	// assumed to be the same as the package OID. On 8.2, we have an API :-)
-	if (conn->EdbMinimumVersion(8, 2))
+	if (m_args->GetCount() == 0)
 	{
-		PGresult *res;
+		delete m_args;
+		m_args = NULL;
 
-		m_pkgInitOid = 0;
-		res = conn->waitForCommand( wxT( "SELECT pldbg_get_pkg_cons(") + NumToStr(m_pkgOid) + wxT(");"));
+		return;
+	}
 
-		if (PQresultStatus(res) == PGRES_TUPLES_OK)
-		{
-			// Retrieve the query result and return it.
-			m_pkgInitOid = StrToLong(wxString(PQgetvalue(res, 0, 0), wxConvUTF8));
+	if (nArgDefs != 0)
+	{
+		argCnt = m_args->GetCount();
 
-			// Cleanup & exit
-			PQclear(res);
+		// Set the default as the value for the argument
+		for (idx = argCnt - 1; idx >= 0; idx--)
+		{
+			dbgArgInfo *arg = (dbgArgInfo *)((*m_args)[idx]);
+
+			if (arg->GetMode() == pgParam::PG_PARAM_INOUT ||
+			        arg->GetMode() == pgParam::PG_PARAM_IN)
+			{
+				nArgDefs--;
+
+				if (argDefVals[nArgDefs] != wxT("-"))
+				{
+					arg->SetDefault(argDefVals[nArgDefs]);
+				}
+
+				if (nArgDefs == 0)
+				{
+					break;
+				}
+			}
 		}
 	}
-	else if (conn->GetIsEdb())
-		m_pkgInitOid = m_pkgOid;
-	else
-		m_pkgInitOid = 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // operator[]
 //
-//    This operator function makes it easy to index into the m_argInfo[] array
+//    This operator function makes it easy to index into the m_args array
 //    using concise syntax.
-
-wsArgInfo &dbgTargetInfo::operator[]( int index )
+dbgArgInfo *dbgTargetInfo::operator[](int index)
 {
-	return( m_argInfo[index] );
+	if (m_args == NULL)
+		return (dbgArgInfo *)NULL;
+
+	if (index < 0 || index >= m_args->GetCount())
+		return (dbgArgInfo *)NULL;
+
+	return (dbgArgInfo *)((*m_args)[index]);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// wsArgInfo constructor
-//
-//    A wsArgInfo object contains information about a function (or procedure)
-//  argument.  Inside of each wsArgInfo object, we store the name of the argument,
-//    the argument type, and the argument mode (IN (i), OUT (o), or INOUT (b)).
-//
-//    Once the user has had a chance to enter values for each of the IN and INOUT
-//    arguments, we store those values inside of the corresponding wsArgInfo objects
-
-wsArgInfo::wsArgInfo( const wxString &argName, const wxString &argType, const wxString &argMode, const wxString &argTypeOid)
-	: m_name( argName.Strip( wxString::both )),
-	  m_type( argType.Strip( wxString::both )),
-	  m_mode( argMode == wxT( "" ) ? wxT( "i" ) : argMode.Strip( wxString::both )),
-	  m_value()
+dbgArgInfo::dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid,
+                       short _mode)
+	: m_name(_name), m_type(_type), m_typeOid(_typeOid), m_mode(_mode),
+	  m_hasDefault(false), m_useDefault(false), m_null(NULL)
 {
-	long oid;
-	argTypeOid.ToLong(&oid);
-	m_typeOid = (Oid)oid;
+	if (!_type.EndsWith(wxT("[]"), &m_baseType))
+	{
+		m_baseType = wxEmptyString;
+	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// quoteValue()
-//
-//    This function will extract the argument value from the given wsArgInfo object
-//  and will wrap that value in single quotes (unless the value has already been
-//    quoted).  If the argument value (entered by the user) is blank, we return NULL
-//    instead of a quoted string.
-//
-//    NOTE: we quote all value regardless of type - it's perfectly valid to quote a
-//        numeric (or boolean) value in PostgreSQL
 
-const wxString wsArgInfo::quoteValue()
+pgParam *dbgArgInfo::GetParam(wxMBConv *_conv)
 {
-	if (m_value == wxT(""))
-		return (wxT("NULL"));
-	else if (m_value == wxT("''"))
-		return (wxT("''"));
-	else if (m_value == wxT("\\'\\'"))
-		return (wxT("'\\'\\''"));
-	else if (m_value[0] == '\'' )
-		return (m_value);
-	else
-		return(wxString(wxT("'") + m_value + wxT("'")));
+	return new pgParam(m_typeOid,
+	                   (m_null ? (wxString *)NULL : &m_val),
+	                   _conv, m_mode);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// isValidDefVal()
-//
-//    This function checks if the passed in defvalue is sane or not. If it is
-//    empty, nothing needs to be done. However if the backend returns "", then
-//    we need to entertain this as valid input only for stringlike types. Else
-//    we ignore. Obviously if defval is anything other than "", we need to
-//    honor it
-//
-
-bool wsArgInfo::isValidDefVal(const wxString defValue)
+bool dbgTargetInfo::AddForExecution(pgQueryThread *_thread)
 {
-	if (defValue.IsEmpty())
+	wxASSERT(_thread != NULL);
+
+	if (_thread == NULL)
 		return false;
 
-	if (defValue != wxT("\"\""))
-		return true;
+	pgConn *conn = _thread->GetConn();
+
+	pgParamsArray *params   = NULL;
+	wxString       strQuery;
+	bool           useCallable = false;
+
+	// Basically - we can call the function/target three way
+	// 1. If it is a edbspl procedure, we can use callable statement
+	// 2. If the database server is of type EnterpriseDB, and
+	//    function/procedure is type 'edbspl', we should use the anonymous
+	//    function block for:
+	//    a. Version < 9.0
+	//    b. Package function/procedure
+	// 3. Otherwise, we should use the simple function call (except using EXEC
+	//    for the procedure in 'edbspl' instead of using SELECT)
+	if (_thread->SupportCallableStatement() &&
+	        m_language == wxT("edbspl") &&
+	        !m_isFunction)
+	{
+		useCallable = true;
+		strQuery = wxT("CALL ") + m_fqName + wxT("(");
+
+		if (m_args)
+		{
+			params = new pgParamsArray();
+			wxMBConv *conv = conn->GetConv();
+
+			for(int idx = 0; idx < m_args->GetCount(); idx++)
+			{
+				params->Add(((*m_args)[idx])->GetParam(conv));
+
+				if (idx != 0)
+					strQuery += wxT(", ");
+				strQuery += wxString::Format(wxT("$%d::"), idx + 1) +
+				            ((*m_args)[idx])->GetTypeName();
+			}
+		}
+		strQuery += wxT(")");
+	}
+	else if (m_language == wxT("edbspl") && conn->GetIsEdb() &&
+	         (!conn->BackendMinimumVersion(9, 0) || m_pkgOid != 0))
+	{
+		wxString strDeclare, strStatement;
+
+		if (!m_isFunction)
+		{
+			strStatement = wxT("\tEXEC ") + m_fqName;
+		}
+		else if (m_args && m_args->GetCount() > 0 && conn->BackendMinimumVersion(8, 4))
+		{
+			strStatement = wxT("\tPERFORM ") + m_fqName;
+		}
+		else
+		{
+			strStatement = wxT("\tSELECT ") + m_fqName;
+		}
+
+		if (m_args && m_args->GetCount() > 0)
+		{
+			strStatement.Append(wxT("("));
+
+			for(int idx = 0, firstProcessed = false; idx < m_args->GetCount(); idx++)
+			{
+				dbgArgInfo *arg = (*m_args)[idx];
+
+				if (!conn->EdbMinimumVersion(8, 4) &&
+				        arg->GetMode() == pgParam::PG_PARAM_OUT &&
+				        (!m_isFunction || m_language == wxT("edbspl")))
+				{
+					if (firstProcessed)
+						strStatement.Append(wxT(", "));
+					firstProcessed = true;
+
+					strStatement.Append(wxT("NULL::")).Append(arg->GetTypeName());
+				}
+				else if (conn->EdbMinimumVersion(8, 4) &&
+				         (arg->GetMode() == pgParam::PG_PARAM_OUT ||
+				          arg->GetMode() == pgParam::PG_PARAM_INOUT))
+				{
+					if (!m_isFunction || m_language == wxT("edbspl"))
+					{
+						wxString strParam = wxString::Format(wxT("param%d"), idx);
+
+						strDeclare.Append(wxT("\t"))
+						.Append(strParam)
+						.Append(wxT(" "))
+						.Append(arg->GetTypeName());
+
+						if (arg->GetMode() == pgParam::PG_PARAM_INOUT)
+						{
+							strDeclare.Append(wxT(" := "))
+							.Append(arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value()))
+							.Append(wxT("::"))
+							.Append(arg->GetTypeName());
+						}
+						strDeclare.Append(wxT(";\n"));
+
+						if (firstProcessed)
+							strStatement.Append(wxT(", "));
+						firstProcessed = true;
+
+						strStatement.Append(strParam);
+					}
+					else if (arg->GetMode() == pgParam::PG_PARAM_INOUT)
+					{
+						if (firstProcessed)
+							strStatement.Append(wxT(", "));
+						firstProcessed = true;
+
+						strStatement.Append(
+						    arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value()))
+						.Append(wxT("::"))
+						.Append(arg->GetTypeName());
+					}
+				}
+				else
+				{
+					if (firstProcessed)
+						strStatement.Append(wxT(", "));
+					firstProcessed = true;
+
+					if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC)
+						strStatement.Append(wxT("VARIADIC "));
+
+					strStatement.Append(
+					    arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value()))
+					.Append(wxT("::"))
+					.Append(arg->GetTypeName());
+				}
+			}
+			strStatement.Append(wxT(")"));
+
+			if (conn->BackendMinimumVersion(8, 4))
+			{
+				strQuery = wxT("DECLARE\n") +
+				           strDeclare + wxT("BEGIN\n") + strStatement + wxT("END;");
+			}
+			else
+			{
+				strQuery = strStatement;
+			}
+		}
+		else if (!m_isFunction && m_language == wxT("edbspl"))
+		{
+			strQuery = strStatement;
+		}
+		else
+		{
+			strQuery = strStatement.Append(wxT("()"));
+		}
+	}
 	else
 	{
-		// return true only if the type is a stringlike type..
-		switch (getTypeOid())
+		if (!m_isFunction)
 		{
-			case PGOID_TYPE_CHAR:
-			case PGOID_TYPE_NAME:
-			case PGOID_TYPE_TEXT:
-			case PGOID_TYPE_BPCHAR:
-			case PGOID_TYPE_VARCHAR:
-			case PGOID_TYPE_CSTRING:
-				return true;
-
-			default:
-				return false;
+			strQuery = wxT("EXEC ") + m_fqName + wxT("(");
 		}
+		else if (m_returnType == wxT("record"))
+		{
+			strQuery = wxT("SELECT ") + m_fqName + wxT("(");
+		}
+		else
+		{
+			strQuery = wxT("SELECT * FROM ") + m_fqName + wxT("(");
+		}
+
+		if (m_args)
+		{
+			params = new pgParamsArray();
+			wxMBConv *conv = conn->GetConv();
+
+			for(int idx = 0; idx < m_args->GetCount(); idx++)
+			{
+				dbgArgInfo *arg = (*m_args)[idx];
+
+				if (arg->GetMode() != pgParam::PG_PARAM_OUT)
+				{
+					params->Add(arg->GetParam(conv));
+
+					if (idx != 0)
+						strQuery += wxT(", ");
+
+					if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC)
+						strQuery += wxT("VARIADIC ");
+
+					strQuery += wxString::Format(wxT("$%d::"), idx + 1) +
+					            ((*m_args)[idx])->GetTypeName();
+				}
+			}
+
+			/*
+			 * The function may not have IN/IN OUT/VARIADIC arguments, but only
+			 * OUT one(s).
+			 */
+			if (params->GetCount() == 0)
+			{
+				delete params;
+				params = NULL;
+			}
+		}
+		strQuery += wxT(")");
 	}
+
+	_thread->AddQuery(strQuery, params, RESULT_ID_DIRECT_TARGET_COMPLETE, NULL, useCallable);
+
+	return true;
 }
diff --git a/pgadmin/debugger/debugger.cpp b/pgadmin/debugger/debugger.cpp
index 445cd92..603a71a 100644
--- a/pgadmin/debugger/debugger.cpp
+++ b/pgadmin/debugger/debugger.cpp
@@ -14,15 +14,15 @@
 
 // App headers
 #include "pgAdmin3.h"
+#include "frm/frmMain.h"
 #include "debugger/debugger.h"
-#include "debugger/dbgBreakPoint.h"
-#include "debugger/ctlCodeWindow.h"
-#include "debugger/dlgDirectDbg.h"
-#include "debugger/frmDebugger.h"
+#include "debugger/dbgController.h"
 #include "schema/pgFunction.h"
 #include "schema/pgTrigger.h"
 #include "schema/edbPackageFunction.h"
 
+#include <stdexcept>
+
 ///////////////////////////////////////////////////
 // Debugger factory
 ///////////////////////////////////////////////////
@@ -42,7 +42,7 @@ wxWindow *debuggerFactory::StartDialog(frmMain *form, pgObject *obj)
 	if (res->GetVal(wxT("proname")).Contains(wxT(":")))
 	{
 		wxLogError(_("Functions with a colon in the name cannot be debugged."));
-		return 0;
+		return (wxWindow *)NULL;
 	}
 
 	if (res->GetLong(wxT("count")) != 1)
@@ -56,49 +56,20 @@ wxWindow *debuggerFactory::StartDialog(frmMain *form, pgObject *obj)
 			browser->DeleteChildren(coll->GetId());
 			coll->ShowTreeDetail(browser);
 		}
-		return 0;
+		return (wxWindow *)NULL;
 	}
 
-	// Setup the debugger frame
-	frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
-
-	// Setup the connection properties to be used by the debugger
-	dbgConnProp cp;
-	cp.m_database = obj->GetDatabase()->GetIdentifier();
-	cp.m_host = obj->GetServer()->GetName();
-	cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
-	cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
-	cp.m_sslMode = obj->GetServer()->GetSSL();
-	cp.m_userName = obj->GetServer()->GetUsername();
-
-	// Setup the debugging session
-	dlgDirectDbg *directDebugger = NULL;
-	directDebugger = debugger->addDirectDbg(cp);
-	if (directDebugger == NULL)
+	try
 	{
-		return 0;
+		new dbgController(form, obj, true);
 	}
-
-	dbgBreakPointList &breakpoints = directDebugger->getBreakpointList();
-	breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, NumToStr((long)obj->GetOid()), wxT("'NULL'")));
-	if (!directDebugger->startDebugging())
+	catch (const std::runtime_error &)
 	{
-		ctlTree *browser = form->GetBrowser();
-		wxTreeItemId item = browser->GetSelection();
-		if (obj == browser->GetObject(item))
-		{
-			pgCollection *coll = browser->GetParentCollection(obj->GetId());
-			browser->DeleteChildren(coll->GetId());
-			coll->ShowTreeDetail(browser);
-		}
-		return 0;
+		// just ignore this errors, we already logged them in native messages to
+		// the end-user
 	}
 
-	// Return the debugger window to frmMain.
-	if (debugger && !directDebugger->GetCancelled())
-		return debugger;
-	else
-		return 0;
+	return (wxWindow *)NULL;
 }
 
 bool debuggerFactory::CheckEnable(pgObject *obj)
@@ -130,23 +101,14 @@ bool debuggerFactory::CheckEnable(pgObject *obj)
 				if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
 					return false;
 
-				if (func->GetReturnType() != wxT("trigger") && func->GetReturnType() != wxT("\"trigger\""))
+				if (func->GetReturnType() != wxT("trigger") &&
+				        func->GetReturnType() != wxT("\"trigger\""))
 				{
-					if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
+					if (func->GetLanguage() == wxT("plpgsql") &&
+					        obj->GetDatabase()->CanDebugPlpgsql())
 						return true;
-#ifndef EDB_LIBPQ
-#ifdef __WXMSW__
 					else if (func->GetLanguage() == wxT("edbspl") &&
-					         obj->GetConnection()->EdbMinimumVersion(8, 4) &&
-					         !obj->GetConnection()->EdbMinimumVersion(9, 0) &&
-					         !(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
-						return false;
-#else
-					else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
-						return false;
-#endif
-#endif
-					else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
+					         obj->GetDatabase()->CanDebugEdbspl())
 						return true;
 					else
 						return false;
@@ -194,16 +156,18 @@ wxWindow *breakpointFactory::StartDialog(frmMain *form, pgObject *obj)
 	// deep down in query threads.
 	// We also make sure the function name doesn't contain a : as that will
 	// sent the debugger API nuts.
-	pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname"));
+	pgSet *res = obj->GetConnection()->ExecuteSet(
+	                 wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname"));
 	if (res->GetVal(wxT("proname")).Contains(wxT(":")))
 	{
 		wxLogError(_("Functions with a colon in the name cannot be debugged."));
-		return 0;
+		return (wxWindow *)NULL;
 	}
 
 	if (res->GetLong(wxT("count")) != 1)
 	{
 		wxLogError(_("The selected function could not be found."));
+
 		ctlTree *browser = form->GetBrowser();
 		wxTreeItemId item = browser->GetSelection();
 		if (obj == browser->GetObject(item))
@@ -212,36 +176,20 @@ wxWindow *breakpointFactory::StartDialog(frmMain *form, pgObject *obj)
 			browser->DeleteChildren(coll->GetId());
 			coll->ShowTreeDetail(browser);
 		}
-		return 0;
+		return (wxWindow *)NULL;
 	}
 
-	// Setup the debugger frame
-	frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
-	debugger->Show(true);
-	debugger->Raise();
-
-	// Setup the connection properties to be used by the debugger
-	dbgConnProp cp;
-	cp.m_database = obj->GetDatabase()->GetIdentifier();
-	cp.m_host = obj->GetServer()->GetName();
-	cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
-	cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
-	cp.m_sslMode = obj->GetServer()->GetSSL();
-	cp.m_userName = obj->GetServer()->GetUsername();
-
-	// Setup the debugging session
-	ctlCodeWindow *globalDebugger = NULL;
-	globalDebugger = debugger->addDebug(cp);
-	if (globalDebugger == NULL)
-		return 0;
-
-	dbgBreakPointList &breakpoints = globalDebugger->getBreakpointList();
-	breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, dbgOid, wxT("'NULL'")));
-
-	globalDebugger->startGlobalDebugging();
-
-	// Return the debugger window to frmMain.
-	return debugger;
+	try
+	{
+		new dbgController(form, obj, false);
+	}
+	catch (const std::runtime_error &)
+	{
+		// just ignore this errors, we already logged them in native messages to
+		// the end-user
+	}
+
+	return (wxWindow *)NULL;
 }
 
 bool breakpointFactory::CheckEnable(pgObject *obj)
@@ -266,23 +214,15 @@ bool breakpointFactory::CheckEnable(pgObject *obj)
 				pgFunction *func = (pgFunction *)obj;
 
 				// If this is an EDB wrapped function, no debugging allowed
-				if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
+				if (obj->GetConnection()->GetIsEdb() &&
+				        func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
 					return false;
 
-				if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
+				if (func->GetLanguage() == wxT("plpgsql") &&
+				        obj->GetDatabase()->CanDebugPlpgsql())
 					return true;
-#ifndef EDB_LIBPQ
-#ifdef __WXMSW__
 				else if (func->GetLanguage() == wxT("edbspl") &&
-				         obj->GetConnection()->EdbMinimumVersion(8, 4) &&
-				         !(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
-					return false;
-#else
-				else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
-					return false;
-#endif
-#endif
-				else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
+				         obj->GetDatabase()->CanDebugEdbspl())
 					return true;
 				else
 					return false;
@@ -303,12 +243,15 @@ bool breakpointFactory::CheckEnable(pgObject *obj)
 				pgTrigger *trig = (pgTrigger *)obj;
 
 				// If this is an EDB wrapped function, no debugging allowed
-				if (obj->GetConnection()->GetIsEdb() && trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
+				if (obj->GetConnection()->GetIsEdb() &&
+				        trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
 					return false;
 
-				if (trig->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
+				if (trig->GetLanguage() == wxT("plpgsql") &&
+				        obj->GetDatabase()->CanDebugPlpgsql())
 					return true;
-				else if (trig->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
+				else if (trig->GetLanguage() == wxT("edbspl") &&
+				         obj->GetDatabase()->CanDebugEdbspl())
 					return true;
 				else
 					return false;
diff --git a/pgadmin/debugger/dlgDirectDbg.cpp b/pgadmin/debugger/dlgDirectDbg.cpp
index 2e1ef87..bb62988 100644
--- a/pgadmin/debugger/dlgDirectDbg.cpp
+++ b/pgadmin/debugger/dlgDirectDbg.cpp
@@ -16,38 +16,39 @@
 #include <wx/grid.h>
 
 // App headers
-#include "debugger/dlgDirectDbg.h"
-#include "debugger/frmDebugger.h"
-#include "debugger/dbgTargetInfo.h"
-#include "debugger/dbgPgConn.h"
-#include "debugger/ctlResultGrid.h"
-#include "debugger/dbgResultset.h"
+#include "ctl/ctlAuiNotebook.h"
+#include "db/pgConn.h"
+#include "db/pgQueryThread.h"
+#include "db/pgQueryResultEvent.h"
+#include "schema/pgObject.h"
 #include "debugger/dbgConst.h"
-#include "debugger/dbgDbResult.h"
-#include "debugger/ctlCodeWindow.h"
+#include "debugger/dbgBreakPoint.h"
+#include "debugger/dbgController.h"
+#include "debugger/dbgModel.h"
+#include "debugger/ctlStackWindow.h"
+#include "debugger/ctlMessageWindow.h"
+#include "debugger/ctlTabWindow.h"
+#include "debugger/frmDebugger.h"
+#include "debugger/dlgDirectDbg.h"
 
 #include "images/debugger.pngc"
 
-#include <stdexcept>
-
 #define lblMessage                  CTRL_STATIC("lblMessage")
 #define grdParams                   CTRL("grdParams", wxGrid)
 #define chkPkgInit                  CTRL_CHECKBOX("chkPkgInit")
+#define btnDebug                    CTRL_BUTTON("wxID_OK")
 
-IMPLEMENT_CLASS( dlgDirectDbg, pgDialog )
-
-BEGIN_EVENT_TABLE( dlgDirectDbg, pgDialog )
-	EVT_BUTTON( wxID_OK,                    dlgDirectDbg::OnOk )
-	EVT_BUTTON( wxID_CANCEL,                dlgDirectDbg::OnCancel )
-	EVT_BUTTON( MENU_ID_SPAWN_DEBUGGER,  dlgDirectDbg::OnDebug )
-	EVT_BUTTON( MENU_ID_NOTICE_RECEIVED, dlgDirectDbg::OnNoticeReceived )
-
-	EVT_MENU( RESULT_ID_DIRECT_TARGET_COMPLETE, dlgDirectDbg::OnTargetComplete )
-
-	EVT_CLOSE( dlgDirectDbg::OnClose )
+IMPLEMENT_CLASS(dlgDirectDbg, pgDialog)
 
+BEGIN_EVENT_TABLE(dlgDirectDbg, pgDialog)
+	EVT_BUTTON(wxID_OK,                               dlgDirectDbg::OnOk)
+	EVT_BUTTON(wxID_CANCEL,                           dlgDirectDbg::OnCancel)
+	EVT_GRID_CMD_LABEL_LEFT_CLICK(XRCID("grdParams"), dlgDirectDbg::OnClickGridLabel)
+	EVT_MENU(RESULT_ID_ARGS_UPDATED,                  dlgDirectDbg::ResultArgsUpdated)
+	EVT_MENU(RESULT_ID_ARGS_UPDATE_ERROR,             dlgDirectDbg::ResultArgsUpdateError)
 END_EVENT_TABLE()
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // dlgDirectDbg constructor
 //
@@ -62,855 +63,990 @@ END_EVENT_TABLE()
 //  EXEC statement that invokes the target (with the parameter values
 //  provided by the user).
 
-dlgDirectDbg::dlgDirectDbg( frmDebugger *parent, wxWindowID id, const dbgConnProp &connProp )
-	: m_connProp(connProp),
-	  m_targetInfo(NULL),
-	  m_conn(NULL),
-	  m_codeWindow(NULL),
-	  m_parent (parent),
-	  m_cancelled (false)
+dlgDirectDbg::dlgDirectDbg(frmDebugger *_parent, dbgController *_controller,
+                           pgConn *_conn)
+	: m_controller(_controller), m_thread(NULL), m_conn(_conn)
 {
+	int width,height, totalWidth=0;
 	wxWindowBase::SetFont(settings->GetSystemFont());
-	LoadResource(m_parent, wxT("dlgDirectDbg"));
+	LoadResource(_parent, wxT("dlgDirectDbg"));
 
 	// Icon
 	SetIcon(*debugger_png_ico);
 	RestorePosition();
-}
 
-////////////////////////////////////////////////////////////////////////////////
-// setupParamWindow()
-//
-//    This function lays out the parameter prompt window.  It contains a grid that
-//  displays the name and type of each IN (and IN/OUT) parameter and a place to
-//  enter a value for each of those parameters.  It also contains an OK button
-//    and a CANCEL button
-
-void dlgDirectDbg::setupParamWindow( )
-{
-	// Add three columns to the grid control:
-	//   (Parameter) Name, Type, and Value
-	grdParams->CreateGrid( 0, 3 );
-	grdParams->SetColLabelValue( COL_NAME,  _( "Name" ));
-	grdParams->SetColLabelValue( COL_TYPE,  _( "Type" ));
-	grdParams->SetColLabelValue( COL_VALUE, _( "Value" ));
-	grdParams->SetRowLabelSize( 25 );
-	grdParams->SetColSize( 0, 75 );
-	grdParams->SetColSize( 1, 100 );
-	grdParams->SetColSize( 2, grdParams->GetClientSize().x - 210 );
-	grdParams->SetColLabelSize( 18 );
+	grdParams->SetRowLabelSize(wxGRID_AUTOSIZE);
+	grdParams->SetColLabelSize(20);
+	grdParams->AutoSizeColumns(true);
 
 	chkPkgInit->SetValue(false);
-	chkPkgInit->Disable();
-}
 
-////////////////////////////////////////////////////////////////////////////////
-// startDebugging()
-//
-//    This function initializes *this with information about the target function
-//  (or procedure), constructs a grid that prompts the user for parameter values,
-//  and then displays the prompt dialog to the user.  Call this function after
-//  you construct a dlgDirectDbg (obviously) when you're ready to display the
-//  prompt dialog to the user.
+	PopulateParamGrid();
 
-bool dlgDirectDbg::startDebugging( void )
-{
-	// First, figure out what kind of target we are going to debug.
-	// The caller filled in our m_breakpoint list with the name and
-	// type of each target that he's interested in.
-	//
-	// FIXME: For now, we only allow one initial breakpoint for direct
-	//          debugging - you can create other breakpoints once you see
-	//          the source code.
+	LoadSettings();
 
-	dbgBreakPointList::Node *node = m_breakpoints.GetFirst();
+	for(int i=0;i<7;i++)
+		grdParams->AutoSizeColumn(i, true);
 
-	wxASSERT_MSG( node != NULL, wxT( "Expected to find at least one target on the command line" ));
-
-	dbgBreakPoint *breakpoint = node->GetData();
-
-	m_target = breakpoint->getTarget();
-
-	char    targetType = 0;
-
-	switch( breakpoint->getTargetType())
+	// Extend grid to it's parent width.
+	
+	grdParams->GetClientSize(&width, &height);
+	for (int i = 0; i<6; i++)
 	{
-		case dbgBreakPoint::TRIGGER:
-			targetType = 't';
-			break;
-		case dbgBreakPoint::FUNCTION:
-			targetType = 'f';
-			break;
-		case dbgBreakPoint::PROCEDURE:
-			targetType = 'p';
-			break;
-		case dbgBreakPoint::OID:
-			targetType = 'o';
-			break;
-		default:
-		{
-			wxASSERT_MSG( false, wxT( "Unexpected target type" ));
-			break;
-		}
+		totalWidth += grdParams->GetColumnWidth(i);
 	}
-
-	if (!loadTargetInfo( m_target, m_connProp, targetType ))
-		return false;
-
-	populateParamGrid();
-	return true;
+	grdParams->SetColumnWidth(COL_DEF_VAL,width-totalWidth-100); // Total client width - total six column widths - the first (an empty) column width.
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// loadTargetInfo()
+// PopulateParamGrid()
+//
+//    This function reads parameter descriptions from m_targetInfo and adds a
+//    new row to the grid control for each IN (or IN/OUT, VARAIADIC) parameter.
+//    Each row displays the parameter name, the data type, and an entry box
+//    where the user can type in a value for that parameter
 //
-//    This function establishes a connection to the server and creates a new
-//  dbgTargetInfo object that loads information about the debug target (that is,
-//  the function or procedure of interest).  Call this function with two
-//  arguments: target should contain the signature of a function or procedure
-//  or the OID of a function or procedure and connProp should contain the
-//  information required to connect to the server (like the hostname, port number,
-//  and user name).
-
-bool dlgDirectDbg::loadTargetInfo( const wxString &target, const dbgConnProp &connProp, char targetType )
+void dlgDirectDbg::PopulateParamGrid()
 {
-	// Connect to the server using the connection properties contained in connProp
+	pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs();
 
-	m_conn = new dbgPgConn(m_parent, connProp);
+	// If the target is defined within package, offer the user
+	// a chance to debug the initializer (there may or may not
+	// be an initializer, we don't really know at this point)
+	if(m_controller->GetTargetInfo()->GetPkgOid() == 0)
+		chkPkgInit->Disable();
+	else
+		chkPkgInit->Enable();
 
-	if( m_conn && m_conn->isConnected())
+	if (!args)
 	{
-		if( getenv( "DEBUGGER_INIT" ))
-		{
-			PQclear( m_conn->waitForCommand( wxString(getenv( "DEBUGGER_INIT" ), wxConvUTF8 )));
-		}
+		grdParams->SetColLabelValue(COL_NAME, _("No arguments required"));
+		grdParams->SetColSize(0, 350);
+		return;
+	}
 
-		// Our proxy API may throw (perfectly legitimate) errors at us (for example,
-		// if the target process ends while we are waiting for a breakpoint) - apparently
-		// those error messages scare the user when they show up in the log, so we'll
-		// just suppress logging for this session
+	// Add seven columns to the grid control:
+	// - Name, Type, NULL?, EXPR?, Value, Default?, And Default Value
+	grdParams->CreateGrid(0, 7);
 
-		PQclear( m_conn->waitForCommand( wxT( "SET log_min_messages TO fatal" )));
+	grdParams->SetColLabelValue(COL_NAME, _("Names"));
+	grdParams->SetColLabelValue(COL_TYPE, _("Type"));
+	grdParams->SetColLabelValue(COL_NULL, _("Null?"));
+	grdParams->SetColLabelValue(COL_EXPR, _("Expr?"));
+	grdParams->SetColLabelValue(COL_VALUE, _("Value"));
+	grdParams->SetColLabelValue(COL_USE_DEF, _("Default?"));
+	grdParams->SetColLabelValue(COL_DEF_VAL, _("Default Value"));
 
-		// Now load information about the target into m_targetInfo (note:
-		// the dbgTargetInfo() constructor queries the server for all
-		// required information)
+	size_t idx = 0;
 
-		try
-		{
-			m_targetInfo = new dbgTargetInfo( target, m_conn, targetType );
-		}
-		catch( const std::runtime_error &error )
-		{
-			wxLogError(wxT("%s"), wxString(error.what(), wxConvUTF8).c_str());
-			m_conn->Close();
-			return false;
-		}
+	for(size_t pIdx = 0; pIdx < args->Count(); pIdx++)
+	{
+		dbgArgInfo *arg = (*args)[pIdx];
 
-		this->SetTitle(m_targetInfo->getName());
-	}
+		// If this is an IN parameter (or an IN/OUT parameter), add
+		// a new row to the grid
+		if(arg->GetMode() != pgParam::PG_PARAM_OUT)
+		{
+			grdParams->AppendRows(1);
+			grdParams->SetCellValue(idx, COL_NAME,  arg->GetName());
 
-	return true;
-}
+			// Make it obvious which are variadics
+			if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC)
+			{
+				grdParams->SetRowLabelValue(idx, wxEmptyString);
+				grdParams->SetCellValue(idx, COL_TYPE, arg->GetTypeName());
 
-////////////////////////////////////////////////////////////////////////////////
-// populateParamGrid()
-//
-//    This function reads parameter descriptions from m_targetInfo and adds a new
-//  row to the grid control for each IN (or IN/OUT) parameter.  Each row displays
-//    the parameter name, the data type, and an entry box where the user can type
-//  in a value for that parameter
+				if (!arg->IsArray())
+				{
+					// Is the value an expression?
+					grdParams->SetCellEditor(idx, COL_EXPR, new ctlGridCellBoolEditor());
+					grdParams->SetCellRenderer(idx, COL_EXPR, new wxGridCellBoolRenderer());
+					grdParams->SetCellValue(idx, COL_EXPR, wxT(""));
+				}
+				else
+				{
+					grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90));
+				}
 
-void dlgDirectDbg::populateParamGrid( )
-{
-	// First, try to load default values from a previous invocation into
-	// m_targetInfo (assuming that we're debugging the same target this
-	// time around)
+				// Use the default value?
+				grdParams->SetCellRenderer(idx, COL_USE_DEF, new wxGridCellBoolRenderer());
+				grdParams->SetCellEditor(idx, COL_USE_DEF, new ctlGridCellBoolEditor());
+			}
+			else
+			{
+				grdParams->SetCellValue(idx, COL_TYPE, wxT("VARIADIC ") + arg->GetTypeName());
+				grdParams->SetRowLabelValue(idx, wxEmptyString);
 
-	loadSettings();
+				grdParams->AppendRows(1);
+				grdParams->SetRowLabelValue(idx + 1, wxT("+"));
+				grdParams->SetCellValue(idx + 1, COL_NAME, _("Click '+/-' to add/remove value to variadic"));
 
-	int i = 0;
+				grdParams->SetCellBackgroundColour(idx + 1, COL_EXPR,    wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx + 1, COL_VALUE,   wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx + 1, COL_USE_DEF, wxColour(235, 235, 235, 90));
+			}
 
-	for( int count = 0; count < m_targetInfo->getArgCount(); ++count )
-	{
-		wsArgInfo &arg = ((*m_targetInfo)[count] );
+			// Set value to NULL?
+			grdParams->SetCellEditor(idx, COL_NULL, new ctlGridCellBoolEditor(arg));
+			grdParams->SetCellRenderer(idx, COL_NULL, new wxGridCellBoolRenderer());
+			grdParams->SetCellValue(idx, COL_NULL, wxT(""));
 
-		// If this is an IN parameter (or an IN/OUT parameter), add
-		// a new row to the grid
+			if (arg->HasDefault())
+			{
+				// Whenever the default value is available, use that by default
+				grdParams->SetCellValue(idx, COL_USE_DEF, wxT("1"));
+				grdParams->SetCellValue(idx, COL_DEF_VAL, arg->Default());
+
+				// When "Use Defalut?" is enabled, disable VALUE, NULL? and
+				// EXPR? columns
+				grdParams->SetReadOnly(idx, COL_USE_DEF, false);
+				grdParams->SetReadOnly(idx, COL_VALUE, false);
+				grdParams->SetReadOnly(idx, COL_EXPR, false);
+			}
+			else
+			{
+				grdParams->SetCellValue(idx, COL_USE_DEF, wxT(""));
+				grdParams->SetCellValue(idx, COL_DEF_VAL, wxT("-- NO DEFAULT VALUE --"));
 
-		if( arg.getMode() != wxT( "o" ))
-		{
-			grdParams->AppendRows( 1 );
-			grdParams->SetCellValue( i, COL_NAME,  arg.getName());
+				// When default value is not available, we should ask the user
+				// to enter them
+				grdParams->SetReadOnly(idx, COL_USE_DEF, true);
+				grdParams->SetReadOnly(idx, COL_VALUE, arg->IsArray());
+				grdParams->SetReadOnly(idx, COL_EXPR, arg->IsArray());
 
-			// Make it obvious which are variadics
-			if (arg.getMode() != wxT( "v" ))
-				grdParams->SetCellValue( i, COL_TYPE,  arg.getType());
-			else
-				grdParams->SetCellValue( i, COL_TYPE, arg.getType() + wxT(" VARIADIC"));
+				grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90));
+				if (arg->IsArray())
+				{
+					grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90));
+				}
+			}
 
-			grdParams->SetCellValue( i, COL_VALUE, arg.getValue());
+			grdParams->SetReadOnly(idx, COL_NULL, false);
+			grdParams->SetReadOnly(idx, COL_NAME, true);
+			grdParams->SetReadOnly(idx, COL_TYPE, true);
+			grdParams->SetReadOnly(idx, COL_DEF_VAL, true);
+			grdParams->SetCellBackgroundColour(idx, COL_NAME,    wxColour(235, 235, 235, 90));
+			grdParams->SetCellBackgroundColour(idx, COL_TYPE,    wxColour(235, 235, 235, 90));
+			grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90));
 
-			grdParams->SetReadOnly( i, COL_NAME,  true );
-			grdParams->SetReadOnly( i, COL_TYPE,  true );
-			grdParams->SetReadOnly( i, COL_VALUE, false );
+			idx++;
 
-			i++;
+			if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC &&
+			        arg->IsArray())
+			{
+				grdParams->AppendRows(1);
+
+				grdParams->SetRowLabelValue(idx, wxT("+"));
+				grdParams->SetCellValue(idx, COL_NAME, _("Click '+/-' to add/remove value to the array"));
+
+				grdParams->SetReadOnly(idx, COL_NAME,    true);
+				grdParams->SetReadOnly(idx, COL_TYPE,    true);
+				grdParams->SetReadOnly(idx, COL_NULL,    true);
+				grdParams->SetReadOnly(idx, COL_EXPR,    true);
+				grdParams->SetReadOnly(idx, COL_VALUE,   true);
+				grdParams->SetReadOnly(idx, COL_USE_DEF, true);
+				grdParams->SetReadOnly(idx, COL_DEF_VAL, true);
+
+				grdParams->SetCellBackgroundColour(idx, COL_NAME,    wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_TYPE,    wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_NULL,    wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_EXPR,    wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_VALUE,   wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90));
+				grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90));
+
+				idx++;
+			}
 		}
 	}
 
 	// Move the cursor to the first value (so that the user
 	// can just start typing)
 
-	grdParams->SetGridCursor( 0, COL_VALUE );
+	grdParams->SetGridCursor(0, COL_VALUE);
 	grdParams->SetFocus();
+}
 
-	// If the target is defined within package, offer the user
-	// a chance to debug the initializer (there may or may not
-	// be an initializer, we don't really know at this point)
-
-	if( m_targetInfo->getPkgOid() == 0 )
-		chkPkgInit->Disable();
-	else
-		chkPkgInit->Enable();
-
-	// Set the columns' size
-
-	grdParams->SetColSize(COL_NAME, 200);
-	grdParams->SetColSize(COL_TYPE, 100);
-	grdParams->SetColSize(COL_VALUE, 150);
-
-	// If the target function has no parameters (and it's not defined within
-	// a package), there's no good reason to wait for the user to hit the Ok
-	// button before we invoke the target...
+void dlgDirectDbg::LoadLastCellSetting(int row_number, int parameter_index, int index_array_bound, bool isArray )
+{
+	wxString lastValue,valKey;
+	dbgTargetInfo *target = m_controller->GetTargetInfo();
+	long num;
 
-	if((m_targetInfo->getArgInCount() + m_targetInfo->getArgInOutCount() == 0 ) && ( m_targetInfo->getPkgOid() == 0))
+	settings->Read(wxT("Debugger/Proc/OID"), &num, -1L);
+	if(num != target->GetOid())
 	{
-		grdParams->AppendRows( 1 );
-		grdParams->SetReadOnly( i, COL_NAME,  true );
-		grdParams->SetReadOnly( i, COL_TYPE,  true );
-		grdParams->SetReadOnly( i, COL_VALUE, true );
-
-		grdParams->SetCellValue( 0, COL_NAME, _( "No arguments required" ));
-		wxFont font = grdParams->GetCellFont( 0, COL_NAME );
-		font.SetStyle( wxFONTSTYLE_ITALIC );
-		grdParams->SetCellFont( 0, COL_NAME, font );
-
-		activateDebugger();
+		return;
 	}
+
 	else
 	{
-		this->ShowModal();
-	}
-}
+	
+		if(!isArray)
+		{
+			valKey = wxString::Format(wxT("Debugger/Proc/%d/0/"), parameter_index); // Non array elements cell index is 0.
+			settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString);
+			grdParams->SetCellValue(row_number, COL_VALUE, lastValue);
+		}
 
-////////////////////////////////////////////////////////////////////////////////
-// OnOk()
-//
-//    This event handler is called when the user clicks the OK button - we call the
-//  activateDebugger() function to set the required breakpoint and invoke the
-//  target (after nabbing any parameter values from the prompt dialog)
+		else
+		{
+			long arrCnt;
+
+			settings->Read(wxString::Format(wxT("Debugger/Proc/%d/"), parameter_index) + wxT("ArrCnt"), &arrCnt, 0L);
+
+			for( int i=0; i <=index_array_bound && i <= arrCnt-1; i++ ) // Refresh an entire array element 
+			{
+				valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), parameter_index , i);
+				settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString);
+				grdParams->SetCellValue((row_number-index_array_bound) + i, COL_VALUE, lastValue);
+			}
+		}
+	}
 
-void dlgDirectDbg::OnOk( wxCommandEvent &event )
-{
-	activateDebugger();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// loadSettings()
+// LoadSettings()
 //
 //    Loads default values from our .ini file. We save the OID of the most
 //    recent direct-debugging target when close a session. If we're direct-
 //    debugging the same target this time around, we load the argument values
 //    from the .ini file.
-
-void dlgDirectDbg::loadSettings()
+void dlgDirectDbg::LoadSettings()
 {
-	long        lastOID;
+	long     num, arrCnt;
+	wxString tmp, key;
+	bool     initPkgCon = false;
 
-	settings->Read( wxT( "Debugger/Proc/OID" ), &lastOID, -1 );
+	settings->Read(wxT("Debugger/Proc/OID"), &num, -1L);
 
-	if( lastOID == m_targetInfo->getOid())
+	dbgTargetInfo *target = m_controller->GetTargetInfo();
+	pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs();
+
+	if (num != target->GetOid())
 	{
-		int    count = 0;
+		chkPkgInit->SetValue(target->GetPkgInitOid() != 0L);
+		chkPkgInit->Enable(target->GetPkgInitOid() != 0L);
 
-		for( int i = 0; i < m_targetInfo->getArgCount(); ++i )
+		return;
+	}
+	else
+	{
+		settings->Read(wxT("Debugger/Proc/initialize_package_constructor"), &initPkgCon, true);
+
+		chkPkgInit->SetValue(&initPkgCon && target->GetPkgInitOid() != 0L);
+		chkPkgInit->Enable(target->GetPkgInitOid() != 0L);
+	}
+
+	settings->Read(wxT("Debugger/Proc/args"), &num, 0L);
+
+	if (num <= 0L)
+		return;
+
+	if (!args)
+		return;
+
+	for (int cnt = 0, row = 0; cnt < num && cnt < args->Count();)
+	{
+		ctlGridCellBoolEditor *editor =
+		    dynamic_cast<ctlGridCellBoolEditor *>(
+		        grdParams->GetCellEditor(row, COL_NULL));
+		dbgArgInfo *arg
+		= editor != NULL ? editor->GetArg() : NULL;
+
+		if (arg == NULL)
+		{
+			row++;
+
+			continue;
+		}
+
+		key = wxString::Format(wxT("Debugger/Proc/%d/"), cnt);
+
+		// Use NULL?
+		settings->Read(key + wxT("NULL"), &tmp, wxEmptyString);
+		grdParams->SetCellValue(row, COL_NULL, tmp);
+
+		// Use Default (if available)
+		settings->Read(key + wxT("USE_DEF"), &tmp, wxEmptyString);
+		grdParams->SetCellValue(row, COL_USE_DEF, tmp);
+
+		// Is Array/VARIADIC?
+		settings->Read(key + wxT("ArrCnt"), &arrCnt, 0L);
+
+		if (arrCnt > 0L)
 		{
-			wsArgInfo &arg = (*m_targetInfo)[i];
+			// An individual variable can be an expression or can be the 'NULL' value
+			wxString valKey, strVal, strExpr, strNull;
 
-			if( arg.getMode() != wxT( "o" ))
+			for (int idx = 0; idx < arrCnt; idx++, row++)
 			{
-				settings->Read( wxString::Format( wxT( "Debugger/Proc/argValue%d" ), ++count ), &(arg.getValue()), wxT( "" ));
+				valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), cnt, idx);
+
+				// Use 'NULL'?
+				settings->Read(valKey + wxT("NULL"), &strNull, wxEmptyString);
+
+				// Use EXPR?
+				settings->Read(valKey + wxT("EXPR"), &strExpr, wxEmptyString);
+
+				// Value
+				settings->Read(valKey + wxT("VAL"), &strVal, wxEmptyString);
+
+				if (arg->IsArray())
+				{
+					int arrRow = row + 1;
+
+					if (idx == 0)
+					{
+						grdParams->SetReadOnly(row, COL_EXPR, true);
+						grdParams->SetReadOnly(row, COL_VALUE, true);
+
+						grdParams->SetCellBackgroundColour(row, COL_EXPR,  wxColour(235, 235, 235, 90));
+						grdParams->SetCellBackgroundColour(row, COL_VALUE, wxColour(235, 235, 235, 90));
+
+						grdParams->SetRowLabelValue(
+						    row, wxString::Format(wxT("%d"), cnt + 1));
+					}
+					grdParams->InsertRows(arrRow, 1, false);
+					grdParams->SetRowLabelValue(arrRow, wxT("-"));
+
+					grdParams->SetCellValue(arrRow, COL_TYPE, arg->GetBaseType());
+
+					// Is the value an expression?
+					grdParams->SetCellEditor(arrRow, COL_EXPR, new ctlGridCellBoolEditor());
+					grdParams->SetCellRenderer(arrRow, COL_EXPR,
+					                           new wxGridCellBoolRenderer());
+					grdParams->SetCellValue(arrRow, COL_EXPR, strExpr);
+
+					// Set value to NULL?
+					grdParams->SetCellEditor(arrRow, COL_NULL,
+					                         new ctlGridCellBoolEditor(arg));
+					grdParams->SetCellRenderer(arrRow, COL_NULL,
+					                           new wxGridCellBoolRenderer());
+					grdParams->SetCellValue(arrRow, COL_NULL, strNull);
+
+					// Set value
+					grdParams->SetCellValue(arrRow, COL_VALUE, strVal);
+
+					grdParams->SetReadOnly(arrRow, COL_NULL, false);
+					grdParams->SetReadOnly(arrRow, COL_EXPR, false);
+					grdParams->SetReadOnly(arrRow, COL_VALUE, false);
+
+					grdParams->SetCellBackgroundColour(arrRow, COL_NAME,    wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow, COL_TYPE,    wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow, COL_USE_DEF, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow, COL_DEF_VAL, wxColour(235, 235, 235, 90));
+
+					grdParams->SetReadOnly(arrRow + 1, COL_NAME,    true);
+					grdParams->SetReadOnly(arrRow + 1, COL_TYPE,    true);
+					grdParams->SetReadOnly(arrRow + 1, COL_NULL,    true);
+					grdParams->SetReadOnly(arrRow + 1, COL_EXPR,    true);
+					grdParams->SetReadOnly(arrRow + 1, COL_VALUE,   true);
+					grdParams->SetReadOnly(arrRow + 1, COL_USE_DEF, true);
+					grdParams->SetReadOnly(arrRow + 1, COL_DEF_VAL, true);
+
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_NAME, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_TYPE, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_NULL, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_EXPR, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_VALUE, wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_USE_DEF,
+					                                   wxColour(235, 235, 235, 90));
+					grdParams->SetCellBackgroundColour(arrRow + 1, COL_DEF_VAL,
+					                                   wxColour(235, 235, 235, 90));
+
+					grdParams->SetRowLabelValue(arrRow + 1, wxT("+"));
+				}
+				else
+				{
+					grdParams->SetCellValue(row, COL_VALUE, strVal);
+					grdParams->SetCellValue(row, COL_EXPR, strExpr);
+					grdParams->SetCellValue(row, COL_NULL, strNull);
+
+					grdParams->SetReadOnly(row, COL_NULL, false);
+					grdParams->SetReadOnly(row, COL_EXPR, false);
+					grdParams->SetReadOnly(row, COL_VALUE, false);
+
+					grdParams->SetRowLabelValue(
+					    row, wxString::Format(wxT("%d"), cnt + 1));
+				}
 			}
+			if (arg->IsArray())
+				row++;
 		}
+		cnt++;
 	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// saveSettings()
-//
-//    Save default values to our .ini file. We save the OID of the most
-//    recent direct-debugging target when close a session. We also save the
-//  value of each argument - if you debug the same target again next time,
-//    loadSettings() will initialize the parameter-values window with the
-//    same parameter values that you entered in this session.
 
-void dlgDirectDbg::saveSettings()
+void dlgDirectDbg::OnOk(wxCommandEvent &_ev)
 {
-	settings->WriteLong( wxT( "Debugger/Proc/OID" ), m_targetInfo->getOid());
+	if (m_thread)
+		return;
+
+	grdParams->Enable(false);
+	btnDebug->Enable(false);
 
-	int    count = 0;
+	m_thread = new dbgArgValueEvaluator(m_conn, this);
 
-	for( int i = 0; i < m_targetInfo->getArgCount(); ++i )
+	if (m_thread->Create() != wxTHREAD_NO_ERROR)
 	{
-		wsArgInfo &arg = ( *m_targetInfo)[i];
+		delete m_thread;
+		m_thread = NULL;
 
-		if( arg.getMode() != wxT( "o" ))
-		{
-			settings->Write( wxString::Format( wxT( "Debugger/Proc/argName%d" ), ++count ), arg.getName());
-			settings->Write( wxString::Format( wxT( "Debugger/Proc/argType%d" ),   count ), arg.getType());
-			settings->Write( wxString::Format( wxT( "Debugger/Proc/argValue%d" ),  count ), wxString((arg.getValue() == wxT("NULL") ? wxEmptyString : arg.getValue().c_str())));
-		}
+		wxLogError(_("Couldn't create the required thread for this."));
+		EndModal(wxID_CANCEL);
+
+		return;
 	}
+
+	m_thread->Run();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// OnCancel()
-//
-//    This event handler is called when the user clicks the Cancel button - we
-//    close the connection to the server and then close ourself.
 
-void dlgDirectDbg::OnCancel( wxCommandEvent &event )
+void dlgDirectDbg::OnCancel(wxCommandEvent &_ev)
 {
-	// This will raise close event which is handled by
-	// dlgDirectDbg::OnClose().
-	m_cancelled = true;
-	Close();
-}
+	if (m_thread)
+	{
+		m_thread->CancelEval();
 
-////////////////////////////////////////////////////////////////////////////////
-// OnClose()
-//
-//    wxWidgets invokes this event handler when the user closes the parameter
-//    window. We close the connection with server and raise close event for
-//    MainFrame.
+		m_thread->Wait();
 
-void dlgDirectDbg::OnClose( wxCloseEvent &event )
+		delete m_thread;
+		m_thread = NULL;
+	}
+	_ev.Skip();
+}
+
+void dlgDirectDbg::OnClickGridLabel(wxGridEvent &_ev)
 {
-	// Destroy the grid - required as it seems to create threads in some cases
-	if (grdParams)
+	if (_ev.AltDown() || _ev.ControlDown() || _ev.ShiftDown())
 	{
-		grdParams->Destroy();
-		delete grdParams;
+		_ev.Skip();
+
+		return;
 	}
 
-	// Close the debugger (proxy) connection
-	if (m_conn)
+	int row = _ev.GetRow();
+	int col = _ev.GetCol();
+
+	if (row < 0 || col > 0)
 	{
-		m_conn->Close();
-		delete m_conn;
-		m_conn = NULL;
+		_ev.Skip();
+
+		return;
 	}
 
-	// Closing frmMain from here leads to recursive call
-	// to OnClose function on windows
-#ifndef __WXWIN__
-	// This will inform the MainWindow to close.
-	// if it's not visible yet.
-	if (m_parent->IsShown())
-		event.Skip();
+	wxString strLabel = grdParams->GetRowLabelValue(row);
+
+	if (strLabel == wxT("+"))
+	{
+		wxASSERT(row != 0);
+
+		ctlGridCellBoolEditor *editor =
+		    dynamic_cast<ctlGridCellBoolEditor *>(
+		        grdParams->GetCellEditor(row - 1, COL_NULL));
+		dbgArgInfo *arg
+		= editor != NULL ? editor->GetArg() : NULL;
+
+		grdParams->InsertRows(row, 1, false);
+		grdParams->SetRowLabelValue(row, wxT("-"));
+
+		grdParams->SetCellValue(row, COL_TYPE, arg->GetBaseType());
+		grdParams->SetCellBackgroundColour(row, COL_TYPE, wxColour(235, 235, 235, 90));
+		grdParams->SetCellBackgroundColour(row, COL_NAME, wxColour(235, 235, 235, 90));
+		grdParams->SetCellBackgroundColour(row, COL_USE_DEF, wxColour(235, 235, 235, 90));
+		grdParams->SetCellBackgroundColour(row, COL_DEF_VAL, wxColour(235, 235, 235, 90));
+
+		// Is the value an expression?
+		grdParams->SetCellEditor(row, COL_EXPR, new ctlGridCellBoolEditor());
+		grdParams->SetCellRenderer(row, COL_EXPR, new wxGridCellBoolRenderer());
+		grdParams->SetCellValue(row, COL_EXPR, wxT(""));
+
+		// Set value to NULL?
+		grdParams->SetCellEditor(row, COL_NULL, new ctlGridCellBoolEditor(arg));
+		grdParams->SetCellRenderer(row, COL_NULL, new wxGridCellBoolRenderer());
+		grdParams->SetCellValue(row, COL_NULL, wxT("1"));
+
+		row++;
+		grdParams->SetRowLabelValue(row, wxT("+"));
+	}
+	else if (strLabel == wxT("-"))
+	{
+		dbgArgInfo *arg = NULL;
+		grdParams->DeleteRows(row, 1, false);
+	}
 	else
-		m_parent->Close();
-#endif // __WXWIN__
+		return;
+
+	// Update the row labels
+	ctlGridCellBoolEditor *editor = NULL;
+	dbgArgInfo *arg = NULL,
+	            *prev = NULL;
+	wxString strName;
+
+	int totalRows = grdParams->GetNumberRows(),
+	    idx = 0;
+	row = 0;
 
-	if ( this->IsModal() )
+	while (row < totalRows)
 	{
-		if ( m_cancelled )
-			EndModal( wxID_CANCEL );
+		editor =
+		    dynamic_cast<ctlGridCellBoolEditor *>(
+		        grdParams->GetCellEditor(row, COL_NULL));
+		arg	= editor != NULL ? editor->GetArg() : NULL;
+		strName = grdParams->GetCellValue(row, COL_NAME);
+
+		if (strName.IsEmpty() && arg)
+			grdParams->SetRowLabelValue(row, wxT("-"));
+		else if (!strName.IsEmpty() && !arg)
+			grdParams->SetRowLabelValue(row, wxT("+"));
 		else
-			EndModal( wxID_OK);
+		{
+			idx++;
+			grdParams->SetRowLabelValue(row, wxString::Format(wxT("%d"), idx));
+		}
+
+		row++;
 	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// activateDebugger()
+// SaveSettings()
 //
-//    This function is called after the user has filled in any parameter values
-//  and clicked the Ok button.  activateDebugger() extracts the paramter values
-//  from the grid control and copies those values into our dbgTargetInfo object
-//  (m_targetInfo).  Next, we set a breakpoint at the target, and, finally,
-//  we invoke the target function/procedure
-
-bool dlgDirectDbg::activateDebugger( )
+//    Save default values to our .ini file. We save the OID of the most
+//    recent direct-debugging target when close a session. We also save the
+//    value of each argument - if you debug the same target again next time,
+//    loadSettings() will initialize the parameter-values window with the
+//    same parameter values that you entered in this session.
+//
+void dlgDirectDbg::SaveSettings()
 {
-	// Unset the completed flag (if it exists)
-	if (m_codeWindow)
-		m_codeWindow->m_targetComplete = false;
-
-	// Copy the parameter values from the grid into m_targetInfo
-	int i = 0;
-
-	for( int count = 0; count < m_targetInfo->getArgCount(); ++count )
+	wxString    strName, strExpr, strVal, strNull, strDef, strKey, strValExpr;
+	dbgArgInfo *prev = NULL,
+	            *arg = NULL;
+	int         row = 0,
+	            idx = -1,
+	            arrCnt = 1;
+
+	// Save the current function/procedure/trigger OID
+	settings->WriteLong(wxT("Debugger/Proc/OID"),
+	                    m_controller->GetTargetInfo()->GetOid());
+
+	// Save - whether we need to debug the package constructor
+	settings->WriteBool(wxT("Debugger/Proc/initialize_package_constructor"),
+	                    (chkPkgInit->IsEnabled() && chkPkgInit->GetValue()));
+
+	for (; row < grdParams->GetNumberRows(); row++)
 	{
-		wsArgInfo &arg = (*m_targetInfo)[count];
+		ctlGridCellBoolEditor *editor =
+		    dynamic_cast<ctlGridCellBoolEditor *>(
+		        grdParams->GetCellEditor(row, COL_NULL));
+		arg	= editor != NULL ? editor->GetArg() : NULL;
 
-		// Populate the ArgInfo object's IN or INOUT variables only, OUT
-		// variables will be assigned NULL later on.
+		// This should be the information for add/remove values for an array
+		if (arg == NULL)
+		{
+			continue;
+		}
+		else if (prev != arg)
+		{
+			idx++;
+			prev = arg;
 
-		if(arg.getMode() != wxT("o"))
+			if (arg->IsArray())
+			{
+				arrCnt = 0;
+			}
+			else
+			{
+				arrCnt = 1;
+			}
+		}
+		else
 		{
-			arg.setValue( grdParams->GetCellValue(i, COL_VALUE));
-			i++;
+			arrCnt++;
 		}
-	}
 
-	// Write the target OID and argument values to our settings file
-	// so that we can default them next time around
-	saveSettings();
+		settings->WriteInt(wxString::Format(wxT("Debugger/Proc/%d/ArrCnt"), idx), arrCnt);
 
-	// Now set a breakpoint at the target (note: the call to setBreakpoint()
-	// will hang until the  server sends us a response)
+		if ((arrCnt == 0 && arg->IsArray()) ||
+		        (arrCnt == 1 && !arg->IsArray()))
+		{
+			// Use Default (if available)
+			settings->Write(wxString::Format(wxT("Debugger/Proc/%d/USE_DEF"), idx),
+			                grdParams->GetCellValue(row, COL_USE_DEF));
 
-	try
-	{
-		// Debug the initialiser. We can only do so once, so unset, and disable
-		// the option after setting the breakpoint
-		if( chkPkgInit->GetValue())
-			setBreakpoint( m_targetInfo->getPkgOid(), m_targetInfo->getPkgInitOid());
+			// Use NULL?
+			settings->Write(wxString::Format(wxT("Debugger/Proc/%d/NULL"), idx),
+			                grdParams->GetCellValue(row, COL_NULL));
 
-		chkPkgInit->SetValue(false);
-		chkPkgInit->Disable();
+			if (arrCnt == 0 && arg->IsArray())
+				continue;
+		}
 
-		setBreakpoint( m_targetInfo->getPkgOid(), m_targetInfo->getOid());
-	}
-	catch( const std::runtime_error &error )
-	{
-		wxMessageBox( wxString( error.what(), wxConvUTF8 ), _( "Cannot create breakpoint" ), wxOK | wxICON_ERROR );
-		return( false );
-	}
+		strKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), idx, arrCnt - 1);
 
-	// And invoke the target (note: the call to invokeTarget() will *NOT*
-	// wait for a result set from the server - instead, OnResultReady() will
-	// be called when the result set is ready)
+		// Use NULL?
+		settings->Write(strKey + wxT("NULL"),
+		                grdParams->GetCellValue(row, COL_NULL));
 
-	try
-	{
-		invokeTarget();
-	}
-	catch( const std::runtime_error &error )
-	{
-		wxMessageBox( wxString( error.what(), wxConvUTF8 ), _( "Cannot invoke target" ), wxOK | wxICON_ERROR );
-		return( false );
+		// Is value EXPR?
+		settings->Write(strKey + wxT("EXPR"),
+		                grdParams->GetCellValue(row, COL_EXPR));
+
+		// Value
+		settings->Write(strKey + wxT("VAL"),
+		                grdParams->GetCellValue(row, COL_VALUE));
 	}
 
-	return( true );
+	// Save the number of arguments
+	settings->WriteLong(wxT("Debugger/Proc/args"), (long)(idx + 1));
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// setBreakpoint()
-//
-//    This function creates a breakpoint at the target.  For now, we always create
-//  a breakpoint by calling edb_procoid_debug() or plpgsql_procoid_debug() with
-//  the OID of the target.  Later, we'll change this function to use the
-//  new CREATE BREAKPOINT command.
 
-void dlgDirectDbg::setBreakpoint(long pkgOid, long funcOid)
+ctlGridCellBoolEditor::ctlGridCellBoolEditor(dbgArgInfo *_arg)
+	: m_arg(_arg)
+{}
+
+
+void ctlGridCellBoolEditor::BeginEdit(int _row, int _col, wxGrid *_grid)
 {
-	dbgResultset *result;
+	wxGridCellBoolEditor::BeginEdit(_row, _col, _grid);
 
-	if (m_conn->DebuggerApiVersion() <= DEBUGGER_V2_API)
-	{
-		if( m_targetInfo->getLanguage() == wxT( "edbspl" ))
-			result = new dbgResultset(m_conn->waitForCommand(wxString::Format(wxT("select edb_oid_debug( %ld, %ld );"), pkgOid, funcOid)));
-		else
-			result = new dbgResultset(m_conn->waitForCommand(wxString::Format(wxT("select plpgsql_oid_debug( %ld, %ld );"),  pkgOid, funcOid)));
-	}
-	else
+	wxFocusEvent event (wxEVT_KILL_FOCUS);
+	if (m_control)
 	{
-		if( m_targetInfo->getLanguage() == wxT( "edbspl" ))
-			result = new dbgResultset(m_conn->waitForCommand(wxString::Format(wxT("select edb_oid_debug(%ld);"), funcOid)));
-		else
-			result = new dbgResultset(m_conn->waitForCommand(wxString::Format(wxT("select plpgsql_oid_debug(%ld);"), funcOid)));
+		m_control->GetEventHandler()->AddPendingEvent(event);
 	}
-
-	if( result->getCommandStatus() != PGRES_TUPLES_OK )
-		throw( std::runtime_error( result->getRawErrorMessage()));
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// invokeTarget()
-//
-//    This function invokes the debugger target (that is, the function or procedure
-//  that the user wants to debug).  If the target is a function, we generate a
-//  SELECT statement; if the target is a procedure, we generate an EXEC statement.
-//  In either case, we build the argument list from the argument values found
-//  in m_targetInfo
 
-void dlgDirectDbg::invokeTarget()
+wxGrid *dlgDirectDbg::GetParamsGrid()
 {
-	// If we have access the the EDB extended libpq functions,
-	// and this is a stored procedure, we should execute the
-	// procedure using the callable statement interface to allow
-	// us to retrieve the OUT/INOUT parameter results.
-	// Otherwise, just SELECT/EXEC it as per normal.
-#ifdef __WXMSW__
-	if (!m_conn->EdbMinimumVersion(9, 0) &&
-	        !m_targetInfo->getIsFunction() &&
-	        PQiGetOutResult &&
-	        PQiPrepareOut &&
-	        PQiSendQueryPreparedOut)
-		invokeTargetCallable();
-	else
-#else
-#ifdef EDB_LIBPQ
-	if (!m_conn->EdbMinimumVersion(9, 0) &&
-	        !m_targetInfo->getIsFunction())
-		invokeTargetCallable();
-	else
-#endif
-#endif
-		invokeTargetStatement();
-
-	// Since parameter window has done its job, we need to hide
-	// it and let code window come in front.
-	if (m_codeWindow)
-	{
-		m_codeWindow->enableTools();
-		m_codeWindow->resumeLocalDebugging();
-	}
+	return grdParams;
+}
 
-	this->Show( false );
+bool dlgDirectDbg::DebugPkgConstructor()
+{
+	return chkPkgInit->IsEnabled() && chkPkgInit->GetValue();
 }
 
-void dlgDirectDbg::invokeTargetCallable()
+
+wxGridCellEditor *ctlGridCellBoolEditor::Clone() const
 {
-	dbgPgParams *params = new dbgPgParams();
+	return new ctlGridCellBoolEditor(m_arg);
+}
 
-	wxString query = wxT("CALL ") + m_targetInfo->getFQName() + wxT("(");
 
-	// Setup the param struct.
-	params->nParams = m_targetInfo->getArgCount();
-	params->paramTypes = new Oid[params->nParams];
-	params->paramValues = new char*[params->nParams];
-	params->paramModes = new int[params->nParams];
+void dlgDirectDbg::ResultArgsUpdated(wxCommandEvent &_ev)
+{
+	SaveSettings();
+	SavePosition();
 
-	// Iterate through the parameters, adding them to the param
-	// struct and the statement as we go.
-	for( int i = 0; i < params->nParams; ++i )
+	if (m_thread)
 	{
-		wsArgInfo &arg = (*m_targetInfo)[i];
+		m_thread->CancelEval();
+		m_thread->Wait();
 
-		params->paramTypes[i] = arg.getTypeOid();
+		delete m_thread;
+		m_thread = NULL;
+	}
 
-		if(arg.getMode() == wxT("o")) // OUT
-		{
-			params->paramModes[i] = 2;
-			params->paramValues[i] = 0;
-		}
-		else if(arg.getMode() == wxT("b")) // IN OUT
-		{
-			params->paramModes[i] = 3;
-
-			int len = arg.getValue().Length() + 1;
-			char *tmp = new char[len];
-			snprintf(tmp, len, "%s", (const char *)arg.getValue().mb_str(wxConvUTF8));
-			if (strcmp(tmp, "") == 0)
-				params->paramValues[i] = 0;
-			else if (strcmp(tmp, "''") == 0)
-				params->paramValues[i] = (char *)"";
-			else if (strcmp(tmp, "\\'\\'") == 0)
-				params->paramValues[i] = (char *)"''";
-			else
-				params->paramValues[i] = tmp;
-		}
-		else // IN
+	if (IsModal())
+		EndModal(wxID_OK);
+	else
+		Destroy();
+}
+
+
+void dlgDirectDbg::ResultArgsUpdateError(wxCommandEvent &_ev)
+{
+	if (_ev.GetInt() == pgQueryResultEvent::PGQ_CONN_LOST)
+	{
+		if(wxMessageBox(
+		            _("Connection to the database server lost!\nDo you want to try to reconnect to the server?"),
+		            _("Connection Lost"), wxICON_ERROR | wxICON_QUESTION | wxYES_NO) == wxID_YES)
 		{
-			params->paramModes[i] = 1;
-
-			int len = arg.getValue().Length() + 1;
-			char *tmp = new char[len];
-			snprintf(tmp, len, "%s", (const char *)arg.getValue().mb_str(wxConvUTF8));
-			if (strcmp(tmp, "") == 0)
-				params->paramValues[i] = 0;
-			else if (strcmp(tmp, "''") == 0)
-				params->paramValues[i] = (char *)"";
-			else if (strcmp(tmp, "\\'\\'") == 0)
-				params->paramValues[i] = (char *)"''";
-			else
-				params->paramValues[i] = tmp;
+			if (m_thread)
+			{
+				m_thread->CancelEval();
+
+				m_thread->Wait();
+
+				delete m_thread;
+				m_thread = NULL;
+			}
+			m_conn->Reconnect();
+
+			return;
 		}
+		EndModal(wxID_CANCEL);
 
-		if (i)
-			query += wxT(", ");
-		query += wxString::Format(wxT("$%d::"), i + 1) + arg.getType();
+		return;
+	}
 
+	if (m_thread)
+	{
+		m_thread->CancelEval();
+		m_thread->Wait();
+
+		delete m_thread;
+		m_thread = NULL;
 	}
 
-	query += wxT(");");
+	wxLogError(_ev.GetString());
 
-	// And send the completed command to the server - we'll get
-	// a dbgDbResult event when the command completes (and that
-	// event will get routed to dlgDirectDbg::OnResultReady())
-	m_conn->startCommand( query, GetEventHandler(), RESULT_ID_DIRECT_TARGET_COMPLETE, params );
+	grdParams->Enable(true);
+	btnDebug->Enable(true);
 }
 
-void dlgDirectDbg::invokeTargetStatement()
+
+void dbgArgValueEvaluator::NoticeHandler(void *, const char *)
 {
-	wxString query, declareStatement;
-	if (!m_conn->EdbMinimumVersion(8, 4))
-		query = m_targetInfo->getIsFunction() ? wxT( "SELECT " ) : wxT( "EXEC " );
-	else
-	{
-		query = wxT("SELECT");
-		if (!m_targetInfo->getIsFunction())
-			query = wxT("EXEC ");
-		else if (m_targetInfo->getLanguage() == wxT("edbspl"))
-			query = wxT("PERFORM ");
-	}
+	// Ignore the notices
+}
+
+
+void *dbgArgValueEvaluator::Entry()
+{
+	bool argNull, nullVal, useDef;
+	wxString strVal, strValExpr;
+	dbgArgInfo *prev = NULL,
+	            *arg = NULL;
 
-	// If this is a function, and the return type is not record, or
-	// we have at least one OUT/INOUT param, we should select from
-	// the function to get a full resultset.
-	if (m_targetInfo->getIsFunction() && m_targetInfo->getLanguage() != wxT("edbspl") &&
-	        (m_targetInfo->getReturnType() != wxT("record") ||
-	         m_targetInfo->getArgInOutCount() > 0 ||
-	         m_targetInfo->getArgOutCount() > 0))
-		query.Append(wxT("* FROM "));
+	wxGrid *grd = m_dlg->GetParamsGrid();
 
-	// Stuff the verb (SELECT or EXEC), schema, and target name into the query
-	query.Append(m_targetInfo->getFQName());
+	m_dlg->m_controller->GetTargetInfo()->DebugPackageConstructor()
+	= m_dlg->DebugPkgConstructor();
 
-	// Now append the argument list
-	query.Append(wxT("("));
+	m_conn->RegisterNoticeProcessor(dbgArgValueEvaluator::NoticeHandler, NULL);
 
-	for(int i = 0; i < m_targetInfo->getArgCount(); ++i)
+	for (int row = 0, idx = 0, arrCnt = 1, arr_idx_bound = 0;
+	        row < grd->GetNumberRows() && !m_cancelled; row++)
 	{
-		wsArgInfo &arg = (*m_targetInfo)[i];
+		ctlGridCellBoolEditor *editor =
+		    dynamic_cast<ctlGridCellBoolEditor *>(
+		        grd->GetCellEditor(row, dlgDirectDbg::COL_NULL));
+		arg	= editor != NULL ? editor->GetArg() : NULL;
 
-		if(arg.getMode() == wxT("o") && !m_conn->EdbMinimumVersion(8, 4))
-		{
-			if (!m_targetInfo->getIsFunction() || m_targetInfo->getLanguage() == wxT("edbspl"))
-				query.Append( wxT("NULL::") + arg.getType() + wxT(", "));
-		}
-		else if (m_conn->EdbMinimumVersion(8, 4) && (arg.getMode() == wxT("o") || arg.getMode() == wxT("b")))
+		// This should be the information for add/remove values for an array
+		if (arg == NULL)
 		{
-			if (!m_targetInfo->getIsFunction() || m_targetInfo->getLanguage() == wxT("edbspl"))
+			// prev was an array, can we fetch value for the same
+			if (prev && !prev->Null())
 			{
-				wxString strParam = wxString::Format(wxT("param%d"), i);
-				declareStatement +=  strParam + wxT(" ") + arg.getType();
-				if (arg.getMode() == wxT("b"))
+				wxString res =
+				    m_conn->ExecuteScalar(
+				        wxT("SELECT ARRAY[") + strValExpr + wxT("]::") + prev->GetTypeName(),
+				        false);
+
+				if (m_cancelled)
 				{
-					declareStatement += wxT(" := ") + arg.quoteValue();
-					if (!arg.quoteValue().Contains(wxT("::")))
-						declareStatement += wxT("::") + arg.getType();
+					m_conn->RegisterNoticeProcessor(NULL, NULL);
+
+					return (void *)NULL;
 				}
-				declareStatement += wxT(";\n");
-				query.Append(strParam + wxT(", "));
-			}
-			else if (arg.getMode() != wxT("o"))
-			{
-				if (!arg.quoteValue().Contains(wxT("::")))
-					query.Append( arg.quoteValue() + wxT("::") + arg.getType() + wxT(", "));
-				else
-					query.Append( arg.quoteValue() + wxT(", "));
-			}
-		}
-		else if(arg.getMode() == wxT("v"))
-			query.Append( arg.getValue() + wxT(", "));
-		else
-		{
-			if (!arg.quoteValue().Contains(wxT("::")))
-				query.Append( arg.quoteValue() + wxT("::") + arg.getType() + wxT(", "));
-			else
-				query.Append( arg.quoteValue() + wxT(", "));
-		}
-	}
+				if (m_conn->GetStatus() == PGCONN_BAD)
+				{
+					wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR);
 
-	if (query.EndsWith(wxT(", ")))
-		query = query.Left(query.Length() - 2);
-	else if (query.EndsWith(wxT("(")))
-		query = query.Left(query.Length() - 1);
+					ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST);
 
-	// And terminate the argument list
-	if(m_targetInfo->getArgInCount() + m_targetInfo->getArgInOutCount() == 0)
-	{
-		/*
-		 * edbspl function/procedure with OUT parameter takes value/variable as an input
-		 */
-		if (m_conn->GetIsEdb())
-		{
-			if (m_targetInfo->getArgCount() == 0)
-			{
-				if (m_targetInfo->getIsFunction() || m_targetInfo->getLanguage() != wxT("edbspl"))
-					query.Append(wxT("()"));
-			}
-			else if (m_targetInfo->getLanguage() != wxT("edbspl"))
-				query.Append(wxT("()"));
-			else
-				query.Append(wxT(")"));
-		}
-		else if (m_targetInfo->getIsFunction())
-			query.Append(wxT("()"));
-	}
-	else
-	{
-		query.Append(wxT(")"));
-	}
+					m_dlg->GetEventHandler()->AddPendingEvent(ev);
 
-	if (m_conn->EdbMinimumVersion(8, 4) && (m_targetInfo->getLanguage() == wxT("edbspl") || !m_targetInfo->getIsFunction()))
-	{
-		wxString tmpQuery = wxT("DECLARE\n")
-		                    + declareStatement
-		                    + wxT("BEGIN\n")
-		                    + query + wxT(";\n")
-		                    + wxT("END;");
-		query = tmpQuery;
-	}
+					m_conn->RegisterNoticeProcessor(NULL, NULL);
 
-	// And send the completed command to the server - we'll get
-	// a dbgDbResult event when the command completes (and that
-	// event will get routed to dlgDirectDbg::OnResultReady())
-	m_conn->startCommand( query, GetEventHandler(), RESULT_ID_DIRECT_TARGET_COMPLETE );
-}
+					return (void *)NULL;
+				}
+				if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK)
+				{
+					prev->Value() = res;
+				}
+				else
+				{
+					wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR);
+					wxString strName = prev->GetName();
+					wxString strMsg;
+
+					if (strName.IsEmpty())
+					{
+						ev.SetString(
+						    wxString::Format(
+						        _("Specified value for the argument#%d is not valid.\nPlease reenter the value for it."),
+						        idx));
+					}
+					else
+					{
+						ev.SetString(
+						    wxString::Format(
+						        _("Specified value for the argument - '%s' is not valid.\nPlease reenter the value for it."),
+						        strName.c_str()));
+					}
+					ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR);
+					m_dlg->LoadLastCellSetting(row-1, idx-1, arr_idx_bound-1 , true); 
+					m_dlg->GetEventHandler()->AddPendingEvent(ev);
+
+					m_conn->RegisterNoticeProcessor(NULL, NULL);
+
+					return (void *)NULL;
 
+				}
+				prev = NULL;
+				arr_idx_bound = 0;
+			}
 
-////////////////////////////////////////////////////////////////////////////////
-// OnTargetComplete()
-//
-//    This event handler is called when the target function/procedure completes
-//  and a result set (or error) has been returned by the server.  The event
-//  object contains a pointer to the result set.
-//
-//  For now, we display an error message (if an error occurred) or write the
-//  command status to the status bar (if the target completed without error).
-//
-//  We should really display the complete result set somewhere too.
+			continue;
+		}
+		else if (prev != arg)
+		{
+			idx++;
+			argNull = false;
+			nullVal = false;
+			useDef  = false;
 
-void dlgDirectDbg::OnTargetComplete( wxCommandEvent &event )
-{
-	// Extract the result set handle from the event and log the status info
+			strValExpr = wxEmptyString;
+		}
 
-	PGresult    *result = (PGresult *)event.GetClientData();
+		if (prev != arg)
+		{
+			prev = arg;
 
-	wxLogInfo( wxT( "OnTargetComplete() called\n" ));
-	wxLogInfo( wxT( "%s\n" ), wxString(PQresStatus( PQresultStatus( result )), wxConvUTF8).c_str());
+			// Use Default (if available)
+			arg->UseDefault() = wxGridCellBoolEditor::IsTrueValue(
+			                        grd->GetCellValue(row, dlgDirectDbg::COL_USE_DEF));
+			// NULL?
+			arg->Null() = wxGridCellBoolEditor::IsTrueValue(
+			                  grd->GetCellValue(row, dlgDirectDbg::COL_NULL));
 
-	// If the query failed, write the error message to the status line, otherwise, copy the result set into the grid
-	if(( PQresultStatus( result ) == PGRES_NONFATAL_ERROR ) || ( PQresultStatus( result ) == PGRES_FATAL_ERROR ))
-	{
-		wxString    message( PQresultErrorMessage( result ), wxConvUTF8 );
+			if (arg->UseDefault())
+				strValExpr = arg->Default();
 
-		message.Replace( wxT( "\n" ), wxT( " " ));
+			if (arg->IsArray())
+				continue;
+		}
 
-		m_parent->getStatusBar()->SetStatusText( message, 1 );
-		char *state = PQresultErrorField(result, PG_DIAG_SQLSTATE);
+		// Use NULL?
+		//
+		//   Keep this just before 'Use Default' column as - we may have non-empty
+		//   value in the 'VAL' column
 
-		// Don't bother telling the user that he aborted - he already knows!
-		// Depending on the stage, m_conn might not be set all! so check for
-		// that first
-		if (m_conn)
+		if (!arg->UseDefault() || !arg->Null())
 		{
-			if (state != NULL && strcmp(state, "57014"))
-				wxLogError( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str());
+			if (!strValExpr.IsEmpty())
+			{
+				strValExpr += wxT(", ");
+			}
+
+			if (wxGridCellBoolEditor::IsTrueValue(
+			            grd->GetCellValue(row, dlgDirectDbg::COL_NULL)))
+			{
+				strValExpr += wxT("NULL");
+			}
+			else if (wxGridCellBoolEditor::IsTrueValue(
+			             grd->GetCellValue(row, dlgDirectDbg::COL_EXPR)))
+			{
+				strValExpr += grd->GetCellValue(row, dlgDirectDbg::COL_VALUE);
+			}
 			else
-				wxLogInfo( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str());
+			{
+				strValExpr += m_conn->qtDbString(
+				                  grd->GetCellValue(row, dlgDirectDbg::COL_VALUE));
+			}
+			
+			strValExpr.Append(wxT("::"))
+			.Append(arg->IsArray() ?
+			        arg->GetBaseType(): arg->GetTypeName());
+			if(arg->IsArray())
+			{
+				arr_idx_bound ++;
+			}
 		}
-	}
-	else
-	{
-		wxString message( PQcmdStatus( result ), wxConvUTF8 );
+		if (!arg->IsArray() && !arg->Null())
+		{
+			pgSet *set =
+			    m_conn->ExecuteSet(wxT("SELECT ") + strValExpr, false);
 
-		message.Replace( wxT( "\r" ), wxT( "" ));
-		message.Replace( wxT( "\n" ), wxT( " " ));
+			if (m_cancelled)
+			{
+				return (void *)NULL;
+			}
+			if (m_conn->GetStatus() == PGCONN_BAD)
+			{
+				wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR);
 
-		m_parent->getStatusBar()->SetStatusText( message, 1 );
+				ev.SetString(_("Connection to the database server lost!"));
+				ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST);
 
-		// If this result set has any columns, add a result grid to the code window so
-		// we can show the results to the user
+				m_dlg->GetEventHandler()->AddPendingEvent(ev);
 
-		if( m_codeWindow && PQnfields( result ))
-		{
-			m_codeWindow->OnResultSet( result );
-		}
-	}
+				m_conn->RegisterNoticeProcessor(NULL, NULL);
 
-	if (m_codeWindow)
-	{
-		m_codeWindow->m_targetComplete = true;
-		m_codeWindow->disableTools( );
-	}
+				if (set)
+					delete set;
 
-	// Do not show if aborted
-	if ( m_codeWindow && m_codeWindow->m_targetAborted )
-		return;
+				return (void *)NULL;
+			}
+			if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK &&
+			        set && set->NumRows() > 0L)
+			{
+				if (set->IsNull(0))
+				{
+					arg->Null() = true;
+				}
+				else
+				{
+					arg->Null() = false;
+					arg->Value() = set->GetVal(0);
+				}
+			}
+			else
+			{
+				wxString strName = arg->GetName();
 
-	this->Show( true );
-}
+				if (strName.IsEmpty())
+					strName = wxString::Format(_("Param#%d"), idx);
 
-////////////////////////////////////////////////////////////////////////////////
-// OnNoticeReceived()
-//
-//    This event handler is called when a notice is received from the server (in
-//  response to our invoking the target).  For now, we just forward this event
-//  to the debugger window (m_codeWindow) and the notification message is added
-//  to the debugger's message window.
-//
-//  When/if we get around to adding a result set window to this class, we should
-//  also add a message window too and display notice messages here instead of in
-//  the debugger window.
+				wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR);
 
-void dlgDirectDbg::OnNoticeReceived( wxCommandEvent &event )
-{
-	if( m_codeWindow )
-		m_codeWindow->OnNoticeReceived( event );
-}
+				ev.SetString(
+				    wxString::Format(_("Please reenter the value for the argument - '%s'."),
+				                     strName.c_str()));
+				
+				ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR);
 
-////////////////////////////////////////////////////////////////////////////////
-// OnDebug()
-//
-//    This event handler is called when a PLDBGBREAK notice is received from the
-//  server.  A quick review:  we've already set a breakpoint at the target and
-//  then we invoked the target (using the parameter values entered by the user).
-//  Now we're waiting for a result set from the target.  Since we set a breakpoint
-//  inside of the target, the server will send us a specially crafted NOTICE
-//  that tells use which port to attach to in order to contact the debugger
-//  server - that's what 'event' contains.
-//
-//  When we get the PLDBGBREAK message (inside of 'event'), we create a new
-//  debugger window by calling glMainFrame->addDebug() and let that window
-//  take over for a while.  When the target finally completes, we'll get a
-//  a dbgDbResult event and handle the result set inside of OnResultReady()
+				m_dlg->GetEventHandler()->AddPendingEvent(ev);
+				// m_dlg->LoadSettings();
+				m_dlg->LoadLastCellSetting(row, idx-1, 0, false); // For scalar variable, always index of array bound is 0.
+				m_conn->RegisterNoticeProcessor(NULL, NULL);
 
-void dlgDirectDbg::OnDebug( wxCommandEvent &event )
-{
-	// This event contains a string of the form:
-	//     /path/debugger -k --database=db --host=host --port=port --user=user &"
-	// We can use that string to launch a separate debugger client.
-	//
-	// The event also contains a pointer to a map that contains keyword=value
-	// pairs for the debugger connection properties.  To get to that map, we
-	// call event.GetClientData().  Once we have the map, we can look for the
-	// debugger connection properties such as "database", "host", "port", ...
+				return (void *)NULL;
 
-	dbgConnProp *debugProps = (dbgConnProp *)event.GetClientData();
+			}
+		}
+	}
 
-	m_codeWindow = m_parent->addDebug( *debugProps );
+	wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATED);
+	m_dlg->GetEventHandler()->AddPendingEvent(ev);
 
-	if (m_codeWindow)
-		m_codeWindow->startLocalDebugging();
+	m_conn->RegisterNoticeProcessor(NULL, NULL);
 
-	this->Show( false );
+	return (void *)NULL;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// getBreakpointList()
-//
-//    This function returns a non-const reference to our breakpoint list.  The
-//  caller typically populates this list before calling startDebugging() - we
-//  set a breakpoint for each member of the list
 
-dbgBreakPointList &dlgDirectDbg::getBreakpointList()
+void dbgArgValueEvaluator::CancelEval()
 {
-	return( m_breakpoints );
+	m_cancelled = true;
+
+	if (m_conn->GetTxStatus() == PGCONN_TXSTATUS_ACTIVE)
+		m_conn->CancelExecution();
 }
 
+dbgArgValueEvaluator::dbgArgValueEvaluator(pgConn *_conn, dlgDirectDbg *_dlg)
+	: wxThread(wxTHREAD_JOINABLE), m_conn(_conn), m_dlg(_dlg), m_cancelled(false)
+{}
diff --git a/pgadmin/debugger/frmDebugger.cpp b/pgadmin/debugger/frmDebugger.cpp
index 19f2824..bda8974 100644
--- a/pgadmin/debugger/frmDebugger.cpp
+++ b/pgadmin/debugger/frmDebugger.cpp
@@ -13,15 +13,19 @@
 
 // wxWindows headers
 #include <wx/wx.h>
+#include <wx/event.h>
 
 #include <stdexcept>
 
 // App headers
-#include "debugger/frmDebugger.h"
-#include "debugger/ctlCodeWindow.h"
-#include "debugger/dbgPgConn.h"
-#include "debugger/dlgDirectDbg.h"
 #include "ctl/ctlMenuToolbar.h"
+#include "ctl/ctlSQLBox.h"
+#include "ctl/ctlAuiNotebook.h"
+#include "debugger/dbgController.h"
+#include "debugger/ctlTabWindow.h"
+#include "debugger/frmDebugger.h"
+#include "frm/frmMain.h"
+#include "debugger/dbgConst.h"
 
 #include "images/debugger.pngc"
 #include "images/clearAll.pngc"
@@ -31,21 +35,22 @@
 #include "images/stepInto.pngc"
 #include "images/stop.pngc"
 
-IMPLEMENT_CLASS( frmDebugger, pgFrame  )
+IMPLEMENT_CLASS(frmDebugger, pgFrame)
 
-BEGIN_EVENT_TABLE( frmDebugger, pgFrame  )
-	EVT_MENU(MNU_EXIT,  frmDebugger ::OnExit)
-
-	EVT_MENU_RANGE(MENU_ID_TOGGLE_BREAK, MENU_ID_STOP, frmDebugger::OnDebugCommand)
+BEGIN_EVENT_TABLE(frmDebugger, pgFrame)
 	EVT_CLOSE(frmDebugger::OnClose)
 	EVT_SIZE(frmDebugger::OnSize)
 	EVT_ERASE_BACKGROUND(frmDebugger::OnEraseBackground)
+	EVT_AUI_PANE_CLOSE(frmDebugger::OnAuiUpdate)
+
+	EVT_MENU_RANGE(MENU_ID_TOGGLE_BREAK, MENU_ID_STOP, frmDebugger::OnDebugCommand)
 
 	EVT_STC_MARGINCLICK(wxID_ANY,        frmDebugger::OnMarginClick)
 	EVT_STC_UPDATEUI(wxID_ANY,           frmDebugger::OnPositionStc)
 	EVT_LISTBOX(wxID_ANY,                frmDebugger::OnSelectFrame)
 	EVT_GRID_CELL_CHANGE(                frmDebugger::OnVarChange)
 
+	EVT_MENU(MNU_EXIT,                   frmDebugger ::OnExit)
 	EVT_MENU(MENU_ID_VIEW_TOOLBAR,       frmDebugger::OnToggleToolBar)
 	EVT_MENU(MENU_ID_VIEW_STACKPANE,     frmDebugger::OnToggleStackPane)
 	EVT_MENU(MENU_ID_VIEW_OUTPUTPANE,    frmDebugger::OnToggleOutputPane)
@@ -53,8 +58,7 @@ BEGIN_EVENT_TABLE( frmDebugger, pgFrame  )
 
 	EVT_MENU(MNU_CONTENTS,               frmDebugger::OnContents)
 	EVT_MENU(MNU_HELP,                   frmDebugger::OnHelp)
-
-	EVT_AUI_PANE_CLOSE(frmDebugger::OnAuiUpdate)
+	EVT_TIMER(ID_TIMER,                  frmDebugger::OnTimer)
 END_EVENT_TABLE()
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -63,63 +67,81 @@ END_EVENT_TABLE()
 //  frmDebugger manages the user interface for the workstation. This class
 //  manages the toolbar, menu, status bar, and top-level windows.
 
-frmDebugger::frmDebugger(frmMain *parent, const wxString &title)
-	: pgFrame(NULL, title),
-	  m_standaloneDebugger(NULL),
-	  m_standaloneDirectDbg(NULL),
-	  m_parent(parent)
+frmDebugger::frmDebugger(frmMain *_parent, dbgController *_controller,
+                         const wxString &_title) : pgFrame(_parent, _title), m_menuBar(NULL),
+	m_toolBar(NULL), m_viewMenu(NULL), m_debugMenu(NULL), m_statusBar(NULL),
+	m_parent(_parent), m_controller(_controller), m_stackWindow(NULL),
+	m_tabWindow(NULL), m_codeViewer(NULL), m_progressBar(NULL), m_timer(this, ID_TIMER)
 {
 	dlgName = wxT("frmDebugger");
 	RestorePosition(100, 100, 600, 500, 450, 300);
 
 	wxWindowBase::SetFont(settings->GetSystemFont());
 
-	manager.SetManagedWindow(this);
-	manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG);
+	m_manager.SetManagedWindow(this);
+	m_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG);
 
 	// Define the icon for this window
 	SetIcon(*debugger_png_ico);
 
 	// Create (and configure) the menu bar, toolbar, and status bar
-	m_menuBar   = setupMenuBar();
-	m_toolBar   = setupToolBar();
-	m_statusBar = setupStatusBar();
+	m_menuBar   = SetupMenuBar();
+	m_toolBar   = SetupToolBar();
+	m_statusBar = SetupStatusBar();
 
-	manager.AddPane(m_toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(wxT("Toolbar")).ToolbarPane().Top().Row(1).Position(1).LeftDockable(false).RightDockable(false));
+	m_manager.AddPane(
+	    m_toolBar,
+	    wxAuiPaneInfo().Name(wxT("toolBar")).Caption(wxT("Toolbar"))
+	    .ToolbarPane().Top().Row(1).Position(1).LeftDockable(false)
+	    .RightDockable(false));
 
 	// Now load the layout
 	wxString perspective;
-	settings->Read(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), &perspective, FRMDEBUGGER_DEFAULT_PERSPECTIVE);
-	manager.LoadPerspective(perspective, true);
+	settings->Read(
+	    wxT("Debugger/frmDebugger/Perspective-")
+	    + wxString(FRMDEBUGGER_PERSPECTIVE_VER),
+	    &perspective, FRMDEBUGGER_DEFAULT_PERSPECTIVE);
+
+	m_manager.LoadPerspective(perspective, true);
 
 	// and reset the captions for the current language
-	manager.GetPane(wxT("toolBar")).Caption(_("Toolbar"));
+	m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar"));
 
 	// Sync the View menu options
-	m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
+	m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown());
 
-	manager.Update();
+	SetupDebugger();
 
+	m_manager.Update();
 }
 
+
 frmDebugger::~frmDebugger()
 {
 	// Only save the settings if the window was completely setup
 	// This may not be the case if the params dialog was displayed,
 	// and the user hit cancel before the main form opened.
-	wxAuiPaneInfo &pane = manager.GetPane(wxT("sourcePane"));
+	wxAuiPaneInfo &pane = m_manager.GetPane(wxT("sourcePane"));
 	if (pane.IsOk())
-		settings->Write(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), manager.SavePerspective());
+		settings->Write(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), m_manager.SavePerspective());
 
-	manager.UnInit();
+	m_manager.UnInit();
 
 	if (m_parent)
 		m_parent->RemoveFrame(this);
+
+	if (m_controller)
+	{
+		PopEventHandler();
+		delete m_controller;
+		m_controller = NULL;
+	}
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// onContents()
-// onHelp()
+// OnContents()
+// OnHelp()
 //
 //     Help menu options
 void frmDebugger::OnContents(wxCommandEvent &event)
@@ -127,106 +149,486 @@ void frmDebugger::OnContents(wxCommandEvent &event)
 	DisplayHelp(wxT("debugger"), HELP_PGADMIN);
 }
 
+
 void frmDebugger::OnHelp(wxCommandEvent &event)
 {
 	DisplayHelp(wxT("plpgsql"), HELP_POSTGRESQL);
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// addDebug()
+// SetupDebugger()
+//
+//     This function creates the debugger views...
 //
-//     This function creates a new debugger window...
+void frmDebugger::SetupDebugger()
+{
+	wxWindowBase::SetFont(settings->GetSystemFont());
+
+	// Initializing Stack Frame Window
+	if (m_stackWindow == NULL)
+	{
+		m_stackWindow = new ctlStackWindow(this, WINDOW_ID_STACK,  wxDefaultPosition,
+		                                   wxDefaultSize, 0);
+
+		m_manager.AddPane(m_stackWindow,
+		                  wxAuiPaneInfo().Name(wxT("stackPane")).Caption(_("Stack pane")).Right()
+		                  .MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200)));
+	}
+	// Initializing Tab Window
+	if (m_tabWindow == NULL)
+	{
+		m_tabWindow = new ctlTabWindow(this, WINDOW_ID_TABS, wxDefaultPosition,
+		                               wxDefaultSize, wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON);
 
-ctlCodeWindow *frmDebugger::addDebug( const dbgConnProp &connProps )
+		m_manager.AddPane(m_tabWindow,
+		                  wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom()
+		                  .MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300)));
+	}
+	// Initialing Code viewer Window
+	if (m_codeViewer == NULL)
+	{
+		m_codeViewer = new ctlSQLBox(this, -1);
+
+		// Set up the markers that we use to indicate the current line and
+		// the break-point
+		m_codeViewer->MarkerDefine(MARKER_CURRENT, wxSTC_MARK_ARROW, *wxGREEN,
+		                           *wxGREEN);
+		m_codeViewer->MarkerDefine(MARKER_CURRENT_BG, wxSTC_MARK_BACKGROUND, *wxGREEN,
+		                           *wxGREEN);
+		m_codeViewer->MarkerDefine(MARKER_BREAKPOINT, wxSTC_MARK_CIRCLEPLUS, *wxRED,
+		                           *wxRED);
+
+		m_codeViewer->SetMarginWidth(1, 16);
+		m_codeViewer->SetMarginType(1, wxSTC_MARGIN_SYMBOL);
+
+		// Make sure that the text control tells us when the user clicks in the
+		// left margin
+		m_codeViewer->SetMarginSensitive(0, true);
+		m_codeViewer->SetMarginSensitive(1, true);
+		m_codeViewer->SetMarginSensitive(2, true);
+
+		m_manager.AddPane(m_codeViewer,
+		                  wxAuiPaneInfo().Name(wxT("sourcePane")).Caption(_("Source pane")).Center()
+		                  .CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100))
+		                  .BestSize(wxSize(350, 200)));
+	}
+
+	// Make sure the user can't edit the source code for this function
+	m_codeViewer->SetReadOnly(true);
+
+	// Now (re)load the layout
+	wxString perspective;
+	settings->Read(
+	    wxT("Debugger/frmDebugger/Perspective-") +
+	    wxString(FRMDEBUGGER_PERSPECTIVE_VER), &perspective,
+	    FRMDEBUGGER_DEFAULT_PERSPECTIVE);
+	m_manager.LoadPerspective(perspective, true);
+
+	// And reset the captions
+	m_manager.GetPane(wxT("sourcePane")).Caption(_("Source pane"));
+	m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane"));
+	m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
+
+	// Sync the View menu options
+	m_viewMenu->Check(MENU_ID_VIEW_STACKPANE,
+	                  m_manager.GetPane(wxT("stackPane")).IsShown());
+	m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE,
+	                  m_manager.GetPane(wxT("outputPane")).IsShown());
+
+	// Enable the options for these controls
+	m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, true);
+	m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE,  true);
+
+	m_manager.Update();
+
+	// force
+	EnableToolsAndMenus(false);
+
+	PushEventHandler(m_controller);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// EnableToolsAndMenus
+//
+//     Enable or disable the debugging tools and menus
+//
+// Parameters:
+//     - enable/disable (boolean)
+//
+void frmDebugger::EnableToolsAndMenus(bool enable)
 {
-	try
+	if (m_toolBar)
 	{
-		m_standaloneDebugger = new ctlCodeWindow( this , -1, connProps );
-		m_standaloneDebugger->Show( false );
-		return( m_standaloneDebugger );
+		m_toolBar->EnableTool(MENU_ID_STEP_INTO,       enable);
+		m_toolBar->EnableTool(MENU_ID_STEP_OVER,       enable);
+		m_toolBar->EnableTool(MENU_ID_CONTINUE,
+		                      (enable ||
+		                       (m_controller && m_controller->CanRestart())));
+		m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK,    enable);
+		m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, enable);
+		m_toolBar->EnableTool(MENU_ID_STOP,            enable);
 	}
-	catch( const std::runtime_error &error )
+
+	if (m_debugMenu)
 	{
-		wxLogError(wxT("%s"), wxString(error.what(), wxConvUTF8).c_str());
-		return NULL;
+		m_debugMenu->Enable(MENU_ID_STEP_INTO,       enable);
+		m_debugMenu->Enable(MENU_ID_STEP_OVER,       enable);
+		m_debugMenu->Enable(MENU_ID_CONTINUE,
+		                    (enable ||
+		                     (m_controller && m_controller->CanRestart())));
+		m_debugMenu->Enable(MENU_ID_TOGGLE_BREAK,    enable);
+		m_debugMenu->Enable(MENU_ID_CLEAR_ALL_BREAK, enable);
+		m_debugMenu->Enable(MENU_ID_STOP,            enable);
+	}
+	if ((!m_controller || m_controller->IsTerminated()))
+	{
+		m_timer.Stop();
 	}
 }
 
-dlgDirectDbg *frmDebugger::addDirectDbg( const dbgConnProp &connProp )
+
+////////////////////////////////////////////////////////////////////////////////
+// GetLineNo
+//
+//     This function returns the current line-number, where the execution flow
+//     has been stopped
+//
+// Returns:
+//     Current line-number
+//
+int frmDebugger::GetLineNo()
 {
-	try
+	if (m_codeViewer)
 	{
-		m_standaloneDirectDbg = new dlgDirectDbg( this, -1, connProp );
-		m_standaloneDirectDbg->setupParamWindow();
-		return( m_standaloneDirectDbg );
+		return (m_codeViewer->LineFromPosition(m_codeViewer->GetCurrentPos()));
 	}
-	catch( const std::runtime_error &error )
+	else
 	{
-		wxLogError(wxT("%s"), wxString(error.what(), wxConvUTF8).c_str());
-		return NULL;
+		return -1;
 	}
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// OnDebugCommand()
+// IsBreakpoint(int)
 //
-//     This event handler is invoked when the user clicks one of the debugger
-//     tools (on the debugger toolbar) - we simply forward the event to the
-//  debugger window.
+//     This function helps checking if break-point is set on the particular line
+//
+// Parameters:
+//     - line-number
+//
+// Returns:
+//     - True if a break-point is set on the line-no, otherwise false
+//
+bool frmDebugger::IsBreakpoint(int _lineNo)
+{
+	if (m_codeViewer)
+		return (m_codeViewer->MarkerGet(_lineNo) &
+		        MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT) ? true : false);
+	else
+		return false;
+}
+
 
-void frmDebugger::OnDebugCommand( wxCommandEvent &event )
+////////////////////////////////////////////////////////////////////////////////
+// ClearAllBreakpoints
+//
+//     This function clears all the break-points
+//
+void frmDebugger::ClearAllBreakpoints()
 {
-	if (m_standaloneDebugger)
-		m_standaloneDebugger->OnCommand( event );
+	int lineNo = 0;
+	bool updateBreakpoints = false;
+
+	if (m_codeViewer)
+	{
+		while((lineNo = m_codeViewer->MarkerNext(lineNo,
+		                MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1)
+		{
+			// Clear the break-point at particular location
+			m_controller->ClearBreakpoint(lineNo);
+			updateBreakpoints = true;
+		}
+
+		// Update break-points only if required
+		if (updateBreakpoints)
+			m_controller->UpdateBreakpoints();
+	}
 }
 
+
+void frmDebugger::ClearBreakpointMarkers()
+{
+	int lineNo = 0;
+	if (m_codeViewer)
+	{
+		while((lineNo = m_codeViewer->MarkerNext(lineNo,
+		                MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1)
+		{
+			m_codeViewer->MarkerDelete(lineNo++, MARKER_BREAKPOINT);
+		}
+	}
+}
+
+
+void frmDebugger::MarkBreakpoint(int _line)
+{
+	if (m_codeViewer)
+	{
+		m_codeViewer->MarkerAdd(_line, MARKER_BREAKPOINT);
+	}
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
-// OnSelectFrame()
+// UnhilightCurrentLine
 //
-//     This event handler is invoked when the user clicks one of the stack frames
-//  - we simply forward the event to the debugger window.
+//     This function removes the hilight from the current line
+//
+void frmDebugger::UnhilightCurrentLine()
+{
+	if (m_codeViewer)
+	{
+		int lineNo
+		= m_codeViewer->MarkerNext(0, MARKERINDEX_TO_MARKERMASK(MARKER_CURRENT));
+
+		if(lineNo != -1)
+		{
+			m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT);
+			m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG);
+		}
+	}
+}
+
 
-void frmDebugger::OnSelectFrame( wxCommandEvent &event )
+////////////////////////////////////////////////////////////////////////////////
+// OnDebugCommand(wxCommandEvent)
+//
+//     This function handles the user clicks one of the debugger tools and menus
+//     and take care of actions requires. These events are toggle break-point,
+//     clear all break-points, debugging continue, step-in, step-over and stop
+//     debugging.
+//
+//  Parameters
+//     - event object
+//
+void frmDebugger::OnDebugCommand(wxCommandEvent &_event)
 {
-	if (m_standaloneDebugger)
-		m_standaloneDebugger->OnSelectFrame( event );
+	switch(_event.GetId())
+	{
+		case MENU_ID_TOGGLE_BREAK:
+		{
+			int lineNo = GetLineNo();
+
+			// This event should have not been called
+			if (lineNo == -1)
+				return;
+
+			// The user wants to set or clear a breakpoint at the line that
+			// contains the insertion point (the caret)
+			if (IsBreakpoint(lineNo))
+			{
+				m_controller->ClearBreakpoint(lineNo);
+			}
+			else
+			{
+				m_controller->SetBreakpoint(lineNo);
+			}
+			m_controller->UpdateBreakpoints();
+		}
+		break;
+
+		case MENU_ID_CLEAR_ALL_BREAK:
+			// The user wants to clear all the breakpoint
+			ClearAllBreakpoints();
+
+			break;
+
+		case MENU_ID_CONTINUE:
+			// The user wants to continue execution (as opposed to
+			// single-stepping through the code).  Unhilite all
+			// variables and tell the debugger server to continue.
+			if (m_controller)
+			{
+				if (m_controller->CanRestart())
+				{
+					m_controller->Start();
+				}
+				else
+				{
+					LaunchWaitingDialog(_("Waiting for target (continue)... Done."));
+					m_controller->Countinue();
+					UnhilightCurrentLine();
+					EnableToolsAndMenus(false);
+				}
+			}
+			break;
+
+		case MENU_ID_STEP_OVER:
+			// The user wants to step-over a function invocation (or
+			// just single-step). Unhilite all variables and tell the
+			// debugger server to step-over
+			LaunchWaitingDialog(_("Waiting for target (step over)... Done."));
+			m_controller->StepOver();
+
+			GetStatusBar()->SetStatusText(_("Waiting for target (step over)... Done."), 1);
+			UnhilightCurrentLine();
+			EnableToolsAndMenus(false);
+
+			break;
+
+		case MENU_ID_STEP_INTO:
+			// The user wants to step-into a function invocation (or
+			// just single-step). Unhilite all variables and tell the
+			// debugger server to step-into
+			LaunchWaitingDialog(_("Waiting for target (step over)... Done."));
+			m_controller->StepInto();
+
+			GetStatusBar()->SetStatusText(_("Waiting for target (step into)... Done."), 1);
+			UnhilightCurrentLine();
+			EnableToolsAndMenus(false);
+
+			break;
+
+		case MENU_ID_STOP:
+			EnableToolsAndMenus(false);
+			m_controller->Stop();
+			UnhilightCurrentLine();
+
+			break;
+
+		default:
+			break;
+	}
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// OnMarginClick()
+// OnSelectFrame()
+//
+//     This function handles the user click on one of the stack-frames, and
+//     asks the debugger server to switch to that frame, update the breakpoint
+//     markers, and send a list of variables that are in-scope in the selected
+//     frame
 //
-//     This event handler is invoked when the user clicks one of the stack frames
-//  - we simply forward the event to the debugger window.
+// Parametes:
+//     Selection Event Object
+//
+void frmDebugger::OnSelectFrame(wxCommandEvent &_ev)
+{
+	if(_ev.GetSelection() != -1)
+	{
+		m_controller->SelectFrame(_ev.GetSelection());
+	}
+}
 
-void frmDebugger::OnMarginClick( wxStyledTextEvent &event )
+
+////////////////////////////////////////////////////////////////////////////////
+// OnMarginClick()
+//
+//     This function handles the user clicks in the margin to the left of a
+//     line of source code. We use the margin to display breakpoint indicators
+//     so it makes sense that if you click on an breakpoint indicator, we will
+//     clear that breakpoint.  If you click on a spot that does not contain a
+//     breakpoint indicator (but it's still in the margin), we create a new
+//     breakpoint at that line
+//
+// Parametes:
+//     Selection Event Object
+//
+void frmDebugger::OnMarginClick(wxStyledTextEvent &event)
 {
-	if (m_standaloneDebugger)
-		m_standaloneDebugger->OnMarginClick( event );
+	int lineNo;
+
+	// Check that the user clicked on the line number or breakpoint margin
+	// We don't want to set a breakpoint when the user folds/unfolds code
+	if (!(event.GetMargin() == 0 || event.GetMargin() == 1))
+		return;
+
+	lineNo = m_codeViewer->LineFromPosition(event.GetPosition());
+
+	if (lineNo <= 0)
+		return;
+
+	// If we already have a breakpoint at the clickpoint, disable it, otherwise
+	// create a new breakpoint
+	if(m_codeViewer->MarkerGet(lineNo) &
+	        MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))
+	{
+		m_controller->ClearBreakpoint(lineNo);
+	}
+	else
+	{
+		m_controller->SetBreakpoint(lineNo);
+	}
+	m_controller->UpdateBreakpoints();
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // OnPositionStc()
 //
-//     This event handler is invoked when the user positions the cursor in the
-//       code window
-//  - we simply forward the event to the debugger window.
-
-void frmDebugger::OnPositionStc( wxStyledTextEvent &event )
+//     This function handles the event called when the user positions the cursor
+//     in the code viewer. We will update the current line number etc in the
+//     status bar.
+//
+// Parametes:
+//     wxStyledTextEvent Object
+//
+void frmDebugger::OnPositionStc(wxStyledTextEvent &event)
 {
-	if (m_standaloneDebugger)
-		m_standaloneDebugger->OnPositionStc( event );
+	if (m_codeViewer)
+	{
+		wxString strPos;
+
+		int pos = m_codeViewer->GetCurrentPos();
+
+		strPos.Printf(_("Ln %d Col %d Ch %d"), m_codeViewer->LineFromPosition(pos) + 1,
+		              m_codeViewer->GetColumn(pos) + 1, pos + 1);
+
+		GetStatusBar()->SetStatusText(strPos, 2);
+	}
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // OnVarChange()
 //
-//     This event handler is invoked when the user edits a variable value
-//  - we simply forward the event to the debugger window.
-
-void frmDebugger::OnVarChange( wxGridEvent &event )
+//     This functions handles the event occured when the user edits a variable
+//     value. Submit the changed value to the debugger server
+//
+void frmDebugger::OnVarChange(wxGridEvent &_ev)
 {
-	if (m_standaloneDebugger)
-		m_standaloneDebugger->OnVarChange( event );
+	ctlVarWindow *varWin = NULL;
+	wxString      varName, varValue;
+
+	if(_ev.GetId() == ID_PARAMGRID)
+	{
+		varWin = GetParamWindow(false);
+		varName = varWin->GetVarName(_ev.GetRow());
+		varValue = varWin->GetVarValue(_ev.GetRow());
+	}
+	else if (_ev.GetId() == ID_VARGRID)
+	{
+		varWin = GetVarWindow(false);
+		varName = varWin->GetVarName(_ev.GetRow());
+		varValue = varWin->GetVarValue(_ev.GetRow());
+	}
+	else if (_ev.GetId() == ID_PKGVARGRID)
+	{
+		varWin = GetPkgVarWindow(false);
+		varName = wxT("@") + varWin->GetVarName(_ev.GetRow());
+		varValue = varWin->GetVarValue(_ev.GetRow());
+	}
+	else
+	{
+		// Theorically - the execution flow must not reach at this point.
+		return;
+	}
+
+	m_controller->DepositValue(varName, varValue);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -234,113 +636,124 @@ void frmDebugger::OnVarChange( wxGridEvent &event )
 //
 //    This event handler is called when a resize event occurs (that is, when
 //  wxWidgets needs to size the application window)
-
-void frmDebugger::OnSize( wxSizeEvent &event )
+//
+void frmDebugger::OnSize(wxSizeEvent &event)
 {
 	event.Skip();
 }
 
+
 void frmDebugger::OnEraseBackground(wxEraseEvent &event)
 {
 	event.Skip();
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // setupToolBar()
 //
 //    This function creates the standard toolbar
-
-ctlMenuToolbar *frmDebugger::setupToolBar( void )
+//
+ctlMenuToolbar *frmDebugger::SetupToolBar(void)
 {
 	m_toolBar = new ctlMenuToolbar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER);
 
-	m_toolBar->SetToolBitmapSize( wxSize( 16, 16 ));
+	m_toolBar->SetToolBitmapSize(wxSize(16, 16));
 
-	m_toolBar->AddTool( MENU_ID_STEP_INTO,    	wxEmptyString,    		*stepInto_png_bmp, _( "Step into" ));
-	m_toolBar->AddTool( MENU_ID_STEP_OVER,    	wxEmptyString,    		*stepOver_png_bmp, _( "Step over" ));
-	m_toolBar->AddTool( MENU_ID_CONTINUE,    	wxEmptyString,    		*continue_png_bmp, _( "Continue" ));
+	m_toolBar->AddTool(MENU_ID_STEP_INTO, wxEmptyString, *stepInto_png_bmp,
+	                   _("Step into"));
+	m_toolBar->AddTool(MENU_ID_STEP_OVER, wxEmptyString, *stepOver_png_bmp,
+	                   _("Step over"));
+	m_toolBar->AddTool(MENU_ID_CONTINUE, wxEmptyString, *continue_png_bmp,
+	                   _("Continue/Start"));
 	m_toolBar->AddSeparator();
-	m_toolBar->AddTool( MENU_ID_TOGGLE_BREAK,	wxEmptyString,	*setBreak_png_bmp, _( "Toggle breakpoint" ));
-	m_toolBar->AddTool( MENU_ID_CLEAR_ALL_BREAK,	wxEmptyString,	*clearAll_png_bmp, _( "Clear all breakpoints" ));
+	m_toolBar->AddTool(MENU_ID_TOGGLE_BREAK, wxEmptyString, *setBreak_png_bmp,
+	                   _("Toggle breakpoint"));
+	m_toolBar->AddTool(MENU_ID_CLEAR_ALL_BREAK, wxEmptyString, *clearAll_png_bmp,
+	                   _("Clear all breakpoints"));
 	m_toolBar->AddSeparator();
-	m_toolBar->AddTool( MENU_ID_STOP,          	wxEmptyString,    	*stop_png_bmp, _( "Stop debugging" ));
+	m_toolBar->AddTool(MENU_ID_STOP, wxEmptyString, *stop_png_bmp,
+	                   _("Stop debugging"));
 
-	m_toolBar->EnableTool(MENU_ID_STEP_INTO,        false);
-	m_toolBar->EnableTool(MENU_ID_STEP_OVER,        false);
-	m_toolBar->EnableTool(MENU_ID_CONTINUE,         false);
-	m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK,     false);
-	m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK,  false);
-	m_toolBar->EnableTool(MENU_ID_STOP,    		false);
+	m_toolBar->EnableTool(MENU_ID_STEP_INTO,       false);
+	m_toolBar->EnableTool(MENU_ID_STEP_OVER,       false);
+	m_toolBar->EnableTool(MENU_ID_CONTINUE,        false);
+	m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK,    false);
+	m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, false);
+	m_toolBar->EnableTool(MENU_ID_STOP,            false);
 
 	m_toolBar->Realize();
 
-	return( m_toolBar );
+	return(m_toolBar);
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// setupStatusBar()
+// SetupStatusBar()
 //
 //    This function initializes the status bar (we don't have one at the moment
 //  so this function simply returns)
-
-wxStatusBar *frmDebugger::setupStatusBar( void )
+//
+wxStatusBar *frmDebugger::SetupStatusBar(void)
 {
-	wxStatusBar *bar = CreateStatusBar( 3, wxST_SIZEGRIP );
-	int    		  widths[] = { 0, -1, 130 };
+	wxStatusBar *bar = CreateStatusBar(3, wxST_SIZEGRIP);
+	int          widths[] = { 0, -1, 130 };
 
 	bar->SetStatusWidths(3, widths);
-	bar->SetStatusText(_( "Initializing..."), 1);
+	bar->SetStatusText(_("Initializing... Done."), 1);
 
-	return( bar );
+	return(bar);
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-// setupMenuBar()
+// SetupMenuBar()
 //
 //    This function creates the standard menu bar
-
-wxMenuBar *frmDebugger::setupMenuBar(void)
+//
+wxMenuBar *frmDebugger::SetupMenuBar(void)
 {
 	m_menuBar = new wxMenuBar;
 
+	// Don't append the File menu on Mac, as the Exit option
+	// will be moved to the application menu, leaving File empty.
+#ifndef __WXMAC__
 	wxMenu *fileMenu = new wxMenu;
 	fileMenu->Append(MNU_EXIT, _("E&xit\tAlt-F4"), _("Exit debugger window"));
-// Don't append the File menu on Mac, as the Exit option
-// will be moved to the application menu, leaving File empty.
-#ifndef __WXMAC__
+
 	m_menuBar->Append(fileMenu, _("&File"));
 #endif
 
 	m_debugMenu = new wxMenu;
 #ifdef __WXGTK__
-	/*
-	*  F10 is treated as a System menu under GTK. Hence, we will use Ctrl+F10 for
-	*  "step over" operation under GTK, instead of F10.
-	*
-	*  To make the behavior consitent, we will also use Ctrl+ for all the operations
-	*  under GTK. (i.e. Step into, Step over, Continue, Toggle breakpoint, Stop
-	*  debugging)
-	*
-	*  Please follow this link for more details:
-	*  http://trac.wxwidgets.org/ticket/2404
-	*/
-	m_debugMenu->Append(MENU_ID_STEP_INTO,          _( "Step into\tCtrl+F11" ));
-	m_debugMenu->Append(MENU_ID_STEP_OVER,          _( "Step over\tCtrl+F10" ));
-	m_debugMenu->Append(MENU_ID_CONTINUE,           _( "Continue\tCtrl+F5" ));
+	//
+	// F10 is treated as a System menu under GTK. Hence, we will use Ctrl+F10 for
+	// "step over" operation under GTK, instead of F10.
+	//
+	// To make the behavior consitent, we will also use Ctrl+ for all the operations
+	// under GTK. (i.e. Step into, Step over, Continue, Toggle breakpoint, Stop
+	// debugging)
+	//
+	// Please follow this link for more details:
+	// http://trac.wxwidgets.org/ticket/2404
+	//
+	m_debugMenu->Append(MENU_ID_STEP_INTO,       _("Step into\tCtrl+F11"));
+	m_debugMenu->Append(MENU_ID_STEP_OVER,       _("Step over\tCtrl+F10"));
+	m_debugMenu->Append(MENU_ID_CONTINUE,        _("Continue/Start\tCtrl+F5"));
 	m_debugMenu->AppendSeparator();
-	m_debugMenu->Append(MENU_ID_TOGGLE_BREAK,       _( "Toggle breakpoint\tCtrl+F9" ));
-	m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK,    _( "Clear all breakpoints\tCtrl+Shift+F9" ));
+	m_debugMenu->Append(MENU_ID_TOGGLE_BREAK,    _("Toggle breakpoint\tCtrl+F9"));
+	m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9"));
 	m_debugMenu->AppendSeparator();
-	m_debugMenu->Append(MENU_ID_STOP,               _( "Stop debugging\tCtrl+F8" ));
+	m_debugMenu->Append(MENU_ID_STOP,            _("Stop debugging\tCtrl+F8"));
 #else
-	m_debugMenu->Append(MENU_ID_STEP_INTO,          _( "Step into\tF11" ));
-	m_debugMenu->Append(MENU_ID_STEP_OVER,          _( "Step over\tF10" ));
-	m_debugMenu->Append(MENU_ID_CONTINUE,           _( "Continue\tF5" ));
+	m_debugMenu->Append(MENU_ID_STEP_INTO,       _("Step into\tF11"));
+	m_debugMenu->Append(MENU_ID_STEP_OVER,       _("Step over\tF10"));
+	m_debugMenu->Append(MENU_ID_CONTINUE,        _("Continue/Start\tF5"));
 	m_debugMenu->AppendSeparator();
-	m_debugMenu->Append(MENU_ID_TOGGLE_BREAK,       _( "Toggle breakpoint\tF9" ));
-	m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK,    _( "Clear all breakpoints\tCtrl+Shift+F9" ));
+	m_debugMenu->Append(MENU_ID_TOGGLE_BREAK,    _("Toggle breakpoint\tF9"));
+	m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9"));
 	m_debugMenu->AppendSeparator();
-	m_debugMenu->Append(MENU_ID_STOP,               _( "Stop debugging\tF8" ));
+	m_debugMenu->Append(MENU_ID_STOP,            _("Stop debugging\tF8"));
 #endif //__WXGTK__
 	m_debugMenu->Enable(MENU_ID_STEP_INTO,   	    false);
 	m_debugMenu->Enable(MENU_ID_STEP_OVER,   	    false);
@@ -365,9 +778,9 @@ wxMenuBar *frmDebugger::setupMenuBar(void)
 	helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"),                _("Display help on SQL commands."));
 	m_menuBar->Append(helpMenu, _("&Help"));
 
-	SetMenuBar( m_menuBar );
+	SetMenuBar(m_menuBar);
 
-	return( m_menuBar );
+	return(m_menuBar);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -375,18 +788,32 @@ wxMenuBar *frmDebugger::setupMenuBar(void)
 //
 //    wxWidgets invokes this event handler when the user closes the main window
 
-void frmDebugger::OnClose( wxCloseEvent &event )
+void frmDebugger::OnClose(wxCloseEvent &_ev)
 {
-	if (m_standaloneDebugger)
+	bool wasTimerRunning = m_timer.IsRunning();
+	m_timer.Stop();
+
+	if (!m_controller->CanRestart() && _ev.CanVeto())
 	{
-		m_standaloneDebugger->OnClose( event );
-		if (event.GetVeto())
-			return;
+		if (wxMessageBox(
+		            _("Are you sure you wish to abort the debugging session?\nThis will abort the function currently being debugged."),
+		            _("Close debugger"), wxICON_QUESTION | wxYES_NO) != wxYES)
+		{
+			_ev.Veto();
+			if (wasTimerRunning)
+			{
+				m_timer.Start(500);
+			}
 
-		delete m_standaloneDebugger;
-		m_standaloneDebugger = NULL;
+			return;
+		}
 	}
-	event.Skip();
+
+	m_timer.Stop();
+
+	m_controller->CloseDebugger();
+
+	_ev.Skip();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -394,7 +821,7 @@ void frmDebugger::OnClose( wxCloseEvent &event )
 //
 //    Close the debugger
 
-void frmDebugger::OnExit( wxCommandEvent &event )
+void frmDebugger::OnExit(wxCommandEvent &event)
 {
 	Close();
 }
@@ -407,10 +834,11 @@ void frmDebugger::OnExit( wxCommandEvent &event )
 void frmDebugger::OnToggleToolBar(wxCommandEvent &event)
 {
 	if (m_viewMenu->IsChecked(MENU_ID_VIEW_TOOLBAR))
-		manager.GetPane(wxT("toolBar")).Show(true);
+		m_manager.GetPane(wxT("toolBar")).Show(true);
 	else
-		manager.GetPane(wxT("toolBar")).Show(false);
-	manager.Update();
+		m_manager.GetPane(wxT("toolBar")).Show(false);
+
+	m_manager.Update();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -420,10 +848,11 @@ void frmDebugger::OnToggleToolBar(wxCommandEvent &event)
 void frmDebugger::OnToggleStackPane(wxCommandEvent &event)
 {
 	if (m_viewMenu->IsChecked(MENU_ID_VIEW_STACKPANE))
-		manager.GetPane(wxT("stackPane")).Show(true);
+		m_manager.GetPane(wxT("stackPane")).Show(true);
 	else
-		manager.GetPane(wxT("stackPane")).Show(false);
-	manager.Update();
+		m_manager.GetPane(wxT("stackPane")).Show(false);
+
+	m_manager.Update();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -433,10 +862,11 @@ void frmDebugger::OnToggleStackPane(wxCommandEvent &event)
 void frmDebugger::OnToggleOutputPane(wxCommandEvent &event)
 {
 	if (m_viewMenu->IsChecked(MENU_ID_VIEW_OUTPUTPANE))
-		manager.GetPane(wxT("outputPane")).Show(true);
+		m_manager.GetPane(wxT("outputPane")).Show(true);
 	else
-		manager.GetPane(wxT("outputPane")).Show(false);
-	manager.Update();
+		m_manager.GetPane(wxT("outputPane")).Show(false);
+
+	m_manager.Update();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -466,18 +896,157 @@ void frmDebugger::OnAuiUpdate(wxAuiManagerEvent &event)
 //    Reset the AUI view to the default
 void frmDebugger::OnDefaultView(wxCommandEvent &event)
 {
-	manager.LoadPerspective(FRMDEBUGGER_DEFAULT_PERSPECTIVE, true);
+	m_manager.LoadPerspective(FRMDEBUGGER_DEFAULT_PERSPECTIVE, true);
 
 	// Reset the captions for the current language
-	manager.GetPane(wxT("toolBar")).Caption(_("Toolbar"));
-	manager.GetPane(wxT("stackPane")).Caption(_("Stack pane"));
-	manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
+	m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar"));
+	m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane"));
+	m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
 
-	// tell the manager to "commit" all the changes just made
-	manager.Update();
+	// tell the m_manager to "commit" all the changes just made
+	m_manager.Update();
 
 	// Sync the View menu options
-	m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
-	m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, manager.GetPane(wxT("stackPane")).IsShown());
-	m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown());
+	m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown());
+	m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, m_manager.GetPane(wxT("stackPane")).IsShown());
+	m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, m_manager.GetPane(wxT("outputPane")).IsShown());
+}
+
+
+void frmDebugger::HighlightLine(int _lineNo)
+{
+	int lineNo = m_codeViewer->MarkerNext(
+	                 0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT));
+
+	if (lineNo != -1)
+	{
+		m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT);
+		m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG);
+	}
+
+	// Add the current-line indicator to the current line of code
+	m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT);
+	m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT_BG);
+
+	// Scroll the source code listing (if required) to make sure
+	// that this line of code is visible
+	//
+	// (NOTE: we set the anchor and the caret to the same position to avoid
+	// creating a selection region)
+	int pos = m_codeViewer->PositionFromLine(_lineNo);
+
+	m_codeViewer->SetAnchor(pos);
+	m_codeViewer->SetCurrentPos(pos);
+
+	m_codeViewer->EnsureCaretVisible();
+}
+
+void frmDebugger::DisplaySource(dbgCachedStack &_cached)
+{
+	dbgModel *model = m_controller->GetModel();
+
+	m_codeViewer->SetFocus();
+
+	if (model->RequireDisplayUpdate())
+	{
+		ctlVarWindow *varWin = NULL;
+		if ((varWin = GetVarWindow(false)) != NULL)
+		{
+			varWin->DelVar();
+		}
+		if ((varWin = GetParamWindow(false)) != NULL)
+		{
+			varWin->DelVar();
+		}
+		if ((varWin = GetPkgVarWindow(false)) != NULL)
+		{
+			varWin->DelVar();
+		}
+
+		model->GetDisplayedFunction() = _cached.m_func;
+		model->GetDisplayedPackage() = _cached.m_pkg;
+
+		// Now erase any old code and write out the new listing
+		m_codeViewer->SetReadOnly(false);
+
+		m_codeViewer->SetText(_cached.m_source);
+		m_codeViewer->Colourise(0, _cached.m_source.Length());
+
+		m_codeViewer->SetReadOnly(true);
+	}
+	HighlightLine(model->GetCurrLineNo());
+}
+
+
+void frmDebugger::SetStatusText(const wxString &_status)
+{
+	m_statusBar->SetStatusText(_status, 1);
+}
+
+
+void frmDebugger::CloseProgressBar()
+{
+	if (m_progressBar)
+	{
+		m_progressBar->Close();
+		delete m_progressBar;
+		m_progressBar = NULL;
+	}
+}
+
+
+void frmDebugger::LaunchWaitingDialog(const wxString &msg)
+{
+	dbgModel *model = m_controller->GetModel();
+	wxString strStatus,
+	         strTargetPid = model->GetTargetPid(),
+	         strTarget    = model->GetTarget()->GetQualifiedName();
+
+	if (msg.IsEmpty())
+	{
+		if (strTargetPid != wxT("NULL"))
+		{
+			strStatus =
+			    wxString::Format(
+			        _("Waiting for the session (pid:%s) to invoke the specified targets."),
+			        strTargetPid.c_str());
+		}
+		else
+		{
+			strStatus =
+			    wxString::Format(
+			        _("Waiting for another session to invoke the target - \"%s\""), strTarget.c_str());
+		}
+	}
+	else
+	{
+		strStatus = msg;
+	}
+
+	m_statusBar->SetStatusText(strStatus, 1);
+
+	// NOTE: the waiting-dialog takes forever to appear running a remote X session so you can disable it by defining the following env. variable
+	if(getenv("SUPPRESS_WAIT_DIALOG"))
+	{
+		m_progressBar = NULL;
+	}
+	else
+	{
+		m_progressBar =
+		    new wxProgressDialog(_("Waiting for target"), strStatus, 100, this,
+		                         wxPD_SMOOTH | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
+
+		m_timer.Start(500);    // 2 clock ticks per second
+	}
+}
+
+void frmDebugger::OnTimer(wxTimerEvent &_ev)
+{
+	if (m_progressBar)
+	{
+		if (m_progressBar->Pulse() == false)
+		{
+			Close();
+		}
+	}
 }
diff --git a/pgadmin/debugger/module.mk b/pgadmin/debugger/module.mk
index 863ae8e..46fe479 100644
--- a/pgadmin/debugger/module.mk
+++ b/pgadmin/debugger/module.mk
@@ -10,17 +10,15 @@
 #######################################################################
 
 pgadmin3_SOURCES += \
-	debugger/ctlCodeWindow.cpp \
 	debugger/ctlMessageWindow.cpp \
 	debugger/ctlResultGrid.cpp \
 	debugger/ctlStackWindow.cpp \
 	debugger/ctlTabWindow.cpp \
 	debugger/ctlVarWindow.cpp \
 	debugger/dbgBreakPoint.cpp \
-	debugger/dbgDbResult.cpp \
- 	debugger/dbgPgConn.cpp \
-	debugger/dbgPgThread.cpp \
-	debugger/dbgResultset.cpp \
+	debugger/dbgController.cpp \
+	debugger/dbgEvents.cpp \
+	debugger/dbgModel.cpp \
  	debugger/dbgTargetInfo.cpp \
 	debugger/debugger.cpp \
 	debugger/dlgDirectDbg.cpp \
diff --git a/pgadmin/dlg/dlgClasses.cpp b/pgadmin/dlg/dlgClasses.cpp
index 2c764b1..aaeb626 100644
--- a/pgadmin/dlg/dlgClasses.cpp
+++ b/pgadmin/dlg/dlgClasses.cpp
@@ -491,7 +491,11 @@ void ExecutionDialog::Abort()
 	if (thread)
 	{
 		if (thread->IsRunning())
-			thread->Delete();
+		{
+			thread->CancelExecution();
+			thread->Wait();
+		}
+
 		delete thread;
 		thread = 0;
 	}
diff --git a/pgadmin/frm/frmEditGrid.cpp b/pgadmin/frm/frmEditGrid.cpp
index 88efe55..8df535b 100644
--- a/pgadmin/frm/frmEditGrid.cpp
+++ b/pgadmin/frm/frmEditGrid.cpp
@@ -1524,7 +1524,10 @@ void frmEditGrid::Abort()
 	{
 		SetStatusText(_("aborting."), 0);
 		if (thread->IsRunning())
-			thread->Delete();
+		{
+			thread->CancelExecution();
+			thread->Wait();
+		}
 		delete thread;
 		thread = 0;
 	}
diff --git a/pgadmin/frm/frmQuery.cpp b/pgadmin/frm/frmQuery.cpp
index 4e30242..fcfc15f 100644
--- a/pgadmin/frm/frmQuery.cpp
+++ b/pgadmin/frm/frmQuery.cpp
@@ -159,7 +159,7 @@ BEGIN_EVENT_TABLE(frmQuery, pgFrame)
 	EVT_TIMER(CTL_TIMERSIZES,       frmQuery::OnAdjustSizesTimer)
 	EVT_TIMER(CTL_TIMERFRM,         frmQuery::OnTimer)
 // These fire when the queries complete
-	EVT_MENU(QUERY_COMPLETE,        frmQuery::OnQueryComplete)
+	EVT_PGQUERYRESULT(QUERY_COMPLETE, frmQuery::OnQueryComplete)
 	EVT_MENU(PGSCRIPT_COMPLETE,     frmQuery::OnScriptComplete)
 	EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_NTBKCENTER, frmQuery::OnChangeNotebook)
 	EVT_SPLITTER_SASH_POS_CHANGED(GQB_HORZ_SASH, frmQuery::OnResizeHorizontally)
@@ -2415,7 +2415,7 @@ void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singl
 
 
 // When the query completes, it raises an event which we process here.
-void frmQuery::OnQueryComplete(wxCommandEvent &ev)
+void frmQuery::OnQueryComplete(pgQueryResultEvent &ev)
 {
 	QueryExecInfo *qi = (QueryExecInfo *)ev.GetClientData();
 
@@ -2548,7 +2548,7 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
 	else
 	{
 		done = true;
-		outputPane->SetSelection(0);
+		outputPane->SetSelection(0);		
 		long rowsTotal = sqlResult->NumRows();
 
 		if (qi->toFileExportForm)
diff --git a/pgadmin/include/db/module.mk b/pgadmin/include/db/module.mk
index ae79345..03fefa1 100644
--- a/pgadmin/include/db/module.mk
+++ b/pgadmin/include/db/module.mk
@@ -12,9 +12,9 @@
 pgadmin3_SOURCES += \
 	  include/db/pgConn.h \
 	  include/db/pgQueryThread.h \
+	  include/db/pgQueryResultEvent.h \
 	  include/db/pgSet.h
 
-
 EXTRA_DIST += \
     include/db/module.mk
 
diff --git a/pgadmin/include/db/pgConn.h b/pgadmin/include/db/pgConn.h
index f58cb81..c5d3e10 100644
--- a/pgadmin/include/db/pgConn.h
+++ b/pgadmin/include/db/pgConn.h
@@ -24,33 +24,33 @@
 // status enums
 enum
 {
-    PGCONN_OK = CONNECTION_OK,
-    PGCONN_BAD = CONNECTION_BAD,
-    PGCONN_REFUSED,
-    PGCONN_DNSERR,
-    PGCONN_ABORTED,     // connect user aborted
-    PGCONN_BROKEN       // tcp/pipe broken
+	PGCONN_OK = CONNECTION_OK,
+	PGCONN_BAD = CONNECTION_BAD,
+	PGCONN_REFUSED,
+	PGCONN_DNSERR,
+	PGCONN_ABORTED,     // connect user aborted
+	PGCONN_BROKEN       // tcp/pipe broken
 };
 
 enum
 {
-    PGCONN_EMPTY_QUERY = PGRES_EMPTY_QUERY,
-    PGCONN_COMMAND_OK = PGRES_COMMAND_OK,
-    PGCONN_TUPLES_OK = PGRES_TUPLES_OK,
-    PGCONN_COPY_OUT = PGRES_COPY_OUT,
-    PGCONN_COPY_IN = PGRES_COPY_IN,
-    PGCONN_BAD_RESPONSE = PGRES_BAD_RESPONSE,
-    PGCONN_NONFATAL_ERROR = PGRES_NONFATAL_ERROR,
-    PGCONN_FATAL_ERROR = PGRES_FATAL_ERROR
+	PGCONN_EMPTY_QUERY = PGRES_EMPTY_QUERY,
+	PGCONN_COMMAND_OK = PGRES_COMMAND_OK,
+	PGCONN_TUPLES_OK = PGRES_TUPLES_OK,
+	PGCONN_COPY_OUT = PGRES_COPY_OUT,
+	PGCONN_COPY_IN = PGRES_COPY_IN,
+	PGCONN_BAD_RESPONSE = PGRES_BAD_RESPONSE,
+	PGCONN_NONFATAL_ERROR = PGRES_NONFATAL_ERROR,
+	PGCONN_FATAL_ERROR = PGRES_FATAL_ERROR
 };
 
 enum
 {
-    PGCONN_TXSTATUS_IDLE = PQTRANS_IDLE,
-    PGCONN_TXSTATUS_ACTIVE = PQTRANS_ACTIVE,
-    PGCONN_TXSTATUS_INTRANS = PQTRANS_INTRANS,
-    PGCONN_TXSTATUS_INERROR = PQTRANS_INERROR,
-    PGCONN_TXSTATUS_UNKNOWN = PQTRANS_UNKNOWN
+	PGCONN_TXSTATUS_IDLE = PQTRANS_IDLE,
+	PGCONN_TXSTATUS_ACTIVE = PQTRANS_ACTIVE,
+	PGCONN_TXSTATUS_INTRANS = PQTRANS_INTRANS,
+	PGCONN_TXSTATUS_INERROR = PQTRANS_INERROR,
+	PGCONN_TXSTATUS_UNKNOWN = PQTRANS_UNKNOWN
 };
 
 // Our version of a pgNotify
@@ -77,8 +77,9 @@ typedef struct pgError
 	wxString source_line;
 	wxString source_function;
 	wxString formatted_msg;
-} pgError;
 
+	void SetError(PGresult *_res = NULL, wxMBConv *_conv = NULL);
+} pgError;
 
 class pgConn
 {
@@ -110,7 +111,7 @@ public:
 	bool GetIsGreenplum();
 	wxString EncryptPassword(const wxString &user, const wxString &password);
 	wxString qtDbString(const wxString &value);
-	pgConn *Duplicate();
+	pgConn *Duplicate(const wxString &_appName = wxT(""));
 
 	static void ExamineLibpqVersion();
 	static double GetLibpqVersion()
@@ -126,8 +127,10 @@ public:
 	void Close();
 	bool Reconnect();
 	bool ExecuteVoid(const wxString &sql, bool reportError = true);
-	wxString ExecuteScalar(const wxString &sql);
-	pgSet *ExecuteSet(const wxString &sql);
+	wxString ExecuteScalar(const wxString &sql, bool reportError = true);
+	pgSet *ExecuteSet(const wxString &sql, bool reportError = true);
+	void CancelExecution(void);
+
 	wxString GetHostAddr() const
 	{
 		return save_hostaddr;
@@ -257,12 +260,16 @@ public:
 	bool TableHasColumn(wxString schemaname, wxString tblname, const wxString &colname);
 
 protected:
-	PGconn *conn;
+	PGconn   *conn;
+	PGcancel *m_cancelConn;
+	wxMutex   m_cancelConnMutex;
 	int lastResultStatus;
 
 	int connStatus;
 
 	void SetLastResultError(PGresult *res, const wxString &msg = wxEmptyString);
+	void SetConnCancel(void);
+	void ResetConnCancel(void);
 	pgError lastResultError;
 
 	wxMBConv *conv;
diff --git a/pgadmin/include/db/pgQueryThread.h b/pgadmin/include/db/pgQueryThread.h
index a03a32a..59bebf7 100644
--- a/pgadmin/include/db/pgQueryThread.h
+++ b/pgadmin/include/db/pgQueryThread.h
@@ -12,59 +12,271 @@
 #ifndef PGQUERYTHREAD_H
 #define PGQUERYTHREAD_H
 
+#include "wx/wx.h"
+#include "wx/event.h"
+#include "db/pgConn.h"
+
+// Forward declaration
 class pgSet;
+class pgQueryThread;
+class pgBatchQuery;
+
+// Support for the IN & INOUT parameters type
+class pgParam : public wxObject
+{
+public:
+	enum
+	{
+		PG_PARAM_IN       = 1,
+		PG_PARAM_OUT      = 2,
+		PG_PARAM_INOUT    = 3,
+		PG_PARAM_VARIADIC = 4,
+		PG_PARAM_TABLE    = 5
+	};
+
+	// Any data
+	//
+	// This constructor won't call the functions - 'htonl' or 'htons'
+	// It will be the responsibility of the caller to take care
+	// to call 'htonl' or 'htons' depending on requirements.
+	//
+	// NOTE:
+	// This data will be owned by pgParam object and will be released.
+	pgParam(Oid _type, void *_val, int _len, short mode = PG_PARAM_IN);
+
+	// wxString data
+	pgParam(Oid _type, wxString *_val, wxMBConv *_conv = NULL,
+	        short mode = PG_PARAM_IN);
+
+	~pgParam();
+
+	// Returns 0 for text type and 1 for otherwise
+	int   GetFormat();
+
+	Oid   GetType()
+	{
+		return m_type;
+	}
+	short GetMode()
+	{
+		return m_mode;
+	}
+
+protected:
+	Oid    m_type;
+	void  *m_val;
+	int    m_len;
+	short  m_format;
+	// Modes are required by EnterpriseDB's callable statement
+	short  m_mode;
+
+	// Do not allow copy construction and shadow-copy
+	// to avoid ownership
+	// Force to use an pointer
+	pgParam(const pgParam &)
+	{
+		wxASSERT(0);
+	}
+	pgParam &operator= (const pgParam &)
+	{
+		wxASSERT(0);
+	}
+
+	friend class pgConn;
+	friend class pgQueryThread;
+};
+
+WX_DEFINE_ARRAY_PTR(pgParam *, pgParamsArray);
+
+class pgBatchQuery : public wxObject
+{
+public:
+	pgBatchQuery(const wxString &_query, pgParamsArray *_params = NULL,
+	             long _eventId = -1, void *_data = NULL, bool _useCallable = false,
+	             int _resultToRetrieve = 0)
+		: m_query(_query), m_params(_params), m_eventID(_eventId), m_data(_data),
+		  m_useCallable(_useCallable), m_resToRetrieve(_resultToRetrieve),
+		  m_returnCode(-1), m_resultSet(NULL), m_rowsInserted(-1), m_insertedOid(-1)
+	{
+		// Do not honour the empty query string
+		wxASSERT(!_query.IsEmpty());
+	}
+	~pgBatchQuery();
+
+	bool            Release();
+
+	pgSet          *ResultSet()
+	{
+		return m_resultSet;
+	}
+
+	int             ReturnCode()
+	{
+		return m_returnCode;
+	}
+
+	const wxString &GetMessage()
+	{
+		return m_message;
+	}
+
+	long            RowInserted()
+	{
+		return m_rowsInserted;
+	}
+
+	const wxString &GetErrorMessage();
+
+protected:
+	wxString           m_query;         // Query
+	pgParamsArray     *m_params;        // parameters
+	long               m_eventID;       // Event ID
+	void              *m_data;          // Data to be send with event
+	bool               m_useCallable;   // Use EnterpriseDB callable statement if possible
+	int                m_resToRetrieve; // Which result to be retrieved
+	int                m_returnCode;    // Return code
+	pgSet             *m_resultSet;     // Result-Set
+	long               m_rowsInserted;  // No of rows inserted
+	Oid                m_insertedOid;   // Inserted Oid
+	wxString           m_message;       // Message generated during query execution
+	pgError            m_err;           // Error
+
+private:
+	// Do not allow copy construction and '=' operator (shadow copying)
+	// to avoid ownership of parameters and result-set
+	//
+	// This will force this class to be used as an pointer only.
+	pgBatchQuery(const pgBatchQuery &)
+	{
+		wxASSERT(0);
+	}
+	pgBatchQuery &operator= (const pgBatchQuery &)
+	{
+		wxASSERT(0);
+	}
+
+	friend class pgQueryThread;
+};
+WX_DEFINE_ARRAY_PTR(pgBatchQuery *, pgBatchQueryArray);
 
 class pgQueryThread : public wxThread
 {
 public:
-	pgQueryThread(pgConn *_conn, const wxString &qry, int resultToRetrieve = -1, wxWindow *_caller = 0, long eventId = 0, void *_data = 0);
+	// For running a single query (Used by few components)
+	pgQueryThread(pgConn *_conn, const wxString &qry, int resultToRetrieve = -1,
+	              wxWindow *_caller = 0, long eventId = 0, void *_data = 0);
+
+	// Support for multiple queries support
+	pgQueryThread(pgConn *_conn, wxEvtHandler *_caller = NULL,
+	              PQnoticeProcessor _processor = NULL, void *_noticeHandler = NULL);
+
 	~pgQueryThread();
 
+	bool HasMultipleQueriesSupport()
+	{
+		return m_multiQueries;
+	}
+
+	bool SupportCallableStatement()
+	{
+		return m_useCallable;
+	}
+
+	void AddQuery(
+	    const wxString &_qry, pgParamsArray *_params = NULL,
+	    long _eventId = 0, void *_data = NULL, bool _useCallable = false,
+	    int _resultToRetrieve = -1);
+
 	virtual void *Entry();
-	bool DataValid() const
+	bool DataValid(int _idx = -1) const
 	{
-		return dataSet != NULL;
+		if (_idx == -1)
+			_idx = m_currIndex;
+		return (_idx >= 0 && _idx > m_currIndex ? false : (m_queries[_idx]->m_resultSet != NULL));
 	}
-	pgSet *DataSet()
+
+	pgConn *GetConn()
+	{
+		return m_conn;
+	}
+
+	pgSet *DataSet(int _idx = -1)
+	{
+		if (_idx == -1)
+			_idx = m_currIndex;
+		return (_idx >= 0 && _idx > m_currIndex ? NULL : m_queries[_idx]->m_resultSet);
+	}
+
+	int ReturnCode(int _idx = -1) const
+	{
+		if (_idx == -1)
+			_idx = m_currIndex;
+		return (_idx >= 0 && _idx > m_currIndex ? -1 : m_queries[_idx]->m_returnCode);
+	}
+
+	long RowsInserted(int _idx = -1) const
 	{
-		return dataSet;
+		if (_idx == -1)
+			_idx = m_currIndex;
+		return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_rowsInserted);
 	}
-	int ReturnCode() const
+
+	Oid InsertedOid(int _idx = -1) const
 	{
-		return rc;
+		if (_idx == -1)
+			_idx = m_currIndex;
+		return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_insertedOid);
 	}
-	long RowsInserted() const
+
+	inline void CancelExecution()
+	{
+		m_cancelled = true;
+	}
+
+	inline size_t GetNumberQueries()
 	{
-		return rowsInserted;
+		return m_queries.GetCount();
 	}
-	OID InsertedOid() const
+
+	size_t QueriesExecuted()
 	{
-		return insertedOid;
+		return m_currIndex + 1;
 	}
-	wxString GetMessagesAndClear();
-	void appendMessage(const wxString &str);
+
+	wxString GetMessagesAndClear(int _idx = -1);
+	void AppendMessage(const wxString &_str);
+
+	int DeleteReleasedQueries();
 
 private:
-	int rc;
-	int resultToRetrieve;
-	long rowsInserted;
-	OID insertedOid;
-
-	wxString query;
-	pgConn *conn;
-	PGresult *result;
-	wxString messages;
-	pgSet *dataSet;
-	wxCriticalSection criticalSection;
-
-	void *data;
-	wxWindow *caller;
-	long eventId;
-
-	int execute();
-	int raiseEvent(int retval = 0);
-
-	void appendMessageRaw(const wxString &str);
+	int Execute();
+	int RaiseEvent(int _retval = 0);
+
+	// Queries to be exectued
+	pgBatchQueryArray  m_queries;
+	// Current running query index
+	int                m_currIndex;
+	// Connection object
+	pgConn            *m_conn;
+	// Execution cancelled?
+	bool               m_cancelled;
+	// Does this thread support multiple queries
+	bool               m_multiQueries;
+	// Use EDB callable statement (if available and require)
+	bool               m_useCallable;
+	// Is executing a query
+	bool               m_executing;
+	// Queries are being accessed at this time
+	wxMutex            m_queriesLock;
+	// When one thread is accesing messages, other should not be able to access it
+	wxCriticalSection  m_criticalSection;
+	// Event Handler
+	wxEvtHandler      *m_caller;
+	// Database server notice-processor
+	PQnoticeProcessor  m_processor;
+	// Notice Handler
+	void              *m_noticeHandler;
+
 };
 
 #endif
diff --git a/pgadmin/include/db/pgSet.h b/pgadmin/include/db/pgSet.h
index f6543b1..9a5c7b5 100644
--- a/pgadmin/include/db/pgSet.h
+++ b/pgadmin/include/db/pgSet.h
@@ -131,6 +131,14 @@ public:
 		return conv;
 	}
 
+	wxString GetCommandStatus() const
+	{
+		if (res)
+		{
+			return wxString(PQcmdStatus(res), conv);
+		}
+		return wxEmptyString;
+	}
 
 protected:
 	pgConn *conn;
diff --git a/pgadmin/include/debugger/ctlCodeWindow.h b/pgadmin/include/debugger/ctlCodeWindow.h
deleted file mode 100644
index 6267ad9..0000000
--- a/pgadmin/include/debugger/ctlCodeWindow.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// ctlCodeWindow.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class ctlCodeWindow
-//
-//	This class implements the debugger window.  The constructor expects a string
-//  that contains a TCP port number - the constructor connects to the debugger
-//  server waiting at that port.
-//
-//  A ctlCodeWindow object creates (and manages) a toolbar and handles toolbar
-//  and keystroke messages. The input messages are treated as debugger commands.
-//
-//	The m_view member is a ctlSQLBox that displays the code for the PL
-//  function that you're debugging.  The m_hilite member tracks the current
-//  line (that is, the line about to execute).  We use hilight the current line.
-//  If m_hilite is -1, there is no current line.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef CTLCODEWINDOW_H
-#define CTLCODEWINDOW_H
-
-#include <wx/progdlg.h>
-
-#include "ctl/ctlSQLBox.h"
-#include "debugger/frmDebugger.h"
-#include "debugger/dbgBreakPoint.h"
-#include "debugger/ctlTabWindow.h"
-
-class dbgPgConn;
-class dbgResultset;
-class dbgConnProp;
-class wsWaitingDialog;
-class ctlStackWindow;
-class ctlMessageWindow;
-class ctlVarWindow;
-class ctlResultGrid;
-
-
-#define MARKERINDEX_TO_MARKERMASK( MI ) ( 1 << MI )
-
-class wsCodeCache
-{
-public:
-	wsCodeCache() {}
-	wsCodeCache(const wxString &packageOID, const wxString &funcOID, const wxString &source, const wxString &signature);
-
-	const wxString &getSource()
-	{
-		return( m_sourceCode );
-	}
-	const wxString &getSignature()
-	{
-		return( m_signature );
-	}
-
-private:
-	wxString	m_packageOID;	// Package OID
-	wxString	m_funcOID;	// Function OID
-	wxString	m_sourceCode;	// Source code for this function
-	wxString    m_signature; // Function sig
-
-};
-
-class ctlCodeWindow : public pgFrame
-{
-	DECLARE_CLASS( ctlCodeWindow )
-
-public:
-	ctlCodeWindow( frmDebugger *parent, wxWindowID id, const dbgConnProp &connProps );
-
-	void OnClose(wxCloseEvent &event);
-	void startLocalDebugging();	 	                    // Start debugging
-	void resumeLocalDebugging();		                // Start debugging, already attached to the proxy
-	void startGlobalDebugging(); 		                // Start debugging
-	void OnCommand( wxCommandEvent &event );		     // Handle menu/toolbar commands
-	void OnSelectFrame( wxCommandEvent &event );	     // Select a different stack frame
-	void OnMarginClick( wxStyledTextEvent &event );     // Set/clear breakpoint on margin click
-	void OnPositionStc( wxStyledTextEvent &event );     // update the status bar text
-	void OnVarChange( wxGridEvent &event );		     // User changed a variable
-	void processResult( wxString &result );		     // Handle a message from the debugger server
-	void OnNoticeReceived( wxCommandEvent &event );     // NOTICE received from server
-	void OnResultSet( PGresult *result );			     // Result set received from server
-	void disableTools();			                    // Disable toolbar tools
-	void enableTools();		 	                        // Enable toolbar tools
-
-	frmDebugger *GetFrame()
-	{
-		return m_parent;
-	}
-
-	bool	m_targetAborted;		    // Have we aborted the target? (true) or are we waiting for a breakpoint? (false)
-	bool	m_targetComplete;		    // Is the target complete? (true) or is it still running (or aborted)? (false)
-	dbgBreakPointList &getBreakpointList();
-
-	WX_DECLARE_STRING_HASH_MAP( wsCodeCache, sourceHash );
-
-private:
-
-	bool isBreakpoint(int lineNumber)
-	{
-		return (m_view->MarkerGet( lineNumber ) & MARKERINDEX_TO_MARKERMASK( MARKER_BREAKPOINT ) ? true : false);
-	}
-	void clearBreakpoint( int lineNumber, bool requestUpdate );
-	void setBreakpoint( int lineNumber );
-
-	ctlStackWindow   *getStackWindow()
-	{
-		return( m_stackWindow );
-	}
-	ctlMessageWindow *getMessageWindow()
-	{
-		return( m_tabWindow->getMessageWindow());
-	}
-
-	ctlVarWindow     *getVarWindow( bool create )
-	{
-		return( m_tabWindow->getVarWindow( create ));
-	}
-	ctlVarWindow     *getParamWindow( bool create )
-	{
-		return( m_tabWindow->getParamWindow( create ));
-	}
-	ctlVarWindow	 *getPkgVarWindow( bool create )
-	{
-		return( m_tabWindow->getPkgVarWindow( create ));
-	}
-	ctlResultGrid    *getResultWindow()
-	{
-		return( m_tabWindow->getResultWindow());
-	}
-
-	void	setTools(bool enable);		            // Enable/disable debugger options
-	void	OnIdle( wxIdleEvent &event );			// Idle processor
-	void	OnTimer( wxTimerEvent &event );		// Clock tick
-
-	int		getLineNo( );				                    // Compute line number for current cursor position
-	void 	closeConnection();								// Closes proxy connection
-	void	updateUI( dbgResultset &breakpoint );		     // Update the lazy parts of the UI
-	void	updateSourceCode( dbgResultset &breakpoint );	// Update the source code window
-	bool	connectionLost( dbgResultset &resultSet );	     // Returns true if proxy lost it's connection
-	bool	gotFatalError( dbgResultset &resultSet );	     // Returns true if result set indicates a fatal error has occurred
-	void 	popupError(dbgResultset &resultSet);
-	void	addBreakpoint( dbgBreakPoint *breakpoint, wxEventType nextStep );
-
-	void	ResultPortAttach( wxCommandEvent &event );			// Attach to debugger port complete
-	void	ResultBreakpoint( wxCommandEvent &event );			// Breakpoint encountered
-	void	ResultVarList( wxCommandEvent &event );			// Variable list complete
-	void	ResultStack( wxCommandEvent &event );				// Stack trace retrieval complete
-	void	ResultSource( wxCommandEvent &event );				// Source code retrieval complete
-	void 	ResultBreakpoints( wxCommandEvent &event );		// Breakpoint list retrieval complete
-	void	ResultNewBreakpoint( wxCommandEvent &event );		// Set Breakpoint command complete
-	void	ResultNewBreakpointWait( wxCommandEvent &event );	// Set Breakpoint command complete, wait for a target process
-	void	ResultDeletedBreakpoint( wxCommandEvent &event );	// Drop Breakpoint command complete
-	void	ResultDepositValue( wxCommandEvent &event );		// Deposit Value command complete
-	void	ResultAbortTarget( wxCommandEvent &event );		// Abort target command complete
-	void	ResultAddBreakpoint( wxCommandEvent &event );		// getTargetInfo() complete, add a breakpoint
-	void	ResultListenerCreated( wxCommandEvent &event );	// Global listener created, ready to wait for a target
-	void	ResultTargetReady( wxCommandEvent &event );		// Target session attached, ready to wait for a breakpoint
-	void	ResultLastBreakpoint( wxCommandEvent &event );		// Adding last breakpoint
-
-	dbgPgConn	*m_dbgConn;	    // Network connection to debugger server
-	wxString	m_debugPort;	// Port at which debugger server is listening
-
-	frmDebugger 	*m_parent;		// Parent window
-	int	m_currentLineNumber;	// Current line number
-
-	ctlSQLBox       *m_view;	    // Window that displays function source code
-	ctlStackWindow	*m_stackWindow;	// Stack Window
-	ctlTabWindow	*m_tabWindow;	    // Tab Window
-
-	typedef enum
-	{
-	    SESSION_TYPE_UNKNOWN,	// Session could be in-context or direct
-	    SESSION_TYPE_INCONTEXT,	// Session is configured for in-context debugging
-	    SESSION_TYPE_DIRECT		// Session is configured for direct debugging
-	} eSessionType;
-
-	eSessionType	m_sessionType;		// Debugging mode is in-context or direct?
-	bool	m_updateVars;			    // Update variable window in next idle period?
-	bool    m_updateStack;			    // Update stack window in next idle period?
-	bool	m_updateBreakpoints;	    // Update breakpoints in next idle period?
-	dbgBreakPointList    m_breakpoints;	// List of initial breakpoints to create
-
-	enum
-	{
-	    MARKER_CURRENT    = 0x02,		// Current line marker
-	    MARKER_CURRENT_BG = 0x04,		// Current line marker - background hilight
-	    MARKER_BREAKPOINT = 0x01,		// Breakpoint marker
-	};
-
-	sourceHash	m_sourceCodeMap;
-
-	wxString	m_focusPackageOid;	    // Which package has the debug focus?
-	wxString	m_focusFuncOid;		    // Which function has the debug focus?
-	wxString	m_displayedFuncOid;	    // Which function are we currently displaying? (function OID component)
-	wxString	m_displayedPackageOid;	// Which function are we currently displaying? (package OID component)
-	wxString	m_sessionHandle;	    // Handle to proxy's server session
-	wxString	m_targetName;		    // User-friendly target name
-
-	wxProgressDialog *m_progressBar;	// "Waiting for target" dialog
-	wxTimer	m_timer;
-	bool	findSourceInCache( const wxString &packageOID, const wxString &funcOID);
-	void	clearSourceCache();
-	void	getSource(const wxString &packageOID, const wxString &funcOID);
-	void	cacheSource(const wxString &packageOID, const wxString &funcOID, const wxString &sourceCode, const wxString &signature);
-	void	displaySource(const wxString &packageOID, const wxString &funcID);
-	void	unhilightCurrentLine();
-	void	launchWaitingDialog();
-
-	void	clearAllBreakpoints();
-	void	clearBreakpointMarkers();
-	void	stopDebugging();
-
-	static wxString	m_commandAttach;
-	static wxString m_commandWaitForBreakpoint;
-	static wxString m_commandGetVars;
-	static wxString m_commandGetStack;
-	static wxString m_commandGetBreakpoints;
-	static wxString m_commandGetSourceV1;
-	static wxString m_commandGetSourceV2;
-	static wxString m_commandStepOver;
-	static wxString m_commandStepInto;
-	static wxString m_commandContinue;
-	static wxString m_commandSetBreakpointV1;
-	static wxString m_commandSetBreakpointV2;
-	static wxString m_commandClearBreakpointV1;
-	static wxString m_commandClearBreakpointV2;
-	static wxString m_commandSelectFrame;
-	static wxString m_commandDepositValue;
-	static wxString m_commandAbortTarget;
-	static wxString m_commandGetTargetInfo;
-	static wxString m_commandAddBreakpointEDB;
-	static wxString m_commandAddBreakpointPG;
-	static wxString m_commandCreateListener;
-	static wxString m_commandWaitForTarget;
-
-	DECLARE_EVENT_TABLE()
-};
-
-#endif
diff --git a/pgadmin/include/debugger/ctlMessageWindow.h b/pgadmin/include/debugger/ctlMessageWindow.h
index aaab315..f588880 100644
--- a/pgadmin/include/debugger/ctlMessageWindow.h
+++ b/pgadmin/include/debugger/ctlMessageWindow.h
@@ -23,21 +23,14 @@
 
 class ctlMessageWindow : public wxTextCtrl
 {
-	DECLARE_CLASS( ctlMessageWindow )
+	DECLARE_CLASS(ctlMessageWindow)
 
 public:
-	ctlMessageWindow( wxWindow *parent, wxWindowID id );
+	ctlMessageWindow(wxWindow *parent, wxWindowID id);
 
-	void	addMessage( wxString message );	// Add a message to the window
-	void	delMessage( const char *name = NULL );								     // Remove a message from the window
-	wxString	getMessage( int row );
-
-private:
-
-	typedef struct
-	{
-		int	m_row;		// Row number for this variable/grid cell
-	} gridCell;
+	void     AddMessage(wxString message);	// Add a message to the window
+	void     DelMessage(const char *name = NULL);								     // Remove a message from the window
+	wxString GetMessage(int row);
 };
 
 #endif
diff --git a/pgadmin/include/debugger/ctlResultGrid.h b/pgadmin/include/debugger/ctlResultGrid.h
index fa7590e..76fdc28 100644
--- a/pgadmin/include/debugger/ctlResultGrid.h
+++ b/pgadmin/include/debugger/ctlResultGrid.h
@@ -25,12 +25,13 @@
 
 class ctlResultGrid : public wxGrid
 {
-	DECLARE_CLASS( ctlResultGrid )
+	DECLARE_CLASS(ctlResultGrid)
 
 public:
-	ctlResultGrid( wxWindow *parent, wxWindowID id );
+	ctlResultGrid(wxWindow *parent, wxWindowID id);
 
-	void	fillGrid( PGresult *result );	// Copy a result set into the grid
+	// Copy a result set into the grid
+	void	FillResult(pgSet *set);
 };
 
 #endif
diff --git a/pgadmin/include/debugger/ctlStackWindow.h b/pgadmin/include/debugger/ctlStackWindow.h
index b6d94c0..cf64f81 100644
--- a/pgadmin/include/debugger/ctlStackWindow.h
+++ b/pgadmin/include/debugger/ctlStackWindow.h
@@ -36,8 +36,8 @@ class ctlStackWindow : public wxListBox
 public:
 
 	ctlStackWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxCLIP_CHILDREN | wxSW_3D, const wxString &name = wxT( "stackWindow" ));
-	void clear();											// Remove all frames from the stack trace
-	void setStack(const wxArrayString &stack);			// Add an array of frames to the stack trace
+	void ClearStack();											// Remove all frames from the stack trace
+	void SetStack(const wxArrayString &stack);			// Add an array of frames to the stack trace
 };
 
 #endif
diff --git a/pgadmin/include/debugger/ctlTabWindow.h b/pgadmin/include/debugger/ctlTabWindow.h
index 7d09f9b..684b664 100644
--- a/pgadmin/include/debugger/ctlTabWindow.h
+++ b/pgadmin/include/debugger/ctlTabWindow.h
@@ -32,34 +32,37 @@
 #include "debugger/ctlStackWindow.h"
 #include "debugger/ctlResultGrid.h"
 
-WX_DECLARE_HASH_MAP( int, int, wxIntegerHash, wxIntegerEqual, wsTabHash );
+WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, wsTabHash);
 
 class ctlTabWindow : public ctlAuiNotebook
 {
-	DECLARE_CLASS( ctlTabWindow )
+	DECLARE_CLASS(ctlTabWindow)
 
 public:
 
-	ctlTabWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxCLIP_CHILDREN | wxSW_3D, const wxString &name = wxT( "layoutWindow" ));
+	ctlTabWindow(wxWindow *parent, wxWindowID id,
+	             const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
+	             long style = wxCLIP_CHILDREN | wxSW_3D,
+	             const wxString &name = wxT("layoutWindow"));
 
-	ctlVarWindow	*getVarWindow( bool create = true );		// Returns a pointer to the local-variables window (creates it if requested)
-	ctlVarWindow	*getPkgVarWindow( bool create = true );	// Returns a pointer to the package-variables window (creates it if requested)
-	ctlVarWindow	*getParamWindow( bool create = true );		// Returns a pointer to the parameters window (creates it if requested)
+	ctlVarWindow      *GetVarWindow(bool create = true);    // Returns a pointer to the local-variables window (creates it if requested)
+	ctlVarWindow      *GetPkgVarWindow(bool create = true); // Returns a pointer to the package-variables window (creates it if requested)
+	ctlVarWindow      *GetParamWindow(bool create = true);  // Returns a pointer to the parameters window (creates it if requested)
 
-	ctlResultGrid	*getResultWindow( void );					// Returns a pointer to the result window (creates it if necessary)
-	ctlStackWindow	*getStackWindow( void );					// Returns a pointer to the stack-trace window (creates it if necessary)
-	ctlMessageWindow *getMessageWindow( void );					// Returns a pointer to the DBMS messages window (creates it if necessary)
-	void	selectTab( wxWindowID id );
+	ctlResultGrid     *GetResultWindow();					// Returns a pointer to the result window (creates it if necessary)
+	ctlStackWindow    *GetStackWindow();                    // Returns a pointer to the stack-trace window (creates it if necessary)
+	ctlMessageWindow  *GetMessageWindow();                  // Returns a pointer to the DBMS messages window (creates it if necessary)
+	void	           SelectTab(wxWindowID id);
 
 private:
-	ctlResultGrid	*m_resultWindow;	// Displays the result set from a query
-	ctlVarWindow	*m_varWindow;		// Displays the local variables when debugging a PL function
-	ctlVarWindow	*m_pkgVarWindow;	// Displays the package variables when debugging a PL function
-	ctlStackWindow	*m_stackWindow;		// Displays the current call stack
-	ctlVarWindow	*m_paramWindow;		// Displays the parameters when debugging a PL function
-	ctlMessageWindow	*m_messageWindow;	// Displays the DBMS messages when debugging a PL function
+	ctlResultGrid    *m_resultWindow;  // Displays the result set from a query
+	ctlVarWindow     *m_varWindow;     // Displays the local variables when debugging a PL function
+	ctlVarWindow     *m_pkgVarWindow;  // Displays the package variables when debugging a PL function
+	ctlStackWindow   *m_stackWindow;   // Displays the current call stack
+	ctlVarWindow     *m_paramWindow;   // Displays the parameters when debugging a PL function
+	ctlMessageWindow *m_messageWindow; // Displays the DBMS messages when debugging a PL function
 
-	wsTabHash	*m_tabMap;		// Map window ID's to tab numbers;
+	wsTabHash        *m_tabMap;        // Map window ID's to tab numbers;
 };
 
 #endif
diff --git a/pgadmin/include/debugger/ctlVarWindow.h b/pgadmin/include/debugger/ctlVarWindow.h
index 0d2a4a2..665531f 100644
--- a/pgadmin/include/debugger/ctlVarWindow.h
+++ b/pgadmin/include/debugger/ctlVarWindow.h
@@ -35,38 +35,40 @@
 
 class ctlVarWindow : public wxGrid
 {
-	DECLARE_CLASS( ctlVarWindow )
+	DECLARE_CLASS(ctlVarWindow)
 
 public:
-	ctlVarWindow( wxWindow *parent, wxWindowID id );
+	ctlVarWindow(wxWindow *parent, wxWindowID id);
 
-	void	addVar( wxString name, wxString value, wxString type, bool readOnly );	// Add a variable to the window
-	void	delVar( wxString name = wxEmptyString);								    // Remove a variable from the window
-	wxString	getVarName( int row );
-	wxString	getVarValue( int row );
+	// Add a variable to the window
+	void AddVar(wxString name, wxString value, wxString type, bool readOnly);
+	// Remove a variable from the window
+	void DelVar(wxString name = wxEmptyString);
+
+	wxString GetVarName(int row);
+	wxString GetVarValue(int row);
 
 private:
 
 	// The content of a grid cell is defined by the gridCell structure
-
 	typedef struct
 	{
-		int		m_row;	 // Row number for this variable/grid cell
-		wxString	m_value; // Variable value
-		wxString	m_type;	 // Variable type
+		int      m_row;   // Row number for this variable/grid cell
+		wxString m_value; // Variable value
+		wxString m_type;  // Variable type
 	} gridCell;
 
 	enum
 	{
-	    COL_NAME = 0,		// Column 0 contains the variable name
-	    COL_TYPE,		// This column contains the variable type
-	    COL_VALUE		// This column contains the variable value
+		COL_NAME = 0,		// Column 0 contains the variable name
+		COL_TYPE,		// This column contains the variable type
+		COL_VALUE		// This column contains the variable value
 	};
 
 	// The m_cells hash translates variable names into gridCell references
 public:
-	WX_DECLARE_STRING_HASH_MAP( gridCell, wsCellHash );
-	WX_DECLARE_HASH_SET( wxString, wxStringHash, wxStringEqual, wsStringSet );
+	WX_DECLARE_STRING_HASH_MAP(gridCell, wsCellHash);
+	WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, wsStringSet);
 
 private:
 	wsStringSet	m_hiddenNames;	// List of hidden variable names
diff --git a/pgadmin/include/debugger/dbgBreakPoint.h b/pgadmin/include/debugger/dbgBreakPoint.h
index b327504..486038a 100644
--- a/pgadmin/include/debugger/dbgBreakPoint.h
+++ b/pgadmin/include/debugger/dbgBreakPoint.h
@@ -21,36 +21,29 @@
 class dbgBreakPoint
 {
 public:
+	dbgBreakPoint(const wxString &_funcOid, const wxString &_pkgOid = wxT("0"),
+	              const wxString &_lineNo = wxT("NULL"))
+		: m_func(_funcOid), m_pkg(_pkgOid), m_lineNo(_lineNo) {}
 
-	enum eTargetType
+	wxString    &GetFunctionOid()
 	{
-	    TRIGGER,
-	    FUNCTION,
-	    PROCEDURE,
-	    OID
-	};
-
-	dbgBreakPoint(eTargetType targetType, const wxString &target, const wxString &process ): m_targetType(targetType), m_target(target), m_targetProcess(process) {}
-
-	eTargetType   getTargetType()
-	{
-		return( m_targetType );
+		return m_func;
 	}
-	wxString     &getTarget()
+	wxString    &GetPackageOid()
 	{
-		return( m_target );
+		return m_pkg;
 	}
-	wxString     &getTargetProcess()
+	wxString    &GetLineNo()
 	{
-		return( m_targetProcess );
+		return m_lineNo;
 	}
-private:
-	eTargetType 	m_targetType;
-	wxString	m_target;
-	wxString	m_targetProcess;
 
+private:
+	wxString    m_func;
+	wxString    m_pkg;
+	wxString    m_lineNo;
 };
 
-WX_DECLARE_LIST( dbgBreakPoint, dbgBreakPointList );
+WX_DECLARE_LIST(dbgBreakPoint, dbgBreakPointList);
 
 #endif
diff --git a/pgadmin/include/debugger/dbgConnProp.h b/pgadmin/include/debugger/dbgConnProp.h
deleted file mode 100644
index be003de..0000000
--- a/pgadmin/include/debugger/dbgConnProp.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgConnProp.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class dbgConnProp
-//
-//  dbgConnProp object is used to hold a set of connection properties, that is.
-//  it's a collection of all of the information that we need in order to connect
-//  to a server.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef DBGCONNPROP_H
-#define DBGCONNPROP_H
-
-class dbgConnProp
-{
-
-public:
-	wxString	m_host;			// Host name (or IP-address)
-	wxString	m_database;		// Database name
-	wxString	m_userName;		// User name
-	wxString	m_password;		// Password
-	wxString	m_port;			// Port number
-	wxString	m_debugPort;	// Port number for debugger connection
-	int		    m_sslMode;		// SSL Mode
-	wxString	m_applicationName;	// Application name, only on 9.0
-};
-
-#endif
diff --git a/pgadmin/include/debugger/dbgConst.h b/pgadmin/include/debugger/dbgConst.h
index d8b6e9e..5075616 100644
--- a/pgadmin/include/debugger/dbgConst.h
+++ b/pgadmin/include/debugger/dbgConst.h
@@ -18,16 +18,63 @@
 #ifndef DBGCONST_H
 #define DBGCONST_H
 
-const int 	ID_BTNNEXT	   = 1800;
-const int  	ID_GRDFUNCARGS = 1810;
-const int  	ID_TXTMESSAGE  = 1820;
-const int  	ID_TIMER	   = 1830;
-const int  	ID_BTNCANCEL   = 1840;
+const int      ID_BTNNEXT     = 1800;
+const int      ID_GRDFUNCARGS = 1810;
+const int      ID_TXTMESSAGE  = 1820;
+const int      ID_TIMER       = 1830;
+const int      ID_BTNCANCEL   = 1840;
 
-const int  	ID_PARAMGRID   = 1000;
-const int  	ID_VARGRID	   = 1001;
-const int 	ID_MSG_PAGE	   = 1002;
-const int	ID_PKGVARGRID  = 1003;
+const int      ID_PARAMGRID   = 1000;
+const int      ID_VARGRID     = 1001;
+const int      ID_MSG_PAGE    = 1002;
+const int      ID_PKGVARGRID  = 1003;
 
-#endif
+enum
+{
+	MENU_ID_EXECUTE = 10001,            // Execute command entered by user
+
+	MENU_ID_TOGGLE_BREAK,               // Set/Unset breakpoint
+	MENU_ID_CLEAR_ALL_BREAK,            // Clear all breakpoints
+	MENU_ID_CONTINUE,                   // Continue
+	MENU_ID_STEP_OVER,                  // Step over
+	MENU_ID_STEP_INTO,                  // Step into
+	MENU_ID_STOP,                       // Stop debugging
+
+	MENU_ID_START_DEBUGGING,            // Spawn a separate debugger process
+	MENU_ID_NOTICE_RECEIVED,            // NOTICE received from server
+	WINDOW_ID_STACK,                    // Tree-control window
+	WINDOW_ID_CONSOLE,                  // Console window
+	WINDOW_ID_TABS,                     // Tab window
+	WINDOW_ID_BREAKPOINTS,              // Breakpoints window
+	WINDOW_ID_RESULT_GRID,              // Results window
+	WINDOW_ID_COMMAND,                  // Command window
+	SOCKET_ID_DEBUG,                    // Debugger Socket ID
+
+	MENU_ID_VIEW_TOOLBAR,               // View menu options
+	MENU_ID_VIEW_STACKPANE,
+	MENU_ID_VIEW_OUTPUTPANE,
+	MENU_ID_VIEW_DEFAULTVIEW,
+
+	RESULT_ID_ATTACH_TO_PORT,           // Debugger - attach to port completed
+	RESULT_ID_BREAKPOINT,               // Debugger - breakpoint reached
+	RESULT_ID_GET_VARS,                 // Debugger - variable list complete
+	RESULT_ID_GET_STACK,                // Debugger - stack trace complete
+	RESULT_ID_GET_BREAKPOINTS,          // Debugger - breakpoint list complete
+	RESULT_ID_NEW_BREAKPOINT,           // Debugger - set breakpoint complete
+	RESULT_ID_NEW_BREAKPOINT_WAIT,      // Debugger - set breakpoint complete, wait for target progress
+	RESULT_ID_DEL_BREAKPOINT,           // Debugger - drop breakpoint complete
+	RESULT_ID_DEPOSIT_VALUE,            // Debugger - deposit value complete
+	RESULT_ID_ADD_BREAKPOINT,           // Debugger - target info received, now set a breakpoint
+	RESULT_ID_LISTENER_CREATED,         // Debugger - global listener created
+	RESULT_ID_TARGET_READY,             // Debugger - target session attached
+	RESULT_ID_LAST_BREAKPOINT,          // Debugger - last breakpoint created
+	RESULT_ID_ARGS_UPDATED,             // Debugger - Values are evaluated and been updated in the arguments
+	RESULT_ID_ARGS_UPDATE_ERROR,        // Debugger - Error while evaluateling the value for the arguments
 
+	RESULT_ID_DIRECT_TARGET_COMPLETE,   // DirectDebug - target function complete
+
+	ID_DEBUG_INITIALIZER               // Debugger - debug package initializer? checkbox
+
+};
+
+#endif
diff --git a/pgadmin/include/debugger/dbgDbResult.h b/pgadmin/include/debugger/dbgDbResult.h
deleted file mode 100644
index 77e2296..0000000
--- a/pgadmin/include/debugger/dbgDbResult.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgDbResult.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class dbgDbResult
-//
-//	This class is used to convert a PGresult (a query result set) into a wxEvent
-//  We create a dbgDbResult object whenever a result set arrives from the server
-//  and then we send that object (which is really a wxEvent) through the normal
-//  wxWidgets event handler mechanism.
-//
-//  The arrival of a result set thus becomes a wxEvent.  We create dbgDbResult
-//  objects in dbgPgThread.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef DBGDBRESULT_H
-#define DBGDBRESULT_H
-
-#include <libpq-fe.h>
-
-BEGIN_DECLARE_EVENT_TYPES()
-DECLARE_EVENT_TYPE( dbgDBRESULT, wxID_HIGHEST + 1 )
-END_DECLARE_EVENT_TYPES()
-
-class dbgDbResult : public wxEvent
-{
-
-public:
-	dbgDbResult( PGresult *result ) : wxEvent( 0, dbgDBRESULT ), m_result( result ) { }
-
-	wxEvent   *Clone( void ) const
-	{
-		return( new dbgDbResult( *this ));
-	}
-	PGresult *getResult( void )
-	{
-		return( m_result );
-	}
-
-private:
-	PGresult	*m_result;
-};
-
-#endif
diff --git a/pgadmin/include/debugger/dbgPgConn.h b/pgadmin/include/debugger/dbgPgConn.h
deleted file mode 100644
index 31d5ce3..0000000
--- a/pgadmin/include/debugger/dbgPgConn.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgPgConn.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class dbgPgConn
-//
-//    A dbgPgConn object encapsulates the connection to a PostgreSQL server.  This
-//  class is a wrapper around a Pgconn that provides a convenient constructor
-//  and a few member functions.
-//
-//    This class doesn't do much - instead, the real work happens in a dbgPgThread
-//  (a separate thread) that initiates commands and processes result sets.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef DBGPGCONN_H
-#define DBGPGCONN_H
-
-#include <libpq-fe.h>
-
-#include "debugger/frmDebugger.h"
-#include "debugger/dbgPgThread.h"
-#include "debugger/dbgConnProp.h"
-
-enum DebuggerApiVersions
-{
-    DEBUGGER_UNKNOWN_API = 0,
-    DEBUGGER_V1_API = 1,
-    DEBUGGER_V2_API = 2,
-    DEBUGGER_V3_API = 3
-};
-
-class dbgPgParams
-{
-public:
-	int nParams;
-	Oid *paramTypes;
-	char **paramValues;
-	int *paramModes;
-};
-
-class dbgPgConn
-{
-public:
-
-	dbgPgConn( frmDebugger *frame,
-	           const wxString &server   = wxT( "" ),
-	           const wxString &database = wxT( "" ),
-	           const wxString &username = wxT( "" ),
-	           const wxString &password = wxT( "" ),
-	           const wxString &port     = wxT( "5432" ),
-	           int sslmode               = 0,
-	           const wxString &applicationname = wxT( "" ));
-
-	dbgPgConn( frmDebugger *frame, const dbgConnProp &props, bool startThread = true );
-
-	~dbgPgConn();
-
-	bool BackendMinimumVersion(int major, int minor);
-	bool EdbMinimumVersion(int major, int minor);
-	bool GetIsEdb();
-	bool GetIsGreenplum();
-	wxString qtDbString(const wxString &value);
-	DebuggerApiVersions DebuggerApiVersion();
-	wxString GetVersionString();
-	bool isConnected() const;               // Returns true if the connection attempt succeeded
-	const wxString  getName() const;        // Returns human-friendly name for this connection
-	const wxString  getHost() const;        // Returns the host-name (or IP address) for this connection
-	const wxString  getDatabase() const;    // Returns the name of the database that we're connected to
-	PGconn *getConnection();                // Returns the libpq connection handle
-	void Close();                           // Close this connection
-	void Cancel();                          // Cancel any ongoing queries
-
-	void startCommand( const wxString &command, wxEvtHandler *caller, wxEventType eventType = wxEVT_NULL, dbgPgParams *params = NULL );     // Starts executing a command
-	void setNoticeHandler( PQnoticeProcessor handler, void *arg );  // Registers a NOTICE handler
-	PGresult *waitForCommand( const wxString &command );            // Starts a command and waits for completion
-
-private:
-
-	void Init( const wxString &server, const wxString &database, const wxString &userName, const wxString &password, const wxString &port, int sslmode, const wxString &applicationname, bool startThread );
-
-	PGconn *m_pgConn;               // libpq connection handler
-	dbgPgThread *m_workerThread;    // Worker thread (this thread interacts with the server)
-	frmDebugger *m_frame;
-	int m_minorVersion, m_majorVersion;
-	bool m_isEdb;
-	bool m_isGreenplum;
-	DebuggerApiVersions m_debuggerApiVersion;
-};
-
-#endif
diff --git a/pgadmin/include/debugger/dbgPgThread.h b/pgadmin/include/debugger/dbgPgThread.h
deleted file mode 100644
index e100133..0000000
--- a/pgadmin/include/debugger/dbgPgThread.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgPgThread.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class dbgPgThread
-//
-//    A dbgPgThread object encapsulates a separate execution thread that interacts
-//  with a PostgreSQL server.  We use a separate thread to keep the main thread
-//  (and thus the user interface) responsive while we're waiting for the server.
-//
-//    The startCommand() member function initiates a new command - this function
-//  is called by the UI thread. It stores the command text (and the caller) in
-//  the dbgPgThread object and then awakens the thread.  The dbgPgThread then sends
-//  the command string to the server and waits for a reply. When the reply (a
-//  result set) arrives from the server, the Entry() member function converts
-//  the result set (a Pgresult) into a wxEvent (specifically, a dbgDbResult) and
-//  posts that event to the UI thread's event queue.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef DBGPGTHREAD_H
-#define DBGPGTHREAD_H
-
-// #include "debugger/dbgPgConn.h"
-class dbgPgConn;
-class dbgPgParams;
-
-class dbgPgThreadCommand
-{
-public:
-	dbgPgThreadCommand( const wxString &command, wxEvtHandler *caller, wxEventType eventType = wxEVT_NULL, dbgPgParams *params = NULL ) : m_command( command ), m_caller( caller ), m_eventType( eventType ), m_params( params ) {};
-
-	wxString    &getCommand()
-	{
-		return m_command;
-	}
-	dbgPgParams *getParams()
-	{
-		return m_params;
-	}
-
-	wxEvtHandler    *getCaller()
-	{
-		return( m_caller );
-	}
-	wxEventType    getEventType()
-	{
-		return( m_eventType );
-	}
-
-private:
-	wxString    m_command;    // Text of the command we're supposed to execute
-	wxEvtHandler    *m_caller;    // Event handler that we post results to
-	wxEventType    m_eventType;    // Event to report when result set arrives
-	dbgPgParams *m_params;
-};
-
-WX_DECLARE_LIST( dbgPgThreadCommand, ThreadCommandList );
-
-class dbgPgThread : public wxThread
-{
-
-public:
-	dbgPgThread(dbgPgConn &owner);
-
-	virtual void *Entry();
-	void startCommand( const wxString &command, wxEvtHandler *caller, wxEventType eventType = wxEVT_NULL, dbgPgParams *params = NULL );
-	void Die();
-
-private:
-
-	static void noticeHandler( void *arg, const char *message );
-
-	dbgPgThreadCommand *getNextCommand();     // Grab next command from queue
-
-	dbgPgConn &m_owner;        // Connection to the PostgreSQL server
-	wxSemaphore m_queueCounter;        // Number of entries in queue (thread synchronizer)
-	wxMutex m_queueMutex;        // Mutex to serialize access to m_commandQueue
-	ThreadCommandList m_commandQueue;        // Queue of pending commands
-
-	dbgPgThreadCommand *m_currentCommand;    // Currently executing command
-	wxMBConv *conv;
-	long run;
-	bool die;
-};
-
-#endif
diff --git a/pgadmin/include/debugger/dbgResultset.h b/pgadmin/include/debugger/dbgResultset.h
deleted file mode 100644
index 4c8c392..0000000
--- a/pgadmin/include/debugger/dbgResultset.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin III - PostgreSQL Tools
-//
-// Copyright (C) 2002 - 2013, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-// dbgResultset.h - debugger
-//
-//////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-// class dbgResultset
-//
-//	A dbgResultset object encapsulates a result set produced by executing a
-//  database command. This class is a wrapper around a PGresult handle that
-//	provides a few convenient member functions.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef DBGRESULTSET_H
-#define DBGRESULTSET_H
-
-#include <libpq-fe.h>
-
-class dbgResultset
-{
-public:
-	dbgResultset( PGresult *handle );
-
-	const char	*getRawErrorMessage();	// Return error message as a char *
-	const wxString getErrorMessage();	// Return error message as a wxString
-	const wxString getString(int column, int row = 0);
-	const wxString getString(const wxString &columnName, int row = 0);
-	long	getLong(int column, int row = 0);
-	long	getLong(const wxString &columnName, int row = 0);
-	bool	getBool(int column, int row = 0);
-	bool	getBool(const wxString &columnName, int row = 0);
-	int	getRowCount()
-	{
-		return(PQntuples( m_handle));
-	}
-	bool	columnExists(const wxString &columnname);
-
-	ExecStatusType getCommandStatus();
-
-private:
-
-	PGresult *m_handle;
-
-};
-#endif
diff --git a/pgadmin/include/debugger/dbgTargetInfo.h b/pgadmin/include/debugger/dbgTargetInfo.h
index 5649513..ece98a4 100644
--- a/pgadmin/include/debugger/dbgTargetInfo.h
+++ b/pgadmin/include/debugger/dbgTargetInfo.h
@@ -11,57 +11,103 @@
 #ifndef DBGTARGETINFO_H
 #define DBGTARGETINFO_H
 
+#include <wx/wx.h>
+#include "db/pgConn.h"
+#include "db/pgQueryThread.h"
+
+
 ////////////////////////////////////////////////////////////////////////////////
-// class wsArgInfo
+// class dbgArgInfo
 //
-//	A wsArgInfo object contains information about a function (or procedure)
+//	A dbgArgInfo object contains information about a function (or procedure)
 //  argument.  Inside of each wsArgInfo object, we store the name of the argument,
 //	the argument type, and the argument mode (IN (i), OUT (o), or INOUT (b)).
 //
 //	Once the user has had a chance to enter values for each of the IN and INOUT
 //	arguments, we store those values inside of the corresponding wsArgInfo objects
-
-class wsArgInfo
+class dbgArgInfo
 {
 public:
-	wsArgInfo( const wxString &argName, const wxString &argType, const wxString &argMode, const wxString &argTypeOid );
+	dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid,
+	           short _mode = pgParam::PG_PARAM_IN);
 
-	const wxString &getName()
+	Oid             GetType()
 	{
-		return m_name;
+		return m_typeOid;
 	}
-	const wxString &getType()
+	const wxString &GetTypeName()
 	{
 		return m_type;
 	}
-	const wxString &getMode()
+	wxString       &GetName()
+	{
+		return m_name;
+	}
+	short           GetMode()
 	{
 		return m_mode;
 	}
-	const Oid getTypeOid()
+	bool            IsArray()
 	{
-		return m_typeOid;
+		return !(m_baseType.IsEmpty());
+	}
+	const wxString &GetBaseType()
+	{
+		return m_baseType;
+	}
+	bool           &Null()
+	{
+		return m_null;
+	}
+	wxString       &Value()
+	{
+		return m_val;
+	}
+
+	void            SetDefault(const wxString &val)
+	{
+		m_hasDefault = true;
+		m_defValue = val;
 	}
-	wxString &getValue()
+	wxString       &Default()
 	{
-		return m_value;    // NOTE: non-const, caller may modifiy value
+		return m_defValue;
 	}
-	const wxString   quoteValue();
-	bool isValidDefVal( const wxString defvalue );
-	void  setValue( const wxString &newValue )
+	bool            HasDefault()
 	{
-		m_value = newValue;
+		return m_hasDefault;
 	}
+	bool           &UseDefault()
+	{
+		return m_useDefault;
+	}
+
+	pgParam *GetParam(wxMBConv *_conv = NULL);
 
 private:
-	wxString	m_name;
-	wxString	m_type;
-	wxString	m_mode;
-	wxString	m_value;
-	Oid         m_typeOid;
+	dbgArgInfo(const dbgArgInfo &_arg)
+	{
+		wxASSERT(0);
+	}
+
+	dbgArgInfo &operator= (const dbgArgInfo &)
+	{
+		wxASSERT(0);
+	}
+
+	wxString   m_name;       /* Name of the argument */
+	wxString   m_type;       /* Type of the argument */
+	wxString   m_baseType;   /* Base type of an array type */
+	wxString   m_defValue;   /* Default Value */
+	Oid        m_typeOid;    /* OID of Type */
+	short      m_mode;       /* IN, IN OUT, OUT, or VARAIDIC */
+	bool       m_hasDefault; /* Has the default value? */
+	bool       m_useDefault; /* Use the default value? */
+	bool       m_null;       /* Is Value NULL */
+	wxString   m_val;        /* Value */
 };
 
-WX_DECLARE_OBJARRAY(wsArgInfo, wsArgInfoArray);
+WX_DEFINE_ARRAY_PTR(dbgArgInfo *, pgDbgArgs);
 
 ////////////////////////////////////////////////////////////////////////////////
 // class dbgTargetInfo
@@ -82,95 +128,120 @@ WX_DECLARE_OBJARRAY(wsArgInfo, wsArgInfoArray);
 //
 //	This class offers a number of (inline) member functions that you can call
 //  to extract the above information after it's been queried from the server.
-
-class dbgPgConn;
-
+//
 class dbgTargetInfo
 {
 public:
-	dbgTargetInfo( const wxString &target, dbgPgConn *conn, char targetType );
+	dbgTargetInfo(Oid _target, pgConn *_conn);
 
-	int	getArgInCount()
+	const wxString &GetQualifiedName()
 	{
-		return( m_argInCount );
+		return m_fqName;
 	}
-	int 	getArgOutCount()
+
+	const wxString &GetLanguage()
 	{
-		return( m_argOutCount );
+		return m_language;
 	}
-	int 	getArgInOutCount()
+
+	const wxString &GetPackageName()
 	{
-		return( m_argInOutCount );
+		return m_package;
 	}
-	int	getArgCount()
+	const wxString &GetSchemaName()
 	{
-		return( m_argInCount + m_argOutCount + m_argInOutCount );
+		return m_schema;
 	}
 
-	const wxString &getLanguage()
+	const wxString &GetName()
 	{
-		return( m_language );
+		return m_name;
 	}
-	const wxString &getSchema()
+
+	const wxString &GetReturnType()
 	{
-		return( m_schema );
+		return m_returnType;
 	}
-	const wxString &getName()
+
+	long GetOid()
 	{
-		return( m_name );
+		return m_oid;
 	}
-	const wxString &getFQName()
+
+	long GetPkgOid()
 	{
-		return( m_fqName );
+		return m_pkgOid;
 	}
-	const wxString &getReturnType()
+
+	long GetSchemaOid()
 	{
-		return( m_returnType );
+		return m_schemaOid;
 	}
-	long	getOid()
+
+	long GetPkgInitOid()
 	{
-		return( m_oid );
+		return m_pkgInitOid;
 	}
-	long	getPkgOid()
+
+	bool GetIsFunction()
 	{
-		return( m_pkgOid );
+		return m_isFunction;
 	}
-	long	getPkgInitOid()
+
+	bool GetReturnsSet()
 	{
-		return( m_pkgInitOid );
+		return m_returnsSet;
 	}
-	bool	getIsFunction()
+
+	bool RequireUserInput()
 	{
-		return( m_isFunction );
+		return ((m_pkgOid != 0 && m_pkgInitOid != 0) || m_inputParamCnt != 0);
 	}
-	bool	getReturnsSet()
+
+	bool &DebugPackageConstructor()
 	{
-		return( m_returnsSet );
+		return m_debugPkgCon;
 	}
 
-	wsArgInfo &operator[]( int index );
+	dbgArgInfo *operator[](int index);
+
+	pgDbgArgs *GetArgs()
+	{
+		return m_args;
+	}
+
+	bool HasVariadic()
+	{
+		return m_hasVariadic;
+	}
+
+	bool AddForExecution(pgQueryThread *_thread);
 
 private:
-	wxString	m_name;		 // Target name (function or procedure)
-	wxString	m_schema;	 // Schema in which target resides
-	wxString	m_language;	 // Language in which target is defined
-	wxString	m_argNames;	 // Argument names
-	wxString	m_argModes;	 // Argument modes
-	wxString	m_argTypes;	 // Argument types
-	wxString	m_argTypeOids; // Argument type OIDs
-	wxString	m_argDefVals;  // Argument default values
-	wxString	m_fqName;	 // Fully-qualified name (schema.package.func or package.func)
-	wxString    m_returnType;// Return type
-	bool	m_isFunction;	 // true->target is a function, false->target is a procedure
-	bool    m_returnsSet;    // Returns a set?
-	int	m_argInCount;	 // Number of IN arguments
-	int	m_argOutCount;	 // Number of OUT arguments
-	int	m_argInOutCount; // Number of INOUT arguments
-	long	m_oid;		 // Target function/procedure OID
-	long	m_pkgOid;	 // Package in which target defined (if non-zero)
-	long    m_pkgInitOid; // OID of the package initializer function.
-	wsArgInfoArray	m_argInfo;
+	wxString   m_name;          // Target name (function or procedure)
+	wxString   m_schema;        // Schema in which target resides
+	wxString   m_package;       // Package in which target resides
+	wxString   m_language;      // Language in which target is defined
+
+	wxString   m_returnType;    // Return type
+	wxString   m_funcSignature; // Function Signature
+
+	wxString   m_fqName;        // Function qualified name
+
+	bool       m_isFunction;    // true->target is a function, false->target is a procedure
+	bool       m_returnsSet;    // Returns a set?
+	bool       m_hasVariadic;   // Has the variadic argument
+
+	bool       m_debugPkgCon;    // Debug Package Constructor
+
+	long       m_oid;           // Target function/procedure OID
+	long       m_pkgOid;        // Package in which target defined (if non-zero)
+	long       m_pkgInitOid;    // OID of the package initializer function.
+	long       m_schemaOid;     // OID of the schema
+
+	size_t     m_inputParamCnt; // IN/IN OUT parameter count
 
+	pgDbgArgs *m_args;          // Function arguments
 };
 
 #endif
diff --git a/pgadmin/include/debugger/dlgDirectDbg.h b/pgadmin/include/debugger/dlgDirectDbg.h
index d44ff2d..cd15e3a 100644
--- a/pgadmin/include/debugger/dlgDirectDbg.h
+++ b/pgadmin/include/debugger/dlgDirectDbg.h
@@ -27,71 +27,98 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-#ifndef DBGDIRECT_H
-#define DBGDIRECT_H
+#ifndef DLGDIRECTDBG_H
+#define DLGDIRECTDBG_H
+
+#include <wx/wx.h>
+#include <wx/grid.h>
+#include <wx/strconv.h>
 
 #include "dlg/dlgClasses.h"
-#include "debugger/dbgBreakPoint.h"
-#include "debugger/dbgConnProp.h"
-#include "debugger/frmDebugger.h"
 
-class dbgTargetInfo;
-class dbgPgConn;
-class ctlCodeWindow;
+class dbgArgInfo;
+class frmDebugger;
+class dbgController;
 
-class dlgDirectDbg : public pgDialog
+class ctlGridCellBoolEditor : public wxGridCellBoolEditor
 {
-	DECLARE_CLASS( dlgDirectDbg )
-
 public:
+	ctlGridCellBoolEditor(dbgArgInfo *_arg = NULL);
+	void BeginEdit (int _row, int _col, wxGrid *_grid);
+	wxGridCellEditor *Clone() const;
 
-	dlgDirectDbg( frmDebugger *parent, wxWindowID id, const dbgConnProp &connProp );
-	dbgBreakPointList &getBreakpointList();
-	void setupParamWindow();
-	bool startDebugging();
-	bool GetCancelled()
+	dbgArgInfo *GetArg()
 	{
-		return m_cancelled;
-	};
+		return m_arg;
+	}
 
 private:
+	dbgArgInfo *m_arg;
+};
+
+class dlgDirectDbg;
+
+class dbgArgValueEvaluator : public wxThread
+{
+public:
+	dbgArgValueEvaluator(pgConn *, dlgDirectDbg *);
+
+	void *Entry();
+	void  CancelEval();
+	static void NoticeHandler(void *, const char *);
+
+private:
+	pgConn       *m_conn;
+	dlgDirectDbg *m_dlg;
+
+	bool          m_cancelled;
+};
+
+
+class dlgDirectDbg : public pgDialog
+{
+	DECLARE_CLASS(dlgDirectDbg)
+
+public:
+	dlgDirectDbg(frmDebugger *_parent, dbgController *_controller,
+	             pgConn *_conn);
 
 	enum
 	{
-	    COL_NAME = 0,	// Column 0 contains the variable name
-	    COL_TYPE,	// This column contains the variable type
-	    COL_VALUE	// This column contains the variable value
+		COL_NAME = 0, // Column 0 contains the variable name
+		COL_TYPE,     // Type of column
+		COL_NULL,     // Value Set to NULL (yes/no)
+		COL_EXPR,     // Value is an expression (yes/no)
+		COL_VALUE,    // Value (constant ,or an expression)
+		COL_USE_DEF,  // Use the default value
+		COL_DEF_VAL   // Default value for the column
 	};
 
-	wxString	m_target;	// Target name (function/procedure signature or OID)
-	bool		m_isFunc;
-	const dbgConnProp &m_connProp;	// Connection properties (used to connect to the server)
-	dbgTargetInfo     *m_targetInfo;	// Detailed information about the target (like argument types, name, ...)
-	dbgPgConn         *m_conn;		// The connection to the server
-	ctlCodeWindow     *m_codeWindow;		// A pointer to the debugger window that we'll create
-	dbgBreakPointList m_breakpoints;		// List of initial breakpoints to create
-	frmDebugger		 *m_parent;
-	bool m_cancelled;
-
-	bool loadTargetInfo( const wxString &target, const dbgConnProp &connProp, char targetType );
-	void populateParamGrid();
-	void OnOk( wxCommandEvent &event );
-	void OnCancel( wxCommandEvent &event );
-	void OnClose( wxCloseEvent &event );
-	void OnTargetComplete( wxCommandEvent &event );
-	void OnDebug( wxCommandEvent &event );
-	void OnNoticeReceived( wxCommandEvent &event );
-	bool activateDebugger( );
-
-	void saveSettings();
-	void loadSettings();
-	void setBreakpoint( long pkgOid, long funcOid );
-	void invokeTarget();
-	void invokeTargetCallable();
-	void invokeTargetStatement();
+private:
 
-	DECLARE_EVENT_TABLE()
+	void PopulateParamGrid();
 
+	void OnOk(wxCommandEvent &event);
+	void OnCancel(wxCommandEvent &event);
+	void OnClickGridLabel(wxGridEvent &event);
+
+	void ResultArgsUpdated(wxCommandEvent &);
+	void ResultArgsUpdateError(wxCommandEvent &);
+
+	void SaveSettings();
+	void LoadSettings();
+	void LoadLastCellSetting(int row_number, int array_row_number, int index_number, bool isArray); // Function to retrive last cell value if the provieded parameter value is an invalid.
+
+	wxGrid *GetParamsGrid();
+	bool DebugPkgConstructor();
+
+	dbgController        *m_controller;
+	pgConn               *m_conn;
+	dbgArgValueEvaluator *m_thread;
+
+	friend class dbgArgValueEvaluator;
+
+	DECLARE_EVENT_TABLE()
 };
 
 #endif
diff --git a/pgadmin/include/debugger/frmDebugger.h b/pgadmin/include/debugger/frmDebugger.h
index 11c444f..0c7801a 100644
--- a/pgadmin/include/debugger/frmDebugger.h
+++ b/pgadmin/include/debugger/frmDebugger.h
@@ -24,11 +24,7 @@
 #define FRMDEBUGGER_H
 
 #include <wx/aui/aui.h>
-
-#include "ctl/ctlSQLBox.h"
-#include "frm/frmMain.h"
-#include "debugger/dbgConnProp.h"
-#include "debugger/ctlTabWindow.h"
+#include <wx/progdlg.h>
 
 //
 // This number MUST be incremented if changing any of the default perspectives
@@ -45,113 +41,139 @@
 #endif
 #endif
 
-enum
-{
-    MENU_ID_EXECUTE = 10001,            // Execute command entered by user
-
-    MENU_ID_TOGGLE_BREAK,               // Set/Unset breakpoint
-    MENU_ID_CLEAR_ALL_BREAK,            // Clear all breakpoints
-    MENU_ID_CONTINUE,                   // Continue
-    MENU_ID_STEP_OVER,                  // Step over
-    MENU_ID_STEP_INTO,                  // Step into
-    MENU_ID_STOP,                       // Stop debugging
-
-    MENU_ID_SPAWN_DEBUGGER,             // Spawn a separate debugger process
-    MENU_ID_NOTICE_RECEIVED,            // NOTICE received from server
-    WINDOW_ID_STACK,                    // Tree-control window
-    WINDOW_ID_CONSOLE,                  // Console window
-    WINDOW_ID_TABS,                     // Tab window
-    WINDOW_ID_BREAKPOINTS,              // Breakpoints window
-    WINDOW_ID_RESULT_GRID,              // Results window
-    WINDOW_ID_COMMAND,                  // Command window
-    SOCKET_ID_DEBUG,                    // Debugger Socket ID
-
-    MENU_ID_VIEW_TOOLBAR,               // View menu options
-    MENU_ID_VIEW_STACKPANE,
-    MENU_ID_VIEW_OUTPUTPANE,
-    MENU_ID_VIEW_DEFAULTVIEW,
-
-    RESULT_ID_ATTACH_TO_PORT,           // Debugger - attach to port completed
-    RESULT_ID_BREAKPOINT,               // Debugger - breakpoint reached
-    RESULT_ID_GET_VARS,                 // Debugger - variable list complete
-    RESULT_ID_GET_STACK,                // Debugger - stack trace complete
-    RESULT_ID_GET_BREAKPOINTS,          // Debugger - breakpoint list complete
-    RESULT_ID_GET_SOURCE,               // Debugger - source code listing complete
-    RESULT_ID_NEW_BREAKPOINT,           // Debugger - set breakpoint complete
-    RESULT_ID_NEW_BREAKPOINT_WAIT,      // Debugger - set breakpoint complete, wait for target progress
-    RESULT_ID_DEL_BREAKPOINT,           // Debugger - drop breakpoint complete
-    RESULT_ID_DEPOSIT_VALUE,            // Debugger - deposit value complete
-    RESULT_ID_ABORT_TARGET,             // Debugger - abort target (cancel function)
-    RESULT_ID_ADD_BREAKPOINT,           // Debugger - target info received, now set a breakpoint
-    RESULT_ID_LISTENER_CREATED,         // Debugger - global listener created
-    RESULT_ID_TARGET_READY,             // Debugger - target session attached
-    RESULT_ID_LAST_BREAKPOINT,          // Debugger - last breakpoint created
-
-    RESULT_ID_DIRECT_TARGET_COMPLETE,   // DirectDebug - target function complete
-
-    ID_DEBUG_INITIALIZER,               // Debugger - debug package initializer? checkbox
-};
-
+// Debugger Controller
+class dbgController;
+class frmMain;
+class ctlTabWindow;
 class ctlResultGrid;
 class ctlVarWindow;
-class ctlCodeWindow;
-class dlgDirectDbg;
-class wxSizeReportCtrl;
+class ctlSQLBox;
+class dbgCachedStack;
 
 class frmDebugger : public pgFrame
 {
-	DECLARE_CLASS( frmDebugger )
+	DECLARE_CLASS(frmDebugger)
 
 public:
-	frmDebugger(frmMain *parent, const wxString &title);
+	frmDebugger(frmMain *_parent, dbgController *_controller,
+	            const wxString &_title);
 	virtual ~frmDebugger();
 
-	dlgDirectDbg   *addDirectDbg( const dbgConnProp &connProp );        // Create a new direct-debugging window
-	ctlCodeWindow  *addDebug( const dbgConnProp &props );               // Create a new debugger window
-	wxStatusBar   *getStatusBar()
+	void SetupDebugger();
+
+	void SetStatusText(const wxString &_status);
+
+	ctlTabWindow *GetTabWindow()
 	{
-		return( m_statusBar );    // Returns pointer to the status bar
+		return m_tabWindow;
+	}
+	ctlStackWindow *GetStackWindow()
+	{
+		return m_stackWindow;
+	}
+	ctlMessageWindow *GetMessageWindow()
+	{
+		return m_tabWindow->GetMessageWindow();
 	}
 
-	wxMenuBar     *m_menuBar;       // Menu bar
-	ctlMenuToolbar     *m_toolBar;       // Frames' toolbar
-	wxMenu        *m_viewMenu;      // View menu (can be modified by wxCodeWindow)
-	wxMenu        *m_debugMenu;     // Debug menu (can be modified by wxCodeWindow)
+	ctlVarWindow *GetVarWindow(bool create)
+	{
+		return m_tabWindow->GetVarWindow(create);
+	}
+	ctlVarWindow *GetParamWindow(bool create)
+	{
+		return m_tabWindow->GetParamWindow(create);
+	}
+	ctlVarWindow *GetPkgVarWindow(bool create)
+	{
+		return m_tabWindow->GetPkgVarWindow(create);
+	}
+	ctlResultGrid *GetResultWindow()
+	{
+		return m_tabWindow->GetResultWindow();
+	}
+
+	void           DisplaySource(dbgCachedStack &);
 
-	wxAuiManager manager;
-	ctlCodeWindow   *m_standaloneDebugger;      // Standalone debugger window
-	dlgDirectDbg    *m_standaloneDirectDbg;     // Standalone direct debugger
+	void EnableToolsAndMenus(bool enable = true);
+	void UnhilightCurrentLine();
+	void HighlightLine(int _lineNo);
+	void ClearBreakpointMarkers();
+	void MarkBreakpoint(int lineNo);
+	void CloseProgressBar();
+	void LaunchWaitingDialog(const wxString &msg = wxEmptyString);
 
 private:
-	wxStatusBar    *m_statusBar;    // Frame's status bar
 
-	wxMenuBar    *setupMenuBar( void );
-	ctlMenuToolbar    *setupToolBar( void );
-	wxStatusBar  *setupStatusBar( void );
+	int  GetLineNo();
+	bool IsBreakpoint(int _lineNo);
+	void ClearAllBreakpoints();
 
-	frmMain *m_parent;
+	wxMenuBar      *SetupMenuBar( void );
+	ctlMenuToolbar *SetupToolBar( void );
+	wxStatusBar    *SetupStatusBar( void );
+
+	enum
+	{
+		MARKER_CURRENT    = 0x02,       // Current line marker
+		MARKER_CURRENT_BG = 0x04,       // Current line marker - background hilight
+		MARKER_BREAKPOINT = 0x01,       // Breakpoint marker
+	};
 
-	DECLARE_EVENT_TABLE()
 
-	void OnExecute( wxCommandEvent &event );
-	void OnDebugCommand( wxCommandEvent &event );
-	void OnSelectFrame( wxCommandEvent &event );
-	void OnMarginClick( wxStyledTextEvent &event );     // Set/clear breakpoint on margin click
-	void OnPositionStc( wxStyledTextEvent &event );
-	void OnVarChange( wxGridEvent &event );
-	void OnClose( wxCloseEvent &event );
-	void OnExit( wxCommandEvent &event );
-	void OnSize( wxSizeEvent &event );
-	void OnEraseBackground(wxEraseEvent &event);
-	void OnHelp(wxCommandEvent &event);
-	void OnContents(wxCommandEvent &event);
-
-	void OnToggleToolBar(wxCommandEvent &event);
-	void OnToggleStackPane(wxCommandEvent &event);
-	void OnToggleOutputPane(wxCommandEvent &event);
-	void OnAuiUpdate(wxAuiManagerEvent &event);
-	void OnDefaultView(wxCommandEvent &event);
+private:
+	// Menu bar
+	wxMenuBar      *m_menuBar;
+	// Frames' toolbar
+	ctlMenuToolbar *m_toolBar;
+	// View menu (can be modified by wxCodeWindow)
+	wxMenu         *m_viewMenu;
+	// Debug menu (can be modified by wxCodeWindow)
+	wxMenu         *m_debugMenu;
+
+	wxAuiManager    m_manager;
+	// Frame's status bar
+	wxStatusBar    *m_statusBar;
+	// Main Frame
+	frmMain        *m_parent;
+	// Debugger Controller
+	dbgController  *m_controller;
+
+	// Stack Window
+	ctlStackWindow *m_stackWindow;
+	// Tab Window
+	ctlTabWindow   *m_tabWindow;
+	// Function Code Viewer
+	ctlSQLBox      *m_codeViewer;
+	// Timer
+	wxTimer         m_timer;
+	// "Waiting for target" dialog
+	wxProgressDialog *m_progressBar;
+
+	DECLARE_EVENT_TABLE()
 
+	// Idle processor
+	void OnTimer(wxTimerEvent &_ev);
+
+	void OnExecute(wxCommandEvent &_ev);
+	void OnDebugCommand(wxCommandEvent &_ev);
+	void OnSelectFrame(wxCommandEvent &_ev);
+	// Toggle break-point on margin click
+	void OnMarginClick(wxStyledTextEvent &_ev);
+	void OnPositionStc(wxStyledTextEvent &_ev);
+	void OnVarChange(wxGridEvent &_ev);
+	void OnClose(wxCloseEvent &_ev);
+	void OnExit(wxCommandEvent &_ev);
+	void OnSize(wxSizeEvent &_ev);
+	void OnEraseBackground(wxEraseEvent &_ev);
+	void OnHelp(wxCommandEvent &_ev);
+	void OnContents(wxCommandEvent &_ev);
+
+	void OnToggleToolBar(wxCommandEvent &_ev);
+	void OnToggleStackPane(wxCommandEvent &_ev);
+	void OnToggleOutputPane(wxCommandEvent &_ev);
+	void OnAuiUpdate(wxAuiManagerEvent &_ev);
+	void OnDefaultView(wxCommandEvent &_ev);
 };
 
 #endif
diff --git a/pgadmin/include/debugger/module.mk b/pgadmin/include/debugger/module.mk
index 1ce5bce..9dc8ad6 100644
--- a/pgadmin/include/debugger/module.mk
+++ b/pgadmin/include/debugger/module.mk
@@ -10,19 +10,15 @@
 #######################################################################
 
 pgadmin3_SOURCES += \
-	include/debugger/ctlCodeWindow.h \
+	include/debugger/dbgController.h \
+	include/debugger/dbgModel.h \
 	include/debugger/ctlMessageWindow.h \
 	include/debugger/ctlResultGrid.h \
 	include/debugger/ctlStackWindow.h \
 	include/debugger/ctlTabWindow.h \
 	include/debugger/ctlVarWindow.h \
 	include/debugger/dbgBreakPoint.h \
-	include/debugger/dbgConnProp.h \
 	include/debugger/dbgConst.h \
-	include/debugger/dbgDbResult.h \
-	include/debugger/dbgPgConn.h \
-	include/debugger/dbgPgThread.h \
- 	include/debugger/dbgResultset.h \
 	include/debugger/dbgTargetInfo.h \
  	include/debugger/debugger.h \
 	include/debugger/dlgDirectDbg.h \
diff --git a/pgadmin/include/frm/frmQuery.h b/pgadmin/include/frm/frmQuery.h
index 1f35a78..a5cd06a 100644
--- a/pgadmin/include/frm/frmQuery.h
+++ b/pgadmin/include/frm/frmQuery.h
@@ -13,6 +13,7 @@
 #define __FRM_QUERY_H
 
 #include "ctl/ctlAuiNotebook.h"
+#include "db/pgQueryResultEvent.h"
 #include "dlg/dlgClasses.h"
 #include "gqb/gqbViewController.h"
 #include "gqb/gqbModel.h"
@@ -222,7 +223,7 @@ private:
 	void OpenLastFile();
 	void updateMenu(bool allowUpdateModelSize = true);
 	void execQuery(const wxString &query, int resultToRetrieve = 0, bool singleResult = false, const int queryOffset = 0, bool toFile = false, bool explain = false, bool verbose = false);
-	void OnQueryComplete(wxCommandEvent &ev);
+	void OnQueryComplete(pgQueryResultEvent &ev);
 	void completeQuery(bool done, bool explain, bool verbose);
 	void OnScriptComplete(wxCommandEvent &ev);
 	void setTools(const bool running);
diff --git a/pgadmin/include/precomp.h b/pgadmin/include/precomp.h
index 3040ebd..3defe6c 100644
--- a/pgadmin/include/precomp.h
+++ b/pgadmin/include/precomp.h
@@ -46,21 +46,18 @@
 
 #include "db/pgConn.h"
 #include "db/pgQueryThread.h"
+#include "db/pgQueryResultEvent.h"
 #include "db/pgSet.h"
 
-#include "debugger/ctlCodeWindow.h"
 #include "debugger/ctlMessageWindow.h"
 #include "debugger/ctlResultGrid.h"
 #include "debugger/ctlStackWindow.h"
 #include "debugger/ctlTabWindow.h"
 #include "debugger/ctlVarWindow.h"
 #include "debugger/dbgBreakPoint.h"
-#include "debugger/dbgConnProp.h"
 #include "debugger/dbgConst.h"
-#include "debugger/dbgDbResult.h"
-#include "debugger/dbgPgConn.h"
-#include "debugger/dbgPgThread.h"
-#include "debugger/dbgResultset.h"
+#include "debugger/dbgController.h"
+#include "debugger/dbgModel.h"
 #include "debugger/dbgTargetInfo.h"
 #include "debugger/debugger.h"
 #include "debugger/dlgDirectDbg.h"
diff --git a/pgadmin/pgAdmin3.vcxproj b/pgadmin/pgAdmin3.vcxproj
index 521b1e1..5a1800c 100644
--- a/pgadmin/pgAdmin3.vcxproj
+++ b/pgadmin/pgAdmin3.vcxproj
@@ -1007,17 +1007,15 @@
       </PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="utils\utffile.cpp" />
-    <ClCompile Include="debugger\ctlCodeWindow.cpp" />
     <ClCompile Include="debugger\ctlMessageWindow.cpp" />
     <ClCompile Include="debugger\ctlResultGrid.cpp" />
     <ClCompile Include="debugger\ctlStackWindow.cpp" />
     <ClCompile Include="debugger\ctlTabWindow.cpp" />
     <ClCompile Include="debugger\ctlVarWindow.cpp" />
     <ClCompile Include="debugger\dbgBreakPoint.cpp" />
-    <ClCompile Include="debugger\dbgDbResult.cpp" />
-    <ClCompile Include="debugger\dbgPgConn.cpp" />
-    <ClCompile Include="debugger\dbgPgThread.cpp" />
-    <ClCompile Include="debugger\dbgResultset.cpp" />
+    <ClCompile Include="debugger\dbgController.cpp" />
+    <ClCompile Include="debugger\dbgEvents.cpp" />
+    <ClCompile Include="debugger\dbgModel.cpp" />
     <ClCompile Include="debugger\dbgTargetInfo.cpp" />
     <ClCompile Include="debugger\debugger.cpp" />
     <ClCompile Include="debugger\dlgDirectDbg.cpp" />
@@ -1689,20 +1687,17 @@
     <ClInclude Include="include\schema\pgView.h" />
     <ClInclude Include="include\db\pgConn.h" />
     <ClInclude Include="include\db\pgQueryThread.h" />
+    <ClInclude Include="include\db\pgQueryResultEvent.h" />
     <ClInclude Include="include\db\pgSet.h" />
-    <ClInclude Include="include\debugger\ctlCodeWindow.h" />
     <ClInclude Include="include\debugger\ctlMessageWindow.h" />
     <ClInclude Include="include\debugger\ctlResultGrid.h" />
     <ClInclude Include="include\debugger\ctlStackWindow.h" />
     <ClInclude Include="include\debugger\ctlTabWindow.h" />
     <ClInclude Include="include\debugger\ctlVarWindow.h" />
     <ClInclude Include="include\debugger\dbgBreakPoint.h" />
-    <ClInclude Include="include\debugger\dbgConnProp.h" />
     <ClInclude Include="include\debugger\dbgConst.h" />
-    <ClInclude Include="include\debugger\dbgDbResult.h" />
-    <ClInclude Include="include\debugger\dbgPgConn.h" />
-    <ClInclude Include="include\debugger\dbgPgThread.h" />
-    <ClInclude Include="include\debugger\dbgResultset.h" />
+    <ClInclude Include="include\debugger\dbgController.h" />
+    <ClInclude Include="include\debugger\dbgModel.h" />
     <ClInclude Include="include\debugger\dbgTargetInfo.h" />
     <ClInclude Include="include\debugger\debugger.h" />
     <ClInclude Include="include\debugger\dlgDirectDbg.h" />
@@ -2239,4 +2234,4 @@
   <ImportGroup Label="ExtensionTargets">
     <Import Project="..\pgAdmin3.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/pgadmin/pgAdmin3.vcxproj.filters b/pgadmin/pgAdmin3.vcxproj.filters
index 252589b..66f021b 100644
--- a/pgadmin/pgAdmin3.vcxproj.filters
+++ b/pgadmin/pgAdmin3.vcxproj.filters
@@ -823,7 +823,13 @@
     <ClCompile Include="utils\utffile.cpp">
       <Filter>utils</Filter>
     </ClCompile>
-    <ClCompile Include="debugger\ctlCodeWindow.cpp">
+    <ClCompile Include="debugger\dbgController.cpp">
+      <Filter>debugger</Filter>
+    </ClCompile>
+    <ClCompile Include="debugger\dbgEvents.cpp">
+      <Filter>debugger</Filter>
+    </ClCompile>
+    <ClCompile Include="debugger\dbgModel.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
     <ClCompile Include="debugger\ctlMessageWindow.cpp">
@@ -844,18 +850,6 @@
     <ClCompile Include="debugger\dbgBreakPoint.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
-    <ClCompile Include="debugger\dbgDbResult.cpp">
-      <Filter>debugger</Filter>
-    </ClCompile>
-    <ClCompile Include="debugger\dbgPgConn.cpp">
-      <Filter>debugger</Filter>
-    </ClCompile>
-    <ClCompile Include="debugger\dbgPgThread.cpp">
-      <Filter>debugger</Filter>
-    </ClCompile>
-    <ClCompile Include="debugger\dbgResultset.cpp">
-      <Filter>debugger</Filter>
-    </ClCompile>
     <ClCompile Include="debugger\dbgTargetInfo.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
@@ -2702,9 +2696,6 @@
     <ClInclude Include="include\db\pgSet.h">
       <Filter>include\db</Filter>
     </ClInclude>
-    <ClInclude Include="include\debugger\ctlCodeWindow.h">
-      <Filter>include\debugger</Filter>
-    </ClInclude>
     <ClInclude Include="include\debugger\ctlMessageWindow.h">
       <Filter>include\debugger</Filter>
     </ClInclude>
@@ -2723,22 +2714,13 @@
     <ClInclude Include="include\debugger\dbgBreakPoint.h">
       <Filter>include\debugger</Filter>
     </ClInclude>
-    <ClInclude Include="include\debugger\dbgConnProp.h">
-      <Filter>include\debugger</Filter>
-    </ClInclude>
     <ClInclude Include="include\debugger\dbgConst.h">
       <Filter>include\debugger</Filter>
     </ClInclude>
-    <ClInclude Include="include\debugger\dbgDbResult.h">
-      <Filter>include\debugger</Filter>
-    </ClInclude>
-    <ClInclude Include="include\debugger\dbgPgConn.h">
-      <Filter>include\debugger</Filter>
-    </ClInclude>
-    <ClInclude Include="include\debugger\dbgPgThread.h">
+    <ClInclude Include="include\debugger\dbgController.h">
       <Filter>include\debugger</Filter>
     </ClInclude>
-    <ClInclude Include="include\debugger\dbgResultset.h">
+    <ClInclude Include="include\debugger\dbgModel.h">
       <Filter>include\debugger</Filter>
     </ClInclude>
     <ClInclude Include="include\debugger\dbgTargetInfo.h">
@@ -4307,4 +4289,4 @@
   <ItemGroup>
     <ResourceCompile Include="pgAdmin3.rc" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/pgadmin/ui/dlgDirectDbg.xrc b/pgadmin/ui/dlgDirectDbg.xrc
index b314fd0..bc3d991 100644
--- a/pgadmin/ui/dlgDirectDbg.xrc
+++ b/pgadmin/ui/dlgDirectDbg.xrc
@@ -2,7 +2,7 @@
 <resource>
   <object class="wxDialog" name="dlgDirectDbg">
     <title>View Data Options</title>
-    <size>300,265d</size>
+    <size>450,210d</size>
     <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER</style>
     <object class="wxFlexGridSizer">
       <cols>1</cols>
@@ -10,7 +10,7 @@
       <growablecols>0</growablecols>
       <object class="sizeritem">
         <object class="wxNotebook" name="nbNotebook">
-          <size>296,240d</size>
+          <size>400,180d</size>
           <selected>0</selected>
           <object class="notebookpage">
             <label>Properties</label>
@@ -58,7 +58,7 @@
           </object>
           <object class="sizeritem">
             <object class="wxButton" name="wxID_OK">
-              <label>&amp;OK</label>
+              <label>&amp;Debug</label>
               <tooltip>Accept the current options and close the dialogue.</tooltip>
               <default>1</default>
             </object>
diff --git a/pgadmin/ui/embed-xrc b/pgadmin/ui/embed-xrc
old mode 100755
new mode 100644
diff --git a/pgadmin/ui/xrcDialogs.cpp b/pgadmin/ui/xrcDialogs.cpp
index eb5eca0..13f9b63 100644
--- a/pgadmin/ui/xrcDialogs.cpp
+++ b/pgadmin/ui/xrcDialogs.cpp
@@ -3982,7 +3982,7 @@ static unsigned char xml_res_file_10[] = {
 62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,
 114,99,101,62,10};
 
-static size_t xml_res_size_11 = 3331;
+static size_t xml_res_size_11 = 3334;
 static unsigned char xml_res_file_11[] = {
 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101,
 110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62,
@@ -3991,7 +3991,7 @@ static unsigned char xml_res_file_11[] = {
 101,61,34,100,108,103,68,105,114,101,99,116,68,98,103,34,62,10,32,32,32,
 32,60,116,105,116,108,101,62,86,105,101,119,32,68,97,116,97,32,79,112,116,
 105,111,110,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,
-122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,
+122,101,62,52,53,48,44,50,49,48,100,60,47,115,105,122,101,62,10,32,32,32,
 32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,
 79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,
 89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,
@@ -4006,8 +4006,8 @@ static unsigned char xml_res_file_11[] = {
 122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,
 106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,
 111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,
-34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,
-50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,
+34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,48,48,44,
+49,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,
 60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,
 100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,
 108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,
@@ -4098,47 +4098,47 @@ static unsigned char xml_res_file_11[] = {
 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,
 99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,
 101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,
-32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,
-98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,
-108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117,114,114,
-101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,32,99,108,111,
-115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,
-111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,
-100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,
-32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,
-32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,
-65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,
-32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,
-101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,
-62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,
+32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,101,98,117,103,
+60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+60,116,111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,
+99,117,114,114,101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,
+32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,
+46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,
+108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,
+99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,
+120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,
+32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,
+98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,
+106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,
+116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,
+10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,
+97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,
+34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,
+32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,
+101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110,
+121,32,99,104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32,
+116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108,
+116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,
+101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,
+62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,
+62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,
+51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,
+47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,
+101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,
+88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,
+82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,
+106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,
 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,
-32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,
-61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,
-73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,
-32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,
-47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,
-116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110,121,32,99,
-104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32,116,104,101,
-32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108,116,105,112,
-62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,
-10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,
-88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,
-32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,
-114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,
-99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,
-32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,
-124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,
-60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,
-62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,
-34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,
-60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,
-117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,
-117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,
-108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,
-101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,
-32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,
-98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,
-101,115,111,117,114,99,101,62,10};
+32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,
+120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,
+107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,
+32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,
+47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,
+99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,
+32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,
+62,10,60,47,114,101,115,111,117,114,99,101,62,10};
 
 static size_t xml_res_size_12 = 12541;
 static unsigned char xml_res_file_12[] = {
diff --git a/pgadmin/ver_svn.bat b/pgadmin/ver_svn.bat
old mode 100755
new mode 100644
diff --git a/pgadmin/ver_svn.sh b/pgadmin/ver_svn.sh
old mode 100755
new mode 100644
diff --git a/pkg/debian/rules b/pkg/debian/rules
old mode 100755
new mode 100644
diff --git a/pkg/mac/complete-bundle.sh b/pkg/mac/complete-bundle.sh
old mode 100755
new mode 100644
diff --git a/pkg/mac/debug-bundle.sh b/pkg/mac/debug-bundle.sh
old mode 100755
new mode 100644
diff --git a/stringextract b/stringextract
old mode 100755
new mode 100644
diff --git a/stringmerge b/stringmerge
old mode 100755
new mode 100644
diff --git a/xtra/wx-build/build-wxgtk b/xtra/wx-build/build-wxgtk
old mode 100755
new mode 100644
diff --git a/xtra/wx-build/build-wxmac b/xtra/wx-build/build-wxmac
old mode 100755
new mode 100644
