
#ifndef __VMHOLDER
#define __VMHOLDER

#include <vector>
#include <hash_map>
#include <cstdarg>			// std::va_list and friends

#include <jni.h>


#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#ifndef _THREAD_HXX_
#include <osl/thread.hxx>
#endif

class JavaVMContext {
	typedef ::std::hash_map<sal_uInt32, sal_uInt32/*, ::std::hash<sal_uInt32>, ::std::equal_to<sal_uInt32*/> UINT32_UINT32_HashMap;
	::osl::Mutex                 _mutex;
	UINT32_UINT32_HashMap _registeredThreadMap;

public:
	JavaVM * _pJavaVM;

	JavaVMContext(JavaVM * pJavaVM) {
		OSL_TRACE("JavaVMContext::JavaVMContext");
		_pJavaVM = pJavaVM;
	}

	~JavaVMContext() {
		OSL_TRACE("JavaVMContext::~JavaVMContext");
	}

	sal_Bool isThreadAttached(void) throw() {
        sal_Int32 nThreadID = ::osl::Thread::getCurrentIdentifier();

		::osl::MutexGuard guard(_mutex);
		return _registeredThreadMap.end() != _registeredThreadMap.find(nThreadID);
	}

	sal_Bool registerThread(void) throw() {
        sal_Int32 nThreadID = ::osl::Thread::getCurrentIdentifier();
		
		::osl::MutexGuard guard(_mutex);
		
		sal_Bool result = sal_False; // true means, we have to detach

		UINT32_UINT32_HashMap::iterator aIt = _registeredThreadMap.find(nThreadID);

		if (aIt == _registeredThreadMap.end()) {
			_registeredThreadMap[nThreadID] = 1;
			result = sal_True;
		}
		else
			(*aIt).second++;

		return result;
	}

	void revokeThread(void) throw() {
        sal_Int32 nThreadID = ::osl::Thread::getCurrentIdentifier();
		
		::osl::MutexGuard guarg(_mutex);
		
		UINT32_UINT32_HashMap::iterator aIt = _registeredThreadMap.find(nThreadID);
		OSL_ASSERT(aIt != _registeredThreadMap.end());
		if (aIt != _registeredThreadMap.end()) {
			if ( 0 == --((*aIt).second) )
				_registeredThreadMap.erase(nThreadID);
		}
	}
};



#endif
