* Removed all Id tags.
[cacao.git] / src / native / jvmti / jvmti.c
index f2edf857aefb5f8ecb82f6ea6dc8b1a650095a78..f4d613d389d500551cba4b2537f64341c5cf231a 100644 (file)
@@ -1,10 +1,10 @@
-/* src/native/jvmti.c - implementation of the Java Virtual Machine Tool 
-                        Interface functions
+/* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine 
+                              Tool Interface functions
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Author: Martin Platter
 
-   Changes:             
-
+   Changes: Edwin Steiner
+            Samuel Vinson
+            Christan Thalinger
    
-   $Id: jvmti.c 3066 2005-07-19 12:35:37Z twisti $
-
 */
 
 
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+#include <linux/unistd.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ltdl.h>
+#include <unistd.h>
+#include <sched.h>
+
 #include "native/jni.h"
+#include "native/native.h"
+#include "native/jvmti/cacaodbg.h"
 #include "native/jvmti/jvmti.h"
+#include "vm/jit/stacktrace.h"
 #include "vm/global.h"
 #include "vm/loader.h"
 #include "vm/builtin.h"
 #include "vm/jit/asmpart.h"
-#include "mm/boehm.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "mm/gc-common.h"
 #include "toolbox/logging.h"
 #include "vm/options.h"
-#include "cacao/cacao.h"
 #include "vm/stringlocal.h"
 #include "mm/memory.h"
 #include "threads/native/threads.h"
+#include "threads/native/lock.h"
 #include "vm/exceptions.h"
+#include "native/include/java_util_Vector.h"
+#include "native/include/java_io_PrintStream.h"
+#include "native/include/java_io_InputStream.h"
+#include "native/include/java_lang_Cloneable.h"
+#include "native/include/java_lang_ThreadGroup.h"
+#include "native/include/java_lang_VMObject.h"
+#include "native/include/java_lang_VMSystem.h"
+#include "native/include/java_lang_VMClass.h"
+#include "vm/suck.h"
+#include "boehm-gc/include/gc.h"
+
+#if defined(ENABLE_THREADS)
+#include "threads/native/threads.h"
+#include <sched.h>
+#include <pthread.h>
+#endif 
+
+#include "dbg.h"
 
-#include <string.h>
-#include <linux/unistd.h>
-#include <sys/time.h>
+
+typedef struct _environment environment;
+static environment *envs=NULL;
+pthread_mutex_t dbgcomlock;
+
+extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
 
 static jvmtiPhase phase; 
+typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
+struct _jvmtiEventModeLL {
+       jvmtiEventMode mode;
+       jthread event_thread;
+       jvmtiEventModeLL *next;
+};
 
-typedef struct {
+typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
+struct _jvmtiThreadLocalStorage{
+       jthread thread;
+       void *data;
+       jvmtiThreadLocalStorage *next;
+};
+
+struct _environment {
     jvmtiEnv env;
+       environment *next;
     jvmtiEventCallbacks callbacks;
-    jobject *events;   /* hashtable for enabled/disabled jvmtiEvents */
+    /* table for enabled/disabled jvmtiEvents - first element contains global 
+          behavior */
+    jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM]; 
     jvmtiCapabilities capabilities;
     void *EnvironmentLocalStorage;
-} environment;
-
-
-/* jmethodID and jclass caching */
-static jclass ihmclass = NULL;
-static jmethodID ihmmid = NULL;
+       jvmtiThreadLocalStorage *tls;
+};
 
-jvmtiEnv JVMTI_EnvTable;
-jvmtiCapabilities JVMTI_Capabilities;
+static struct jvmtiEnv_struct JVMTI_EnvTable;
+static jvmtiCapabilities JVMTI_Capabilities;
+static lt_ptr unload;
 
-#define CHECK_PHASE_START  if (!(0 
+#define CHECK_PHASE_START  if (!(false 
 #define CHECK_PHASE(chkphase) || (phase == chkphase)
 #define CHECK_PHASE_END  )) return JVMTI_ERROR_WRONG_PHASE
