/*
 * Class:     java/lang/reflect/VMMethod
 * Method:    getDefaultValue
 * Signature: ()Ljava/lang/Object;
 *
 * Parses the annotation default value and returnes it (boxed, if it's a primitive).
 */
JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_getDefaultValue(JNIEnv *env, jobject _this)
{
	static methodinfo *m_parseAnnotationDefault   = NULL; /* parser method (will be chached, therefore static) */
	Utf8String         utf_parseAnnotationDefault = NULL; /* parser method name                                */
	Utf8String         utf_desc        = NULL;            /* parser method descriptor (signature)              */

	if (_this == NULL) {
		exceptions_throw_nullpointerexception();
		return NULL;
	}

	// TODO Use a constructor.
	java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);

	if (h == NULL)
		return NULL;

	sun_reflect_ConstantPool cp(h);
	
	java_lang_reflect_VMMethod rvmm(_this);
	classinfo* declaringClass = rvmm.get_clazz();
	cp.set_constantPoolOop(declaringClass);

	/* only resolve the parser method the first time */
	if (m_parseAnnotationDefault == NULL) {
		utf_parseAnnotationDefault = Utf8String::from_utf8("parseAnnotationDefault");
		utf_desc = Utf8String::from_utf8(
			"(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
			"Ljava/lang/Object;");

		if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
			/* out of memory */
			return NULL;
		}

		classinfo *referer = rvmm.get_Class();

		m_parseAnnotationDefault = class_resolveclassmethod(
			class_sun_reflect_annotation_AnnotationParser,
			utf_parseAnnotationDefault,
			utf_desc,
			referer,
			true);

		if (m_parseAnnotationDefault == NULL) {
			/* method not found */
			return NULL;
		}
	}

	java_lang_reflect_Method rm(rvmm.get_m());
	java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();

	java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());

	return (jobject) result;
}
/*
 * Class:     java/lang/VMObject
 * Method:    getClass
 * Signature: (Ljava/lang/Object;)Ljava/lang/Class;
 */
JNIEXPORT jclass JNICALL Java_java_lang_VMObject_getClass(JNIEnv* env, jclass clazz, jobject obj)
{
	if (obj == NULL) {
		exceptions_throw_nullpointerexception();
		return NULL;
	}

	java_lang_Object o(obj);

	return (jclass) LLNI_classinfo_wrap(o.get_Class());
}
/*
 * Class:     gnu/classpath/VMSystemProperties
 * Method:    preInit
 * Signature: (Ljava/util/Properties;)V
 */
JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
{
	java_objectheader *p;

	p = (java_objectheader *) properties;

	if (p == NULL) {
		exceptions_throw_nullpointerexception();
		return;
	}

	/* fill the java.util.Properties object */

	properties_system_add_all(p);
}
/*
 * Class:     gnu/classpath/VMSystemProperties
 * Method:    postInit
 * Signature: (Ljava/util/Properties;)V
 */
JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_postInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
{
	java_objectheader *p;
#if defined(WITH_JRE_LAYOUT)
	char *path;
	s4    len;
#endif

	p = (java_objectheader *) properties;

	if (p == NULL) {
		exceptions_throw_nullpointerexception();
		return;
	}

	/* post-set some properties */

#if defined(WITH_JRE_LAYOUT)
	/* XXX when we do it that way, we can't set these properties on
	   commandline */

	properties_system_add(p, "gnu.classpath.home", cacao_prefix);

	len =
		strlen("file://") +
		strlen(cacao_prefix) +
		strlen("/lib") +
		strlen("0");

	path = MNEW(char, len);

	strcpy(path, "file://");
	strcat(path, cacao_prefix);
	strcat(path, "/lib");

	properties_system_add(p, "gnu.classpath.home.url", path);

	MFREE(path, char, len);
#endif
}