AIArtHandle JNICALL PlacedFile_place(JNIEnv *env, AIDocumentHandle doc, jobject file, jboolean linked) {
    Document_activate(doc);
    AIPlaceRequestData request;
    SPPlatformFileSpecification fileSpec;
#if kPluginInterfaceVersion >= kAI12
    ai::FilePath filePath;
#endif
    memset(&request, 0, sizeof(AIPlaceRequestData));
    request.m_lPlaceMode = kVanillaPlace;
    if (file != NULL) {
        if (!gEngine->convertFile(env, file, &fileSpec))
            throw new StringException("Unable to create placed item.");
#if kPluginInterfaceVersion < kAI12
        request.m_pSPFSSpec = &fileSpec;
#else
        filePath = ai::FilePath(fileSpec);
        request.m_pFilePath = &filePath;
#endif
    }
    request.m_filemethod = linked ? 1 : 0;
    if (
#if kPluginInterfaceVersion < kAI12
        sAIPlaced->ExecPlaceRequest(&request)
#else
        sAIPlaced->ExecPlaceRequest(request)
#endif
        || request.m_hNewArt == NULL)
        throw new StringException("Unable to create placed item.");

    return request.m_hNewArt;
}
/*
 * int nativeSize(int docHandle)
 */
JNIEXPORT jint JNICALL Java_com_scriptographer_ai_DocumentViewList_nativeSize(JNIEnv *env, jclass cls, jint docHandle) {
	long count = 0;
	try {
		Document_activate((AIDocumentHandle) docHandle);
		sAIDocumentView->CountDocumentViews(&count);
	} EXCEPTION_CONVERT(env);
	return (jint) count;
}
/*
 * int nativeSize(int docHandle)
 */
JNIEXPORT jint JNICALL Java_com_scriptographer_ai_LayerList_nativeSize(JNIEnv *env, jclass cls, jint docHandle) {
	ai::int32 count = 0;
	try {
		Document_activate((AIDocumentHandle) docHandle);
		sAILayer->CountLayers(&count);
	} EXCEPTION_CONVERT(env);
	return count;
}
/*
 * int nativeGetView(int docHandle, int index)
 */
JNIEXPORT jint JNICALL Java_com_scriptographer_ai_DocumentViewList_nativeGet(JNIEnv *env, jclass cls, jint docHandle, jint index) {
	AIDocumentViewHandle view = NULL;
	try {
		Document_activate((AIDocumentHandle) docHandle);
		// according to the documentation, the views start at index 1:
		sAIDocumentView->GetNthDocumentView(index + 1, &view);
	} EXCEPTION_CONVERT(env);
	return (jint) view;
}
/*
 * int nativeCreate()
 */
JNIEXPORT jint JNICALL Java_com_scriptographer_ai_Gradient_nativeCreate(JNIEnv *env, jclass cls) {
	try {
		// Make sure we're switching to the right doc (gCreationDoc)
		Document_activate();
		AIGradientHandle gradient = NULL;
		sAIGradient->NewGradient(&gradient);
		return (jint) gradient;
	} EXCEPTION_CONVERT(env);
	return 0;
}
/*
 * java.lang.Object nativeGet(int docHandle, int index)
 */
JNIEXPORT jobject JNICALL Java_com_scriptographer_ai_LayerList_nativeGet__II(JNIEnv *env, jclass cls, jint docHandle, jint index) {
	jobject layerObj = NULL;
	try {
		Document_activate((AIDocumentHandle) docHandle);
		AILayerHandle layer = NULL;
		sAILayer->GetNthLayer(index, &layer);
		if (layer != NULL)
			layerObj = gEngine->wrapLayerHandle(env, layer, (AIDocumentHandle) docHandle);
	} EXCEPTION_CONVERT(env);
	return layerObj;
}
/*
 * int nativeCreate(int docHandle, int artHandle)
 */
JNIEXPORT jint JNICALL Java_com_scriptographer_ai_Tracing_nativeCreate(JNIEnv *env, jclass cls, jint docHandle, jint artHandle) {
	try {
#if kPluginInterfaceVersion >= kAI12
		AIArtHandle tracing = NULL;
		Document_activate((AIDocumentHandle) docHandle);
		// we just pass the image itself for prep. TODO: find out what we're supposed to pass here!
		sAITracing->CreateTracing(kPlaceAbove, (AIArtHandle) artHandle, (AIArtHandle) artHandle, &tracing);
		return (jint) tracing;
#else
		TRACING_EXCEPTION
#endif
	} EXCEPTION_CONVERT(env);
	return 0;
}
/*
 * java.lang.Object nativeGet(int docHandle, java.lang.String name)
 */
JNIEXPORT jobject JNICALL Java_com_scriptographer_ai_LayerList_nativeGet__ILjava_lang_String_2(JNIEnv *env, jclass cls, jint docHandle, jstring name) {
	jobject layerObj = NULL;
	try {
		Document_activate((AIDocumentHandle) docHandle);
		AILayerHandle layer = NULL;
#if kPluginInterfaceVersion < kAI12
		char *str = gEngine->convertString(env, name);
		sAILayer->GetLayerByTitle(&layer, gPlugin->toPascal(str, (unsigned char *) str));
		delete str;
#else
		ai::UnicodeString str = gEngine->convertString_UnicodeString(env, name);
		sAILayer->GetLayerByTitle(&layer, str);
#endif
		if (layer != NULL)
			layerObj = gEngine->wrapLayerHandle(env, layer, (AIDocumentHandle) docHandle);
	} EXCEPTION_CONVERT(env);
	return layerObj;
}