+#define CHECK_CAPABILITY(env,CAP) if(((environment*)                            \
+                                                                                env)->capabilities.CAP == 0)           \
+                                     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) ==                 \
+                                  JVMTI_ERROR_THREAD_NOT_ALIVE)                 \
+                                       return JVMTI_ERROR_THREAD_NOT_ALIVE;
+
+
+
+
+/* check_thread_is_alive *******************************************************
+
+   checks if the given thread is alive
+
+*******************************************************************************/
+static jvmtiError check_thread_is_alive(jthread t) {
+       if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
+       if(((java_lang_Thread*) t)->vmThread == NULL) 
+               return JVMTI_ERROR_THREAD_NOT_ALIVE;
+       return JVMTI_ERROR_NONE;
+}
+
+/* execute_callback ************************************************************
+
+   executes the registerd callbacks for the given jvmti event with parameter
+   in the data structure.
+
+*******************************************************************************/
+static void execute_callback(jvmtiEvent e, functionptr ec, 
+                                                        genericEventData* data) {
+       JNIEnv* jni_env = (JNIEnv*)_Jv_env;
+
+       fprintf(stderr,"execcallback called (event: %d)\n",e);
+
+       switch (e) {
+       case JVMTI_EVENT_VM_INIT:
+               if (phase != JVMTI_PHASE_LIVE) return;
+    case JVMTI_EVENT_THREAD_START:
+    case JVMTI_EVENT_THREAD_END: 
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+                       ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
+               break;
+
+    case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
+               ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env, 
+                                                                                  jni_env, 
+                                                                                  data->klass,
+                                                                                  data->object,
+                                                                                  data->name,
+                                                                                  data->protection_domain,
+                                                                                  data->jint1,
+                                                                                  data->class_data,
+                                                                                  data->new_class_data_len,
+                                                                                  data->new_class_data);
+
+               /* if class data has been modified use it as class data for other agents 
+                  waiting for the same event */
+               if (data->new_class_data != NULL) {
+                       data->jint1 = *(data->new_class_data_len);
+                       data->class_data = *(data->new_class_data); 
+               }
+               break;
+
+
+    case JVMTI_EVENT_CLASS_PREPARE: 
+    case JVMTI_EVENT_CLASS_LOAD:
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+                       ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env, 
+                                                                          data->thread, data->klass);
+               break;
+
+    case JVMTI_EVENT_VM_DEATH:
+               if (phase != JVMTI_PHASE_LIVE) return;
+    case JVMTI_EVENT_VM_START: 
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+               ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
+               break;
+
+    case JVMTI_EVENT_NATIVE_METHOD_BIND:
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
+                       ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env, 
+                                                                                         data->thread, 
+                                                                                         data->method,
+                                                                                         data->address,
+                                                                                         data->new_address_ptr);
+               break;
+       
+
+    case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
+                       ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
+                                                                                                 data->name,
+                                                                                                 data->address,
+                                                                                                 data->jint1);
+               break;
+
+
+
+       default:
+               if (phase != JVMTI_PHASE_LIVE) return;
+               switch (e) {
+               case JVMTI_EVENT_EXCEPTION:                     
+                       ((jvmtiEventException)ec) (data->jvmti_env, jni_env, 
+                                                                          data->thread, 
+                                                                          data->method, 
+                                                                          data->location,
+                                                                          data->object,
+                                                                          data->catch_method,
+                                                                          data->catch_location);
+                       break;
+                       
+               case JVMTI_EVENT_EXCEPTION_CATCH:
+                       ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env, 
+                                                                                       data->thread, 
+                                                                                       data->method, 
+                                                                                       data->location,
+                                                                                       data->object);
+                       break;
+
+               case JVMTI_EVENT_BREAKPOINT:
+               case JVMTI_EVENT_SINGLE_STEP:
+                       ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env, 
+                                                                               data->thread, 
+                                                                               data->method, 
+                                                                               data->location);
+                       break;
+
+               case JVMTI_EVENT_FRAME_POP:
+                       ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env, 
+                                                                         data->thread, 
+                                                                         data->method, 
+                                                                         data->b);
+                       break;
+
+
+               case JVMTI_EVENT_FIELD_ACCESS: 
+                       ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->method, 
+                                                                                data->location,
+                                                                                data->klass,
+                                                                                data->object,
+                                                                                data->field);
+                       break;
+
+               case JVMTI_EVENT_FIELD_MODIFICATION:
+
+                       ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env, 
+                                                                                          data->thread, 
+                                                                                          data->method, 
+                                                                                          data->location,
+                                                                                          data->klass,
+                                                                                          data->object,
+                                                                                          data->field,
+                                                                                          data->signature_type,
+                                                                                          data->value);
+                       break;
+
+               case JVMTI_EVENT_METHOD_ENTRY:
+                       ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->method);
+                       break;
+
+               case JVMTI_EVENT_METHOD_EXIT: 
+                       ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env, 
+                                                                               data->thread, 
+                                                                               data->method,
+                                                                               data->b,
+                                                                               data->value);
+                       break;
+
+               case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+                       ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env, 
+                                                                                               data->method,
+                                                                                               data->jint1,
+                                                                                               data->address,
+                                                                                               data->jint2,
+                                                                                               data->map,
+                                                                                               data->compile_info);
+                       break;
+               
+               case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+                       ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+                                                                                                 data->method,
+                                                                                                 data->address);
+                       break;
+
+               case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+               case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+               case JVMTI_EVENT_DATA_DUMP_REQUEST: 
+                       ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
+                       break;
+
+               case JVMTI_EVENT_MONITOR_WAIT:
+                       ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->object,
+                                                                                data->jlong);
+                       break;
+
+               case JVMTI_EVENT_MONITOR_WAITED:
+                       ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env, 
+                                                                                  data->thread, 
+                                                                                  data->object,
+                                                                                  data->b);
+                       break;
+
+
+               case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+               case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+                       ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+                                                                                                  data->thread, 
+                                                                                                  data->object);
+                       break;
+
+               case JVMTI_EVENT_OBJECT_FREE: 
+                       ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
+                       break;
+
+               case JVMTI_EVENT_VM_OBJECT_ALLOC:
+                       ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env, 
+                                                                                  data->thread, 
+                                                                                  data->object,
+                                                                                  data->klass,
+                                                                                  data->jlong);
+                       break;
+               default:
+                       log_text ("unknown event");
+               }
+               break;
+       }
+}
+
+
+/* dofireEvent ******************************************************************
+
+   sends event if it is enabled either globally or for some threads
+
+*******************************************************************************/
+static void dofireEvent(jvmtiEvent e, genericEventData* data) {
+       environment* env;
+       jvmtiEventModeLL *evm;
+       functionptr ec;
+
+       env = envs;
+       while (env != NULL) {
+               if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
+                       evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
+            /* test if the event is enable for some threads */
+                       while (evm != NULL) { 
+                               if (evm->mode == JVMTI_ENABLE) {
+                                       ec = ((functionptr*)
+                                                 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
+                                       if (ec != NULL) {
+                                               data->jvmti_env=&env->env;
+                                               execute_callback(e, ec, data);
+                                       }
+                               }
+                               evm=evm->next;
+                       }
+               } else { /* event enabled globally */
+                       data->jvmti_env=&env->env;
+                       ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
+                       if (ec != NULL) execute_callback(e, ec, data);
+               }
+               
+               env=env->next;
+       }
+}
+
+
+/* fireEvent ******************************************************************
+
+   fire event callback with data arguments. This function mainly fills the
+   missing EventData.
+
+*******************************************************************************/
+void jvmti_fireEvent(genericEventData* d) {
+       jthread thread;
+    /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
+
+       if (d->ev == JVMTI_EVENT_VM_START)
+               thread = NULL;
+       else
+               thread = jvmti_get_current_thread();
+
+
+       d->thread = thread;
+       dofireEvent(d->ev,d);
+}
 
 
 /* SetEventNotificationMode ****************************************************
@@ -83,34 +431,130 @@ jvmtiCapabilities JVMTI_Capabilities;
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
                          jvmtiEvent event_type, jthread event_thread, ...)
 {
+       environment* cacao_env;
+       jvmtiEventModeLL *ll;
+
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");    
-    
+
+       if(event_thread != NULL) {
+               if (!builtin_instanceof(event_thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               CHECK_THREAD_IS_ALIVE(event_thread);
+       }
+       
+       cacao_env = (environment*) env;    
+       if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
+               return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+       switch (event_type) { /* check capability and set system breakpoint */
+    case JVMTI_EVENT_EXCEPTION:
+       case JVMTI_EVENT_EXCEPTION_CATCH:
+               CHECK_CAPABILITY(env,can_generate_exception_events)
+               break;
+    case JVMTI_EVENT_SINGLE_STEP:
+               CHECK_CAPABILITY(env,can_generate_single_step_events)
+               break;
+    case JVMTI_EVENT_FRAME_POP:
+               CHECK_CAPABILITY(env,can_generate_frame_pop_events)
+               break;
+    case JVMTI_EVENT_BREAKPOINT:
+               CHECK_CAPABILITY(env,can_generate_breakpoint_events)
+               break;
+    case JVMTI_EVENT_FIELD_ACCESS:
+               CHECK_CAPABILITY(env,can_generate_field_access_events)
+               break;
+    case JVMTI_EVENT_FIELD_MODIFICATION:
+               CHECK_CAPABILITY(env,can_generate_field_modification_events)
+               break;
+    case JVMTI_EVENT_METHOD_ENTRY:
+               CHECK_CAPABILITY(env,can_generate_method_entry_events)
+               break;
+    case JVMTI_EVENT_METHOD_EXIT:
+               CHECK_CAPABILITY(env, can_generate_method_exit_events)
+               break;
+    case JVMTI_EVENT_NATIVE_METHOD_BIND:
+               CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
+               break;
+    case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+    case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+               CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
+               break;
+    case JVMTI_EVENT_MONITOR_WAIT:
+    case JVMTI_EVENT_MONITOR_WAITED:
+    case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+    case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+               CHECK_CAPABILITY(env,can_generate_monitor_events)
+               break;
+    case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+       case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+               CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
+               break;
+    case JVMTI_EVENT_OBJECT_FREE:
+               CHECK_CAPABILITY(env,can_generate_object_free_events)
+               break;
+    case JVMTI_EVENT_VM_OBJECT_ALLOC:
+               CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
+               break;
+       default:
+               /* all other events are required */
+               if ((event_type < JVMTI_EVENT_START_ENUM) ||
+                       (event_type > JVMTI_EVENT_END_ENUM))
+                       return JVMTI_ERROR_INVALID_EVENT_TYPE;          
+               break;
+       }
+
+
+       if (event_thread != NULL) {
+               /* thread level control */
+               if ((JVMTI_EVENT_VM_INIT == mode) ||
+                       (JVMTI_EVENT_VM_DEATH == mode) ||
+                       (JVMTI_EVENT_VM_START == mode) ||
+                       (JVMTI_EVENT_THREAD_START == mode) ||
+                       (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
+                       (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
+                       (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
+                       (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
+                       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+               ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
+               while (ll->next != NULL) {
+                       ll = ll->next;
+                       if (ll->event_thread == event_thread) {
+                               ll->mode=mode;
+                               return JVMTI_ERROR_NONE;
+                       }
+               }
+               ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
+               ll->next->mode=mode;            
+       } else {
+               /* global control */
+               cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
+       }
+
+       
     return JVMTI_ERROR_NONE;
 }
 
-
 /* GetAllThreads ***************************************************************
 
    Get all live threads
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
               jthread ** threads_ptr)
 {
-    int i = 0; 
-    threadobject* thread;
-
+       threadobject** threads;
+       int i;
+       jvmtiError retval;
+       
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
@@ -118,252 +562,567 @@ GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
     if ((threads_count_ptr == NULL) || (threads_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
-    thread = mainthreadobj;
-    do {
-        i++;
-        thread = thread->info.prev;
-    } while (thread != mainthreadobj);
-    
-    *threads_count_ptr = i;
+       retval=jvmti_get_all_threads(threads_count_ptr, &threads);
+       if (retval != JVMTI_ERROR_NONE) return retval;
 
-    *threads_ptr = (jthread*) heap_allocate(sizeof(jthread) * i,true,NULL);
-    i=0;
-    do {
-        memcpy(*threads_ptr[i],thread,sizeof(jthread));
-        thread = thread->info.prev;
-        i++;
-    } while (thread != mainthreadobj);
+       *threads_ptr = 
+               heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
 
+       for (i=0; i<*threads_count_ptr; i++)
+               (*threads_ptr)[i] = threads[i]->o.thread;
     return JVMTI_ERROR_NONE;
 }
 
 
 /* SuspendThread ***************************************************************
 
-   
+   Suspend specified thread
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SuspendThread (jvmtiEnv * env, jthread thread)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_PHASE_START
+       CHECK_PHASE(JVMTI_PHASE_LIVE)
+       CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_suspend);
+    
+       if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+       if (!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+       CHECK_THREAD_IS_ALIVE(thread);
+
+    /* threads_suspend_thread will implement suspend
+          threads_suspend_thread (
+          (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
+       
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* ResumeThread ***************************************************************
 
-   
+   Resume a suspended thread
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ResumeThread (jvmtiEnv * env, jthread thread)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+    CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_suspend);
+
+       if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+       if (!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+       CHECK_THREAD_IS_ALIVE(thread);
+
+    /* threads_resume_thread will implement resume
+          threads_resume_thread (
+          (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
+
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* StopThread *****************************************************************
 
-   
+   Send asynchronous exception to the specified thread. Similar to 
+   java.lang.Thread.stop(). Used to kill thread.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_signal_thread);
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+       return JVMTI_ERROR_NOT_AVAILABLE;
+
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* InterruptThread ************************************************************
 
-   
+   Interrupt specified thread. Similar to java.lang.Thread.interrupt()
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 InterruptThread (jvmtiEnv * env, jthread thread)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_signal_thread)
+
+#if defined(ENABLE_THREADS)
+       if(!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+
+       CHECK_THREAD_IS_ALIVE(thread);
+
+       threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
+
+
     return JVMTI_ERROR_NONE;
+#else
+       return JVMTI_ERROR_NOT_AVAILABLE;
+#endif
 }
 
 /* GetThreadInfo ***************************************************************
 
-   Get thread information. The fields of the jvmtiThreadInfo structure ar
-   filled in with details of the specified thread.
+   Get thread information. Details of the specified thread are stored in th
+   jvmtiThreadInfo structure.
 
 *******************************************************************************/
 
-jvmtiError
-GetThreadInfo (jvmtiEnv * env, jthread thread, jvmtiThreadInfo * info_ptr)
+static jvmtiError
+GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
 {
+       utf *name;
+       java_lang_Thread* th = (java_lang_Thread*)t;
+
+
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       info_ptr->priority=(jint)th->priority;
+       info_ptr->is_daemon=(jboolean)th->daemon;
+       info_ptr->thread_group=(jthreadGroup)th->group;
+       info_ptr->context_class_loader=(jobject)th->contextClassLoader;
+
+       name = javastring_toutf(th->name,false);
+       info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
+       utf_sprint_convert_to_latin1(info_ptr->name, name);
+
     return JVMTI_ERROR_NONE;
 }
 
 /* GetOwnedMonitorInfo *********************************************************
 
-   
+   Gets all  monitors owned by the specified thread
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
                     jint * owned_monitor_count_ptr,
                     jobject ** owned_monitors_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       int i,j,size=20;
+       java_objectheader **om;
+       lock_record_pool_t* lrp;
+       threadobject* t;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_get_owned_monitor_info);
+
+       if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               t = (threadobject*) thread;
+       }
+
+#if defined(ENABLE_THREADS)
+
+       om=MNEW(java_objectheader*,size);
+
+       pthread_mutex_lock(&lock_global_pool_lock);
+       lrp=lock_global_pool;
+
+       /* iterate over all lock record pools */
+       while (lrp != NULL) {
+               /* iterate over every lock record in a pool */
+               for (j=0; j<lrp->header.size; j++) {
+                       /* if the lock record is owned by the given thread add it to 
+                          the result array */
+                       if(lrp->lr[j].owner == t) {
+                               if (i >= size) {
+                                       MREALLOC(om, java_objectheader*, size, size * 2);
+                                       size = size * 2;
+                               }
+                               om[i] = lrp->lr[j].obj;
+                               i++;
+                               }
+               }
+               lrp=lrp->header.next;
+       }
+
+       pthread_mutex_unlock(&lock_global_pool_lock);
+
+       *owned_monitors_ptr     = 
+               heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
+       memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
+       MFREE(om, java_objectheader*, size);
+
+       *owned_monitor_count_ptr = i;
+
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetCurrentContendedMonitor *************************************************
 
-   
+   Get the object the specified thread waits for.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
                            jobject * monitor_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       int j;
+       lock_record_pool_t* lrp;
+       threadobject* t;
+       lock_waiter_t* waiter;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env, can_get_current_contended_monitor)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+       *monitor_ptr=NULL;
+
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               t = (threadobject*) thread;
+       }
+
+#if defined(ENABLE_THREADS)
+
+       pthread_mutex_lock(&lock_global_pool_lock);
+
+       lrp=lock_global_pool;
+
+       /* iterate over all lock record pools */
+       while ((lrp != NULL) && (*monitor_ptr == NULL)) {
+               /* iterate over every lock record in a pool */
+               for (j=0; j<lrp->header.size; j++) {
+                       /* iterate over every thread that is wait on this lock record */
+                       waiter = lrp->lr[j].waiters;
+                       while (waiter != NULL) 
+                               /* if the waiting thread equals to the given thread we are 
+                                  done. Stop iterateting. */
+                               if(waiter->waiter == t) {
+                                       *monitor_ptr=lrp->lr[j].obj;
+                                       break;
+                               }
+               }
+               lrp=lrp->header.next;
+       }
+
+       pthread_mutex_unlock(&lock_global_pool_lock);
+
+
+#endif
     return JVMTI_ERROR_NONE;
 }
 
+typedef struct {
+       jvmtiStartFunction sf;
+       jvmtiEnv* jvmti_env;
+       void* arg;
+} runagentparam;
 
-/* *****************************************************************************
 
-   
+static void *threadstartup(void *t) {
+       runagentparam *rap = (runagentparam*)t;
+       rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
+       return NULL;
+}
+
+/* RunAgentThread *************************************************************
+
+   Starts the execution of an agent thread of the specified native function 
+   within the specified thread
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
                const void *arg, jint priority)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       pthread_attr_t threadattr;
+       struct sched_param sp;
+       runagentparam rap;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread))) 
+               return JVMTI_ERROR_INVALID_THREAD;
+       if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
+       if ((priority < JVMTI_THREAD_MIN_PRIORITY) || 
+               (priority > JVMTI_THREAD_MAX_PRIORITY)) 
+               return JVMTI_ERROR_INVALID_PRIORITY;
+
+       /* XXX:  Threads started with this function should not be visible to 
+          Java programming language queries but are included in JVM TI queries */
+
+       rap.sf = proc;
+       rap.arg = (void*)arg;
+       rap.jvmti_env = env;
+
+#if defined(ENABLE_THREADS)
+       pthread_attr_init(&threadattr);
+       pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
+       if (priority == JVMTI_THREAD_MIN_PRIORITY) {
+               sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
+       }
+       if (priority == JVMTI_THREAD_MAX_PRIORITY) {
+               sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
+       }
+       pthread_attr_setschedparam(&threadattr,&sp);
+       if (pthread_create(&((threadobject*) 
+                                                thread)->tid, &threadattr, &threadstartup, &rap)) {
+               log_text("pthread_create failed");
+               assert(0);
+       }
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetTopThreadGroups *********************************************************
 
-   
+   Get all top-level thread groups in the VM.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
                    jthreadGroup ** groups_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       jint threads_count_ptr;
+       threadobject *threads_ptr;
+       int i,j,x,size=20;
+       jthreadGroup **tg,*ttgp;
+
+    CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+    if ((groups_ptr == NULL) || (group_count_ptr == NULL)) 
+        return JVMTI_ERROR_NULL_POINTER;
+
+#if defined(ENABLE_THREADS)
+       tg = MNEW(jthreadGroup*,size);
+       x = 0;
+       if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
+               return JVMTI_ERROR_INTERNAL;
+
+       for (i=0;i<threads_count_ptr;i++){
+               if (threads_ptr[i].o.thread->group == NULL) {
+                       log_text("threadgroup not set");
+                       return JVMTI_ERROR_INTERNAL;
+               }
+               ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
+               if (ttgp == NULL) {
+                       j=0;
+                       while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
+                               j++;
+                       }
+                       if (j == x) {
+                               if (x >= size){
+                                       MREALLOC(tg,jthreadGroup*,size,size*2);
+                                       size=size*2;
+                               }
+                               tg[x]=ttgp;
+                               x++;
+                       }
+               }
+       }
+
+       *groups_ptr     = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
+       memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
+       MFREE(tg,jthreadGroup*,size);
+
+       *group_count_ptr = x;
+
+#else
+       return JVMTI_ERROR_NOT_AVAILABLE;
+#endif
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetThreadGroupInfo *********************************************************
 
