NS_IMETHODIMP nsWFSecureEnv::FatalError(/*[in]*/ const char* msg)
{
    if (m_env == NULL)
        return NS_ERROR_NULL_POINTER;
    
    OJI_LOG2("Fatal error: %s", msg);
    m_env->FatalError(msg);

    return NS_OK;
}
NS_IMETHODIMP 
nsPluggableJVM::StartupJVM(const char *classPath, 
			   nsPluggableJVMStatus *status,
			   jlong sup)
{
  JavaVMInitArgs vm_args;
  jint res;
  OJI_LOG("nsPluggableJVM::StartupJVM");
  *status = nsPluggableJVMStatus_Failed;
  if (sup == nsnull) return NS_ERROR_FAILURE;
  const char* plugin_home = getenv("WFHOME");
  if (plugin_home == NULL) {
    OJI_LOG("Env variable JAVA_PLUGIN_HOME not set");
    return NS_ERROR_FAILURE;
  }
  if (NS_FAILED(loadPluginDLL(plugin_home))) 
    return NS_ERROR_FAILURE;
  memset(&vm_args, 0, sizeof(vm_args));
  vm_args.version = JNI_VERSION_1_2;
  // XXX: add classpath here
  if (NS_FAILED(initJVM(&m_ctx, &vm_args))) 
    return NS_ERROR_FAILURE;
  // initialize capability mechanism 
  JVMP_SecurityCap cap;
  JVMP_FORBID_ALL_CAPS(cap);
  JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_SYSTEM);
  JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_SYSEVENT)
  JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_EVENT);
  JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_CALL);
  jbyte** prins;
  jint    pnum = 2;
  jint*   plen;
  if (!newPrincipalsFromStrings(&prins, &plen, 
				pnum, "CAPS", "MOZILLA"))
    return JNI_FALSE;
  if ((m_jvmp_context->JVMP_EnableCapabilities)
      (m_ctx, &cap, pnum, plen, prins) != JNI_TRUE) 
    {
      OJI_LOG("Can\'t enable caps");
      return JNI_FALSE;
    };
  deletePrincipals(prins, plen, pnum);
  SetConsoleVisibility(PR_TRUE);
  char* ext_dll = PR_GetLibraryName(plugin_home, LIBEXT);
  OJI_LOG2("JVMP_RegisterExtension: %s", ext_dll);
  res = (m_jvmp_context->JVMP_RegisterExtension)(m_ctx, 
						 ext_dll,
						 &m_extID,
						 sup);
  PR_Free(ext_dll);
  if (res != JNI_TRUE || m_extID == 0) return NS_ERROR_FAILURE;  
  OJI_LOG("JVMP_RegisterExtension OK");
  *status = nsPluggableJVMStatus_Running;
  return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::GetValue(nsPluginInstanceVariable variable, void *value)
{
  OJI_LOG2("nsAppletHTMLObject::GetValue: %d", variable);
  if (variable == nsPluginInstanceVariable_DoCacheBool) 
    {
      //OJI_LOG("SET NO PLUGIN CACHING");
      *(PRBool*)value = PR_FALSE;
      return NS_OK;
    }
  return NS_OK;
}
NS_IMETHODIMP 
nsPluggableJVM::GetWFCtx(JVMP_RuntimeContext* *rt_ctx, 
			 JVMP_CallingContext* *c_ctx)
{
  if (!m_jvmp_context) return NS_ERROR_FAILURE;
  *rt_ctx = m_jvmp_context;
  if ((m_jvmp_context->JVMP_GetCallingContext)(c_ctx) != JNI_TRUE)
    {
      OJI_LOG2("JVMP_GetCallingContext failed: %ld", (*c_ctx)->err);
      return NS_ERROR_FAILURE;
    }
  return NS_OK;
}
NS_IMETHODIMP 
nsPluggableJVM::RegisterWindow(nsPluginWindow* rwin, 
			       jint *ID)
{
  JVMP_DrawingSurfaceInfo w;

  OJI_LOG("nsPluggableJVM::RegisterWindow");
  w.window =  (JPluginWindow *)rwin->window;
  w.x = rwin->x;
  w.y = rwin->y;
  w.width = rwin->width;
  w.height = rwin->height;
  if ((m_jvmp_context->JVMP_RegisterWindow)(m_ctx, &w, ID) != JNI_TRUE) 
    {
      OJI_LOG("can\'t register window");
      return NS_ERROR_FAILURE;
    };
  OJI_LOG2("Registed our native window with ID %ld", *ID);
  return NS_OK;
}
NS_IMETHODIMP
nsAppletHTMLObject::Initialize(nsIPluginInstancePeer *peer)
{
  nsresult res;
  OJI_LOG("nsAppletHTMLObject::Initialize");
  m_peer = peer;
  NS_ADDREF(m_peer);
  peer->QueryInterface(kIPluginInstancePeer2IID,
                       (void **)&m_peer2);
  m_jobject = new nsJavaHTMLObject(m_factory);
  NS_ADDREF(m_jobject);
  res = nsServiceManager::GetService(kPluginManagerCID, 
				     kIPluginManagerIID,
				     getter_AddRefs(m_mgr));
  if (NS_FAILED(res)) return res;
  m_id = 0;
  if (NS_FAILED(res = m_factory->GetJVM(&m_jvm)))          return res;
  if (NS_FAILED(res = m_jvm->GetJNIEnv(&m_env)))           return res;
  if (NS_FAILED(res = m_jobject->Initialize(peer, m_jvm))) return res;
  // find out applet information from our peer and explain it 
  // to nsJavaHTMLObject
  // in new API nsJavaHTMLObject should get everything needed
  // from peer
  nsJavaObjectInfo* info = 
    new nsJavaObjectInfo((nsIWFInstanceWrapper*)this);
  NS_ADDREF(info);
  nsIPluginTagInfo *tagInfo;
  if (NS_SUCCEEDED(res = peer->QueryInterface(kIPluginTagInfoIID,
					      (void **)&tagInfo)))
    {
      PRUint16 argc = 0, i;
      char **keys, **vals;
      tagInfo->GetAttributes(argc, (const char* const* &)keys, 
			     (const char* const* &) vals);
      for (i=0; i<argc; i++) 
	info->AddParameter(keys[i], vals[i]);
      NS_RELEASE(tagInfo);
    }
  
  nsIPluginTagInfo2 *extTagInfo;
  if (NS_SUCCEEDED(res = peer->QueryInterface(kIPluginTagInfo2IID, 
					      (void **)&extTagInfo)))
    {
      nsPluginTagType tagType = nsPluginTagType_Unknown;
      if (NS_SUCCEEDED(extTagInfo->GetTagType(&tagType)))
        {
          if (tagType == nsPluginTagType_Applet || 
              tagType == nsPluginTagType_Object) 
	    {
	      PRUint16 argc = 0, i;
	      char **keys, **vals;
	      extTagInfo->GetParameters(argc, 
					(const char*const*&)keys,
					(const char*const*&) vals); 
	      for (i=0; i<argc; i++) 
		info->AddParameter(keys[i], vals[i]);
	    }
	  nsJavaObjectType type = mapType(tagType);
	  info->SetType(type);
	  if (NS_FAILED(res = m_jobject->SetType(type)))
	    return res;
        }
      const char *docbase = NULL;
      if (NS_FAILED(res = extTagInfo->GetDocumentBase(&docbase)))
	{
	  OJI_LOG("Failed to obtain doc base");
	}
      if (docbase != NULL) 
	{
	  char *slash = strrchr((char*)docbase, '/');
	  if (slash != NULL) *(slash+1) = 0;
	  OJI_LOG2("real docbase is %s", docbase);
	  info->SetDocBase(docbase);
        }            
      NS_RELEASE(extTagInfo);
    }
  // really it's crucial to call SetType() _before_ passing Java object info
  // otherwise parameters will be passed to wrapper - and silently ignored
  res = m_jobject->SetJavaObjectInfo(info);
  NS_RELEASE(info);
  return res;
}