diff --git a/.idea/artifacts/KotlinJpsPlugin.xml b/.idea/artifacts/KotlinJpsPlugin.xml
index 3780f366e85..e33799f83e9 100644
--- a/.idea/artifacts/KotlinJpsPlugin.xml
+++ b/.idea/artifacts/KotlinJpsPlugin.xml
@@ -11,7 +11,6 @@
-
diff --git a/.idea/libraries/cli_parser.xml b/.idea/libraries/cli_parser.xml
deleted file mode 100644
index 9e3c7cbd887..00000000000
--- a/.idea/libraries/cli_parser.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java
index 2feb0cf2683..fdcf4cce51b 100644
--- a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java
+++ b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.compilerRunner;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ComparatorUtil;
-import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
import java.lang.reflect.Field;
import java.util.ArrayList;
diff --git a/build.xml b/build.xml
index 0bab79efbac..95f130117d3 100644
--- a/build.xml
+++ b/build.xml
@@ -1,4 +1,4 @@
-
+
@@ -72,7 +72,6 @@
-
@@ -589,7 +588,6 @@
-
diff --git a/compiler/cli/cli-common/cli-common.iml b/compiler/cli/cli-common/cli-common.iml
index 7447a45530f..a44850e98ce 100644
--- a/compiler/cli/cli-common/cli-common.iml
+++ b/compiler/cli/cli-common/cli-common.iml
@@ -9,7 +9,6 @@
-
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java
index 21a07c9204e..dbb8f970d5c 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java
@@ -17,8 +17,8 @@
package org.jetbrains.kotlin.cli.common.arguments;
import com.intellij.util.SmartList;
-import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
import java.io.Serializable;
import java.util.List;
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java
index 37da1d56d8b..cafc7fc278b 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.cli.common.arguments;
-import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL;
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL;
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java
index 23b1509125a..4d62eca82b4 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java
@@ -16,8 +16,8 @@
package org.jetbrains.kotlin.cli.common.arguments;
-import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
public class K2JVMCompilerArguments extends CommonCompilerArguments {
public static final long serialVersionUID = 0L;
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java
index d87c7c240f2..18e5d383bb4 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.cli.common.arguments;
-import com.sampullara.cli.Argument;
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
public class K2MetadataCompilerArguments extends CommonCompilerArguments {
public static final long serialVersionUID = 0L;
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt
index 33a87c78d47..2b8bdc1136f 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.cli.common.arguments
import com.intellij.util.xmlb.XmlSerializerUtil
-import com.sampullara.cli.Args
+import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Args
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.util.*
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java
new file mode 100644
index 00000000000..6d9ff44aa85
--- /dev/null
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java
@@ -0,0 +1,529 @@
+/*
+ * Copyright (c) 2005, Sam Pullara. All Rights Reserved.
+ * You may modify and redistribute as long as this attribution remains.
+ */
+
+package org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli;
+
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.PrintStream;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+public class Args {
+
+ /**
+ * {@link ValueCreator} building object using a one arg constructor taking a {@link String} object as parameter
+ */
+ public static final ValueCreator FROM_STRING_CONSTRUCTOR = new ValueCreator() {
+ public Object createValue(Class> type, String value) {
+ Object v = null;
+ try {
+ Constructor> init = type.getDeclaredConstructor(String.class);
+ v = init.newInstance(value);
+ } catch (NoSuchMethodException e) {
+ // ignore
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Failed to convert " + value + " to type " + type.getName(), e);
+ }
+ return v;
+ }
+ };
+ public static final ValueCreator ENUM_CREATOR = new ValueCreator() {
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public Object createValue(Class type, String value) {
+ if (Enum.class.isAssignableFrom(type)) {
+ return Enum.valueOf(type, value);
+ }
+ return null;
+ }
+ };
+ private static final List DEFAULT_VALUE_CREATORS = Arrays.asList(Args.FROM_STRING_CONSTRUCTOR, Args.ENUM_CREATOR);
+ private static List valueCreators = new ArrayList(DEFAULT_VALUE_CREATORS);
+
+ /**
+ * A convenience method for parsing and automatically producing error messages.
+ *
+ * @param target Either an instance or a class
+ * @param args The arguments you want to parse and populate
+ * @return The list of arguments that were not consumed
+ */
+ public static List parseOrExit(Object target, String[] args) {
+ try {
+ return parse(target, args);
+ } catch (IllegalArgumentException e) {
+ System.err.println(e.getMessage());
+ Args.usage(target);
+ System.exit(1);
+ throw e;
+ }
+ }
+
+ public static List parse(Object target, String[] args) {
+ return parse(target, args, true);
+ }
+
+ /**
+ * Parse a set of arguments and populate the target with the appropriate values.
+ *
+ * @param target
+ * Either an instance or a class
+ * @param args
+ * The arguments you want to parse and populate
+ * @param failOnExtraFlags
+ * Throw an IllegalArgumentException if extra flags are present
+ * @return The list of arguments that were not consumed
+ */
+ public static List parse(Object target, String[] args, boolean failOnExtraFlags) {
+ List arguments = new ArrayList();
+ arguments.addAll(Arrays.asList(args));
+ Class> clazz;
+ if (target instanceof Class) {
+ clazz = (Class) target;
+ } else {
+ clazz = target.getClass();
+ try {
+ BeanInfo info = Introspector.getBeanInfo(clazz);
+ for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
+ processProperty(target, pd, arguments);
+ }
+ } catch (IntrospectionException e) {
+ // If its not a JavaBean we ignore it
+ }
+ }
+
+ // Check fields of 'target' class and its superclasses
+ for (Class> currentClazz = clazz; currentClazz != null; currentClazz = currentClazz.getSuperclass()) {
+ for (Field field : currentClazz.getDeclaredFields()) {
+ processField(target, field, arguments);
+ }
+ }
+
+ if (failOnExtraFlags) {
+ for (String argument : arguments) {
+ if (argument.startsWith("-")) {
+ throw new IllegalArgumentException("Invalid argument: " + argument);
+ }
+ }
+ }
+ return arguments;
+ }
+
+ private static void processField(Object target, Field field, List arguments) {
+ Argument argument = field.getAnnotation(Argument.class);
+ if (argument != null) {
+ boolean set = false;
+ for (Iterator i = arguments.iterator(); i.hasNext(); ) {
+ String arg = i.next();
+ String prefix = argument.prefix();
+ String delimiter = argument.delimiter();
+ if (arg.startsWith(prefix)) {
+ Object value;
+ String name = getName(argument, field);
+ String alias = getAlias(argument);
+ arg = arg.substring(prefix.length());
+ Class> type = field.getType();
+ if (arg.equals(name) || (alias != null && arg.equals(alias))) {
+ i.remove();
+ value = consumeArgumentValue(type, argument, i);
+ if (!set) {
+ setField(type, field, target, value, delimiter);
+ } else {
+ addArgument(type, field, target, value, delimiter);
+ }
+ set = true;
+ }
+ if (set && !type.isArray()) break;
+ }
+ }
+ if (!set && argument.required()) {
+ String name = getName(argument, field);
+ throw new IllegalArgumentException("You must set argument " + name);
+ }
+ }
+ }
+
+ private static void addArgument(Class type, Field field, Object target, Object value, String delimiter) {
+ try {
+ Object[] os = (Object[]) field.get(target);
+ Object[] vs = (Object[]) getValue(type, value, delimiter);
+ Object[] s = (Object[]) Array.newInstance(type.getComponentType(), os.length + vs.length);
+ System.arraycopy(os, 0, s, 0, os.length);
+ System.arraycopy(vs, 0, s, os.length, vs.length);
+ field.set(target, s);
+ } catch (IllegalAccessException iae) {
+ throw new IllegalArgumentException("Could not set field " + field, iae);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e);
+ }
+ }
+
+ private static void addPropertyArgument(Class type, PropertyDescriptor property, Object target, Object value, String delimiter) {
+ try {
+ Object[] os = (Object[]) property.getReadMethod().invoke(target);
+ Object[] vs = (Object[]) getValue(type, value, delimiter);
+ Object[] s = (Object[]) Array.newInstance(type.getComponentType(), os.length + vs.length);
+ System.arraycopy(os, 0, s, 0, os.length);
+ System.arraycopy(vs, 0, s, os.length, vs.length);
+ property.getWriteMethod().invoke(target, (Object) s);
+ } catch (IllegalAccessException iae) {
+ throw new IllegalArgumentException("Could not set property " + property, iae);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e);
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException("Failed to validate argument " + value + " for " + property);
+ }
+ }
+
+ private static void processProperty(Object target, PropertyDescriptor property, List arguments) {
+ Method writeMethod = property.getWriteMethod();
+ if (writeMethod != null) {
+ Argument argument = writeMethod.getAnnotation(Argument.class);
+ if (argument != null) {
+ boolean set = false;
+ for (Iterator i = arguments.iterator(); i.hasNext(); ) {
+ String arg = i.next();
+ String prefix = argument.prefix();
+ String delimiter = argument.delimiter();
+ if (arg.startsWith(prefix)) {
+ Object value;
+ String name = getName(argument, property);
+ String alias = getAlias(argument);
+ arg = arg.substring(prefix.length());
+ Class> type = property.getPropertyType();
+ if (arg.equals(name) || (alias != null && arg.equals(alias))) {
+ i.remove();
+ value = consumeArgumentValue(type, argument, i);
+ if (!set) {
+ setProperty(type, property, target, value, delimiter);
+ } else {
+ addPropertyArgument(type, property, target, value, delimiter);
+ }
+ set = true;
+ }
+ if (set && !type.isArray()) break;
+ }
+ }
+ if (!set && argument.required()) {
+ String name = getName(argument, property);
+ throw new IllegalArgumentException("You must set argument " + name);
+ }
+ }
+ }
+ }
+
+ /**
+ * Generate usage information based on the target annotations.
+ *
+ * @param target An instance or class.
+ */
+ public static void usage(Object target) {
+ usage(System.err, target);
+ }
+
+ /**
+ * Generate usage information based on the target annotations.
+ *
+ * @param errStream A {@link java.io.PrintStream} to print the usage information to.
+ * @param target An instance or class.
+ */
+ public static void usage(PrintStream errStream, Object target) {
+ Class> clazz;
+ if (target instanceof Class) {
+ clazz = (Class) target;
+ } else {
+ clazz = target.getClass();
+ }
+ errStream.println("Usage: " + clazz.getName());
+ for (Class> currentClazz = clazz; currentClazz != null; currentClazz = currentClazz.getSuperclass()) {
+ for (Field field : currentClazz.getDeclaredFields()) {
+ fieldUsage(errStream, target, field);
+ }
+ }
+ try {
+ BeanInfo info = Introspector.getBeanInfo(clazz);
+ for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
+ propertyUsage(errStream, target, pd);
+ }
+ } catch (IntrospectionException e) {
+ // If its not a JavaBean we ignore it
+ }
+ }
+
+ private static void fieldUsage(PrintStream errStream, Object target, Field field) {
+ Argument argument = field.getAnnotation(Argument.class);
+ if (argument != null) {
+ String name = getName(argument, field);
+ String alias = getAlias(argument);
+ String prefix = argument.prefix();
+ String delimiter = argument.delimiter();
+ String description = argument.description();
+ makeAccessible(field);
+ try {
+ Object defaultValue = field.get(target);
+ Class> type = field.getType();
+ propertyUsage(errStream, prefix, name, alias, type, delimiter, description, defaultValue);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException("Could not use thie field " + field + " as an argument field", e);
+ }
+ }
+ }
+
+ private static void propertyUsage(PrintStream errStream, Object target, PropertyDescriptor field) {
+ Method writeMethod = field.getWriteMethod();
+ if (writeMethod != null) {
+ Argument argument = writeMethod.getAnnotation(Argument.class);
+ if (argument != null) {
+ String name = getName(argument, field);
+ String alias = getAlias(argument);
+ String prefix = argument.prefix();
+ String delimiter = argument.delimiter();
+ String description = argument.description();
+ try {
+ Method readMethod = field.getReadMethod();
+ Object defaultValue;
+ if (readMethod == null) {
+ defaultValue = null;
+ } else {
+ defaultValue = readMethod.invoke(target, (Object[]) null);
+ }
+ Class> type = field.getPropertyType();
+ propertyUsage(errStream, prefix, name, alias, type, delimiter, description, defaultValue);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException("Could not use thie field " + field + " as an argument field", e);
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException("Could not get default value for " + field, e);
+ }
+ }
+ }
+
+ }
+
+ private static void propertyUsage(PrintStream errStream, String prefix, String name, String alias, Class> type, String delimiter, String description, Object defaultValue) {
+ StringBuilder sb = new StringBuilder(" ");
+ sb.append(prefix);
+ sb.append(name);
+ if (alias != null) {
+ sb.append(" (");
+ sb.append(prefix);
+ sb.append(alias);
+ sb.append(")");
+ }
+ if (type == Boolean.TYPE || type == Boolean.class) {
+ sb.append(" [flag] ");
+ sb.append(description);
+ } else {
+ sb.append(" [");
+ if (type.isArray()) {
+ String typeName = getTypeName(type.getComponentType());
+ sb.append(typeName);
+ sb.append("[");
+ sb.append(delimiter);
+ sb.append("]");
+ } else {
+ String typeName = getTypeName(type);
+ sb.append(typeName);
+ }
+ sb.append("] ");
+ sb.append(description);
+ if (defaultValue != null) {
+ sb.append(" (");
+ if (type.isArray()) {
+ List