-   
+   Get information about the specified thread group.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
                    jvmtiThreadGroupInfo * info_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       int size;
+       char* name;
+       java_lang_ThreadGroup* grp;
+       
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+       if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
+               return JVMTI_ERROR_INVALID_THREAD_GROUP;
+
+       grp = (java_lang_ThreadGroup*)group;
+       
+       info_ptr->parent = (jthreadGroup) 
+               Java_java_lang_VMObject_clone(NULL, 
+                                                                         (jclass)grp->header.vftbl->class,
+                                                                         (java_lang_Cloneable*) &grp->parent);
+
+       name = javastring_tochar((java_objectheader*)grp->name);
+       size = strlen(name);
+       info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
+       strncpy(info_ptr->name,name,size);
+       info_ptr->max_priority= (jint)grp->maxpri;
+       info_ptr->is_daemon= (jboolean)grp->daemon_flag;
+       
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetThreadGroupChildren *****************************************************
 
-   
+   Get the live threads and active subgroups in this thread group. 
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
                        jint * thread_count_ptr, jthread ** threads_ptr,
                        jint * group_count_ptr, jthreadGroup ** groups_ptr)
 {
+       java_lang_ThreadGroup* tgp;
+
     CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
+               (group_count_ptr == NULL) || (groups_ptr == NULL)) 
+        return JVMTI_ERROR_NULL_POINTER;
+
+       if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
+               return JVMTI_ERROR_INVALID_THREAD_GROUP;
+
+       tgp = (java_lang_ThreadGroup*)group;
+
+       *thread_count_ptr = (jint)tgp->threads->elementCount;
+
+       *threads_ptr = 
+               heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
+
+       memcpy(*threads_ptr, &tgp->threads->elementData, 
+                  (*thread_count_ptr)*sizeof(java_objectarray*));
+
+       *group_count_ptr = (jint) tgp->groups->elementCount;
+
+       *groups_ptr     = 
+               heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);       
+
+       memcpy(*groups_ptr, &tgp->threads->elementData,
+                  (*group_count_ptr)*sizeof(jthreadGroup*));
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* getcacaostacktrace *********************************************************
 
+   Helper function that retrives stack trace for specified thread. 
    
+*******************************************************************************/
+
+static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
+       threadobject *t;
+       bool resume;
+       
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+               *trace = stacktrace_create(t);
+       } else {
+               t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
+/*             if (t != jvmti_get_current_thread())
+                       resume = threads_suspend_thread_if_running(thread);
+    
+               *trace = stacktrace_create(thread );
+               
+               if (resume)
+               threads_resume_thread ( thread );*/
+       }
+
+    return JVMTI_ERROR_NONE;
+}
+
+
+/* GetFrameCount **************************************************************
+
+
+   Get the number of frames in the specified thread's stack. Calling function
+   has to take care of suspending/resuming thread.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       stacktracebuffer* trace;
+       jvmtiError er;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    
+       if (thread != NULL){
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
+       
+       if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       er = getcacaostacktrace(&trace, thread);
+       if (er == JVMTI_ERROR_NONE) {
+               heap_free(trace);
+               return er;
+       }
+
+       *count_ptr = trace->used;
+
+       heap_free(trace);
     return JVMTI_ERROR_NONE;
 }
 
@@ -374,91 +1133,153 @@ GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
 {
+       java_lang_Thread* th = (java_lang_Thread*)thread;
+       threadobject* t = (threadobject*)th->vmThread;
+
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if(!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+
+       if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       *thread_state_ptr = 0;
+#if defined(ENABLE_THREADS)
+       if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
+               /* not alive */
+               if (((threadobject*)th->vmThread)->tid == 0)
+                       *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
+       } else {
+               /* alive */
+               *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
+               if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
+               /* XXX todo -  info not available */
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
+               if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
+               if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
+               if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
+       }
+#else
+       return JVMTI_ERROR_INTERNAL;
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetFrameLocation ************************************************************
 
-   
+   Get the location of the instruction currently executing
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
                  jmethodID * method_ptr, jlocation * location_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       stackframeinfo   *sfi;
+       int i;
+       threadobject* th;
+               
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (thread == NULL) {
+               th = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
+       }
+
+       if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+       if ((method_ptr == NULL)&&(location_ptr == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+       
+       sfi = th->_stackframeinfo;
+       
+       i = 0;
+       while ((sfi != NULL) && (i<depth)) {
+               sfi = sfi->prev;
+               i++;
+       }
+       
+       if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
+
+       *method_ptr=(jmethodID)sfi->method;
+       *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
+       
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* NotifyFramePop *************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_generate_frame_pop_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetLocalObject *************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalObject (jvmtiEnv * env,
                jthread thread, jint depth, jint slot, jobject * value_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_access_local_variables)
+
+  log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetLocalInt ****************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalInt (jvmtiEnv * env,
             jthread thread, jint depth, jint slot, jint * value_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_access_local_variables)        
+  log_text ("JVMTI-Call: TBD OPTIONAL  IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -468,16 +1289,16 @@ GetLocalInt (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
              jlong * value_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)        
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -488,16 +1309,16 @@ GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
               jfloat * value_ptr)
 {
     CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)        
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -508,16 +1329,16 @@ GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jdouble * value_ptr)
 {
     CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)        
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -528,16 +1349,16 @@ GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jobject value)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_access_local_variables)
+    
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -548,16 +1369,16 @@ SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
             jint value)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -568,16 +1389,16 @@ SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
              jlong value)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -588,16 +1409,16 @@ SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
               jfloat value)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_access_local_variables)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -608,169 +1429,227 @@ SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jdouble value)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_access_local_variables)
+    
+        log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* CreateRawMonitor ***********************************************************
 
