Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/native/MacLauncher/.idea/.name b/native/MacLauncher/.idea/.name
new file mode 100644
index 0000000..dc9c257
--- /dev/null
+++ b/native/MacLauncher/.idea/.name
@@ -0,0 +1 @@
+MacLauncher
\ No newline at end of file
diff --git a/native/MacLauncher/.idea/AppLauncher.iml b/native/MacLauncher/.idea/AppLauncher.iml
new file mode 100644
index 0000000..f9b36de
--- /dev/null
+++ b/native/MacLauncher/.idea/AppLauncher.iml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="CIDR_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/native/MacLauncher/.idea/dictionaries/max.xml b/native/MacLauncher/.idea/dictionaries/max.xml
new file mode 100644
index 0000000..81b3e8d
--- /dev/null
+++ b/native/MacLauncher/.idea/dictionaries/max.xml
@@ -0,0 +1,3 @@
+<component name="ProjectDictionaryState">
+  <dictionary name="max" />
+</component>
\ No newline at end of file
diff --git a/native/MacLauncher/.idea/encodings.xml b/native/MacLauncher/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/native/MacLauncher/.idea/encodings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/native/MacLauncher/.idea/find.xml b/native/MacLauncher/.idea/find.xml
new file mode 100644
index 0000000..6892330
--- /dev/null
+++ b/native/MacLauncher/.idea/find.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="OCFindUsagesOptions" text="true" ivars="false" properties="true" derivedClasses="false" />
+</project>
+
diff --git a/native/MacLauncher/.idea/misc.xml b/native/MacLauncher/.idea/misc.xml
new file mode 100644
index 0000000..11e74ae
--- /dev/null
+++ b/native/MacLauncher/.idea/misc.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectResources">
+    <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
+  </component>
+  <component name="ProjectRootManager" version="2" />
+</project>
+
diff --git a/native/MacLauncher/.idea/modules.xml b/native/MacLauncher/.idea/modules.xml
new file mode 100644
index 0000000..e774462
--- /dev/null
+++ b/native/MacLauncher/.idea/modules.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/AppLauncher.iml" filepath="$PROJECT_DIR$/.idea/AppLauncher.iml" />
+    </modules>
+  </component>
+</project>
+
diff --git a/native/MacLauncher/.idea/scopes/scope_settings.xml b/native/MacLauncher/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/native/MacLauncher/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/native/MacLauncher/.idea/vcs.xml b/native/MacLauncher/.idea/vcs.xml
new file mode 100644
index 0000000..9ab281a
--- /dev/null
+++ b/native/MacLauncher/.idea/vcs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
+  </component>
+</project>
+
diff --git a/native/MacLauncher/.idea/xcode.xml b/native/MacLauncher/.idea/xcode.xml
new file mode 100644
index 0000000..28f4cb3
--- /dev/null
+++ b/native/MacLauncher/.idea/xcode.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="XcodeMetaData" PROJECT_FILE="$PROJECT_DIR$/MacLauncher.xcodeproj" />
+</project>
+
diff --git a/native/MacLauncher/Info.plist b/native/MacLauncher/Info.plist
new file mode 100644
index 0000000..a189b85
--- /dev/null
+++ b/native/MacLauncher/Info.plist
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>JetBrains.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>Java</key>
+	<dict>
+		<key>ClassPath</key>
+		<string>$APP_PACKAGE</string>
+		<key>MainClass</key>
+		<string>com.intellij.idea.Main</string>
+		<key>Properties</key>
+		<dict>
+			<key>CVS_PASSFILE</key>
+			<string>~/.cvspass</string>
+			<key>apple.laf.useScreenMenuBar</key>
+			<string>true</string>
+			<key>com.apple.mrj.application.live-resize</key>
+			<string>false</string>
+			<key>idea.config.path</key>
+			<string>~/Library/Preferences/IntelliJIdea10CE/</string>
+			<key>idea.is.internal</key>
+			<string>true</string>
+			<key>idea.log.path</key>
+			<string>~/Library/Logs/IntelliJIdea10CE/</string>
+			<key>idea.platform.prefix</key>
+			<string>Idea</string>
+			<key>idea.plugins.path</key>
+			<string>~/Library/Application Support/IntelliJIdea10CE/</string>
+			<key>idea.system.path</key>
+			<string>~/Library/Caches/IntelliJIdea10CE/</string>
+			<key>idea.use.default.antialiasing.in.editor</key>
+			<string>true</string>
+		</dict>
+		<key>VMOptions</key>
+		<string>-ea</string>
+		<key>VMOptions.i386</key>
+		<string>-Xms128m -Xmx512m -XX:MaxPermSize=250m</string>
+		<key>VMOptions.x86_64</key>
+		<string>-Xms128m -Xmx800m -XX:MaxPermSize=350m -XX:+UseCompressedOops -XX:ReservedCodeCacheSize=256m</string>
+		<key>WorkingDirectory</key>
+		<string>$APP_PACKAGE/bin</string>
+	</dict>
+	<key>LSMinimumSystemVersion</key>
+	<string>${MACOSX_DEPLOYMENT_TARGET}</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright © 2012 JetBrains inc. All rights reserved.</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
diff --git a/native/MacLauncher/Launcher.h b/native/MacLauncher/Launcher.h
new file mode 100644
index 0000000..ec34086
--- /dev/null
+++ b/native/MacLauncher/Launcher.h
@@ -0,0 +1,20 @@
+//
+// Created by max on 5/4/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import <Foundation/Foundation.h>
+#import <JavaVM/jni.h>
+
+
+@interface Launcher : NSObject {
+    int argc;
+    char **argv;
+}
+- (id)initWithArgc:(int)anArgc argv:(char **)anArgv;
+
+
+- (void) launch;
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/Launcher.m b/native/MacLauncher/Launcher.m
new file mode 100644
index 0000000..f00945c
--- /dev/null
+++ b/native/MacLauncher/Launcher.m
@@ -0,0 +1,388 @@
+//
+// Created by max on 5/4/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import "Launcher.h"
+#import "VMOptionsReader.h"
+#import "PropertyFileReader.h"
+#import "utils.h"
+#import <dlfcn.h>
+
+typedef jint (JNICALL *fun_ptr_t_CreateJavaVM)(JavaVM **pvm, void **env, void *args);
+
+
+@interface NSString (CustomReplacements)
+- (NSString *)replaceAll:(NSString *)pattern to:(NSString *)replacement;
+
+@end
+
+@implementation NSString (CustomReplacements)
+- (NSString *)replaceAll:(NSString *)pattern to:(NSString *)replacement {
+    if ([self rangeOfString:pattern].length == 0) return self;
+
+    NSMutableString *answer = [[self mutableCopy] autorelease];
+    [answer replaceOccurrencesOfString:pattern withString:replacement options:0 range:NSMakeRange(0, [self length])];
+    return answer;
+}
+@end
+
+@interface NSDictionary (TypedGetters)
+- (NSDictionary *)dictionaryForKey:(id)key;
+- (id)valueForKey:(NSString *)key inDictionary:(NSString *)dictKey defaultObject:(NSString *)defaultValue;
+@end
+
+@implementation NSDictionary (TypedGetters)
+- (NSDictionary *)dictionaryForKey:(id)key {
+    id answer = [self objectForKey:key];
+    if ([answer isKindOfClass:[NSDictionary class]]) {
+        return answer;
+    }
+    return nil;
+}
+
+- (id)valueForKey:(NSString *)key inDictionary:(NSString *)dictKey defaultObject: (NSString*) defaultValue {
+    NSDictionary *dict = [self dictionaryForKey:dictKey];
+    if (dict == nil) return nil;
+    id answer = [dict valueForKey:key];
+    return answer != nil ? answer : defaultValue;
+}
+@end
+
+@implementation Launcher
+
+- (id)initWithArgc:(int)anArgc argv:(char **)anArgv {
+    self = [super init];
+    if (self) {
+        argc = anArgc;
+        argv = anArgv;
+    }
+
+    return self;
+}
+
+
+void appendJvmBundlesAt(NSString *path, NSMutableArray *sink) {
+    NSError *error = nil;
+    NSArray *names = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
+
+    if (names != nil) {
+        for (NSString *name in names) {
+            if ([name hasSuffix:@".jdk"] || [name hasSuffix:@".jre"]) {
+                NSBundle *bundle = [NSBundle bundleWithPath:[path stringByAppendingPathComponent:name]];
+                if (bundle != nil) {
+                    [sink addObject:bundle];
+                }
+            }
+        }
+    }
+}
+
+NSArray *allVms() {
+    NSMutableArray *jvmBundlePaths = [NSMutableArray array];
+
+    NSString *explicit = [[[NSProcessInfo processInfo] environment] objectForKey:@"IDEA_JDK"];
+
+    if (explicit != nil) {
+        appendJvmBundlesAt(explicit, jvmBundlePaths);
+    }
+    else {
+        NSBundle *bundle = [NSBundle mainBundle];
+        NSString *appDir = bundle.bundlePath;
+
+        appendJvmBundlesAt([appDir stringByAppendingPathComponent:@"jre"], jvmBundlePaths);
+        if (jvmBundlePaths.count > 0) return jvmBundlePaths;
+
+        appendJvmBundlesAt([NSHomeDirectory() stringByAppendingPathComponent:@"Library/Java/JavaVirtualMachines"], jvmBundlePaths);
+        appendJvmBundlesAt(@"/Library/Java/JavaVirtualMachines", jvmBundlePaths);
+        appendJvmBundlesAt(@"/System/Library/Java/JavaVirtualMachines", jvmBundlePaths);
+    }
+
+    return jvmBundlePaths;
+}
+
+NSString *jvmVersion(NSBundle *bundle) {
+    return [bundle.infoDictionary valueForKey:@"JVMVersion" inDictionary:@"JavaVM" defaultObject:@"0"];
+}
+
+NSString *requiredJvmVersion() {
+    return [[NSBundle mainBundle].infoDictionary valueForKey:@"JVMVersion" inDictionary:@"Java" defaultObject:@"1.7*"];
+}
+
+BOOL satisfies(NSString *vmVersion, NSString *requiredVersion) {
+    if ([requiredVersion hasSuffix:@"+"]) {
+        requiredVersion = [requiredVersion substringToIndex:[requiredVersion length] - 1];
+        return [requiredVersion compare:vmVersion options:NSNumericSearch] <= 0;
+    }
+
+    if ([requiredVersion hasSuffix:@"*"]) {
+        requiredVersion = [requiredVersion substringToIndex:[requiredVersion length] - 1];
+    }
+
+    return [vmVersion hasPrefix:requiredVersion];
+}
+
+NSComparisonResult compareVMVersions(id vm1, id vm2, void *context) {
+    return [jvmVersion(vm2) compare:jvmVersion(vm1) options:NSNumericSearch];
+}
+
+NSBundle *findMatchingVm() {
+    NSArray *vmBundles = [allVms() sortedArrayUsingFunction:compareVMVersions context:NULL];
+
+    if (isDebugEnabled()) {
+        debugLog(@"Found Java Virtual Machines:");
+        for (NSBundle *vm in vmBundles) {
+            debugLog([vm bundlePath]);
+        }
+    }
+
+    NSString *required = requiredJvmVersion();
+    debugLog([NSString stringWithFormat:@"Required VM: %@", required]);
+
+    for (NSBundle *vm in vmBundles) {
+        if (satisfies(jvmVersion(vm), required)) {
+            debugLog(@"Chosen VM:");
+            debugLog([vm bundlePath]);
+            return vm;
+        }
+    }
+
+    debugLog(@"No matching VM found");
+
+    return nil;
+}
+
+CFBundleRef NSBundle2CFBundle(NSBundle *bundle) {
+    CFURLRef bundleURL = (CFURLRef) ([NSURL fileURLWithPath:bundle.bundlePath]);
+    return CFBundleCreate(kCFAllocatorDefault, bundleURL);
+}
+
+- (NSString *)expandMacros:(NSString *)str {
+    return [[str
+            replaceAll:@"$APP_PACKAGE" to:[[NSBundle mainBundle] bundlePath]]
+            replaceAll:@"$USER_HOME" to:NSHomeDirectory()];
+}
+
+- (NSMutableString *)buildClasspath:(NSBundle *)jvm {
+    NSDictionary *jvmInfo = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Java"];
+    NSMutableString *classpathOption = [NSMutableString stringWithString:@"-Djava.class.path="];
+    [classpathOption appendString:[jvmInfo objectForKey:@"ClassPath"]];
+
+    NSString *toolsJar = [[jvm bundlePath] stringByAppendingString:@"/Contents/Home/lib/tools.jar"];
+    if ([[NSFileManager defaultManager] fileExistsAtPath:toolsJar]) {
+        [classpathOption appendString:@":"];
+        [classpathOption appendString:toolsJar];
+    }
+    return classpathOption;
+}
+
+
+NSString *getSelector() {
+    NSDictionary *jvmInfo = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Java"];
+    NSDictionary *properties = [jvmInfo dictionaryForKey:@"Properties"];
+    if (properties != nil) {
+        return [properties objectForKey:@"idea.paths.selector"];
+    }
+    return nil;
+}
+
+NSString *getPreferencesFolderPath() {
+    return [NSString stringWithFormat:@"%@/Library/Preferences/%@", NSHomeDirectory(), getSelector()];
+}
+
+NSString *getPropertiesFilePath() {
+    return [getPreferencesFolderPath() stringByAppendingString:@"/idea.properites"];
+}
+
+NSString *getDefaultPropertiesFilePath() {
+    return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/bin/idea.properties"];
+}
+
+NSString *getDefaultVMOptionsFilePath() {
+    return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/bin/idea.vmoptions"];
+}
+
+NSString *getVMOptionsFilePath() {
+    return [getPreferencesFolderPath() stringByAppendingString:@"/idea.vmoptions"];
+}
+
+NSArray *parseVMOptions() {
+    NSArray *inConfig=[VMOptionsReader readFile:getVMOptionsFilePath()];
+    if (inConfig) return inConfig;
+    return [VMOptionsReader readFile:getDefaultVMOptionsFilePath()];
+}
+
+NSDictionary *parseProperties() {
+    NSDictionary *inConfig = [PropertyFileReader readFile:getPropertiesFilePath()];
+    if (inConfig) return inConfig;
+    return [PropertyFileReader readFile:getDefaultPropertiesFilePath()];
+}
+
+- (void)fillArgs:(NSMutableArray *)args_array fromProperties:(NSDictionary *)properties {
+    if (properties != nil) {
+        for (id key in properties) {
+            [args_array addObject:[NSString stringWithFormat:@"-D%@=%@", key, [properties objectForKey:key]]];
+        }
+    }
+}
+
+- (JavaVMInitArgs)buildArgsFor:(NSBundle *)jvm {
+    NSMutableString *classpathOption = [self buildClasspath:jvm];
+
+    NSDictionary *jvmInfo = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Java"];
+    NSMutableArray *args_array = [NSMutableArray array];
+
+    [args_array addObject:classpathOption];
+
+    [args_array addObjectsFromArray:[[jvmInfo objectForKey:@"VMOptions"] componentsSeparatedByString:@" "]];
+    [args_array addObjectsFromArray:parseVMOptions()];    
+
+    [self fillArgs:args_array fromProperties:[jvmInfo dictionaryForKey:@"Properties"]];
+    [self fillArgs:args_array fromProperties:parseProperties()];
+
+    JavaVMInitArgs args;
+    args.version = JNI_VERSION_1_6;
+    args.ignoreUnrecognized = JNI_TRUE;
+
+    args.nOptions = (jint)[args_array count];
+    args.options = calloc((size_t) args.nOptions, sizeof(JavaVMOption));
+    for (NSUInteger idx = 0; idx < args.nOptions; idx++) {
+        id obj = [args_array objectAtIndex:idx];
+        args.options[idx].optionString = strdup([[self expandMacros:[obj description]] UTF8String]);
+    }
+    return args;
+}
+
+- (const char *)mainClassName {
+    NSDictionary *jvmInfo = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Java"];
+    char *answer = strdup([[jvmInfo objectForKey:@"MainClass"] UTF8String]);
+    
+    char *cur = answer;
+    while (*cur) {
+        if (*cur == '.') {
+            *cur = '/';
+        }
+        cur++;
+    }
+    
+    return answer;
+}
+
+- (void)process_cwd {
+    NSDictionary *jvmInfo = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Java"];
+    NSString *cwd = [jvmInfo objectForKey:@"WorkingDirectory"];
+    if (cwd != nil) {
+        cwd = [self expandMacros:cwd];
+        if (chdir([cwd UTF8String]) != 0) {
+            NSLog(@"Cannot chdir to working directory at %@", cwd);
+        }
+    }
+}
+
+- (void)launch {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    NSBundle *vm = findMatchingVm();
+    if (vm == nil) {
+        NSString *old_launcher = [self expandMacros:@"$APP_PACKAGE/Contents/MacOS/idea_appLauncher"];
+        execv([old_launcher fileSystemRepresentation], self->argv);
+
+        NSLog(@"Cannot find matching VM, aborting");
+        exit(-1);
+    }
+
+    NSError *error = nil;
+    BOOL ok = [vm loadAndReturnError:&error];
+    if (!ok) {
+        NSLog(@"Cannot load JVM bundle: %@", error);
+        exit(-1);
+    }
+
+    CFBundleRef cfvm = NSBundle2CFBundle(vm);
+
+    fun_ptr_t_CreateJavaVM create_vm = CFBundleGetFunctionPointerForName(cfvm, CFSTR("JNI_CreateJavaVM"));
+
+    if (create_vm == NULL) {
+        // We have Apple VM chosen here...
+/*
+        [self execCommandLineJava:vm];
+        return;
+*/
+
+        NSString *serverLibUrl = [vm.bundlePath stringByAppendingPathComponent:@"Contents/Libraries/libserver.dylib"];
+
+        void *libHandle = dlopen(serverLibUrl.UTF8String, RTLD_NOW + RTLD_GLOBAL);
+        if (libHandle) {
+            create_vm = dlsym(libHandle, "JNI_CreateJavaVM_Impl");
+        }
+    }
+
+    if (create_vm == NULL) {
+        NSLog(@"Cannot find JNI_CreateJavaVM in chosen JVM bundle at %@", vm.bundlePath);
+        exit(-1);
+    }
+
+    [self process_cwd];
+
+    JNIEnv *env;
+    JavaVM *jvm;
+
+    JavaVMInitArgs args = [self buildArgsFor:vm];
+
+    jint create_vm_rc = create_vm(&jvm, &env, &args);
+    if (create_vm_rc != JNI_OK || jvm == NULL) {
+        NSLog(@"JNI_CreateJavaVM (%@) failed: %d", vm.bundlePath, create_vm_rc);
+        exit(-1);
+    }
+
+    jclass string_class = (*env)->FindClass(env, "java/lang/String");
+    if (string_class == NULL) {
+        NSLog(@"No java.lang.String in classpath!");
+        exit(-1);
+    }
+
+    const char *mainClassName = [self mainClassName];
+    jclass mainClass = (*env)->FindClass(env, mainClassName);
+    if (mainClass == NULL || (*env)->ExceptionOccurred(env)) {
+        NSLog(@"Main class %s not found", mainClassName);
+        (*env)->ExceptionDescribe(env);
+        exit(-1);
+    }
+
+    jmethodID mainMethod = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");
+    if (mainMethod == NULL || (*env)->ExceptionOccurred(env)) {
+        NSLog(@"Cant't find main() method");
+        (*env)->ExceptionDescribe(env);
+        exit(-1);
+    }
+
+    // See http://stackoverflow.com/questions/10242115/os-x-strange-psn-command-line-parameter-when-launched-from-finder
+    // about psn_ stuff
+    int arg_count = 0;
+    for (int i = 1; i < argc; i++) {
+        if (memcmp(argv[i], "-psn_", 4) != 0) arg_count++;
+    }
+
+    jobject jni_args = (*env)->NewObjectArray(env, arg_count, string_class, NULL);
+
+    arg_count = 0;
+    for (int i = 1; i < argc; i++) {
+        if (memcmp(argv[i], "-psn_", 4) != 0) {
+            jstring jni_arg = (*env)->NewStringUTF(env, argv[i]);
+            (*env)->SetObjectArrayElement(env, jni_args, arg_count, jni_arg);
+            arg_count++;
+        }
+    }
+
+    (*env)->CallStaticVoidMethod(env, mainClass, mainMethod, jni_args);
+
+    (*jvm)->DetachCurrentThread(jvm);
+    (*jvm)->DestroyJavaVM(jvm);
+
+    [pool release];
+}
+
+
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/Launcher.pch b/native/MacLauncher/Launcher.pch
new file mode 100644
index 0000000..7504e2d
--- /dev/null
+++ b/native/MacLauncher/Launcher.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'Launcher' target in the 'Launcher' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
diff --git a/native/MacLauncher/MacLauncher.xcodeproj/project.pbxproj b/native/MacLauncher/MacLauncher.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..2e2d7d9
--- /dev/null
+++ b/native/MacLauncher/MacLauncher.xcodeproj/project.pbxproj
@@ -0,0 +1,263 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1A5645DB6F789D018FF4A4AF /* PropertyFileReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5645FEAD4A0FF166644D97 /* PropertyFileReader.m */; };
+		1A564BCFE66693BF0B2DD4A9 /* VMOptionsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A564EDDE28564EF1AEBCD13 /* VMOptionsReader.m */; };
+		1A564C27F0BA05F900F34907 /* utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A564EEF77B93DBD7FD23161 /* utils.m */; };
+		50E17738155444B900E97451 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E17737155444B900E97451 /* Cocoa.framework */; };
+		50E1775715552D2900E97451 /* JavaVM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0B58A123544A15DA59B13E3 /* JavaVM.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+		C0B58A123544A15DA59B13E4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C0B58A123544A15DA59B13DC /* main.m */; };
+		C0B58A123544A15DA59B13E5 /* Launcher.m in Sources */ = {isa = PBXBuildFile; fileRef = C0B58A123544A15DA59B13E0 /* Launcher.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		1A5645FEAD4A0FF166644D97 /* PropertyFileReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PropertyFileReader.m; sourceTree = "<group>"; };
+		1A564A1031F4C91C464C1B75 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
+		1A564D7CEEAA02F14A6D4F20 /* VMOptionsReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMOptionsReader.h; sourceTree = "<group>"; };
+		1A564EDDE28564EF1AEBCD13 /* VMOptionsReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VMOptionsReader.m; sourceTree = "<group>"; };
+		1A564EEF77B93DBD7FD23161 /* utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = utils.m; sourceTree = "<group>"; };
+		1A564F6D5833A0B9CE6E2839 /* PropertyFileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyFileReader.h; sourceTree = "<group>"; };
+		50E17735155444B900E97451 /* Launcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Launcher.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		50E17737155444B900E97451 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		50E1773F155444B900E97451 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		50E17745155444B900E97451 /* Launcher.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Launcher.pch; sourceTree = "<group>"; };
+		C0B58A123544A15DA59B13DC /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		C0B58A123544A15DA59B13DE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		C0B58A123544A15DA59B13E0 /* Launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Launcher.m; sourceTree = "<group>"; };
+		C0B58A123544A15DA59B13E2 /* Launcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Launcher.h; sourceTree = "<group>"; };
+		C0B58A123544A15DA59B13E3 /* JavaVM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaVM.framework; path = System/Library/Frameworks/JavaVM.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		50E17732155444B900E97451 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				50E1775715552D2900E97451 /* JavaVM.framework in Frameworks */,
+				50E17738155444B900E97451 /* Cocoa.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		C0B58A123544A15DA59B13CA = {
+			isa = PBXGroup;
+			children = (
+				C0B58A123544A15DA59B13DC /* main.m */,
+				C0B58A123544A15DA59B13E0 /* Launcher.m */,
+				C0B58A123544A15DA59B13E2 /* Launcher.h */,
+				50E17745155444B900E97451 /* Launcher.pch */,
+				50E1773F155444B900E97451 /* Info.plist */,
+				C0B58A123544A15DA59B13CB /* Products */,
+				C0B58A123544A15DA59B13D6 /* Frameworks */,
+				1A5645FEAD4A0FF166644D97 /* PropertyFileReader.m */,
+				1A564F6D5833A0B9CE6E2839 /* PropertyFileReader.h */,
+				1A564EDDE28564EF1AEBCD13 /* VMOptionsReader.m */,
+				1A564D7CEEAA02F14A6D4F20 /* VMOptionsReader.h */,
+				1A564A1031F4C91C464C1B75 /* utils.h */,
+				1A564EEF77B93DBD7FD23161 /* utils.m */,
+			);
+			sourceTree = "<group>";
+		};
+		C0B58A123544A15DA59B13CB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				50E17735155444B900E97451 /* Launcher.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		C0B58A123544A15DA59B13D6 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				C0B58A123544A15DA59B13E3 /* JavaVM.framework */,
+				C0B58A123544A15DA59B13DE /* Foundation.framework */,
+				50E17737155444B900E97451 /* Cocoa.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		50E17734155444B900E97451 /* Launcher */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 50E17751155444BA00E97451 /* Build configuration list for PBXNativeTarget "Launcher" */;
+			buildPhases = (
+				50E17731155444B900E97451 /* Sources */,
+				50E17732155444B900E97451 /* Frameworks */,
+				50E17733155444B900E97451 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Launcher;
+			productName = Launcher;
+			productReference = 50E17735155444B900E97451 /* Launcher.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		C0B58A123544A15DA59B13C8 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0450;
+			};
+			buildConfigurationList = C0B58A123544A15DA59B13C9 /* Build configuration list for PBXProject "MacLauncher" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = C0B58A123544A15DA59B13CA;
+			productRefGroup = C0B58A123544A15DA59B13CB /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				50E17734155444B900E97451 /* Launcher */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		50E17733155444B900E97451 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		50E17731155444B900E97451 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				C0B58A123544A15DA59B13E4 /* main.m in Sources */,
+				C0B58A123544A15DA59B13E5 /* Launcher.m in Sources */,
+				1A5645DB6F789D018FF4A4AF /* PropertyFileReader.m in Sources */,
+				1A564BCFE66693BF0B2DD4A9 /* VMOptionsReader.m in Sources */,
+				1A564C27F0BA05F900F34907 /* utils.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		50E1774F155444BA00E97451 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = Launcher.pch;
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				INFOPLIST_FILE = Info.plist;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = NO;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = macosx10.7;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		50E17750155444BA00E97451 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = Launcher.pch;
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				INFOPLIST_FILE = Info.plist;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = NO;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = macosx10.7;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		C0B58A123544A15DA59B13CC /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		C0B58A123544A15DA59B13CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		50E17751155444BA00E97451 /* Build configuration list for PBXNativeTarget "Launcher" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				50E1774F155444BA00E97451 /* Release */,
+				50E17750155444BA00E97451 /* Debug */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C0B58A123544A15DA59B13C9 /* Build configuration list for PBXProject "MacLauncher" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C0B58A123544A15DA59B13CC /* Release */,
+				C0B58A123544A15DA59B13CD /* Debug */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = C0B58A123544A15DA59B13C8 /* Project object */;
+}
diff --git a/native/MacLauncher/PropertyFileReader.h b/native/MacLauncher/PropertyFileReader.h
new file mode 100644
index 0000000..44e46a9
--- /dev/null
+++ b/native/MacLauncher/PropertyFileReader.h
@@ -0,0 +1,13 @@
+//
+// Created by max on 11/6/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import <Foundation/Foundation.h>
+
+
+@interface PropertyFileReader : NSObject
++ (NSDictionary *)readFile:(NSString *)path;
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/PropertyFileReader.m b/native/MacLauncher/PropertyFileReader.m
new file mode 100644
index 0000000..43b0682
--- /dev/null
+++ b/native/MacLauncher/PropertyFileReader.m
@@ -0,0 +1,46 @@
+//
+// Created by max on 11/6/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import "PropertyFileReader.h"
+#import "utils.h"
+
+
+@implementation PropertyFileReader {
+}
+
++ (void)parseProperty:(NSString *)string to:(NSMutableDictionary *)to {
+    NSRange delimiter = [string rangeOfString:@"="];
+    if (delimiter.length > 0 && delimiter.location + 1 <= string.length) {
+        NSString *key = [string substringToIndex:delimiter.location];
+        NSString *value=[string substringFromIndex:delimiter.location + 1];
+        [to setObject:value forKey:key];
+    }
+}
+
++ (NSDictionary *)readFile:(NSString *)path {
+    NSMutableDictionary *answer = [NSMutableDictionary dictionary];
+
+    NSString *contents = readFile(path);
+
+    if (contents) {
+        NSArray *lines = [contents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+        for (NSString *line in lines) {
+            NSString *trimmedLine = trim(line);
+            if ([trimmedLine length] > 0) {
+                if ([trimmedLine characterAtIndex:0] != '#') {
+                    [self parseProperty:trimmedLine to:answer];
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    return nil;
+}
+
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/VMOptionsReader.h b/native/MacLauncher/VMOptionsReader.h
new file mode 100644
index 0000000..bb4dbea
--- /dev/null
+++ b/native/MacLauncher/VMOptionsReader.h
@@ -0,0 +1,13 @@
+//
+// Created by max on 11/6/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import <Foundation/Foundation.h>
+
+
+@interface VMOptionsReader : NSObject
++ (NSArray *) readFile: (NSString *)path;
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/VMOptionsReader.m b/native/MacLauncher/VMOptionsReader.m
new file mode 100644
index 0000000..19237cb
--- /dev/null
+++ b/native/MacLauncher/VMOptionsReader.m
@@ -0,0 +1,36 @@
+//
+// Created by max on 11/6/12.
+//
+// To change the template use AppCode | Preferences | File Templates.
+//
+
+
+#import "VMOptionsReader.h"
+#import "utils.h"
+
+
+@implementation VMOptionsReader {
+
+}
++ (NSArray *)readFile:(NSString *)path {
+    NSMutableArray *answer = [NSMutableArray array];
+
+    NSString *contents = readFile(path);
+    if (contents) {
+        NSArray *lines = [contents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+        for (NSString *line in lines) {
+            NSString *trimmedLine = trim(line);
+            if ([trimmedLine length] > 0) {
+                if ([trimmedLine characterAtIndex:0] != '#') {
+                    [answer addObject:trimmedLine];
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    return nil;
+}
+
+@end
\ No newline at end of file
diff --git a/native/MacLauncher/main.m b/native/MacLauncher/main.m
new file mode 100644
index 0000000..c9ef36a
--- /dev/null
+++ b/native/MacLauncher/main.m
@@ -0,0 +1,41 @@
+#import "Launcher.h"
+
+#define FOREVER ((CFTimeInterval) 1e20)
+
+static void timer_empty(CFRunLoopTimerRef timer, void *info) {
+}
+
+static void parkRunLoop() {
+    CFRunLoopTimerRef t = CFRunLoopTimerCreate(kCFAllocatorDefault, FOREVER, (CFTimeInterval)0.0, 0, 0, timer_empty, NULL);
+    CFRunLoopAddTimer(CFRunLoopGetCurrent(), t, kCFRunLoopDefaultMode);
+    CFRelease(t);
+
+    SInt32 result;
+    do {
+        result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, FOREVER, false);
+    } while (result != kCFRunLoopRunFinished);
+}
+
+static void makeSameStackSize(NSThread *thread) {
+    struct rlimit l;
+    int err = getrlimit(RLIMIT_STACK, &l);
+    if (err == ERR_SUCCESS && l.rlim_cur > 0) {
+        thread.stackSize = (NSUInteger) l.rlim_cur;
+    }
+}
+
+static void launchInNewThread(Launcher *launcher) {
+    NSThread *thread = [[[NSThread alloc] initWithTarget:launcher selector:@selector(launch) object:nil] autorelease];
+    makeSameStackSize(thread);
+    [thread start];
+}
+
+int main(int argc, char *argv[]) {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    launchInNewThread([[[Launcher alloc] initWithArgc:argc argv:argv] autorelease]);
+    parkRunLoop();
+
+    [pool release];
+    return 0;
+}
diff --git a/native/MacLauncher/utils.h b/native/MacLauncher/utils.h
new file mode 100644
index 0000000..4c28b35
--- /dev/null
+++ b/native/MacLauncher/utils.h
@@ -0,0 +1,5 @@
+NSString *readFile(NSString *path);
+NSString *trim(NSString *line);
+
+void debugLog(NSString *message);
+BOOL isDebugEnabled();
diff --git a/native/MacLauncher/utils.m b/native/MacLauncher/utils.m
new file mode 100644
index 0000000..63c3922
--- /dev/null
+++ b/native/MacLauncher/utils.m
@@ -0,0 +1,30 @@
+#include "utils.h"
+
+NSString *readFile(NSString *path) {
+    NSError *err = nil;
+    NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&err];
+    if (contents == nil) {
+        debugLog([NSString stringWithFormat:@"Reading at %@ failed, Error is: %@", path, err.localizedDescription]);
+        return nil;
+    }
+
+    debugLog([NSString stringWithFormat: @"Reading at %@ OK", path]);
+
+    return contents;
+}
+
+NSString *trim(NSString *line) {
+    return [line stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]];
+}
+
+BOOL isDebugEnabled() {
+    return getenv("IDEA_LAUNCHER_DEBUG") != NULL;
+}
+
+void debugLog(NSString *message) {
+    if (isDebugEnabled()) {
+        NSLog(@"%@", message);
+    }
+}
+
+