Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/build/scripts/common_tests.gant b/build/scripts/common_tests.gant
new file mode 100644
index 0000000..c942c97
--- /dev/null
+++ b/build/scripts/common_tests.gant
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
+
+includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant")
+
+requireProperty("out", "$home/out/classes")
+
+target(compile: "Compile project") {
+  ant.delete(failonerror: false) {
+    fileset(dir: "$home/reports")
+    fileset(dir: "$home/bin", includes: "*.hprof")
+  }
+
+  loadProject()
+  projectBuilder.useInProcessJavac = true
+  projectBuilder.targetFolder = out
+  projectBuilder.cleanOutput()
+  projectBuilder.buildAll()
+}
+
+private pass(String prop) {
+  if (isDefined(prop)) {
+    ant.jvmarg(value: "-D$prop=${p(prop)}")
+  }
+}
+
+target('default': 'The default target') {
+  depends([compile])
+
+  ant.junit(fork: "yes", showoutput: "true", logfailedtests:false) {
+    pass("idea.test.group")
+    pass("idea.test.patterns")
+    pass("idea.fast.only")
+    pass("teamcity.build.tempDir")
+    pass("teamcity.tests.recentlyFailedTests.file")
+    jvmarg (value: "-Didea.platform.prefix=Idea")
+    jvmarg (value: "-Djava.system.class.loader=com.intellij.util.lang.UrlClassLoader")
+
+    System.getProperties().entrySet().each {
+      if (it.key.startsWith("pass.")) {
+        def trimmed = it.key.substring("pass.".length());
+        jvmarg(value: "-D${trimmed}=${it.value}");
+      };
+    }
+
+    commonJvmArgs().each { jvmarg(value: it) }
+
+    if (isDefined("jvm_args")) {
+      jvm_args.each { jvmarg(value: it) }
+    }
+
+    classpath {
+      projectBuilder.moduleRuntimeClasspath(findModule("community-main"), true).each {
+        pathelement(location: it)
+      }
+      pathelement(location: "${jdkHome}/lib/tools.jar")
+    }
+
+    testcases.each {
+      test (name: it)
+    }
+  }
+}
diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant
new file mode 100644
index 0000000..fed966d
--- /dev/null
+++ b/build/scripts/dist.gant
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
+
+includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant")
+
+requireProperty("out", "$home/out")
+
+class Paths {
+  final sandbox
+  final distWin
+  final distAll
+  final distUnix
+  final distMac
+  final artifacts
+  final artifacts_core
+  final artifacts_core_upsource
+  final artifacts_jps
+
+  def Paths(String out) {
+    sandbox = out
+    distWin = "$sandbox/dist.win.ce"
+    distAll = "$sandbox/dist.all.ce"
+    distUnix = "$sandbox/dist.unix.ce"
+    distMac = "$sandbox/dist.mac.ce"
+    artifacts = "$sandbox/artifacts"
+    artifacts_core = "$artifacts/core"
+    artifacts_core_upsource = "$artifacts/core-upsource"
+    artifacts_jps = "$artifacts/jps"
+  }
+}
+
+def paths = new Paths(out)
+setProperty("paths", paths)
+
+target(compile: "Compile project") {
+  loadProject()
+  projectBuilder.arrangeModuleCyclesOutputs = true
+
+  projectBuilder.stage("Cleaning up sandbox folder")
+  forceDelete(paths.sandbox)
+
+  [paths.sandbox, paths.distWin, paths.distAll, paths.distUnix, paths.distMac, paths.artifacts, paths.artifacts_core, paths.artifacts_jps].each {
+    ant.mkdir(dir: it)
+  }
+
+  projectBuilder.targetFolder = "$out/classes"
+  projectBuilder.cleanOutput()
+  projectBuilder.buildProduction()
+  projectBuilder.makeModuleTests(findModule("jps-builders"))
+}
+
+private String appInfoFile() {
+  return "${projectBuilder.moduleOutput(findModule("community-resources"))}/idea/IdeaApplicationInfo.xml"
+}
+
+target('default': 'The default target') {
+  depends([compile])
+
+  // load ApplicationInfo.xml properties
+  ant.xmlproperty(file: appInfoFile(), collapseAttributes: "true")
+
+  zipSources(home, paths.artifacts)
+
+  layoutAll([buildNumber: "IC-$snapshot",
+             system_selector: "IdeaIC${p("component.version.major")}",
+             tools_jar: true],
+            home, null, paths, true)
+}
+
+target('build-dist-jars' : 'Target to build jars from locally compiled classes') {
+  loadProject()
+  // load ApplicationInfo.xml properties
+  ant.xmlproperty(file: appInfoFile(), collapseAttributes: "true")
+
+  layoutAll([buildNumber: "IC-$snapshot",
+             system_selector: "IdeaIC${p("component.version.major")}",
+             tools_jar: true],
+             home, null, paths)
+}
+
+def layoutAll(Map args, String home, String out, Paths _paths = null, buildJps = false) {
+  Paths paths = _paths != null ? _paths : new Paths(out)
+
+  wireBuildDate(args.buildNumber, appInfoFile())
+  ant.echo(message: args.buildNumber, file: "$paths.distAll/build.txt")
+
+  def layouts = includeFile("$home/build/scripts/layouts.gant")
+  layouts.layoutFull(home, paths.distAll)
+  layouts.layout_core(home, paths.artifacts_core)
+  notifyArtifactBuilt(paths.artifacts_core)
+  layouts.layout_core_upsource(home, paths.artifacts_core_upsource)
+  notifyArtifactBuilt(paths.artifacts_core_upsource)
+  if (buildJps) {
+    layouts.layout_jps(home, paths.artifacts_jps)
+    notifyArtifactBuilt(paths.artifacts_jps)
+  }
+
+  layout(paths.distAll) {
+    dir("bin") {
+      fileset(dir: "${home}/bin") {
+        include(name: "*.*")
+      }
+    }
+    dir("license") {
+      fileset(dir: "${home}/license")
+    }
+    fileset(file: "${home}/LICENSE.txt")
+  }
+  patchPropertiesFile(paths.distAll, args + [appendices: ["$home/build/conf/ideaCE.properties"]])
+
+  layoutWin(args, home, paths)
+  layoutMac(args, home, paths)
+  layoutUnix(args, home, paths)
+
+  buildWinZip("$paths.artifacts/idea${args.buildNumber}.win.zip", [paths.distAll, paths.distWin])
+
+  def macAppRoot = isEap() ? "${p("component.version.codename")}-${args.buildNumber}.app" : "IntelliJ IDEA ${p("component.version.major")} CE.app"
+  buildMacZip(macAppRoot, "$paths.artifacts/idea${args.buildNumber}.mac.zip", [paths.distAll], paths.distMac)
+
+  buildTarGz("idea-${args.buildNumber}", "$paths.artifacts/idea${args.buildNumber}.tar", [paths.distAll, paths.distUnix])
+}
+
+private layoutWin(Map args, String home, Paths paths) {
+  String target = paths.distWin
+
+  layout(target) {
+    dir("bin") {
+      fileset(dir: "$home/bin/win")
+    }
+  }
+
+  ant.copy(file: "$home/platform/icons/src/idea_CE.ico", tofile: "$target/bin/idea.ico")
+
+  winScripts(target, home, "idea.bat", args)
+  winVMOptions(target, null, "idea.exe", "idea64.exe")
+}
+
+private layoutMac(Map _args, String home, Paths paths) {
+  String target = paths.distMac
+
+  Map args = new HashMap(_args)
+  args.bundleIdentifier = "com.jetbrains.intellij.ce"
+  args.doc_types = """
+      <dict>
+        <key>CFBundleTypeExtensions</key>
+        <array>
+          <string>ipr</string>
+        </array>
+        <key>CFBundleTypeIconFile</key>
+        <string>idea.icns</string>
+        <key>CFBundleTypeName</key>
+        <string>IntelliJ IDEA Project File</string>
+        <key>CFBundleTypeRole</key>
+        <string>Editor</string>
+      </dict>
+"""
+  args."idea.properties.path" = "${paths.distAll}/bin/idea.properties"
+  args.mac_no_yjp = true
+  layoutMacApp(target, home, args)
+}
+
+private layoutUnix(Map args, String home, Paths paths) {
+  String target = paths.distUnix
+
+  layout(target) {
+    dir("bin") {
+      fileset(dir: "$home/bin/linux")
+    }
+  }
+
+  ant.copy(file: "$home/platform/icons/src/icon_CE.png", tofile: "$target/bin/idea.png")
+
+  unixScripts(target, home, "idea.sh", args)
+  unixVMOptions(target, "idea")
+  unixReadme(target, home, args)
+}
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
new file mode 100644
index 0000000..a649951
--- /dev/null
+++ b/build/scripts/layouts.gant
@@ -0,0 +1,676 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
+
+includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant")
+
+target('default': "Developers update") {
+  def patchedDescriptorDir = patchAppDescriptor(deploy)
+  layoutFull(home, deploy, patchedDescriptorDir)
+  ant.delete(dir: patchedDescriptorDir)
+}
+
+target('build-jps': 'Build JPS standalone distribution') {
+  println("Building jps standalone distribution")
+  layout_jps("$home/build/lib/jps")
+}
+
+String appInfoFileName() {
+  return "idea/IdeaApplicationInfo.xml"
+}
+
+String patchAppDescriptor(String targetDirectory) {
+  def patchedDirectory = "${targetDirectory}/../patched"
+
+  ant.delete(dir: patchedDirectory)
+
+  layout(patchedDirectory) {
+    module("community-resources") {
+      include(name: appInfoFileName())
+    }
+  }
+
+  ant.replace(file: "$patchedDirectory/${appInfoFileName()}", token: "__BUILD_NUMBER__", value: "IC-$snapshot")
+  ant.replace(file: "$patchedDirectory/${appInfoFileName()}", token: "__BUILD_DATE__", value: new Date().format("yyyyMMddHHmm"))
+
+  return patchedDirectory
+}
+
+def layoutFull(String home, String targetDirectory, String patchedDescriptorDir = null) {
+  projectBuilder.stage("layout to $targetDirectory")
+
+  //noinspection GroovyAssignabilityCheck
+  List<String> openapiModules = [platformApiModules,
+          "java-psi-api", "java-indexing-api", "openapi", "testFramework-java", "debugger-openapi", "compiler-openapi", "dom-openapi", "execution-openapi",
+          "jsp-openapi", "jsp-base-openapi"].flatten()
+
+  //noinspection GroovyAssignabilityCheck
+  List<String> implementationModules = [platformImplementationModules,
+          "testFramework",
+          "tests_bootstrap",
+          "instrumentation-util",
+          "platform-main",
+          "java-psi-impl",
+          "java-indexing-impl",
+          "java-impl",
+          "compiler-impl",
+          "debugger-impl",
+          "dom-impl",
+          "execution-impl",
+          "jsp-spi",
+          "idea-ui"
+          ].flatten()
+
+  ant.patternset(id: "resources.included") {
+    include(name: "**/*.properties")
+    include(name: "fileTemplates/**/*")
+    include(name: "inspectionDescriptions/**/*")
+    include(name: "intentionDescriptions/**/*")
+    include(name: "tips/**/*")
+  }
+
+  ant.patternset(id: "resources.excluded") {
+    exclude(name: "**/*.properties")
+    exclude(name: "fileTemplates/**/*")
+    exclude(name: "fileTemplates")
+    exclude(name: "inspectionDescriptions/**/*")
+    exclude(name: "inspectionDescriptions")
+    exclude(name: "intentionDescriptions/**/*")
+    exclude(name: "intentionDescriptions")
+    exclude(name: "tips/**/*")
+    exclude(name: "tips")
+  }
+
+  def info = layout(targetDirectory) {
+    dir("lib") {
+      dir("rt") {
+        fileset(dir: "${home}/lib/rt", includesfile: "${home}/lib/rt/required_for_dist.txt")
+      }
+
+      jar("util.jar") {
+        module("util")
+        module("util-rt")
+      }
+
+      jar("openapi.jar") {
+        openapiModules.each { module it}
+      }
+
+      jar("annotations.jar") { module("annotations")}
+      jar("jdkAnnotations.jar") {
+        fileset(dir: "${home}/java/jdkAnnotations")
+      }
+
+      jar("extensions.jar") { module("extensions")}
+
+      jar("idea.jar") {
+        implementationModules.each { module it}
+      }
+
+      jar("bootstrap.jar") { module("bootstrap") }
+
+      jar("resources.jar") {
+        module("colorSchemes")
+        module("resources")
+        module("platform-resources")
+        module("community-resources") {
+          if (patchedDescriptorDir != null) {
+            exclude(name: appInfoFileName())
+          }
+        }
+        if (patchedDescriptorDir != null) {
+          fileset(dir: patchedDescriptorDir)
+        }
+      }
+
+      jar("idea_rt.jar") { module("java-runtime")}
+
+      jar("forms_rt.jar") {
+        module("forms_rt")
+        module("forms-compiler")
+      }
+
+      jar("resources_en.jar") {
+        module("resources-en")
+        module("platform-resources-en")
+      }
+
+      jar("icons.jar") { module("icons") }
+      jar("boot.jar") { module("boot") }
+
+      jar("javac2.jar") {
+        module("javac2")
+        module("forms-compiler")
+        module("forms_rt")
+        module("instrumentation-util")
+      }
+
+      jar("jps-server.jar") {
+        module("jps-builders")
+      }
+
+      fileset(dir: "$home/jps/lib") {
+        include(name: "optimizedFileManager.jar")
+      }
+
+      fileset(dir: "$home/lib", includesfile: "${home}/lib/required_for_dist.txt")
+
+      fileset(dir: "$home/lib/src") {
+        include(name: "trove4j_changes.txt")
+        include(name: "trove4j_src.jar")
+      }
+      fileset(dir: "$home/xml/relaxng/lib", includes: "*.jar")
+
+      dir("ant") {
+        fileset(dir: "$home/lib/ant") {
+          exclude(name: "**/src/**")
+        }
+      }
+    }
+
+    layoutCommunityPlugins(home)
+
+    dir("plugins") {
+      dir("IntelliLang") {
+        dir("lib") {
+          jar("IntelliLang.jar") {
+            module("IntelliLang")
+            module("IntelliLang-java")
+            module("IntelliLang-xml")
+            module("IntelliLang-javaee")
+          }
+          jar("intellilang-jps-plugin.jar") {
+            module("intellilang-jps-plugin")
+          }
+        }
+      }
+    }
+  }
+
+  printUnusedModules(info.usedModules)
+
+  //reorder(targetDirectory)
+}
+
+public def layoutCommunityPlugins(String home) {
+  dir("plugins") {
+    def simplePlugins = ["commander", "copyright", "properties", "java-i18n", "hg4idea", "github", "ui-designer-new", "tasks-time-tracking"]
+
+    simplePlugins.each {
+      layoutPlugin it
+    }
+
+    layoutPlugin("ant", "ant", "antIntegration") {
+      jar("ant-jps-plugin.jar") {
+        module("ant-jps-plugin")
+      }
+    }
+    layoutPlugin("InspectionGadgets", "InspectionGadgetsPlugin")
+    layoutPlugin("IntentionPowerPack", "IntentionPowerPackPlugin")
+    layoutPlugin("ToString", "generate-tostring", "toString")
+    layoutPlugin("uiDesigner", "ui-designer", "uiDesigner") {
+      dir("jps") {
+        jar("ui-designer-jps-plugin.jar") {
+          module("ui-designer-jps-plugin")
+        }
+      }
+    }
+
+    layoutPlugin("maven") {
+      jar("maven-jps-plugin.jar") {
+        module("maven-jps-plugin")
+      }
+      jar("maven-server-api.jar") {
+        module("maven-server-api")
+      }
+      jar("maven2-server-impl.jar") {
+        module("maven2-server-impl")
+      }
+      jar("maven3-server-impl.jar") {
+        module("maven3-server-impl")
+      }
+
+      dir("maven3") {
+        fileset(dir: "$home/plugins/maven/maven3-server-impl/lib") {include(name: "*.jar")}
+        fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/lib") {include(name: "*.jar")}
+        fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/boot")
+      }
+
+      dir("maven2") {
+        fileset(dir: "$home/lib/") { include(name: "jaxb*.jar")}
+        fileset(dir: "$home/plugins/maven/maven2-server-impl/lib")
+      }
+
+      fileset(dir: "$home/plugins/maven/lib")
+      fileset(dir: "$home/plugins/maven/maven-server-api/lib")
+    }
+
+    layoutPlugin("gradle") {
+      jar("gradle.jar") {
+        module("gradle")
+      }
+      fileset(dir: "$home/plugins/gradle/lib") { include(name: "*.jar") }
+    }
+    
+    layoutPlugin("git4idea") {
+      jar("git4idea-rt.jar") {
+        module("git4idea-rt")
+      }
+      fileset(dir: "$home/plugins/git4idea/lib") {
+        include(name: "trilead-ssh2.jar")
+      }
+      fileset(dir: "$home/plugins/git4idea/lib/ini4j") {
+        include(name: "ini4j*.jar")
+        exclude(name: "ini4j*sources.jar")
+      }
+      fileset(dir: "$home/plugins/git4idea/lib/jgit") {
+        include(name: "org.eclipse.jgit*.jar")
+        include(name: "jsch*.jar")
+        exclude(name: "*.zip")
+      }
+    }
+
+    layoutPlugin("svn4idea") {
+      fileset(dir: "$home/plugins/svn4idea/lib", excludes: "**/svnkitsrc.zip")
+    }
+
+    layoutPlugin("junit", "junit", "idea-junit") {
+      jar("junit-rt.jar") {
+        module("junit_rt")
+      }
+    }
+
+    pluginDir("ByteCodeViewer") {
+      dir("lib") {
+        jar("byteCodeViewer.jar") {
+          noResources("ByteCodeViewer")
+        }
+      }
+    }
+
+    pluginDir("cvsIntegration") {
+      dir("lib") {
+        jar("cvs_util.jar") {noResources("cvs-core")}
+        jar("cvsIntegration.jar") {noResources("cvs-plugin")}
+        jar("javacvs-src.jar") {noResources("javacvs-src")}
+        jar("smartcvs-src.jar") {noResources("smartcvs-src")}
+
+        resources(["cvs-core", "cvs-plugin", "javacvs-src", "smartcvs-src"])
+
+        fileset(dir: "${home}/plugins/cvs/lib")
+      }
+    }
+
+    pluginDir("testng") {
+      dir("lib") {
+        jar("testng-plugin.jar") {
+          noResources("testng")
+          noResources("testng_rt")
+        }
+
+        resources("testng")
+
+        fileset(dir: "$home/plugins/testng/lib") {
+          include(name: "testng.jar")
+        }
+      }
+    }
+
+    layoutPlugin("xpath") {
+      dir("rt") {
+        jar("xslt-rt.jar") {module("xslt-rt")}
+      }
+    }
+
+    layoutPlugin("xslt-debugger") {
+      jar("xslt-debugger-engine.jar") {
+        module("xslt-debugger-engine") {
+          excludes: "lib"
+        }
+      }
+      fileset(dir: "$home/plugins/xslt-debugger/engine/lib") {
+        include(name: "**/rmi-stubs.jar")
+      }
+      dir("rt") {
+        jar("xslt-debugger-engine-impl.jar") {
+          module("xslt-debugger-engine-impl") {
+            exclude(name: "lib")
+            exclude(name: "**/*.jar")
+            exclude(name: "**/*.html")
+          }
+        }
+        fileset(dir: "$home/plugins/xslt-debugger/engine/impl/lib") {
+          include(name: "**/*.jar")
+          exclude(name: "**/rmi-stubs.jar")
+          include(name: "**/*.html")
+        }
+      }
+    }
+
+    pluginDir("Groovy") {
+      dir("lib") {
+        jar("Groovy.jar") {
+          module("jetgroovy") {
+            exclude(name: "standardDsls/**")
+          }
+        }
+        //layout of groovy jars must be consistent with GroovyBuilder.getGroovyRtRoot method
+        jar("groovy-jps-plugin.jar") {
+          module("groovy-jps-plugin")
+          module("groovy-rt-constants")
+        }
+        jar("groovy_rt.jar") {
+          module("groovy_rt")
+          module("groovy-rt-constants")
+        }
+        dir("standardDsls") {
+          fileset(dir: "$home/plugins/groovy/resources/standardDsls")
+        }
+        dir("agent") {
+          fileset(dir: "${home}/plugins/groovy/hotswap") {
+            include(name: "gragent.jar")
+          }
+        }
+
+
+        fileset(dir: "$home/plugins/groovy/resources/conf")
+      }
+    }
+
+    pluginDir("tasks") {
+      dir("lib") {
+        jar("tasks-api.jar") { module("tasks-api") }
+        jar("tasks-core.jar") { module("tasks-core") }
+        jar("jira-connector.jar") { module("jira-connector") }
+        jar("tasks-java.jar") { moduleOptional("tasks-java") }
+        fileset(dir: "${home}/plugins/tasks/tasks-core/lib") {
+          include(name: "**/*.jar")
+        }
+      }
+    }
+
+    layoutPlugin("devkit") {
+      dir("jps") {
+        jar("devkit-jps-plugin.jar") {
+          module("devkit-jps-plugin")
+        }
+      }
+    }
+    layoutPlugin("eclipse") {
+      jar("eclipse-jps-plugin.jar") {
+        module("eclipse-jps-plugin")
+      }
+      jar("common-eclipse-util.jar") {
+        module("common-eclipse-util")
+      }
+    }
+
+    layoutPlugin("android") {
+      fileset(dir: "${home}/plugins/android/lib") {
+        include(name: "**/*.jar")
+        exclude(name: "**/ddmlib_1.jar")
+      }
+
+      jar("android-common.jar") {
+        module("android-common")
+      }
+
+      jar("android-rt.jar") {
+        module("android-rt")
+      }
+
+      dir("jps") {
+        jar("android-jps-plugin.jar") { module("android-jps-plugin") }
+      }
+    }
+
+    layoutPlugin("android-designer") {
+      jar("android-designer.jar") {
+        module("android-designer")
+      }
+    }
+  }
+}
+
+
+def layoutPlugin(String moduleName) {
+  layoutPlugin(moduleName, moduleName, {})
+}
+
+def layoutPlugin(String moduleName, Closure custom) {
+  layoutPlugin(moduleName, moduleName, custom)
+}
+
+def layoutPlugin(String pluginName, String moduleName) {
+  layoutPlugin(pluginName, moduleName, {})
+}
+
+def layoutPlugin(String pluginName, String moduleName, Closure custom) {
+  layoutPlugin(pluginName, moduleName, pluginName, custom)
+}
+
+def layoutPlugin(String pluginName, String moduleName, String jarName) {
+  layoutPlugin(pluginName, moduleName, jarName, {})
+}
+
+def layoutPlugin(String pluginName, String moduleName, String jarName, Closure custom) {
+  if (isDefined("pluginFilter")) {
+    if (!pluginFilter.contains(moduleName) && !pluginFilter.contains(pluginName)) return
+  }
+
+  dir(pluginName) {
+    dir("lib") {
+      jar("${jarName}.jar") {
+        noResources(moduleName)
+      }
+
+      resources(moduleName)
+      custom()
+    }
+  }
+}
+
+def pluginDir(String dirName, Closure initializer) {
+  if (isDefined("pluginFilter")) {
+    if (!pluginFilter.contains(dirName)) return
+  }
+
+  dir(dirName) {
+    initializer()
+  }
+}
+
+private def resources(List<String> modules) {
+  jar("resources_en.jar") {
+    modules.each {
+      module(it) {
+        patternset(refid: "resources.included")
+      }
+    }
+  }
+}
+
+private def resources(String moduleName) {
+  jar("resources_en.jar") {
+    module(moduleName) {
+      patternset(refid: "resources.included")
+    }
+  }
+}
+
+private def noResources(String moduleName) {
+  module(moduleName) {
+    patternset(refid: "resources.excluded")
+  }
+}
+
+def moduleOptional(String name) {
+  if (isDefined("pluginFilter")) {
+    if (!pluginFilter.contains(name)) return
+  }
+
+  module(name)
+}
+
+def moduleOptional(String name, Closure init) {
+  if (isDefined("pluginFilter")) {
+    if (!pluginFilter.contains(name)) return
+  }
+
+  module(name, init)
+}
+
+def reorder(String home, String targetDirectory) {
+  if (findModule("util") != null) {
+    ant.java(classname: "com.intellij.util.io.zip.ReorderJarsMain", fork: "true") {
+      arg(value: "$home/build/order.txt")
+      arg(value: targetDirectory)
+      arg(value: targetDirectory)
+      arg(value: "$home/lib")
+      classpath {
+        pathelement(location: projectBuilder.moduleOutput(findModule("util")))
+        pathelement(location: projectBuilder.moduleOutput(findModule("util-rt")))
+        pathelement(location: "$home/lib/jna.jar")
+        pathelement(location: "$home/lib/trove4j.jar")
+      }
+    }
+  }
+}
+
+def layout_jps(String home, String target) {
+  layout(target) {
+    jar("util.jar") {
+      module("annotations")
+      module("util-rt")
+      module("util")
+    }
+    jar("jps-model.jar") {
+      module("jps-model-api")
+      module("jps-model-impl")
+      module("jps-model-serialization")
+    }
+    jar("jps-builders.jar") {
+      module("forms_rt")
+      module("forms-compiler")
+      module("instrumentation-util")
+      module("jps-builders")
+      module("jps-standalone-builder")
+      module("java-runtime")
+    }
+    jar("groovy-jps-plugin.jar") {
+      module("groovy-jps-plugin")
+      module("groovy-rt-constants")
+    }
+    jar("groovy_rt.jar") {
+      module("groovy_rt")
+    }
+    jar("ui-designer-jps-plugin.jar") {
+      module("ui-designer-jps-plugin")
+    }
+    fileset(dir: "$home/lib") {
+      include(name: "jdom.jar")
+      include(name: "jna.jar")
+      include(name: "trove4j.jar")
+      include(name: "asm4-all.jar")
+      include(name: "nanoxml-*.jar")
+      include(name: "protobuf-*.jar")
+      include(name: "optimizedFileManager.jar")
+      include(name: "log4j.jar")
+      include(name: "jgoodies-forms.jar")
+    }
+    dir("test") {
+      jar("jps-build-test.jar") {
+        moduleTests("jps-builders")
+        moduleTests("jps-model-impl")
+        moduleTests("jps-model-serialization")
+      }
+    }
+  }
+}
+
+def layout_core(String home, String target) {
+  layout(target) {
+    jar("intellij-core.jar") {
+      module("util-rt")
+      module("util")
+      module("core-api")
+      module("core-impl")
+      module("boot")
+      module("extensions")
+      module("java-psi-api")
+      module("java-psi-impl")
+    }
+
+    jar("annotations.jar") {
+      module("annotations")
+    }
+
+    fileset(dir: "$home/lib") {
+      include(name: "guava-12.0.jar")
+      include(name: "picocontainer.jar")
+      include(name: "trove4j.jar")
+      include(name: "asm.jar")
+      include(name: "asm-commons.jar")
+      include(name: "cli-parser-1.1.jar")
+    }
+  }
+}
+
+def layout_core_upsource(String home, String target) {
+  layout(target) {
+    jar("intellij-core-upsource.jar") {
+      module("util-rt")
+      module("util")
+      module("icons")
+      module("core-api")
+      module("core-impl")
+      module("boot")
+      module("extensions")
+      module("indexing-api")
+      module("indexing-impl")
+      module("java-psi-api")
+      module("java-psi-impl")
+      module("projectModel-api")
+      module("projectModel-impl")
+      module("jps-model-api")
+      module("jps-model-impl")
+      module("jps-model-serialization")
+      module("java-indexing-api")
+      module("java-indexing-impl")
+      module("platform-resources")
+      module("platform-resources-en")
+    }
+
+    jar("annotations.jar") {
+      module("annotations")
+    }
+
+    fileset(dir: "$home/lib") {
+      include(name: "guava-12.0.jar")
+      include(name: "picocontainer.jar")
+      include(name: "trove4j.jar")
+      include(name: "asm.jar")
+      include(name: "asm-commons.jar")
+      include(name: "asm4-all.jar")
+      include(name: "cli-parser-1.1.jar")
+      include(name: "jna.jar")
+      include(name: "log4j.jar")
+      include(name: "xstream-1.4.3.jar")
+      include(name: "xpp3-1.1.4-min.jar")
+      include(name: "jdom.jar")
+    }
+  }
+}
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
new file mode 100644
index 0000000..53caf65
--- /dev/null
+++ b/build/scripts/libLicenses.gant
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.jetbrains.jps.ClasspathKind
+import org.jetbrains.jps.Library
+import org.jetbrains.jps.Module
+
+class LibraryLicense {
+  String name, url, version
+  List<String> libraryNames
+  String license, licenseUrl
+  String attachedTo
+}
+
+List<LibraryLicense> licensesList = []
+List<String> jetbrainsLibraries = []
+Map<String, String> predefinedLicenseUrls = ["Apache 2.0": "http://www.apache.org/licenses/LICENSE-2.0"]
+
+binding.setVariable("libraryLicense", {Map args ->
+  if (args.libraryNames == null) {
+    args.libraryNames = [args.libraryName?:args.name]
+    args.remove("libraryName")
+  }
+  if (args.licenseUrl == null) {
+    args.licenseUrl = predefinedLicenseUrls[args.license]
+  }
+  licensesList << new LibraryLicense(args)
+})
+
+binding.setVariable("jetbrainsLibrary", {String name ->
+  jetbrainsLibraries << name
+})
+
+def String getLibraryName(Library lib) {
+  def name = lib.name
+  if (name.startsWith("moduleLibrary#")) {
+    if (lib.classpath.size() != 1) {
+      projectBuilder.warning("Non-single entry module library $name: $lib.classpath");
+    }
+    String filePath = lib.classpath[0]
+    return filePath.substring(filePath.lastIndexOf('/')+1)
+  }
+  return name
+}
+
+binding.setVariable("checkLibLicenses", {
+  def libraries = new HashSet<Library>()
+  def lib2Module = new HashMap<Library, Module>();
+  allModules().each {Module module ->
+    module.getClasspath(ClasspathKind.PRODUCTION_RUNTIME).each {
+      if (it instanceof Library) {
+        lib2Module[it] = module
+        libraries << it
+      }
+    }
+  }
+
+  def libWithLicenses = licensesList.collectAll {it.libraryNames}.flatten() as Set
+  libWithLicenses.addAll(jetbrainsLibraries)
+
+  List<String> withoutLicenses = []
+  libraries.each {Library lib ->
+    def name = getLibraryName(lib)
+    if (!libWithLicenses.contains(name)) {
+      withoutLicenses << "$name (used in module ${lib2Module[lib].name})".toString()
+    }
+  }
+
+  if (!withoutLicenses.isEmpty()) {
+    def errorMessage = []
+    errorMessage << "Licenses aren't specified for ${withoutLicenses.size()} libraries:"
+    withoutLicenses.sort(String.CASE_INSENSITIVE_ORDER)
+    withoutLicenses.each { errorMessage << it}
+    errorMessage << "If a library is packaged into IDEA installation information about its license must be added to libLicenses.gant file"
+    errorMessage << "If a library is used in tests only change its scope to 'Test'"
+    errorMessage << "If a library is used for compilation only change its scope to 'Provided'"
+    projectBuilder.error(errorMessage.join("\n"))
+  }
+});
+
+binding.setVariable("generateLicensesTable", {String filePath, Set<String> usedModulesNames ->
+  projectBuilder.info("Generating licenses table")
+  projectBuilder.info("Used modules: $usedModulesNames")
+  Set<Module> usedModules = allModules().findAll {usedModulesNames.contains(it.name)}
+  Map<String, String> usedLibraries = [:]
+  usedModules.each {Module module ->
+    module.getClasspath(ClasspathKind.PRODUCTION_RUNTIME).each {item ->
+      if (item instanceof Library) {
+        usedLibraries[getLibraryName(item)] = module.name
+      }
+    }
+  }
+
+  Map<LibraryLicense, String> licenses = [:]
+  licensesList.each {LibraryLicense lib ->
+    if (usedModulesNames.contains(lib.attachedTo)) {
+      licenses[lib] = lib.attachedTo
+    }
+    else {
+      lib.libraryNames.each {
+        String module = usedLibraries[it]
+        if (module != null) {
+          licenses[lib] = module
+        }
+      }
+    }
+  }
+
+  projectBuilder.info("Used libraries:")
+  List<String> lines = []
+  licenses.entrySet().each {
+    LibraryLicense lib = it.key
+    String moduleName = it.value
+    def name = lib.url != null ? "[$lib.name|$lib.url]" : lib.name
+    def license = lib.licenseUrl != null ? "[$lib.license|$lib.licenseUrl]" : lib.license
+    projectBuilder.info(" $lib.name (in module $moduleName)")
+    lines << "|$name| ${lib.version?:""}|$license|".toString()
+  }
+  //projectBuilder.info("Unused libraries:")
+  //licensesList.findAll {!licenses.containsKey(it)}.each {LibraryLicense lib ->
+  //  projectBuilder.info(" $lib.name")
+  //}
+
+  lines.sort(String.CASE_INSENSITIVE_ORDER)
+  File file = new File(filePath)
+  file.parentFile.mkdirs()
+  FileWriter out = new FileWriter(file)
+  try {
+    out.println("|| Software || Version || License ||")
+    lines.each {
+      out.println(it)
+    }
+  }
+  finally {
+    out.close()
+  }
+  notifyArtifactBuilt(filePath)
+})
+
+libraryLicense(name: "Alloy L&F", libraryName: "alloy.jar", version: "1.4.4", license: "link (company license)", url: "http://www.incors.com/lookandfeel/", licenseUrl: "http://lookandfeel.incors.com/display_licence.php?back=purchase.php&selMenu=Purchase")
+libraryLicense(name: "Ant", version: "1.7", license: "Apache 2.0", url: "http://ant.apache.org/", licenseUrl: "http://ant.apache.org/license.html")
+libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
+libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm4", version: "4.0", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
+libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/axis.LICENSE")
+libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html")
+libraryLicense(name: "classworlds", libraryName: "classworlds-1.1.jar", version: "1.1", license: "codehaus", url: "http://classworlds.codehaus.org/", licenseUrl: "http://classworlds.codehaus.org/license.html")
+libraryLicense(name: "Android SDK Tools", libraryName: "android-sdk-tools", license: "Apache 2.0", url: "http://source.android.com/")
+libraryLicense(name: "Android SDK Tools JPS", libraryName: "android-sdk-tools-jps", license: "Apache 2.0", url: "http://source.android.com/")
+libraryLicense(name: "Apache Commons BeanUtils", libraryName: "commons-beanutils.jar", version: "1.6", license: "Apache 2.0", url: "http://commons.apache.org/beanutils/")
+libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html")
+libraryLicense(name: "Apache Commons Discovery", libraryName: "commons-discovery-0.4.jar", version: "0.4", license: "Apache 2.0", url: "http://jakarta.apache.org/commons/discovery/", licenseUrl: "http://commons.apache.org/license.html")
+libraryLicense(name: "Apache Commons HTTPClient", libraryName: "http-client-3.1", version: "3.1&nbsp; (with patch by JetBrains)", license: "Apache 2.0", url: "http://hc.apache.org/httpclient-3.x")
+libraryLicense(name: "Apache Commons Net", libraryName: "commons-net", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/net/")
+libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/")
+libraryLicense(name: "Apache Lucene", libraryName: "lucene-core-2.4.1.jar", version: "2.4.1", license: "Apache 2.0", url: "http://lucene.apache.org/java")
+libraryLicense(name: "Apache Sanselan", libraryName: "Sanselan", version: "0.98", license: "Apache 2.0", url: "http://commons.apache.org/sanselan/")
+libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", license: "BSD", url: "http://www.brics.dk/automaton/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
+libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http://sourceforge.net/projects/dtdparser/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1")
+libraryLicense(name: "Ganymed", version: "bundled with SVNKit", libraryName: "svnkit.jar", license: "BSD", url: "http://www.ganymed.ethz.ch/ssh2/", licenseUrl: "http://www.ganymed.ethz.ch/ssh2/LICENSE.txt")
+libraryLicense(name: "sqljet", version: "bundled with SVNKit", libraryName: "sqljet.jar", license: "link (commercial license)", url: "http://sqljet.com", licenseUrl: "http://svnkit.com/license.html")
+libraryLicense(name: "svnkit-javahl", version: "bundled with SVNKit", libraryName: "svnkit-javahl.jar", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html")
+libraryLicense(name: "javahl", version: "1.7.2", libraryName: "javahl.jar", license: "Apache", url: "http://subversion.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Apache Commons HTTPClient", libraryName: "httpclient-4.1.1.jar", version:"4.1.1", license: "Apache 2.0",
+               url: "http://hc.apache.org/httpcomponents-client-ga/index.html", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Apache Commons HTTPCore", libraryName: "httpcore-4.1.jar", version: "4.1", license: "Apache 2.0",
+               url: "http://hc.apache.org/httpcomponents-core-ga/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Antlr", libraryName: "antlr.jar", version: "3.1.3", license: "BSD", url: "http://www.antlr.org",
+               licenseUrl: "http://www.antlr.org/license.html")
+libraryLicense(name: "Guava", version: "12.0", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html")
+libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/")
+libraryLicense(name: "Gson", libraryName: "gson", license: "Apache 2.0", url: "http://code.google.com/p/google-gson/")
+libraryLicense(name: "ini4j", libraryName: "ini4j-0.5.2-patched", version: "0.5.2 (with a patch by JetBrains)", license: "Apache 2.0", url: "http://ini4j.sourceforge.net/", attachedTo: "git4idea")
+libraryLicense(name: "ISO RELAX", libraryName: "isorelax.jar", license: "MIT License", url: "http://sourceforge.net/projects/iso-relax/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
+libraryLicense(name: "JavaCVS", attachedTo: "javacvs-src", version: "no version number available (with patches by JetBrains)", license: "Sun Public License", url: "http://javacvs.netbeans.org/library/", licenseUrl: "http://www.netbeans.org/about/legal/spl.html")
+libraryLicense(name: "JAXB", libraryName: "JAXB", version: "2.2.4-1", license: "CDDL 1.1", url: "http://jaxb.java.net/", licenseUrl: "http://glassfish.java.net/public/CDDL+GPL_1_1.html")
+libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "http://www.jaxen.org/", licenseUrl: "http://www.jaxen.org/license.html")
+libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/")
+libraryLicense(name: "JCIP Annotations", libraryName: "jcip", license: "Creative Commons Attribution License", url: "http://www.jcip.net", licenseUrl: "http://creativecommons.org/licenses/by/2.5")
+libraryLicense(name: "JDOM", version: "1.1 (with patches by JetBrains)", license: "modified Apache", url: "http://www.jdom.org/", licenseUrl: "http://www.jdom.org/docs/faq.html#a0030")
+libraryLicense(name: "jgit-2.1.0", version: "2.1.0.201209190230", license: "EDL/BSD", url: "http://www.eclipse.org/jgit/", licenseUrl: "http://www.eclipse.org/org/documents/edl-v10.php", attachedTo: "git4idea")
+libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "1.1-preview 2006-05-04 11:55:37", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
+libraryLicense(name: "JGoodies Looks", libraryName: "jgoodies-looks", version: "2.4.2", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
+libraryLicense(name: "JGoodies Common", libraryName: "jgoodies-common", version: "1.2.1", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
+libraryLicense(name: "JNA", libraryName: "jna", version: "3.4.0", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
+libraryLicense(name: "JSch", libraryName: "JSch", version: "0.1.44", license: "BSD", url: "http://www.jcraft.com/jsch/", licenseUrl: "http://www.jcraft.com/jsch/LICENSE.txt")
+libraryLicense(name: "JUnit", libraryName: "JUnit3", version: "3.8.1", license: "CPL 1.0", url: "http://junit.org/")
+libraryLicense(name: "JUnit", libraryName: "JUnit4", version: "4.8", license: "CPL 1.0", url: "http://junit.org/")
+libraryLicense(name: "Log4j", libraryName: "Log4J", version: "1.2", license: "Apache 2.0", url: "http://logging.apache.org/log4j/1.2/index.html", licenseUrl: "http://logging.apache.org/license.html")
+libraryLicense(name: "Maven", version: "2.2.1", license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
+libraryLicense(name: "Maven3", libraryNames: ["Maven3", "maven-dependency-tree-1.2.jar", "archetype-catalog-2.2.jar", "archetype-common-2.2.jar"], version: "3.0.3", license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
+libraryLicense(name: "Gradle", version: "1.3", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
+libraryLicense(name: "Slf4j", version: "1.6.6", license: "MIT License", url: "http://slf4j.org/", licenseUrl: "http://slf4j.org/license.html")
+libraryLicense(name: "GradleGuava", version: "11.0.2", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Jsr305", version: "1.3.9", license: "New BSD", url: "http://code.google.com/p/jsr-305/", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
+libraryLicense(name: "markdownj", attachedTo: "tasks-core", version: "", license: "BSD", url: "http://markdownj.org/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
+libraryLicense(name: "mercurial_prompthooks", attachedTo: "hg4idea", version: "", license: "GPLv2 (used as hg extension called from hg executable)", url: "https://github.com/willemv/mercurial_prompthooks", licenseUrl: "https://github.com/willemv/mercurial_prompthooks/blob/master/LICENSE.txt")
+libraryLicense(name: "Microba", libraryName: "microba", version: "0.4.2", license: "BSD", url: "http://microba.sourceforge.net/", licenseUrl: "http://microba.sourceforge.net/license.txt")
+libraryLicense(name: "MigLayout", libraryName: "miglayout-swing", version: "3.7.1", license: "BSD", url: "http://www.miglayout.com/", licenseUrl: "http://www.miglayout.com/mavensite/license.html")
+libraryLicense(name: "NanoXML", version: "2.2.3", license: "zlib/libpng", url: "http://nanoxml.cyberelf.be/", licenseUrl: "http://devkix.com/nanoxml.php")
+libraryLicense(name: "nekohtml", libraryName: "nekohtml", version: "1.9.14", license: "Apache 2.0", url: "http://nekohtml.sourceforge.net/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0.txt")
+libraryLicense(name: "Eclipse JDT Core", libraryName: "Eclipse", version: "4.2", license: "CPL 1.0", url: "http://www.eclipse.org/jdt/core/index.php")
+libraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache", url: "http://jakarta.apache.org/oro/", licenseUrl: "http://svn.apache.org/repos/asf/jakarta/oro/trunk/LICENSE")
+libraryLicense(name: "PicoContainer", libraryName: "picocontainer", version: "1.2", license: "BSD", url: "http://www.picocontainer.org/", licenseUrl: "http://docs.codehaus.org/display/PICO/License")
+libraryLicense(name: "Plexus Utils", libraryName: "plexus-utils-1.5.5.jar", version: "1.5.5", license: "Apache 2.0", url: "http://plexus.codehaus.org/plexus-utils")
+libraryLicense(name: "Relax NG Object Model", libraryName: "rngom-20051226-patched.jar", license: "MIT", url: "http://java.net/projects/rngom/", licenseUrl: "http://www.opensource.org/licenses/mit-license.php")
+libraryLicense(name: "RMI Stubs", attachedTo: "xslt-debugger-engine", license: "Apache 2.0", url: "http://confluence.jetbrains.net/display/CONTEST/XSLT-Debugger", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Saxon-9HE", version: "9", license: "Mozilla Public License", url: "http://saxon.sourceforge.net/", licenseUrl: "http://www.mozilla.org/MPL/")
+libraryLicense(name: "Saxon-6.5.5", version: "6.5.5", license: "Mozilla Public License", url: "http://saxon.sourceforge.net/", licenseUrl: "http://www.mozilla.org/MPL/")
+libraryLicense(name: "Sonatype Nexus: Indexer", libraryName: "nexus-indexer-1.2.3.jar", version: "1.2.3", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
+libraryLicense(name: "Sonatype Nexus: Indexer", libraryName: "nexus-indexer-3.0.4.jar", version: "3.0.4", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
+libraryLicense(name: "Sonatype Nexus Indexer Artifact", libraryName: "nexus-indexer-artifact-1.0.1.jar", version: "1.0.1", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
+libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "SVN version, 1.1 branch as of 1 Oct 2007", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html")
+libraryLicense(name: "Sequence", libraryName: "sequence-library.jar", version: "bundled with SVNKit", license: "", url:"http://www.syntevo.com", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/svn4idea/lib/SEQUENCE-LICENSE")
+libraryLicense(name: "swingx", libraryName: "swingx", version: "1.6.2", license: "LGPL 2.1", url: "http://java.net/downloads/swingx/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
+libraryLicense(name: "TestNG", version: "5.7 snapshot", license: "Apache 2.0", url: "http://testng.org/doc/", licenseUrl: "http://code.google.com/p/testng/")
+libraryLicense(name: "Trilead SSH", libraryName: "trilead-ssh2", version: "build 213", license: "BSD style (see LICENSE.txt in trilead.jar)", url: "http://www.trilead.com/SSH_Library/")
+libraryLicense(name: "Trove4j", version: "1.1 (with patches by JetBrains)", license: "LGPL", url: "http://trove4j.sourceforge.net/", licenseUrl: "http://trove4j.sourceforge.net/html/license.html")
+libraryLicense(name: "Velocity", version: "1.7", license: "Apache 2.0", url: "http://velocity.apache.org/", licenseUrl: "http://velocity.apache.org/index.html")
+libraryLicense(name: "winp", version: "1.16 (patched)", license: "MIT", url: "http://winp.dev.java.net/", licenseUrl: "https://winp.dev.java.net/license.html")
+libraryLicense(name: "Xalan", libraryName:"Xalan-2.7.1", version: "2.7.1", license: "Apache 2.0", url: "http://xml.apache.org/xalan-j/", licenseUrl: "http://xml.apache.org/xalan-j/")
+libraryLicense(name: "Xerces", version: "2.9.1", license: "Apache 2.0", url: "http://xerces.apache.org/xerces2-j/", licenseUrl: "http://xerces.apache.org/xerces2-j/")
+libraryLicense(name: "XML Commons (xml-apis.jar, resolver.jar)", version: "", license: "Apache 2.0, W3C Software License , public domain", url: "http://xml.apache.org/commons/", licenseUrl: "http://xml.apache.org/commons/licenses.html")
+libraryLicense(name: "XMLBeans", libraryName: "XmlBeans", version: "2.3.0", license: "Apache 2.0", url: "http://xmlbeans.apache.org/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/xmlbeans-2.3.0/xmlbeans.LICENSE")
+libraryLicense(name: "XML-RPC", libraryName: "XmlRPC", version: "2.0", license: "Apache 2.0", url: "http://ws.apache.org/xmlrpc/xmlrpc2/", licenseUrl: "http://ws.apache.org/xmlrpc/xmlrpc2/license.html")
+libraryLicense(name: "XStream", version: "1.4.3", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
+libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
+libraryLicense(name: "protobuf", version: "2.3.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
+libraryLicense(name: "Netty", libraryName: "Netty", version: "3.5.10", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Kryo", libraryName: "Kryo", version: "1.04", license: "New BSD License", url: "http://code.google.com/p/kryo/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
+libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "1.0.4.1", license: "Apache 2.0", url: "http://code.google.com/p/snappy-java/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
+libraryLicense(name: "Cucumber-JVM", libraryName: "cucumber-jvm", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
+libraryLicense(name: "Cucumber-Groovy", libraryName: "cucumber-groovy", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
+libraryLicense(name: "proxy-vole", libraryName: "proxy-vole", version: "20120920", license: "New BSD License", url: "http://code.google.com/p/proxy-vole/", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
+libraryLicense(name: "Rhino JavaScript Engine", libraryName: "rhino-js-1_7R4", version: "1.7R4", license: "MPL 1.1", url: "http://www.mozilla.org/rhino/", licenseUrl: "http://www.mozilla.org/MPL/MPL-1.1.html")
+libraryLicense(name: "asm-4.0-all", libraryName: "asm-4.0-all", version: "4.0", attachedTo: "ByteCodeViewer", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
+jetbrainsLibrary("JPS")
+jetbrainsLibrary("Maven Embedder")
+jetbrainsLibrary("tcServiceMessages")
+jetbrainsLibrary("optimizedFileManager.jar")
diff --git a/build/scripts/scripts.gdsl b/build/scripts/scripts.gdsl
new file mode 100644
index 0000000..5d8b8a0
--- /dev/null
+++ b/build/scripts/scripts.gdsl
@@ -0,0 +1,10 @@
+def ctx = context(scope: scriptScope(), filetypes : ["gant"])
+
+contributor ([ctx], {
+  method name:"loadProject", type:"void", params:[:]
+  method name:"isDefined", type:"boolean", params:[key:"String"]
+  method name:"requireProperty", type:"String", params:[key:"String"]
+  method name:"requireProperty", type:"String", params:[key:"String", defaultValue:"String"]
+  method name:"printUnusedModules", type:"void", params:[usedModules:"java.util.Set<String>"]
+  method name:"notifyArtifactBuilt", type:"void", params:[artifactPath:"String"]
+})
\ No newline at end of file
diff --git a/build/scripts/tests.gant b/build/scripts/tests.gant
new file mode 100644
index 0000000..9fc565e
--- /dev/null
+++ b/build/scripts/tests.gant
@@ -0,0 +1,14 @@
+import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
+
+includeTargets << new File("${guessHome(this)}/build/scripts/common_tests.gant")
+
+setProperty("testcases", ["com.intellij.AllTests"])
+
+def isMac = System.getProperty("os.name").toLowerCase().startsWith("mac")
+def args = [
+        "-Xmx450m",
+        "-XX:MaxPermSize=430m",
+]
+if (isMac) args << "-d32";
+
+setProperty("jvm_args", args)
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
new file mode 100644
index 0000000..f8b8f7f
--- /dev/null
+++ b/build/scripts/utils.gant
@@ -0,0 +1,699 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.jetbrains.jps.Jps
+import org.jetbrains.jps.Module
+import org.jetbrains.jps.idea.IdeaProjectLoader
+
+includeTool << Jps
+
+binding.setVariable("p", {String key ->
+  return getProperty(key) as String
+})
+
+binding.setVariable("guessJdk", {
+  String javaHome = p("java.home")
+
+  if (new File(javaHome).getName() == "jre") {
+    javaHome = new File(javaHome).getParent()
+  }
+
+  return javaHome
+})
+
+binding.setVariable("includeFile", {String filePath ->
+  Script s = groovyShell.parse(new File(filePath))
+  s.setBinding(binding)
+  s
+})
+
+binding.setVariable("isMac", {
+  return System.getProperty("os.name").toLowerCase().startsWith("mac")
+})
+
+binding.setVariable("isWin", {
+  return System.getProperty("os.name").toLowerCase().startsWith("windows")
+})
+
+binding.setVariable("isEap", {
+  return "true" == p("component.version.eap")
+})
+
+binding.setVariable("mem32", "-Xms128m -Xmx512m -XX:MaxPermSize=250m -XX:ReservedCodeCacheSize=64m -XX:+UseCodeCacheFlushing")
+binding.setVariable("mem64", "-Xms128m -Xmx800m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=64m -XX:+UseCodeCacheFlushing")
+binding.setVariable("common_vmoptions", "-ea -Dsun.io.useCanonCaches=false")
+
+binding.setVariable("vmOptions", { "$common_vmoptions ${isEap() ? '-XX:+HeapDumpOnOutOfMemoryError' : ''}".trim() })
+binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() })
+binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() })
+binding.setVariable("vmOptions32yjp", { String systemSelector ->
+  "${vmOptions32()} -agentlib:yjpagent=disablej2ee,disablealloc,onlylocal,sessionname=$systemSelector".trim()
+})
+binding.setVariable("vmOptions64yjp", { String systemSelector ->
+  "${vmOptions64()} -agentlib:yjpagent64=disablej2ee,disablealloc,onlylocal,sessionname=$systemSelector".trim()
+})
+
+binding.setVariable("isDefined", {String key ->
+  try {
+    this[key]
+    return true
+  }
+  catch (MissingPropertyException ignored) {
+    return false
+  }
+})
+
+private String require(String key) {
+  try {
+    this[key]
+  }
+  catch (MissingPropertyException ignored) {
+    projectBuilder.error("Property $key is required")
+  }
+}
+
+private String require(String key, String defaultValue) {
+  try {
+    this[key]
+  }
+  catch (MissingPropertyException ignored) {
+    projectBuilder.info("$key is not defined. Defaulting to $defaultValue")
+    this[key] = defaultValue
+  }
+}
+
+binding.setVariable("requireProperty", {String key, String defaultValue = null ->
+  if (defaultValue == null) {
+    require(key)
+  }
+  else {
+    require(key, defaultValue)
+  }
+})
+
+binding.setVariable("guessHome", {
+  // Current file is supposed to be at build/scripts/release.gant path
+  new File(requireProperty("gant.file").substring("file:".length())).getParentFile().getParentFile().getParent()
+})
+
+binding.setVariable("loadProject", {
+  requireProperty("jdkHome", guessJdk())
+  def mac = isMac()
+  jdk("IDEA jdk", jdkHome) {
+    if (!mac) {
+      classpath "$jdkHome/lib/tools.jar"
+    }
+  }
+  IdeaProjectLoader.loadFromPath(project, "${home}")
+})
+
+boolean hasSourceRoots(Module module) {
+  return !module.sourceRoots.isEmpty()
+}
+
+binding.setVariable("findModule", {String name ->
+  project.modules[name]
+})
+
+binding.setVariable("allModules", {
+  return project.modules.values()
+})
+
+binding.setVariable("printUnusedModules", {Set<String> usedModules ->
+  allModules().each {Module m ->
+    if (!usedModules.contains(m.name) && hasSourceRoots(m)) {
+      projectBuilder.warning("Module $m.name is not used in project layout")
+    }
+  }
+})
+
+requireProperty("home", guessHome())
+
+String readSnapshotBuild() {
+  def file = new File("$home/community/build.txt")
+  if (!file.exists()) {
+    file = new File("$home/build.txt")
+  }
+
+  return file.readLines().get(0)
+}
+
+binding.setVariable("snapshot", readSnapshotBuild())
+
+projectBuilder.buildInfoPrinter = new org.jetbrains.jps.teamcity.TeamcityBuildInfoPrinter()
+projectBuilder.compressJars = false
+
+binding.setVariable("notifyArtifactBuilt", { String artifactPath ->
+  if (!artifactPath.startsWith(home)) {
+    projectBuilder.error("Artifact path $artifactPath should start with $home")
+  }
+  def relativePath = artifactPath.substring(home.length())
+  if (relativePath.startsWith("/")) {
+    relativePath = relativePath.substring(1)
+  }
+  def file = new File(artifactPath)
+  if (file.isDirectory()) {
+    relativePath += "=>" + file.name
+  }
+  projectBuilder.info("##teamcity[publishArtifacts '$relativePath']")
+})
+
+def suspendUntilDebuggerConnect = System.getProperty("debug.suspend") ?: "n"
+def debugPort = System.getProperty("debug.port") ?: 5555
+if (suspendUntilDebuggerConnect == 'y') {
+  println """\
+------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<----
+-------------------------------------------^------^------^------^------^------^------^-----------------------  
+"""
+}
+
+binding.setVariable("patchFiles", { List files, Map args, String marker = "__" ->
+  files.each { file ->
+    args.each { arg ->
+      ant.replace(file: file, token: "${marker}${arg.key}${marker}", value:  arg.value)
+    }
+  }
+})
+
+binding.setVariable("copyAndPatchFile", { String file, String target, Map args, String marker = "__" ->
+  ant.copy(file: file, tofile: target, overwrite: "true") {
+    filterset(begintoken: marker, endtoken: marker) {
+      args.each {
+        filter(token: it.key, value: it.value)
+      }
+    }
+  }
+})
+
+binding.setVariable("copyAndPatchFiles", { Closure files, String target, Map args, String marker = "__" ->
+  ant.copy(todir: target, overwrite: "true") {
+    files()
+
+    filterset(begintoken: marker, endtoken: marker) {
+      args.each {
+        filter(token: it.key, value: it.value)
+      }
+    }
+  }
+})
+
+binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
+  ant.tstamp()
+  patchFiles([appInfoFile], ["BUILD_NUMBER": buildNumber, "BUILD_DATE": DSTAMP])
+})
+
+binding.setVariable("commonJvmArgs", {
+  return [
+   "-ea",
+   "-Didea.home.path=$home",
+   "-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
+   "-XX:+HeapDumpOnOutOfMemoryError",
+   "-Didea.system.path=${p("teamcity.build.tempDir")}/system",
+   "-Didea.config.path=${p("teamcity.build.tempDir")}/config",
+   "-Xdebug",
+   "-Xrunjdwp:transport=dt_socket,server=y,suspend=$suspendUntilDebuggerConnect,address=$debugPort"]
+})
+
+binding.setVariable("classPathLibs", [
+        "bootstrap.jar",
+        "extensions.jar",
+        "util.jar",
+        "jdom.jar",
+        "log4j.jar",
+        "trove4j.jar",
+        "jna.jar"
+])
+
+binding.setVariable("platformApiModules", [
+        "core-api",
+        "indexing-api",
+        "projectModel-api",
+        "jps-model-api",
+        "platform-api",
+        "lvcs-api",
+        "lang-api",
+        "vcs-api",
+        "usageView",
+        "xdebugger-api",
+        "xml-openapi",
+])
+
+
+binding.setVariable("platformImplementationModules", [
+        "core-impl",
+        "indexing-impl",
+        "jps-model-impl",
+        "jps-model-serialization",
+        "projectModel-impl",
+        "platform-impl",
+        "vcs-impl",
+        "lang-impl",
+        "testRunner",
+        "smRunner",
+        "xdebugger-impl",
+        "xml",
+        "relaxng",
+        "lvcs-impl",
+        "spellchecker",
+        "images",
+        "RegExpSupport",
+        "dvcs"
+])
+
+binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
+  ant.copy(todir: "$path/bin") {
+    fileset(dir: "$ch/bin/mac")
+  }
+
+  ant.copy(todir: path) {
+    fileset(dir: "$ch/build/conf/mac")
+  }
+
+  ant.tstamp() {
+    format(property: "todayYear", pattern: "yyyy")
+  }
+
+  String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase()
+  String helpId = args.help_id != null ? args.help_id : "IJ"
+  String icns = "idea.icns"
+  String helpIcns = "$path/Contents/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
+  if (args.icns != null) {
+    ant.delete(file: "$path/Contents/Resources/idea.icns")
+    ant.copy(file: args.icns, todir: "$path/Contents/Resources")
+    ant.copy(file: args.icns, tofile: helpIcns)
+    icns = new File((String)args.icns).getName();
+  } else {
+    ant.copy(file: "$path/Contents/Resources/idea.icns", tofile: helpIcns)
+  }
+
+  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
+
+  String vmOptions = "${vmOptions()} -Xverify:none"
+  if (isEap() && !args.mac_no_yjp) {
+    vmOptions += " -agentlib:yjpagent=disablej2ee,disablealloc,sessionname=${args.system_selector}"
+  }
+
+  String minor = p("component.version.minor")
+  String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"
+
+  Map properties = readIdeaProperties(args)
+
+  def coreKeys = ["idea.platform.prefix", "idea.paths.selector"]
+
+  String coreProperties = submapToXml(properties, coreKeys);
+
+  StringBuilder effectiveProperties = new StringBuilder()
+  properties.each { k, v ->
+    if (!coreKeys.contains(k)) {
+      effectiveProperties.append("$k=$v\n");
+    }
+  }
+
+  new File("$path/bin/idea.properties").text = effectiveProperties.toString()
+  new File("$path/bin/idea.vmoptions").text = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
+
+  String classPath = classPathLibs.collect {"\$APP_PACKAGE/lib/${it}" }.join(":")
+
+  ant.replace(file: "$path/Contents/Info.plist") {
+    replacefilter(token: "@@build@@", value: args.buildNumber)
+    replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, ""))
+    replacefilter(token: "@@executable@@", value: executable)
+    replacefilter(token: "@@icns@@", value: icns)
+    replacefilter(token: "@@bundle_name@@", value: fullName)
+    replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier)
+    replacefilter(token: "@@year@@", value: "$todayYear")
+    replacefilter(token: "@@version@@", value: version)
+    replacefilter(token: "@@vmoptions@@", value: vmOptions)
+    replacefilter(token: "@@idea_properties@@", value: coreProperties)
+    replacefilter(token: "@@class_path@@", value: classPath)
+    replacefilter(token: "@@help_id@@", value: helpId)
+  }
+
+  if (executable != "idea") {
+    ant.move(file: "$path/Contents/MacOS/idea", tofile: "$path/Contents/MacOS/$executable")
+  }
+
+  ant.replace(file: "$path/bin/inspect.sh") {
+    replacefilter(token: "@@product_full@@", value: fullName)
+    replacefilter(token: "@@script_name@@", value: executable)
+  }
+  if (args.inspect_script != null && args.inspect_script != "inspect") {
+    ant.move(file: "$path/bin/inspect.sh", tofile: "$path/bin/${args.inspect_script}.sh")
+  }
+})
+
+binding.setVariable("winScripts", { String target, String home, String name, Map args ->
+  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
+  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
+  String vm_options = args.vm_options != null ? args.vm_options : "${p("component.names.product").toLowerCase()}.exe"
+  if (vm_options.endsWith(".exe")) {
+    vm_options = vm_options.replace(".exe", "%BITS%.exe")
+  }
+  else {
+    vm_options = vm_options + "%BITS%"
+  }
+
+  String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${classPathLibs[0]}\n"
+  classPath += classPathLibs[1..-1].collect {"SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${it}"}.join("\n")
+  if (args.tools_jar) classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar"
+
+  ant.copy(todir: "$target/bin") {
+    fileset(dir: "$home/bin/scripts/win")
+
+    filterset(begintoken: "@@", endtoken: "@@") {
+      filter(token: "product_full", value: fullName)
+      filter(token: "product_uc", value: product_uc)
+      filter(token: "vm_options", value: vm_options)
+      filter(token: "isEap", value: isEap())
+      filter(token: "system_selector", value: args.system_selector)
+      filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
+      filter(token: "class_path", value: classPath)
+      filter(token: "script_name", value: name)
+    }
+  }
+
+  if (name != "idea.bat") {
+    ant.move(file: "$target/bin/idea.bat", tofile: "$target/bin/$name")
+  }
+  if (args.inspect_script != null && args.inspect_script != "inspect") {
+    ant.move(file: "$target/bin/inspect.bat", tofile: "$target/bin/${args.inspect_script}.bat")
+  }
+
+  ant.fixcrlf(srcdir: "$target/bin", includes: "*.bat", eol: "dos")
+})
+
+private ifNull(v, defVal) { v != null ? v : defVal }
+
+binding.setVariable("unixScripts", { String target, String home, String name, Map args ->
+  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
+  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
+  String vm_options = args.vm_options != null ? args.vm_options : p("component.names.product").toLowerCase()
+
+  String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${classPathLibs[0]}\"\n"
+  classPath += classPathLibs[1..-1].collect {"CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\""}.join("\n")
+  if (args.tools_jar) classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\""
+
+  ant.copy(todir: "$target/bin") {
+    fileset(dir: "$home/bin/scripts/unix")
+
+    filterset(begintoken: "@@", endtoken: "@@") {
+      filter(token: "product_full", value: fullName)
+      filter(token: "product_uc", value: product_uc)
+      filter(token: "vm_options", value: vm_options)
+      filter(token: "isEap", value: isEap())
+      filter(token: "system_selector", value: args.system_selector)
+      filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
+      filter(token: "class_path", value: classPath)
+      filter(token: "script_name", value: name)
+    }
+  }
+
+  if (name != "idea.sh") {
+    ant.move(file: "$target/bin/idea.sh", tofile: "$target/bin/$name")
+  }
+  if (args.inspect_script != null && args.inspect_script != "inspect") {
+    ant.move(file: "$target/bin/inspect.sh", tofile: "$target/bin/${args.inspect_script}.sh")
+  }
+
+  ant.fixcrlf(srcdir: "$target/bin", includes: "*.sh", eol: "unix")
+})
+
+binding.setVariable("winVMOptions", { String target, String system_selector, String name, String name64 = null ->
+  def options = isEap() && system_selector != null ? vmOptions32yjp(system_selector) : vmOptions32()
+  ant.echo(file: "$target/bin/${name}.vmoptions", message: options.replace(' ', '\n'))
+
+  if (name64 != null) {
+    options = isEap() && system_selector != null ? vmOptions64yjp(system_selector) : vmOptions64()
+    ant.echo(file: "$target/bin/${name64}.vmoptions", message: options.replace(' ', '\n'))
+  }
+
+  ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "dos")
+})
+
+binding.setVariable("unixVMOptions", { String target, String name ->
+  ant.echo(file: "$target/bin/${name}.vmoptions", message: vmOptions32().replace(' ', '\n'))
+  ant.echo(file: "$target/bin/${name}64.vmoptions", message: vmOptions64().replace(' ', '\n'))
+  ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "unix")
+})
+
+binding.setVariable("unixReadme", { String target, String home, Map args ->
+  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
+  String settings_dir = args.system_selector.replaceFirst("\\d+", "")
+  copyAndPatchFile("$home/build/Install-Linux-tar.txt", "$target/Install-Linux-tar.txt",
+                   ["product_full": fullName,
+                    "product": p("component.names.product").toLowerCase(),
+                    "system_selector": args.system_selector,
+                    "settings_dir": settings_dir], "@@")
+  ant.fixcrlf(file: "$target/bin/Install-Linux-tar.txt", eol: "unix")
+})
+
+binding.setVariable("forceDelete", { String dirPath ->
+  // if wasn't deleted - retry several times
+  attempt = 1
+  while (attempt < 21 && (new File(dirPath).exists())) {
+    if (attempt > 1) {
+      ant.echo "Deleting $dirPath ... (attempt=$attempt)"
+
+      // let's wait a bit and try again - may be help
+      // in some cases on our windows 7 agents
+      sleep(2000)
+    }
+
+    ant.delete(failonerror: false, dir: dirPath)
+
+    attempt++
+  }
+
+  if (new File(dirPath).exists()) {
+    ant.project.log ("Cannot delete directory: $dirPath" )
+    System.exit (1)
+  }
+})
+
+binding.setVariable("patchPropertiesFile", { String target, Map args = [:] ->
+  String file = "$target/bin/idea.properties"
+
+  if (args.appendices != null) {
+    ant.concat(destfile: file, append:  true) {
+      args.appendices.each {
+        fileset(file: it)
+      }
+    }
+  }
+
+  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
+  String settings_dir = args.system_selector.replaceFirst("\\d+", "")
+  ant.replace(file: file) {
+    replacefilter(token: "@@product_uc@@", value: product_uc)
+    replacefilter(token: "@@settings_dir@@", value: settings_dir)
+  }
+
+  String message = (isEap() ? """
+#-----------------------------------------------------------------------
+# Change to 'disabled' if you don't want to receive instant visual notifications
+# about fatal errors that happen to an IDE or plugins installed.
+#-----------------------------------------------------------------------
+idea.fatal.error.notification=enabled
+"""
+                 : """
+#-----------------------------------------------------------------------
+# Change to 'enabled' if you want to receive instant visual notifications
+# about fatal errors that happen to an IDE or plugins installed.
+#-----------------------------------------------------------------------
+idea.fatal.error.notification=disabled
+""")
+  ant.echo(file: file, append: true, message: message)
+})
+
+binding.setVariable("zipSources", { String home, String targetDir ->
+  String sources = "$targetDir/sources.zip"
+  projectBuilder.stage("zip sources to $sources")
+
+  ant.mkdir(dir: targetDir)
+  ant.delete(file: sources)
+  ant.zip(destfile: sources) {
+    fileset(dir: home) {
+      ["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each {
+        include(name: "**/*.$it")
+      }
+      exclude(name: "**/testData/**")
+    }
+  }
+
+  notifyArtifactBuilt(sources)
+})
+
+/**
+ * E.g.
+ *
+ * Load all properties from file:
+ *    readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties")
+ *
+ * Load all properties except "idea.cycle.buffer.size", change "idea.max.intellisense.filesize" to 3000
+ * and enable "idea.is.internal" mode:
+ *    readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties",
+ *                       "idea.properties" : ["idea.max.intellisense.filesize" : 3000,
+ *                                           "idea.cycle.buffer.size" : null,
+ *                                           "idea.is.internal" : true ])
+ * @param args
+ * @return text xml properties description in xml
+ */
+private Map readIdeaProperties(Map args) {
+  String ideaPropertiesPath =  args == null ? null : args.get("idea.properties.path")
+  if (ideaPropertiesPath == null) {
+    return [:]
+  }
+
+  // read idea.properties file
+  Properties ideaProperties = new Properties();
+  FileInputStream ideaPropertiesFile = new FileInputStream(ideaPropertiesPath);
+  ideaProperties.load(ideaPropertiesFile);
+  ideaPropertiesFile.close();
+
+  def defaultProperties = ["CVS_PASSFILE": "~/.cvspass",
+                           "com.apple.mrj.application.live-resize": "false",
+                           "idea.paths.selector": args.system_selector,
+                           "java.endorsed.dirs": "",
+                           "idea.smooth.progress": "false",
+                           "apple.laf.useScreenMenuBar": "true",
+                           "apple.awt.graphics.UseQuartz": "true",
+                           "apple.awt.fullscreencapturealldisplays": "false"]
+  if (args.platform_prefix != null) {
+    defaultProperties.put("idea.platform.prefix", args.platform_prefix)
+  }
+
+  Map properties = defaultProperties
+  def customProperties = args.get("idea.properties")
+  if (customProperties != null) {
+    properties += customProperties
+  }
+
+  properties.each {k, v ->
+    if (v == null) {
+      // if overridden with null - ignore property
+      ideaProperties.remove(k)
+    } else {
+      // if property is overridden in args map - use new value
+      ideaProperties.put(k, v)
+    }
+  }
+
+  return ideaProperties;
+}
+
+private String submapToXml(Map properties, List keys) {
+// generate properties description for Info.plist
+  StringBuilder buff = new StringBuilder()
+
+  keys.each { key ->
+    String value = properties[key]
+    if (value != null) {
+      String string =
+        """
+        <key>$key</key>
+        <string>$value</string>
+"""
+      buff.append(string)
+    }
+  }
+  return buff.toString()
+}
+
+binding.setVariable("buildWinZip", { String zipPath, List paths ->
+  projectBuilder.stage(".win.zip")
+
+  fixIdeaPropertiesEol(paths, "dos")
+
+  ant.zip(zipfile: zipPath) {
+    paths.each {
+      fileset(dir: it)
+    }
+  }
+
+  notifyArtifactBuilt(zipPath)
+})
+
+binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths, String macPath, List extraBins = [] ->
+  projectBuilder.stage(".mac.zip")
+
+  allPaths = paths + [macPath]
+  ant.zip(zipfile: zipPath) {
+    allPaths.each {
+      zipfileset(dir: it, prefix: zipRoot) {
+        exclude(name: "bin/*.sh")
+        exclude(name: "bin/fsnotifier")
+        exclude(name: "bin/relaunch")
+        exclude(name: "Contents/MacOS/*")
+        extraBins.each {
+          exclude(name: it)
+        }
+        exclude(name: "bin/idea.properties")
+      }
+    }
+
+    allPaths.each {
+      zipfileset(dir: it, filemode: "755", prefix: zipRoot) {
+        include(name: "bin/*.sh")
+        include(name: "bin/fsnotifier")
+        include(name: "bin/relaunch")
+        include(name: "Contents/MacOS/*")
+        extraBins.each {
+          include(name: it)
+        }
+      }
+    }
+
+    zipfileset(file: "$macPath/bin/idea.properties", prefix: "$zipRoot/bin")
+  }
+})
+
+binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths ->
+  projectBuilder.stage(".tar.gz")
+
+  fixIdeaPropertiesEol(paths, "unix")
+
+  ant.tar(tarfile: tarPath, longfile: "gnu") {
+    paths.each {
+      tarfileset(dir: it, prefix: tarRoot) {
+        exclude(name: "bin/*.sh")
+        exclude(name: "bin/fsnotifier*")
+        type(type: "file")
+      }
+    }
+
+    paths.each {
+      tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
+        include(name: "bin/*.sh")
+        include(name: "bin/fsnotifier*")
+        type(type: "file")
+      }
+    }
+  }
+
+  String gzPath = "${tarPath}.gz"
+  ant.gzip(src: tarPath, zipfile: gzPath)
+  ant.delete(file: tarPath)
+  notifyArtifactBuilt(gzPath)
+})
+
+private void fixIdeaPropertiesEol(List paths, String eol) {
+  paths.each {
+    String file = "$it/bin/idea.properties"
+    if (new File(file).exists()) {
+      ant.fixcrlf(file: file, eol: eol)
+    }
+  }
+}