-   
+   This function creates a new raw monitor.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 CreateRawMonitor (jvmtiEnv * env, const char *name,
                  jrawMonitorID * monitor_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
+               
+       CHECK_PHASE_START
+    CHECK_PHASE(JVMTI_PHASE_ONLOAD)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if ((name == NULL) || (monitor_ptr == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+#if defined(ENABLE_THREADS)
+       monitor->name=javastring_new_from_ascii(name);
+#else
+       log_text ("CreateRawMonitor not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* DestroyRawMonitor **********************************************************
 
-   
+   This function destroys a raw monitor.   
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
+    CHECK_PHASE(JVMTI_PHASE_ONLOAD)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
-    return JVMTI_ERROR_NONE;
+
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+               return JVMTI_ERROR_NOT_MONITOR_OWNER;
+       
+       lock_monitor_exit((java_objectheader *) monitor->name);
+
+       heap_free(monitor);
+#else
+       log_text ("DestroyRawMonitor not supported");
+#endif
+
+       return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RawMonitorEnter ************************************************************
 
-   
+  Gain exclusive ownership of a raw monitor
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       lock_monitor_enter((java_objectheader *) monitor->name);
+#else
+       log_text ("RawMonitorEnter not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RawMonitorExit *************************************************************
 
-   
+   Release raw monitor
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       /* assure current thread owns this monitor */
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+               return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+       lock_monitor_exit((java_objectheader *) monitor->name);
+#else
+       log_text ("RawMonitorExit not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RawMonitorWait *************************************************************
 
-   
+   Wait for notification of the raw monitor.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       /* assure current thread owns this monitor */
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+               return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+       lock_wait_for_object(&monitor->name->header, millis,0);
+       if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
+               return JVMTI_ERROR_INTERRUPT;
+
+#else
+       log_text ("RawMonitorWait not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RawMonitorNotify ***********************************************************
 
-   
+ Notify one thread waiting on the given monitor.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       /* assure current thread owns this monitor */
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+               return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+       lock_notify_object((java_objectheader*)&monitor->name);
+#else
+       log_text ("RawMonitorNotify not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RawMonitorNotifyAll *********************************************************
 
-   
+ Notify all threads waiting on the given monitor.   
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+               return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+       /* assure current thread owns this monitor */
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+               return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+       lock_notify_all_object((java_objectheader*)&monitor->name);
+#else
+       log_text ("RawMonitorNotifyAll not supported");
+#endif
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* SetBreakpoint **************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_generate_breakpoint_events)
+
+               /* addbrkpt */
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -781,34 +1660,34 @@ SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_generate_breakpoint_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* SetFieldAccessWatch ********************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_generate_field_access_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -819,15 +1698,15 @@ SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_generate_field_access_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -838,15 +1717,15 @@ ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_generate_field_modification_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -857,15 +1736,15 @@ SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_generate_field_modification_events)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -877,7 +1756,7 @@ ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
 {
     
@@ -899,10 +1778,11 @@ Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 Deallocate (jvmtiEnv * env, unsigned char *mem)
 {
     /* let Boehm GC do the job */
+       heap_free(mem);
     return JVMTI_ERROR_NONE;
 }
 
@@ -914,53 +1794,73 @@ Deallocate (jvmtiEnv * env, unsigned char *mem)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
                   char **generic_ptr)
 {
-    int nsize,psize;
-
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-       
-    if ((generic_ptr== NULL)||(signature_ptr == NULL)) 
-        return JVMTI_ERROR_NULL_POINTER;
-
-    nsize=((classinfo*)klass)->name->blength;
-    psize=((classinfo*)klass)->packagename->blength;
-
-    *signature_ptr = (char*) 
-        heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
+    
+       if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
+       if (!builtin_instanceof(klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS;
 
-    *signature_ptr[0]='L';
-    memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
-    *signature_ptr[psize+2]='/';
-    memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
-    *signature_ptr[nsize+psize+3]=';';
-    *signature_ptr[nsize+psize+4]='\0';
+       if (signature_ptr != NULL) {
+               *signature_ptr = (char*)
+                       heap_allocate(sizeof(char) * 
+                                                 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
+               
+               utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
+       }
 
-    *generic_ptr = NULL;
+       if (generic_ptr!= NULL)
+               *generic_ptr = NULL;
 
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetClassStatus *************************************************************
 
-   
+   Get status of the class.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
 {
+       classinfo *c;
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS; 
+
+    if (status_ptr == NULL) 
+        return JVMTI_ERROR_NULL_POINTER;
+
+       c = (classinfo*)klass;
+       *status_ptr = 0;        
+
+/*     if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
+       if (c->state & CLASS_LINKED) 
+               *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
+
+       if (c->state & CLASS_INITIALIZED) 
+               *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
+
+       if (c->state & CLASS_ERROR) 
+               *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
+
+       if (c->vftbl->arraydesc != NULL) 
+               *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
+
+       if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c)) 
+               *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE; 
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -971,7 +1871,7 @@ GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
 {
     int size; 
@@ -980,65 +1880,78 @@ GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_get_source_file_name)
         
     if ((klass == NULL)||(source_name_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
     
-    size = (((classinfo*)klass)->sourcefile->blength);
+    size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
 
     *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
     
     memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
+       (*source_name_ptr)[size]='\0';
 
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetClassModifiers **********************************************************
 
-   
+   For class klass return the access flags
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if (modifiers_ptr == NULL)
+               return JVMTI_ERROR_NULL_POINTER;        
+
+       if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS;
+
+       *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
+       
     return JVMTI_ERROR_NONE;
 }
 
 
 /* GetClassMethods *************************************************************
 
-   For the class indicated by klass, return a count of methods and a list of 
-   method IDs
+   For class klass return a count of methods and a list of method IDs
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
                 jmethodID ** methods_ptr)
 {
-    CHECK_PHASE_START
+       int i;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
+       
     if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
+       if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS;
+
     *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
     *methods_ptr = (jmethodID*) 
         heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
-    
-    memcpy (*methods_ptr, ((classinfo*)klass)->methods, 
-            sizeof(jmethodID) * (*method_count_ptr));
-    
+
+    for (i=0; i<*method_count_ptr;i++)
+               (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -1050,7 +1963,7 @@ GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
                jfieldID ** fields_ptr)
 {
@@ -1073,23 +1986,47 @@ GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
 }
 
 
-/* *****************************************************************************
+/* GetImplementedInterfaces ***************************************************
 
-   
+   Return the direct super-interfaces of this class.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
                          jint * interface_count_ptr,
                          jclass ** interfaces_ptr)
 {
-      CHECK_PHASE_START
+       int i;
+       classref_or_classinfo *interfaces;
+       classinfo *tmp;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
+               return JVMTI_ERROR_NULL_POINTER;        
+
+       if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS;
+
+               
+    *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
+    *interfaces_ptr = 
+               heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
+
+       interfaces = ((classinfo*)klass)->interfaces;
+       for (i=0; i<*interface_count_ptr; i++) {
+               if (IS_CLASSREF(interfaces[i]))
+                       tmp = load_class_bootstrap(interfaces[i].ref->name);
+               else
+                       tmp = interfaces[i].cls;
+               
+               *interfaces_ptr[i]=tmp;
+       }
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -1100,7 +2037,7 @@ GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
 {
     CHECK_PHASE_START
@@ -1122,7 +2059,7 @@ IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
 {
     CHECK_PHASE_START
@@ -1133,7 +2070,7 @@ IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
     if (is_array_class_ptr == NULL) 
         return JVMTI_ERROR_NULL_POINTER;
 
-    *is_array_class_ptr = ((classinfo*)klass)->name->text[0] == '[';
+    *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
 
     return JVMTI_ERROR_NONE;
 }
@@ -1146,7 +2083,7 @@ IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
 {
     CHECK_PHASE_START
@@ -1163,21 +2100,26 @@ GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
 }
 
 
-/* *****************************************************************************
+/* GetObjectHashCode **********************************************************
 
-   
+   Return hash code for object object
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+   
+       if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+       if (!builtin_instanceof(object,class_java_lang_Object))
+               return JVMTI_ERROR_INVALID_OBJECT;
+     
+       *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -1188,16 +2130,16 @@ GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
                       jvmtiMonitorUsage * info_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_get_monitor_info)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1209,7 +2151,7 @@ GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
              char **name_ptr, char **signature_ptr, char **generic_ptr)
 {
@@ -1219,19 +2161,29 @@ GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL)) 
-        return JVMTI_ERROR_NULL_POINTER;
-    
-    size = (((fieldinfo*)field)->name->blength);
-    *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
-    memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
-
-    size = (((fieldinfo*)field)->descriptor->blength);
-    *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
-    memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
 
-    *generic_ptr = NULL;
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
+    
+    if (name_ptr != NULL) {
+               size = utf_bytes(((fieldinfo*)field)->name)+1;
+               *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
+               utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
+       }
+
+       if (signature_ptr != NULL) {
+               size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
+               *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL); 
+               utf_sprint_convert_to_latin1(*signature_ptr, 
+                                                                        ((fieldinfo*)field)->descriptor);
+       }
+
+       if (generic_ptr != NULL) 
+               *generic_ptr = NULL;
 
     return JVMTI_ERROR_NONE;
 }
@@ -1245,7 +2197,7 @@ GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
                        jclass * declaring_class_ptr)
 {
@@ -1253,49 +2205,71 @@ GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    /* todo: find declaring class  */
 
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;     
+
+    if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetFieldModifiers **********************************************************
 
-   
+   Return access flags of field field 
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
                   jint * modifiers_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
+
+       if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+       *modifiers_ptr = ((fieldinfo*)field)->flags;
+       
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* IsFieldSynthetic ***********************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
                  jboolean * is_synthetic_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_get_synthetic_attribute)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1307,7 +2281,7 @@ IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
               char **signature_ptr, char **generic_ptr)
 {
@@ -1318,17 +2292,25 @@ GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
-        || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
 
-    *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
-    memcpy(*name_ptr, m->name->text, m->name->blength);
+       if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
 
-    *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
-    memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
-    
-    /* there is no generic signature attribute */
-    *generic_ptr = NULL;
+       if (name_ptr != NULL) {
+               *name_ptr = (char*)
+                       heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
+               utf_sprint_convert_to_latin1(*name_ptr, m->name);
+       }
+       
+       if (signature_ptr != NULL) {
+               *signature_ptr = (char*)
+                       heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
+               utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
+       }
+
+       if (generic_ptr != NULL) {
+        /* there is no generic signature attribute */
+               *generic_ptr = NULL;
+       }
 
     return JVMTI_ERROR_NONE;
 }
@@ -1340,7 +2322,7 @@ GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
                         jclass * declaring_class_ptr)
 {
@@ -1364,7 +2346,7 @@ GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
 {
     CHECK_PHASE_START
@@ -1389,7 +2371,7 @@ GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
 {
     CHECK_PHASE_START
@@ -1402,7 +2384,7 @@ GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
     
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
-   
     *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
 
     return JVMTI_ERROR_NONE;
@@ -1416,7 +2398,7 @@ GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
 {
     CHECK_PHASE_START
@@ -1430,20 +2412,19 @@ GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
 
-    *size_ptr = (jint)((methodinfo*)method)->paramcount;
+    *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
     return JVMTI_ERROR_NONE;
 }
 
 
 
-/* GetLineNumberTable ***********************************************************
+/* GetLineNumberTable **********************************************************
 
-   For the method indicated by method, return a table of source line number 
-   entries.
+   Return table of source line number entries for a given method
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
                    jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
 {
@@ -1453,11 +2434,14 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_get_line_numbers)
    
     if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;    
+
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
+
     if (((methodinfo*)method)->linenumbers == NULL) 
         return JVMTI_ERROR_ABSENT_INFORMATION;
 
@@ -1467,9 +2451,9 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
 
 
     for (i=0; i < *entry_count_ptr; i++) {
-        (*table_ptr[i]).start_location = 
-            (jlocation) method->linenumbers[i].start_pc;
-        (*table_ptr[i]).line_number = 
+        (*table_ptr)[i].start_location = 
+            (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
+        (*table_ptr)[i].line_number = 
             (jint) ((methodinfo*)method)->linenumbers[i].line_number;
     }
     
@@ -1485,7 +2469,7 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodLocation (jvmtiEnv * env, jmethodID method,
                   jlocation * start_location_ptr,
                   jlocation * end_location_ptr)
@@ -1497,11 +2481,31 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if ((method == NULL) || (start_location_ptr == NULL) || 
-        (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
+       if (method == NULL)     return JVMTI_ERROR_INVALID_METHODID;
+
+       if (((methodinfo*)method)->flags & ACC_NATIVE) 
+               return JVMTI_ERROR_NATIVE_METHOD;
+
+    if ((start_location_ptr == NULL) || (end_location_ptr == NULL)) 
+       return JVMTI_ERROR_NULL_POINTER;
     
-    *start_location_ptr = (jlocation)m->mcode;
-    *end_location_ptr = (jlocation)(m->mcode)+m->mcodelength;
+       /* XXX we return the location of the most recent code. Don't know
+        * if there is a way to teach jvmti that a method can have more
+        * than one location. -Edwin */
+
+       /* XXX Don't know if that's the right way to deal with not-yet-
+        * compiled methods. -Edwin */
+
+    fprintf(stderr,"GetMethodLocation *** XXX todo \n");
+
+
+       /* -1 states location information is not available */
+    *start_location_ptr = (jlocation)-1;
+    *end_location_ptr = (jlocation)-1;
+
+/*     
+    *start_location_ptr = (jlocation)m->code->mcode;
+    *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
     return JVMTI_ERROR_NONE;
 }
 
@@ -1512,7 +2516,7 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
                       jint * entry_count_ptr,
                       jvmtiLocalVariableEntry ** table_ptr)
@@ -1520,8 +2524,9 @@ GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_access_local_variables)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
 
     return JVMTI_ERROR_NONE;
 }
@@ -1534,7 +2539,7 @@ GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetBytecodes (jvmtiEnv * env, jmethodID method,
              jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
 {
@@ -1544,6 +2549,7 @@ GetBytecodes (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_get_bytecodes)
         
     if ((method == NULL) || (bytecode_count_ptr == NULL) || 
         (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
@@ -1563,7 +2569,7 @@ GetBytecodes (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
 {
     CHECK_PHASE_START
@@ -1590,7 +2596,7 @@ IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
                   jboolean * is_synthetic_ptr)
 {
@@ -1598,8 +2604,9 @@ IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_get_synthetic_attribute)
+
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1610,17 +2617,21 @@ IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
-GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr,
-                 jclass ** classes_ptr)
+static jvmtiError
+GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-    if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    if (class_count_ptr == NULL)
+               return JVMTI_ERROR_NULL_POINTER;
+
+    if (classes_ptr == NULL)
+               return JVMTI_ERROR_NULL_POINTER;
+
+       classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -1632,57 +2643,63 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
                       jint * class_count_ptr, jclass ** classes_ptr)
 {
+       log_text("GetClassLoaderClasses called");
+
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-    if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+    if ((class_count_ptr == NULL) || (classes_ptr == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
         
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
-    return JVMTI_ERROR_NONE;
+       /* behave like jdk 1.1 and make no distinction between initiating and 
+          defining class loaders */
+       
+    return GetLoadedClasses(env, class_count_ptr, classes_ptr);
 }
 
 
-/* *****************************************************************************
+/* PopFrame *******************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 PopFrame (jvmtiEnv * env, jthread thread)
 {
     CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+    CHECK_CAPABILITY(env,can_pop_frame)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+               log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* RedefineClasses ************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RedefineClasses (jvmtiEnv * env, jint class_count,
                 const jvmtiClassDefinition * class_definitions)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_redefine_classes)    
+       CHECK_CAPABILITY(env,can_redefine_any_class)
+
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1693,12 +2710,12 @@ RedefineClasses (jvmtiEnv * env, jint class_count,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
 {
     if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
 
-    *version_ptr = JVMTI_VERSION_1_0;
+    *version_ptr = JVMTI_VERSION;
     
     return JVMTI_ERROR_NONE;
 }
@@ -1706,12 +2723,12 @@ GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
 
 /* GetCapabilities ************************************************************
 
-   Returns via capabilities_ptr the optional JVM TI features which this 
-   environment currently possesses.
+   Returns the optional JVM TI features which this environment currently 
+   possesses.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 {
     if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -1728,7 +2745,7 @@ GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
                         char **source_debug_extension_ptr)
 {
@@ -1736,8 +2753,9 @@ GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_get_source_debug_extension)
         
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1748,7 +2766,7 @@ GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
                  jboolean * is_obsolete_ptr)
 {
@@ -1756,167 +2774,316 @@ IsMethodObsolete (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_redefine_classes)        
+
+    log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
-
+/* SuspendThreadList **********************************************************
    
+   Suspend all threads in the request list.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SuspendThreadList (jvmtiEnv * env, jint request_count,
                   const jthread * request_list, jvmtiError * results)
 {
-      CHECK_PHASE_START
+       int i;
+       int suspendme = -1;
+       jthread me;
+
+    CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_suspend);
+    
+       if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+       if ((request_list == NULL) || (results == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       me = jvmti_get_current_thread();
+
+       for (i=0;i<request_count;i++) {
+               if (request_list[i] == me) 
+                       suspendme = i;
+               else 
+                       results[i]=SuspendThread(env, request_list[i]);
+       }
+
+       if (suspendme != -1) 
+               results[suspendme]=SuspendThread(env, request_list[suspendme]);
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* ResumeThreadList ***********************************************************
 
-   
+   Resumes all threads in the request list.   
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ResumeThreadList (jvmtiEnv * env, jint request_count,
                  const jthread * request_list, jvmtiError * results)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       int i;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_suspend);
+    
+       if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+       if ((request_list == NULL) || (results == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       for (i=0;i<request_count;i++) 
+                       results[i]=ResumeThread(env, request_list[i]);
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetStackTrace **************************************************************
 
-   
+   Get information about the stack of a thread
 
 *******************************************************************************/
 
-jvmtiError
-GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
-                  jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
+static jvmtiError
+GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
+              jint max_frame_count, jvmtiFrameInfo * frame_buffer,
+              jint * count_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       stacktracebuffer* trace;
+       jvmtiError er;
+       int i,j;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    
+       if (thread != NULL){
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
+
+       if((count_ptr == NULL)||(frame_buffer == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+       er = getcacaostacktrace(&trace, thread);
+       if (er == JVMTI_ERROR_NONE) {
+               heap_free(trace);
+               return er;
+       }
+
+       if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth)) 
+               return JVMTI_ERROR_ILLEGAL_ARGUMENT; 
+       
+       for (i=start_depth, j=0;i<trace->used;i++,j++) {
+               frame_buffer[j].method = (jmethodID)trace->entries[i].method;
+        /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
+               frame_buffer[j].location = 0;
+               }
+
+       heap_free(trace);
+       
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetThreadListStackTraces ***************************************************
 
-   
+   Get information about the stacks of the supplied threads.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
                          const jthread * thread_list,
                          jint max_frame_count,
                          jvmtiStackInfo ** stack_info_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       int i;
+       jvmtiError er;
+       
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if ((stack_info_ptr == NULL)||(thread_list == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+       if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+       *stack_info_ptr = (jvmtiStackInfo*) 
+               heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
+
+       for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
+               (*stack_info_ptr)[i].thread=thread_list[i];
+               GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
+               (*stack_info_ptr)[i].frame_buffer = 
+                       heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
+               er = GetStackTrace(env,thread_list[i],0,max_frame_count,
+                                                  (*stack_info_ptr)[i].frame_buffer,
+                                                  &((*stack_info_ptr)[i].frame_count));
+
+               if (er != JVMTI_ERROR_NONE) return er;
+       }
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetAllStackTraces **********************************************************
 
-   
+   Get stack traces of all live threads
 
 *******************************************************************************/
 
-jvmtiError
-GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
+static jvmtiError
+GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
+                  jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       jthread *threads_ptr;
+       jvmtiError er;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    
+       if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+    
+       if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
+               return JVMTI_ERROR_INTERNAL;
+
+       GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
+                                                        max_frame_count, stack_info_ptr);
+
+       if (er != JVMTI_ERROR_NONE) return er;
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* GetThreadLocalStorage ******************************************************
 
-   
+   Get the value of the JVM TI thread-local storage.
 
 *******************************************************************************/
 
-jvmtiError
-SetThreadLocalStorage (jvmtiEnv * env, jthread thread, const void *data)
+static jvmtiError
+GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
 {
-      CHECK_PHASE_START
+       jvmtiThreadLocalStorage *tls;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if(thread == NULL)
+               thread = (jthread) THREADOBJECT;
+       else {
+               if (!builtin_instanceof(thread,class_java_lang_Thread)) 
+                       return JVMTI_ERROR_INVALID_THREAD;
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
+
+       if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       tls = ((environment*)env)->tls;
+       while ((tls->thread != thread) && (tls != NULL)) {
+               tls = tls->next;
+       }
+       
+       if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
+       
+       *data_ptr = tls->data;
+       
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* SetThreadLocalStorage *******************************************************
 
-   
+   Stores a pointer value associated with each environment-thread pair. The 
+   value is NULL unless set with this function. Agents can allocate memory in 
+   which they store thread specific information
 
 *******************************************************************************/
 
 jvmtiError
-GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
-              jint max_frame_count, jvmtiFrameInfo * frame_buffer,
-              jint * count_ptr)
+SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
 {
-      CHECK_PHASE_START
+       jvmtiThreadLocalStorage *tls, *pre;
+       environment* env = (environment*)jenv;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       if(thread == NULL)
+               thread = (jthread) THREADOBJECT;
+       else {
+               if (!builtin_instanceof(thread,class_java_lang_Thread)) 
+                       return JVMTI_ERROR_INVALID_THREAD;
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
+       
+       if (env->tls == NULL) {
+               tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
+       } else {
+               tls = env->tls;
+               while ((tls->thread != thread) && (tls->next != NULL)) {
+                       tls = tls->next;
+               }
+               if (tls->thread != thread) {
+                       tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
+                       tls = tls->next;
+               }
+       }
+       
+       if (data != NULL) {
+               tls->data = (void*)data;
+       } else { 
+               /* remove current tls */
+               pre = env->tls;
+               while (pre->next == tls) pre = pre->next;
+               pre->next = tls->next;
+       }
     return JVMTI_ERROR_NONE;
 }
 
+
 /* *****************************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_tag_objects)
+    
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -1926,67 +3093,68 @@ GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetTag (jvmtiEnv * env, jobject object, jlong tag)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_tag_objects)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* ForceGarbageCollection *****************************************************
 
-   
+   Force boehm-gc to perform a garbage collection
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ForceGarbageCollection (jvmtiEnv * env)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       gc_call();        
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* IterateOverObjectsReachableFromObject **************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
                                       jvmtiObjectReferenceCallback
                                       object_reference_callback,
                                       void *user_data)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_tag_objects)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* IterateOverReachableObjects ************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
                             heap_root_callback,
                             jvmtiStackReferenceCallback
@@ -1994,55 +3162,55 @@ IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
                             jvmtiObjectReferenceCallback
                             object_ref_callback, void *user_data)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_tag_objects)
+    
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* IterateOverHeap ************************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
                 jvmtiHeapObjectCallback heap_object_callback,
                 void *user_data)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_tag_objects)
+    
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* IterateOverInstancesOfClass ************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
                             jvmtiHeapObjectFilter object_filter,
                             jvmtiHeapObjectCallback
                             heap_object_callback, void *user_data)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_tag_objects)
+   
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -2053,17 +3221,17 @@ IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
                    jint * count_ptr, jobject ** object_result_ptr,
                    jlong ** tag_result_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_tag_objects)
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
@@ -2074,7 +3242,7 @@ GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetJNIFunctionTable (jvmtiEnv * env,
                     const jniNativeInterface * function_table)
 { 
@@ -2084,8 +3252,8 @@ SetJNIFunctionTable (jvmtiEnv * env,
     CHECK_PHASE_END;;
     
     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
-    ptr_env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
-    memcpy(ptr_env, function_table, sizeof(jniNativeInterface));
+    _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
+    memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
     return JVMTI_ERROR_NONE;
 }
 
@@ -2097,7 +3265,7 @@ SetJNIFunctionTable (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
 {
     CHECK_PHASE_START
@@ -2108,7 +3276,7 @@ GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
     *function_table = (jniNativeInterface*)
         heap_allocate(sizeof(jniNativeInterface),true,NULL);
-    memcpy(*function_table, ptr_env, sizeof(jniNativeInterface));
+    memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
     return JVMTI_ERROR_NONE;
 }
 
@@ -2120,7 +3288,7 @@ GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEventCallbacks (jvmtiEnv * env,
                   const jvmtiEventCallbacks * callbacks,
                   jint size_of_callbacks)
@@ -2131,9 +3299,11 @@ SetEventCallbacks (jvmtiEnv * env,
     CHECK_PHASE_END;
 
     if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-    
-    if (callbacks == NULL) { /* remove the existing callbacks */
-        memset(&(((environment* )env)->callbacks), 0, sizeof(jvmtiEventCallbacks));
+
+
+       if (callbacks == NULL) { /* remove the existing callbacks */
+        memset(&(((environment* )env)->callbacks), 0, 
+                          sizeof(jvmtiEventCallbacks));
     }
 
     memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
@@ -2142,21 +3312,21 @@ SetEventCallbacks (jvmtiEnv * env,
 }
 
 
-/* *****************************************************************************
+/* GenerateEvents *************************************************************
 
-   
+   Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent 
+   the current state of the VM.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
 {
     CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -2167,7 +3337,7 @@ GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
                       jvmtiExtensionFunctionInfo ** extensions)
 {
@@ -2176,7 +3346,7 @@ GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-    if ((extension_count_ptr== NULL)||(extensions == NULL)) 
+    if ((extension_count_ptr == NULL)||(extensions == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
     /* cacao has no extended functions yet */
@@ -2192,7 +3362,7 @@ GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
                    jvmtiExtensionEventInfo ** extensions)
 {
@@ -2201,7 +3371,7 @@ GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-    if ((extension_count_ptr== NULL)||(extensions == NULL)) 
+    if ((extension_count_ptr == NULL)||(extensions == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
     /* cacao has no extended events yet */
@@ -2217,7 +3387,7 @@ GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
                           jvmtiExtensionEvent callback)
 {
@@ -2237,12 +3407,40 @@ SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 DisposeEnvironment (jvmtiEnv * env)
 {
-    ((environment* )env)->events = NULL;
-    ((environment* )env)->EnvironmentLocalStorage = NULL;
-    /* let Boehm GC do the rest */
+       environment* cacao_env = (environment*)env;
+       environment* tenvs = envs;
+       jvmtiThreadLocalStorage *jtls, *tjtls;
+
+       if (tenvs != cacao_env) {
+               while (tenvs->next != cacao_env) {
+                       tenvs = tenvs->next;
+               }
+               tenvs->next = cacao_env->next;
+       } else
+               envs = NULL;
+
+       cacao_env->env=NULL;
+    memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    cacao_env->EnvironmentLocalStorage = NULL;
+
+       jtls = cacao_env->tls;
+       while (jtls != NULL) {
+               tjtls = jtls;
+               jtls = jtls->next;
+               tjtls->next = NULL;
+       }
+       cacao_env->tls = NULL;
+
+
+       jvmti_cacaodbgserver_quit();
+
+    /* let the GC do the rest */
     return JVMTI_ERROR_NONE;
 }
 
@@ -2257,7 +3455,7 @@ DisposeEnvironment (jvmtiEnv * env)
                                     memcpy(*name_ptr, &str, sizeof(str)); \
                                     break
 
-jvmtiError
+static jvmtiError
 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
 {
     if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -2371,10 +3569,10 @@ GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
 {
-    *format_ptr = JVMTI_JLOCATION_MACHINEPC;
+    *format_ptr = JVMTI_JLOCATION_OTHER;
     return JVMTI_ERROR_NONE;
 }
 
@@ -2386,11 +3584,10 @@ GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
 {
-    jmethodID mid;
-    jmethodID moremid;
+       jmethodID mid, moremid;
     classinfo *sysclass, *propclass, *enumclass;
     java_objectheader *sysprop, *keys, *obj;
     char* ch;
@@ -2409,47 +3606,47 @@ GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
 
     if (!sysclass) throw_main_exception_exit();
 
-    mid = class_resolvemethod(sysclass, 
+    mid = (jmethodID)class_resolvemethod(sysclass, 
                               utf_new_char("getProperties"),
                               utf_new_char("()Ljava/util/Properties;"));
     if (!mid) throw_main_exception_exit();
 
 
-    sysprop = asm_calljavafunction(mid, sysclass, NULL, NULL, NULL);
+    sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
     if (!sysprop) throw_main_exception_exit();
 
     propclass = sysprop->vftbl->class;
 
-    mid = class_resolvemethod(propclass, 
+    mid = (jmethodID)class_resolvemethod(propclass, 
                               utf_new_char("size"),
                               utf_new_char("()I"));
     if (!mid) throw_main_exception_exit();
 
     *count_ptr = 
-        JNI_JNIEnvTable.CallIntMethod(NULL, sysprop, mid);
+        _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
     *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
 
-    mid = class_resolvemethod(propclass, 
+    mid = (jmethodID)class_resolvemethod(propclass, 
                               utf_new_char("keys"),
                               utf_new_char("()Ljava/util/Enumeration;"));
     if (!mid) throw_main_exception_exit();
 
-    keys = JNI_JNIEnvTable.CallObjectMethod(NULL, sysprop, mid);
+    keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
     enumclass = keys->vftbl->class;
         
-    moremid = class_resolvemethod(enumclass, 
+    moremid = (jmethodID)class_resolvemethod(enumclass, 
                                   utf_new_char("hasMoreElements"),
                                   utf_new_char("()Z"));
     if (!moremid) throw_main_exception_exit();
 
-    mid = class_resolvemethod(propclass, 
+    mid = (jmethodID)class_resolvemethod(propclass, 
                               utf_new_char("nextElement"),
                               utf_new_char("()Ljava/lang/Object;"));
     if (!mid) throw_main_exception_exit();
 
     i = 0;
-    while (JNI_JNIEnvTable.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
-        obj = JNI_JNIEnvTable.CallObjectMethod(NULL, keys, mid);
+    while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
+        obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
         ch = javastring_tochar(obj);
         *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
         memcpy(*property_ptr[i], ch, strlen (ch));
@@ -2467,7 +3664,7 @@ GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
 {
     jmethodID mid;
@@ -2486,22 +3683,22 @@ GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
     sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
     if (!sysclass) throw_main_exception_exit();
 
-    mid = class_resolvemethod(sysclass, 
+    mid = (jmethodID)class_resolvemethod(sysclass, 
                               utf_new_char("getProperties"),
                               utf_new_char("()Ljava/util/Properties;"));
     if (!mid) throw_main_exception_exit();
 
-    sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
+    sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
 
     propclass = sysprop->vftbl->class;
 
-    mid = class_resolvemethod(propclass, 
+    mid = (jmethodID)class_resolvemethod(propclass, 
                               utf_new_char("getProperty"),
                               utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
     if (!mid) throw_main_exception_exit();
 
-    obj = (java_objectheader*)JNI_JNIEnvTable.CallObjectMethod(
-        NULL, sysprop, mid, javastring_new_char(property));
+    obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
+        NULL, sysprop, mid, javastring_new_from_ascii(property));
     if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
 
     ch = javastring_tochar(obj);
@@ -2519,7 +3716,7 @@ GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
 {
     jmethodID mid;
@@ -2536,22 +3733,22 @@ SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
     sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
     if (!sysclass) throw_main_exception_exit();
 
-    mid = class_resolvemethod(sysclass, 
+    mid = (jmethodID)class_resolvemethod(sysclass, 
                               utf_new_char("getProperties"),
                               utf_new_char("()Ljava/util/Properties;"));
     if (!mid) throw_main_exception_exit();
 
-    sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
+    sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
 
     propclass = sysprop->vftbl->class;
 
-    mid = class_resolvemethod(propclass, 
+    mid = (jmethodID)class_resolvemethod(propclass, 
                               utf_new_char("setProperty"),
                               utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
     if (!mid) throw_main_exception_exit();
 
-    JNI_JNIEnvTable.CallObjectMethod(
-        NULL, sysprop, mid, javastring_new_char(property),javastring_new_char(value));
+    _Jv_JNINativeInterface.CallObjectMethod(
+        NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
     
     return JVMTI_ERROR_NONE;
 }
@@ -2562,7 +3759,7 @@ SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
 {
     if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -2572,93 +3769,97 @@ GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetCurrentThreadCpuTimerInfo ************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)     
+
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetCurrentThreadCpuTime ****************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
+       CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)     
         
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetThreadCpuTimerInfo ******************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_get_thread_cpu_time)
+    
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetThreadCpuTime ***********************************************************
 
    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_get_thread_cpu_time)        
+  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetTimerInfo ***************************************************************
 
-   
+   Get information about the GetTime timer.    
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
-      CHECK_PHASE_START
-    CHECK_PHASE(JVMTI_PHASE_START)
-    CHECK_PHASE(JVMTI_PHASE_LIVE)
-    CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+    info_ptr->max_value = !0x0;
+       info_ptr->may_skip_forward = true;
+       info_ptr->may_skip_backward = true;
+       info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
+   
     return JVMTI_ERROR_NONE;
 }
 
@@ -2668,7 +3869,7 @@ GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
 {
     /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
@@ -2677,7 +3878,7 @@ GetTime (jvmtiEnv * env, jlong * nanos_ptr)
     if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
 
     if (gettimeofday (&tp, NULL) == -1)
-        JNI_JNIEnvTable.FatalError (NULL, "gettimeofday call failed.");
+        _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
     
     *nanos_ptr = (jlong) tp.tv_sec;
     *nanos_ptr *= 1000;
@@ -2693,9 +3894,8 @@ GetTime (jvmtiEnv * env, jlong * nanos_ptr)
 
 *******************************************************************************/
 
-jvmtiError
-GetPotentialCapabilities (jvmtiEnv * env,
-                         jvmtiCapabilities * capabilities_ptr)
+static jvmtiError
+GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
@@ -2710,16 +3910,13 @@ GetPotentialCapabilities (jvmtiEnv * env,
 }
 
 
-jvmtiError static capabilityerror() 
-{
-    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-}
-
-#define CHECK_POTENTIAL_AVAILABLE(CAN)      \
-        if ((capabilities_ptr->CAN == 1) && \
-           (JVMTI_Capabilities.CAN == 0))   \
-           return JVMTI_ERROR_NOT_AVAILABLE; 
-
+#define CHECK_ADD_CAPABILITY(env,CAN)          \
+        if (capabilities_ptr->CAN == 1) {      \
+           if (JVMTI_Capabilities.CAN == 0)    \
+             return JVMTI_ERROR_NOT_AVAILABLE; \
+           else                                \
+             env->capabilities.CAN = 1;        \
+        }                                     
 
 /* AddCapabilities ************************************************************
 
@@ -2728,7 +3925,7 @@ jvmtiError static capabilityerror()
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
 {
     environment* cacao_env;
@@ -2742,236 +3939,57 @@ AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
         return JVMTI_ERROR_NULL_POINTER;
     
     cacao_env = (environment*)env;
+    
+    CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
+    CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
+    CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
+    CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
+    CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
+    CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
+    CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
+    CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
+    CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
 
-    CHECK_POTENTIAL_AVAILABLE(can_tag_objects)
-    else {
-        cacao_env->capabilities.can_tag_objects = 1;
-        env->GetTag = &GetTag;
-        env->SetTag = &SetTag;
-        env->IterateOverObjectsReachableFromObject = 
-            &IterateOverObjectsReachableFromObject;
-        env->IterateOverReachableObjects =
-            &IterateOverReachableObjects;
-        env->IterateOverHeap = &IterateOverHeap;
-        env->IterateOverInstancesOfClass = &IterateOverInstancesOfClass;
-        env->GetObjectsWithTags = &GetObjectsWithTags;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_field_modification_events)
-    else {
-        cacao_env->capabilities.can_generate_field_modification_events = 1;
-        env->SetFieldModificationWatch = &SetFieldModificationWatch;
-        env->SetEventNotificationMode = &SetEventNotificationMode;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_field_access_events)
-    else {
-        cacao_env->capabilities.can_generate_field_access_events = 1;
-        env->SetFieldAccessWatch = &SetFieldAccessWatch;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_bytecodes)
-    else {
-        cacao_env->capabilities.can_get_bytecodes  = 1;
-        env->GetBytecodes = &GetBytecodes;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_synthetic_attribute)
-    else {
-        cacao_env->capabilities.can_get_synthetic_attribute  = 1;
-        env->IsFieldSynthetic = &IsFieldSynthetic;
-        env->IsMethodSynthetic = &IsMethodSynthetic;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_owned_monitor_info)
-    else {
-        cacao_env->capabilities.can_get_owned_monitor_info  = 1;
-        env->GetOwnedMonitorInfo = &GetOwnedMonitorInfo;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_current_contended_monitor)
-    else {
-        cacao_env->capabilities.can_get_current_contended_monitor  = 1;
-        env->GetCurrentContendedMonitor = &GetCurrentContendedMonitor;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_monitor_info)
-    else {
-        cacao_env->capabilities.can_get_monitor_info  = 1;
-        env->GetObjectMonitorUsage  = &GetObjectMonitorUsage;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_pop_frame)
-    else {
-        cacao_env->capabilities.can_pop_frame  = 1;
-        env->PopFrame  = &PopFrame;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_redefine_classes)
-    else {
-        cacao_env->capabilities.can_redefine_classes  = 1;
-        env->RedefineClasses = &RedefineClasses;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_signal_thread)
-    else {
-        cacao_env->capabilities.can_signal_thread  = 1;
-        env->StopThread = &StopThread;
-        env->InterruptThread = &InterruptThread;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_source_file_name)
-    else {
-        cacao_env->capabilities.can_get_source_file_name  = 1;
-        env->GetSourceFileName = &GetSourceFileName;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_line_numbers)
-    else {
-        cacao_env->capabilities.can_get_line_numbers  = 1;
-        env->GetLineNumberTable = &GetLineNumberTable;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_source_debug_extension)
-    else {
-        cacao_env->capabilities.can_get_source_debug_extension  = 1;
-        env->GetSourceDebugExtension = &GetSourceDebugExtension;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_access_local_variables)
-    else {
-        cacao_env->capabilities.can_access_local_variables  = 1;
-        env->GetLocalObject = &GetLocalObject;
-        env->GetLocalInt = &GetLocalInt;
-        env->GetLocalLong = &GetLocalLong;
-        env->GetLocalFloat = &GetLocalFloat;
-        env->GetLocalDouble = &GetLocalDouble;
-        env->SetLocalObject = &SetLocalObject;
-        env->SetLocalInt = &SetLocalInt;
-        env->SetLocalLong = &SetLocalLong;
-        env->SetLocalFloat = &SetLocalFloat;
-        env->SetLocalDouble = &SetLocalDouble;
-        env->GetLocalVariableTable = &GetLocalVariableTable;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_maintain_original_method_order)
-    else {
-        cacao_env->capabilities.can_maintain_original_method_order  = 1;
-        env->GetClassMethods  = &GetClassMethods;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_single_step_events)
-    else {
-        cacao_env->capabilities.can_generate_single_step_events  = 1;
-        env->SetEventNotificationMode = &SetEventNotificationMode;
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_exception_events)
-    else {
-        cacao_env->capabilities.can_generate_exception_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_frame_pop_events)
-    else {
-        cacao_env->capabilities.can_generate_frame_pop_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_breakpoint_events)
-    else {
-        cacao_env->capabilities.can_generate_breakpoint_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_suspend)
-    else {
-        cacao_env->capabilities.can_suspend  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_redefine_any_class)
-    else {
-        cacao_env->capabilities.can_redefine_any_class  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_current_thread_cpu_time)
-    else {
-        cacao_env->capabilities.can_get_current_thread_cpu_time  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_get_thread_cpu_time)
-    else {
-        cacao_env->capabilities.can_get_thread_cpu_time  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_method_entry_events)
-    else {
-        cacao_env->capabilities.can_generate_method_entry_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_method_exit_events)
-    else {
-        cacao_env->capabilities.can_generate_method_exit_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_all_class_hook_events)
-    else {
-        cacao_env->capabilities.can_generate_all_class_hook_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_compiled_method_load_events)
-    else {
-        cacao_env->capabilities.can_generate_compiled_method_load_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_monitor_events)
-    else {
-        cacao_env->capabilities.can_generate_monitor_events= 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_vm_object_alloc_events)
-    else {
-        cacao_env->capabilities.can_generate_vm_object_alloc_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_native_method_bind_events)
-    else {
-        cacao_env->capabilities.can_generate_native_method_bind_events  = 1;
-        /* env->  = &; */
-    }
-
-    CHECK_POTENTIAL_AVAILABLE(can_generate_garbage_collection_events)
-    else {
-        cacao_env->capabilities.can_generate_garbage_collection_events  = 1;
-        /* env->  = &; */
-    }
 
-    CHECK_POTENTIAL_AVAILABLE(can_generate_object_free_events)
-    else {
-        cacao_env->capabilities.can_generate_object_free_events  = 1;
-        /* env->  = &; */
-    }
-    
     return JVMTI_ERROR_NONE;    
 }
 
+
+#define CHECK_DEL_CAPABILITY(env,CAN)      \
+        if (capabilities_ptr->CAN == 1) \
+           env->capabilities.CAN = 0;
+
 /* RelinquishCapabilities *****************************************************
 
    Relinquish the capabilities pointed to by capabilities_ptr.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RelinquishCapabilities (jvmtiEnv * env,
                        const jvmtiCapabilities * capabilities_ptr)
 {
@@ -2986,42 +4004,64 @@ RelinquishCapabilities (jvmtiEnv * env,
         return JVMTI_ERROR_NULL_POINTER;
 
     cacao_env = (environment*)env;
-    
-    if (capabilities_ptr->can_tag_objects == 1) {
-        cacao_env->capabilities.can_tag_objects = 0;
-        env->GetTag = &capabilityerror;
-        env->SetTag = &capabilityerror;
-        env->IterateOverObjectsReachableFromObject = &capabilityerror;
-        env->IterateOverReachableObjects = &capabilityerror;          
-        env->IterateOverHeap = &capabilityerror;
-        env->IterateOverInstancesOfClass = &capabilityerror;
-        env->GetObjectsWithTags = &capabilityerror;  
-    }
-
-/*    todo if ((capabilities_ptr->  == 1) {
-        cacao_env->capabilities.  = 0;
-        env->SetFieldModificationWatch = &capabilityerror;
-        }*/
 
+    CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
+    CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
+    CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
+    CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
+    CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
+    CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
+    CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
+    CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
+    CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
 
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetAvailableProcessors *****************************************************
 
-   
+   Get number of processors available to the virtual machine.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
 {
-      CHECK_PHASE_START
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+    
+       if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
+       
+       *processor_count_ptr = 1; /* where do I get this ?*/
+       
     return JVMTI_ERROR_NONE;
 }
 
@@ -3031,7 +4071,7 @@ GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
 {
     if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
@@ -3048,12 +4088,12 @@ GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
 {
     if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
 
-    ((environment*)env)->EnvironmentLocalStorage = data;
+    ((environment*)env)->EnvironmentLocalStorage = (void*) data;
 
     return JVMTI_ERROR_NONE;
 }
@@ -3065,7 +4105,7 @@ SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
 {
     char* tmp_bcp;
@@ -3094,12 +4134,14 @@ AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
 {
     switch (flag) {
     case JVMTI_VERBOSE_OTHER: 
-        runverbose = value;
+               /* where is this defined ? 
+                  runverbose = value;
+               */
         break;
     case JVMTI_VERBOSE_GC: 
         opt_verbosegc = value;
@@ -3117,21 +4159,24 @@ SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
 
 /* GetObjectSize **************************************************************
 
-   For the object indicated by object, return the size of the object. This size 
-   is an implementation-specific approximation of the amount of storage consumed 
-   by this object.
+   For the object object return the size.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+       if (!builtin_instanceof(object,class_java_lang_Object))
+               return JVMTI_ERROR_INVALID_OBJECT;
+
+       *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -3142,14 +4187,21 @@ GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
 
 *******************************************************************************/
 
-jvmtiCapabilities JVMTI_Capabilities = {
+static jvmtiCapabilities JVMTI_Capabilities = {
   0,                           /* can_tag_objects */
   0,                           /* can_generate_field_modification_events */
   0,                           /* can_generate_field_access_events */
   1,                           /* can_get_bytecodes */
   0,                           /* can_get_synthetic_attribute */
+
+#if defined(ENABLE_THREADS)
+  1,                           /* can_get_owned_monitor_info */
+  1,                           /* can_get_current_contended_monitor */
+#else
   0,                           /* can_get_owned_monitor_info */
   0,                           /* can_get_current_contended_monitor */
+#endif
+
   0,                           /* can_get_monitor_info */
   0,                           /* can_pop_frame */
   0,                           /* can_redefine_classes */
@@ -3160,25 +4212,25 @@ jvmtiCapabilities JVMTI_Capabilities = {
   0,                           /* can_access_local_variables */
   0,                           /* can_maintain_original_method_order */
   0,                           /* can_generate_single_step_events */
-  0,                           /* can_generate_exception_events */
+  1,                           /* can_generate_exception_events */
   0,                           /* can_generate_frame_pop_events */
-  0,                           /* can_generate_breakpoint_events */
-  0,                           /* can_suspend */
+  1,                           /* can_generate_breakpoint_events */
+  1,                           /* can_suspend */
   0,                           /* can_redefine_any_class */
   0,                           /* can_get_current_thread_cpu_time */
   0,                           /* can_get_thread_cpu_time */
-  0,                           /* can_generate_method_entry_events */
+  1,                           /* can_generate_method_entry_events */
   0,                           /* can_generate_method_exit_events */
   0,                           /* can_generate_all_class_hook_events */
   0,                           /* can_generate_compiled_method_load_events */
-  0,                           /* can_generate_monitor_events */
+  1,                           /* can_generate_monitor_events */
   0,                           /* can_generate_vm_object_alloc_events */
   0,                           /* can_generate_native_method_bind_events */
   0,                           /* can_generate_garbage_collection_events */
   0,                           /* can_generate_object_free_events */
 };
 
-jvmtiEnv JVMTI_EnvTable = {
+static struct jvmtiEnv_struct JVMTI_EnvTable = {
     NULL,
     &SetEventNotificationMode,
     NULL,
@@ -3335,57 +4387,167 @@ jvmtiEnv JVMTI_EnvTable = {
     &GetObjectSize
 };
 
-void jvmti_init() {
-    ihmclass = load_class_from_sysloader(
-        utf_new_char_classname ("java/util/IdentityHashMap"));
-    if (ihmclass == NULL) {
-        log_text("JVMTI-Init: unable to find java.util.IdentityHashMap");
-    }
-    
-    ihmmid = class_resolvemethod(ihmclass, 
-                            utf_new_char("<init>"), 
-                            utf_new_char("()V"));
-    if (ihmmid == NULL) {
-        log_text("JVMTI-Init: unable to find constructor in java.util.IdentityHashMap");
-    }
-}
+/* jvmti_set_phase ************************************************************
+
+  sets a new jvmti phase a fires an apropriate event.
+
+*******************************************************************************/
+
+void jvmti_set_phase(jvmtiPhase p) {
+       genericEventData d;
+
+       fprintf (stderr,"set JVMTI phase %d\n",p);
+       fflush(stderr);
 
-void set_jvmti_phase(jvmtiPhase p) {
-    phase = p;
     switch (p) {
     case JVMTI_PHASE_ONLOAD:
-        /* todo */
-        break;
+               phase = p;
+        return;
     case JVMTI_PHASE_PRIMORDIAL:
-        /* todo */
-        break;
+               phase = p;
+        return;
     case JVMTI_PHASE_START: 
-        /* todo: send VM Start Event*/
+               phase = p;
+               d.ev = JVMTI_EVENT_VM_START;
         break;
     case JVMTI_PHASE_LIVE: 
-        /* todo: send VMInit Event */
-        break;
+               phase = p; 
+               d.ev = JVMTI_EVENT_VM_INIT;
+               jvmti_fireEvent(&d);
+               /* thread start event for main thread */
+               d.ev = JVMTI_EVENT_THREAD_START;
+               break;
     case JVMTI_PHASE_DEAD:
-        /* todo: send VMDeath Event */
+               phase = p;
+               d.ev = JVMTI_EVENT_VM_DEATH;
         break;
+       default:
+               log_text("wrong jvmti phase to be set");
+               exit(1);
     }
+
+       jvmti_fireEvent(&d);
 }
 
-jvmtiEnv* new_jvmtienv() {
+
+/* jvmti_new_environment ******************************************************
+
+  creates a new JVMTI environment
+
+*******************************************************************************/
+
+jvmtiEnv* jvmti_new_environment() {
     environment* env;
-    java_objectheader *o;
 
-    env = heap_allocate(sizeof(environment),true,NULL);
-    memcpy(&(env->env),&JVMTI_EnvTable,sizeof(jvmtiEnv));
-    env->events = (jobject*)builtin_new(ihmclass);
-    asm_calljavafunction(ihmmid, o, NULL, NULL, NULL);
+       if (envs == NULL) {
+               envs = heap_allocate(sizeof(environment),true,NULL);
+               env = envs;
+       } else {
+               env = envs;
+               while (env->next != NULL) env = env->next;
+               env->next = heap_allocate(sizeof(environment),true,NULL);
+               env = env->next;
+       }
+
+       env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
+    memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
+       memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
+                  sizeof(jvmtiEventModeLL));
     /* To possess a capability, the agent must add the capability.*/
-    memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
+    memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
     RelinquishCapabilities(&(env->env),&(env->capabilities));
     env->EnvironmentLocalStorage = NULL;
-    return &(env->env);
+       env->tls = NULL;
+       
+       /* initialize cacao debugging facilities */
+       jvmti_cacao_debug_init();
+
+       return (jvmtiEnv*)env;
+}
+
+/* jvmti_agentload ************************************************************
+
+  loads the indicated shared library containing the jvmti agent and calls the
+  Agent_OnLoad function.
+
+*******************************************************************************/
+
+void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle  *handle, char **libname) {
+       lt_ptr onload;
+       char *arg;
+       int i=0,len;
+       jint retval;
+
+       len = strlen(opt_arg);
+       
+       /* separate arguments */
+
+       while ((opt_arg[i] != '=') && (i < len))
+               i++;
+
+       opt_arg[i] = '\0';
+
+       if (i < len)
+               arg = &opt_arg[i + 1];
+       else
+               arg = "";
+
+       if (agentbypath) {
+               /* -agentpath */
+
+               *libname = GCMNEW(char, i);
+
+               strcpy(*libname, opt_arg);
+       }
+       else {
+               /* -agentlib */
+
+               len = strlen("lib") + i + strlen(".so") + strlen("0");
+
+               *libname = GCMNEW(char, len);
+
+               strcpy(*libname, "lib");
+               strcat(*libname, opt_arg);
+               strcat(*libname, ".so");
+       }
+
+       /* try to open the library */
+       lt_dlinit();
+       if (!(*handle = lt_dlopen(*libname))) {
+               fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
+       }
+               
+       /* resolve Agent_OnLoad function */
+       if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
+               fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
+       }
+
+       /* resolve Agent_UnLoad function */
+       unload = lt_dlsym(*handle, "Agent_Unload");
+
+       retval = 
+               ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
+                onload) ((JavaVM *) _Jv_jvm, arg, NULL);
+
+       if (retval != 0) exit (retval);
+}
+
+/* jvmti_agentunload **********************************************************
+
+  calls the Agent_UnLoad function in the jvmti agent if present.
+
+*******************************************************************************/
+
+void jvmti_agentunload() {
+       if (unload != NULL) {
+               ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload) 
+                       ((JavaVM*) &_Jv_JNIInvokeInterface);
+       }
 }
 
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
@@ -3397,4 +4559,5 @@ jvmtiEnv* new_jvmtienv() {
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */